I have a problem with camera movement using joystick in Unity. I wrote this code to my joystick
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.EventSystems;
public class VirtualJoystick : MonoBehaviour, IDragHandler, IPointerUpHandler, IPointerDownHandler {
private Image bgImg;
private Image joystickImg;
private Vector2 pos;
private void Start()
{
bgImg = GetComponent<Image>();
joystickImg = transform.GetChild(0).GetComponent<Image>();
}
public virtual void OnDrag(PointerEventData ped)
{
Vector2 pos;
if (RectTransformUtility.ScreenPointToLocalPointInRectangle(bgImg.rectTransform, ped.position, ped.pressEventCamera, out pos))
{
pos.x = (pos.x * 2 + 1) / bgImg.rectTransform.sizeDelta.x;
pos.y = (pos.y * 2 - 1) / bgImg.rectTransform.sizeDelta.y;
pos = (pos.magnitude > 1.0f) ? pos.normalized : pos;
// Move Joystrick IMG
joystickImg.rectTransform.anchoredPosition = new Vector2(pos.x * (bgImg.rectTransform.sizeDelta.x / 3), pos.y * (bgImg.rectTransform.sizeDelta.y / 3));
}
}
public virtual void OnPointerDown(PointerEventData ped)
{
OnDrag(ped);
}
public virtual void OnPointerUp(PointerEventData ped)
{
pos = Vector2.zero;
joystickImg.rectTransform.anchoredPosition = Vector2.zero;
}
public float Horizontal()
{
if (pos.x != 0)
{
return pos.x;
}
else
{
return Input.GetAxis("Horizontal");
}
}
public float Vertical()
{
if (pos.y != 0)
{
return pos.y;
}
else
{
return Input.GetAxis("Vertical");
}
}
}
This code works well and return dynamicly Vector2(x,y). So, now I want to move camera (change position X,Y) using this joystick and these coordinates. Do you have any idea how to do it? Everyones show how to move cube or sphere and nowhere how to translate a camera...
Camera behave like any other game object in the scene
you translate , rotate , scale (will not be shown )
cause it is have Transform component .
This can be easily be done with the Translate function
Camera.main.transform.Translate(pos, Space.World);
You need to also multiply it a number(speed) and Time.deltaTime to make sure the movement is the-same on every devices.
So, this is how the code should look like:
private Vector2 pos;
public float moveSpeed = 100f;
Then, in your OnDrag or Update function:
Vector3 newPos = new Vector3(pos.x * moveSpeed, pos.y * moveSpeed, 0);
newPos *= Time.deltaTime;
Camera.main.transform.Translate(newPos, Space.World);
Related
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class teleporttospawn : MonoBehaviour
{
public GameObject player; /// player
public Transform fps; /// also player
private void OnTriggerEnter(Collider other)
{
Debug.Log("teleport succes.");
fps.transform.position = new Vector3(-3.82f, 1.08f, -1.69f); // DONT WORK
player.transform.position = new Vector3(-3.82f, 1.08f, -1.69f); //DONT WORK
}
}
I have two players in the script above because I tried to move it in two ways but nothing worked
So I tried to set the object to vector3 and try to move the player to the object, so nothing comes out
I need teleport player when he triger the collider. Debug.Log work but transform.position dont work.
Its dosent work from this script -> fpscontroller
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class fpscontroller : MonoBehaviour
{
public float walkingSpeed = 7.5f;
public float runningSpeed = 11.5f;
public float jumpSpeed = 8.0f;
public float gravity = 20.0f;
public Camera playerCamera;
public float lookSpeed = 2.0f;
public float lookXLimit = 45.0f;
CharacterController characterController;
Vector3 moveDirection = Vector3.zero;
float rotationX = 0;
[HideInInspector]
public bool canMove = true;
public GameObject tp;
private void OnTriggerEnter(Collider collision)
{
if (collision.gameObject.CompareTag("tp"))
{
while(transform.position != tp.transform.position)
{
Debug.Log("teleport succes.");
gameObject.transform.position = tp.transform.position;
}
}
}
void Start()
{
transform.position = gameObject.transform.position;
characterController = GetComponent<CharacterController>();
// Lock cursor
Cursor.lockState = CursorLockMode.Locked;
Cursor.visible = false;
}
void Update()
{
// We are grounded, so recalculate move direction based on axes
Vector3 forward = transform.TransformDirection(Vector3.forward);
Vector3 right = transform.TransformDirection(Vector3.right);
// Press Left Shift to run
bool isRunning = Input.GetKey(KeyCode.LeftShift);
float curSpeedX = canMove ? (isRunning ? runningSpeed : walkingSpeed) * Input.GetAxis("Vertical") : 0;
float curSpeedY = canMove ? (isRunning ? runningSpeed : walkingSpeed) * Input.GetAxis("Horizontal") : 0;
float movementDirectionY = moveDirection.y;
moveDirection = (forward * curSpeedX) + (right * curSpeedY);
if (Input.GetButton("Jump") && canMove && characterController.isGrounded)
{
moveDirection.y = jumpSpeed;
}
else
{
moveDirection.y = movementDirectionY;
}
// Apply gravity. Gravity is multiplied by deltaTime twice (once here, and once below
// when the moveDirection is multiplied by deltaTime). This is because gravity should be applied
// as an acceleration (ms^-2)
if (!characterController.isGrounded)
{
moveDirection.y -= gravity * Time.deltaTime;
}
// Move the controller
characterController.Move(moveDirection * Time.deltaTime);
// Player and Camera rotation
if (canMove)
{
rotationX += -Input.GetAxis("Mouse Y") * lookSpeed;
rotationX = Mathf.Clamp(rotationX, -lookXLimit, lookXLimit);
playerCamera.transform.localRotation = Quaternion.Euler(rotationX, 0, 0);
transform.rotation *= Quaternion.Euler(0, Input.GetAxis("Mouse X") * lookSpeed, 0);
}
}
}
Camera rotate by mouse input, How to rotate the move to the default position?
public class CameraOrbit : MonoBehaviour
{
public float turnSpeed = 1.0f;
public Transform player;
private Vector3 offset;
private void Start()
{
offset = new Vector3(0, 2.5f, -5);
}
private void LateUpdate()
{
if (Input.GetMouseButton(0))
{
offset = Quaternion.AngleAxis(Input.GetAxis("Mouse X") * turnSpeed, Vector3.up) * offset;
transform.localPosition = offset;
transform.LookAt(player.position);
}
}
}
This kind of thing moves directly into position and I want to smooth it over.
public void RevertCamera()
{
offset = new Vector3(0, 2.5f, -5);
transform.localPosition = offset;
transform.LookAt(player.position);
}
I have tried multiple variations of this, but none of them seem to work.
the easiest way is to use the camera's transform's RotateAround(...) method:
void LateUpdate
{
if(Input.GetMouseDown(0))
{
float delta = Input.GetAxis("Mouse X") * turnSpeed;
transform.RotateAround(player.position, Vector3.up, delta);
}
}
(taken from: https://docs.unity3d.com/ScriptReference/Transform.RotateAround.html)
Suggestion: I usually set up a camera rig, if I want to control camera movement focused on a certain target.
Though this might be overengineered for a simple RotateAround call.
If you want to achieve smooth transitions. I would advise you to use Slerp on the Quaternion and interpolate between your 2 rotation points.
Slerp Example:
// Interpolates rotation between the rotations "from" and "to"
// (Choose from and to not to be the same as
// the object you attach this script to)
using UnityEngine;
using System.Collections;
public class SlerpExample: MonoBehaviour {
[SerializeField]private Transform from;
[SerializeField]private Transform player;
private bool revertCamera = false;
private float timeCount = 0.0f;
private void Update() {
timeCount = timeCount + Time.deltaTime;
if (revertCamera) {
timeCount = 0.0f;
transform.rotation = Quaternion
.Slerp(from.rotation, player.rotation, timeCount);
if (transform.rotation == player.rotation) {
reverCamera = false;
}
}
}
private void RevertCamera() {
revertCamera = true;
}
}
Slerp
Should I use Cinemachine for that or it's better to do it with a script from scratch ?
The script is attached to the Main Camera.
Now it's orbit only left right. I want it to orbit 360 degrees with clamp so it wont move down to the floor and to up back.
I should also the Y and not only the X but not sure how.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerFollow : MonoBehaviour {
public Transform PlayerTransform;
private Vector3 _cameraOffset;
[Range(0.01f, 1.0f)]
public float SmoothFactor = 0.5f;
public bool LookAtPlayer = false;
public bool RotateAroundPlayer = true;
public float RotationsSpeed = 5.0f;
// Use this for initialization
void Start () {
_cameraOffset = transform.position - PlayerTransform.position;
}
// LateUpdate is called after Update methods
void LateUpdate () {
if(RotateAroundPlayer)
{
Quaternion camTurnAngle =
Quaternion.AngleAxis(Input.GetAxis("Mouse X") * RotationsSpeed, Vector3.up);
_cameraOffset = camTurnAngle * _cameraOffset;
}
Vector3 newPos = PlayerTransform.position + _cameraOffset;
transform.position = Vector3.Slerp(transform.position, newPos, SmoothFactor);
if (LookAtPlayer || RotateAroundPlayer)
transform.LookAt(PlayerTransform);
}
}
I want to rotate camera around a gameObject (Say a cube) on a drag of my mouse to simulate a feeling that the gameObject is rotating (Just like we rotate object in scene editor and like in shopping websites).
The script below is the one that I'm using. But sometimes the script behaves very weirdly. The camera rotates in the opposite direction than the anticipated direction. Why is this happening? What changes do I need to make in the code to make it work? Please help.
using UnityEngine;
using System.Collections;
public class ExampleBehaviourScript : MonoBehaviour
{
public Camera cameraObj;
public GameObject myGameObj;
public float speed = 2f;
void Update()
{
RotateCamera();
}
void RotateCamera()
{
if(Input.GetMouseButton(0))
{
cameraObj.transform.RotateAround(myGameObj.transform.position,
Vector3.up,
-Input.GetAxis("Mouse X")*speed);
cameraObj.transform.RotateAround(myGameObj.transform.position,
Vector3.right,
-Input.GetAxis("Mouse Y")*speed);
}
}
}
I think it is caused by the reference axis.
Because you used Vector3.up, Vector3.right, not the camera's one, it wasn't rotated the anticipated direction.
So, you should change like below.
void RotateCamera()
{
if(Input.GetMouseButton(0))
{
cameraObj.transform.RotateAround(myGameObj.transform.position,
cameraObj.transform.up,
-Input.GetAxis("Mouse X")*speed);
cameraObj.transform.RotateAround(myGameObj.transform.position,
cameraObj.transform.right,
-Input.GetAxis("Mouse Y")*speed);
}
}
My solution to rotate the camera in Unity with Mouse or Touch
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
public class CameraRotator : MonoBehaviour
{
public Transform target;
public Camera mainCamera;
[Range(0.1f, 5f)]
[Tooltip("How sensitive the mouse drag to camera rotation")]
public float mouseRotateSpeed = 0.8f;
[Range(0.01f, 100)]
[Tooltip("How sensitive the touch drag to camera rotation")]
public float touchRotateSpeed = 17.5f;
[Tooltip("Smaller positive value means smoother rotation, 1 means no smooth apply")]
public float slerpValue = 0.25f;
public enum RotateMethod { Mouse, Touch };
[Tooltip("How do you like to rotate the camera")]
public RotateMethod rotateMethod = RotateMethod.Mouse;
private Vector2 swipeDirection; //swipe delta vector2
private Quaternion cameraRot; // store the quaternion after the slerp operation
private Touch touch;
private float distanceBetweenCameraAndTarget;
private float minXRotAngle = -80; //min angle around x axis
private float maxXRotAngle = 80; // max angle around x axis
//Mouse rotation related
private float rotX; // around x
private float rotY; // around y
private void Awake()
{
if (mainCamera == null)
{
mainCamera = Camera.main;
}
}
// Start is called before the first frame update
void Start()
{
distanceBetweenCameraAndTarget = Vector3.Distance(mainCamera.transform.position, target.position);
}
// Update is called once per frame
void Update()
{
if (rotateMethod == RotateMethod.Mouse)
{
if (Input.GetMouseButton(0))
{
rotX += -Input.GetAxis("Mouse Y") * mouseRotateSpeed; // around X
rotY += Input.GetAxis("Mouse X") * mouseRotateSpeed;
}
if (rotX < minXRotAngle)
{
rotX = minXRotAngle;
}
else if (rotX > maxXRotAngle)
{
rotX = maxXRotAngle;
}
}
else if (rotateMethod == RotateMethod.Touch)
{
if (Input.touchCount > 0)
{
touch = Input.GetTouch(0);
if (touch.phase == TouchPhase.Began)
{
//Debug.Log("Touch Began");
}
else if (touch.phase == TouchPhase.Moved)
{
swipeDirection += touch.deltaPosition * Time.deltaTime * touchRotateSpeed;
}
else if (touch.phase == TouchPhase.Ended)
{
//Debug.Log("Touch Ended");
}
}
if (swipeDirection.y < minXRotAngle)
{
swipeDirection.y = minXRotAngle;
}
else if (swipeDirection.y > maxXRotAngle)
{
swipeDirection.y = maxXRotAngle;
}
}
}
private void LateUpdate()
{
Vector3 dir = new Vector3(0, 0, -distanceBetweenCameraAndTarget); //assign value to the distance between the maincamera and the target
Quaternion newQ; // value equal to the delta change of our mouse or touch position
if (rotateMethod == RotateMethod.Mouse)
{
newQ = Quaternion.Euler(rotX , rotY, 0); //We are setting the rotation around X, Y, Z axis respectively
}
else
{
newQ = Quaternion.Euler(swipeDirection.y , -swipeDirection.x, 0);
}
cameraRot = Quaternion.Slerp(cameraRot, newQ, slerpValue); //let cameraRot value gradually reach newQ which corresponds to our touch
mainCamera.transform.position = target.position + cameraRot * dir;
mainCamera.transform.LookAt(target.position);
}
public void SetCamPos()
{
if(mainCamera == null)
{
mainCamera = Camera.main;
}
mainCamera.transform.position = new Vector3(0, 0, -distanceBetweenCameraAndTarget);
}
}
To move your cube in the direction of mouse moves change your code like blow:
void RotateCamera()
{
if (Input.GetMouseButton(0))
{
cameraObj.transform.RotateAround(myGameObj.transform.position,
Vector3.up,
Input.GetAxis("Mouse X") * speed);
cameraObj.transform.RotateAround(myGameObj.transform.position,
Vector3.right,
-Input.GetAxis("Mouse Y") * speed);
}
}
Here is my virtual joystick controller script. Now how can i use this for control fps character controller movement both forward and side?
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.EventSystems;
using System.Collections;
public class JoyStickController : MonoBehaviour , IDragHandler, IPointerUpHandler ,IPointerDownHandler{
private Image bgImg;
private Image joyStickImg;
public Vector3 InputDirection{ set; get; }
// Use this for initialization
void Start () {
bgImg = GetComponent<Image> ();
joyStickImg = transform.GetChild (0).GetComponent<Image> ();
InputDirection = Vector3.zero;
}
public virtual void OnDrag(PointerEventData ped){
Vector2 pos = Vector2.zero;
if (RectTransformUtility.ScreenPointToLocalPointInRectangle (bgImg.rectTransform,
ped.position, ped.pressEventCamera, out pos)) {
pos.x = (pos.x / (bgImg.rectTransform.sizeDelta.x));
pos.y = (pos.y / (bgImg.rectTransform.sizeDelta.y));
float x = (bgImg.rectTransform.pivot.x == 1) ? pos.x * 2 + 1 : pos.x * 2 - 1;
float y = (bgImg.rectTransform.pivot.y == 1) ? pos.y* 2 + 1 : pos.y * 2 - 1;
InputDirection = new Vector3 (x, 0, y);
InputDirection = (InputDirection.magnitude > 1) ? InputDirection.normalized : InputDirection;
joyStickImg.rectTransform.anchoredPosition = new Vector3 (InputDirection.x * (bgImg.rectTransform.sizeDelta.x / 3)
, InputDirection.z * (bgImg.rectTransform.sizeDelta.y / 3));
}
}
public virtual void OnPointerDown(PointerEventData ped){
OnDrag (ped);
}
public virtual void OnPointerUp(PointerEventData ped){
InputDirection = Vector3.zero;
joyStickImg.rectTransform.anchoredPosition = Vector3.zero;
Debug.Log("Unpress");
}
public float Horizontal()
{
if (InputDirection.x != 0)
return InputDirection.x;
else
return Input.GetAxis("Horizontal");
}
public float Vertical()
{
if (InputDirection.z != 0)
return InputDirection.z;
else
return Input.GetAxis("Vertical");
}
}
Here is my virtual joystick controller script. Now how can I use this for control fps character controller movement both forward and side?
FPS uses CharacterController. You move CharacterController with CharacterController.Move and the Move function take Vector3 as parameter.
All you have to do is pass in InputDirection from your Visual Joystick to the Move parameter.
float speed = 20;
CharacterController controller = GetComponent<CharacterController>();
controller.Move(InputDirection * speed * Time.deltaTime);
Or
Use the Horizontal() and Vertical() functions from your Visual Joystick.
public float speed = 6.0F;
public float jumpSpeed = 8.0F;
public float gravity = 20.0F;
private Vector3 moveDirection = Vector3.zero;
void Update() {
CharacterController controller = GetComponent<CharacterController>();
if (controller.isGrounded) {
moveDirection = new Vector3(Horizontal(), 0, Vertical());
moveDirection = transform.TransformDirection(moveDirection);
moveDirection *= speed;
if (Input.GetButton("Jump"))
moveDirection.y = jumpSpeed;
}
moveDirection.y -= gravity * Time.deltaTime;
controller.Move(moveDirection * Time.deltaTime);
}