How can i move the player to the direction that the camera points?
In my game there are 2 joysticks one for the player movement and one for the camera movement when i change the camera angle with the camera joystick and move the player in a direction with the player joystick the player moves in another direction what should i do?`
`Here is the camera script
using UnityEngine;
using System.Collections;
public class FreeCamera : MonoBehaviour {
public Transform lookAt;
public VirtualJoystick camerajs;
private float distance = 10.0f;
private float currentx = 0.0f;
private float currenty = 0.0f;
private float sensitivityx = 3.0f;
private float sensitivityy = 1.0f;
private void Update()
{
currentx += camerajs.InputDirection.x * sensitivityx;
currenty += camerajs.InputDirection.z * sensitivityy;
}
private void LateUpdate()
{
Vector3 dir = new Vector3(0, 0, -distance);
Quaternion rotation = Quaternion.Euler(currenty, currentx, 0);
transform.position = lookAt.position + rotation * dir;
transform.LookAt(lookAt);
}
}
And here is the joystick script
using UnityEngine;
using UnityEngine.EventSystems;
using System.Collections;
using UnityEngine.UI;
public class VirtualJoystick : MonoBehaviour,IDragHandler,IPointerUpHandler,IPointerDownHandler {
private Image bgimg;
private Image joystickimg;
public Vector3 InputDirection { set; get; }
private 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.x * 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;
}
}
The player movement script
using UnityEngine; using System.Collections;
public class Motor : MonoBehaviour {
public float moveSpeed = 5.0f;
public float drag = 0.5f;
public float terminalRotationSpeed = 25.0f;
private Rigidbody controller;
private Transform camtransform;
public VirtualJoystick movejoystick;
private void Start()
{
controller =GetComponent<Rigidbody>();
controller.maxAngularVelocity = terminalRotationSpeed;
controller.drag = drag;
camtransform = Camera.main.transform;
}
private void Update()
{
Vector3 dir = Vector3.zero;
dir.x = Input.GetAxis("Horizontal");
dir.z = Input.GetAxis("Vertical");
if (dir.magnitude > 1)
dir.Normalize();
if (movejoystick.InputDirection != Vector3.zero)
{
dir = movejoystick.InputDirection;
}
Vector3 rotatedDir = camtransform.TransformDirection(dir);
rotatedDir = new Vector3 (rotatedDir.x, 0, rotatedDir.z);
rotatedDir = rotatedDir.normalized * dir.magnitude;
controller.AddForce(dir * moveSpeed);
}
Answer by oswin_c · Dec 23, 2016 at 07:32 PM
I'll answer your questions first, then I have a couple of miscellaneous suggestions to prevent you from running into future problems.
I think your mistake is here.
Vector3 rotatedDir = camtransform.TransformDirection(dir);
rotatedDir = new Vector3 (rotatedDir.x, 0, rotatedDir.z);
rotatedDir = rotatedDir.normalized * dir.magnitude;
controller.AddForce(dir * moveSpeed);
The first of those lines is perfectly fine. Take the camera transform, and get a world space vector based on how that camera is pointing. I have one note for the second line.
-- rotatedDir = new Vector3 (rotatedDir.x, 0, rotatedDir.z);
I see you are trying to limit the force to the XZ plane. This will work, if and only if your object is always moving parallel to the XZ plane 100% of the time, and never needs to go up or down a slope. If that is the case, this is fine, otherwise I highly recommend using Vector3.ProjectOnPlane, as you are not relying on a coordinate system. Using ProjectOnPLane will prevent you from running into problems like depleting velocity on slopes.
The main problem lies in your next two lines of code, it seems. rotatedDir = rotatedDir.normalized dir.magnitude; controller.AddForce(dir moveSpeed);
The first line of code is fine, if you want the rotated direction to be independent of where the joystick is pointing. I don't think that's true.
The next line of code is the chief problem, though.
controller.AddForce(dir * moveSpeed);
You're not using the rotated direction -- you're using dir. You did all this nice work on rotatedDir, and then did nothing with it! I'm sure C# gave you a warning that rotatedDir is declared but never used.
I think your goal here is to have the direction be relative to the camera, but constrained to the XZ plane. Here's how I would do it.
Vector3 rotatedDir = camtransform.right*movejoystick.x + camtransform.up*movejoystick.y + camtransform.forward*movejoystick.z;
// Get a vector relative to the camera's local directions, i.e the unit coordinate vectors.
controller.AddForce(Vector3.ProjectOnPlane(rotatedDir, Vector3.up)*moveSpeed);
/* Project the vector on the plane if desired. Yes, I COULD just remove the camtransform.up*movejoystick.y component, which would work up until I decide to go up a slope. With this method, I can later replace Vector3.up with surface.normal from a raytrace, and have the controller move relative any surface instead of always being constrained to XZ.
Final note -- You probably don't want to use Quaternion.Euler! Quaternion.AngleAxis, unlike euler angles, does not depend on a coordinate system and will not cause gimbal lock, require arctangents, and other such problems with aerospace rotation.
Good luck!
Answer by Andrei1108 · Dec 23, 2016 at 07:48 PM
I want to move the the player up when i press up even after i change the angle and sorry if i make some mistakes i art primarily and i am not so experienced in coding.
So you want the character to move independent of where it is pointing?
If you are primarily an artist, then you're in good shape to start coding! As long as you have some understanding of how vectors work and a basic understanding of what quaternions are and why we use them, then you'll be fine. This is how we learn.
Your answer
Follow this Question
Related Questions
Locking Camera's rotation on a rolling character 0 Answers
,Third Person Movement Script Help 0 Answers
Unity's FPC apply camera deadzone for mouse 0 Answers
Rotate camera around pivot not working on certain angles 0 Answers
Use Joystick Axis As Buttons? 3 Answers