- Home /
Movement based on camera direction.
Hi, Im using Unity's Stealth Game code to manage my character's movement and I've implemented an orbit camera.
The problem is that the character always moves based on the global Z axis, so if I move the camera around pressing the forward key moves the char based on its initial orientation and not the camera's.
Here's the script Im using. Im thinking I need to make the direction of movement relative to the camera, but Im not sure how.
Any pointers would be greatly appreciated.
using UnityEngine;
using System.Collections;
public class PlayerMovement : MonoBehaviour
{
// Variables
public float turnSmoothing = 15f; // A smoothing value for turning the player.
public float speedDampTime = 0.1f; // The damping for the speed parameter
private Animator anim; // Reference to the animator component.
// Functions
void Awake()
{
anim = GetComponent<Animator>();
}
void FixedUpdate()
{
// Cache the inputs.
float h = Input.GetAxis("Horizontal");
float v = Input.GetAxis("Vertical");
MovementManagement(h, v);
}
/////////////////////////////////////////////CHARACTER MOVEMENT/////////////////////////////////////////
void MovementManagement (float horizontal, float vertical)
{
// If there is some axis input...
if(horizontal != 0f || vertical != 0f)
{
// ... set the players rotation and set the speed parameter to 5.3f.
Rotating(horizontal, vertical);
anim.SetFloat("Speed", 5.3f, speedDampTime, Time.deltaTime);
}
else
// Otherwise set the speed parameter to 0.
anim.SetFloat("Speed", 0);
}
void Rotating (float horizontal, float vertical)
{
// Create a new vector of the horizontal and vertical inputs.
Vector3 targetDirection = new Vector3(horizontal, 0f, vertical);
// Create a rotation based on this new vector assuming that up is the global y axis.
Quaternion targetRotation = Quaternion.LookRotation(targetDirection, Vector3.up);
// Create a rotation that is an increment closer to the target rotation from the player's rotation.
Quaternion newRotation = Quaternion.Lerp(rigidbody.rotation, targetRotation, turnSmoothing * Time.deltaTime);
// Change the players rotation to this new rotation.
rigidbody.MoveRotation(newRotation);
}
}
Answer by robertbu · Oct 07, 2014 at 05:52 AM
You can probably just do this:
Vector3 targetDirection = new Vector3(horizontal, 0f, vertical);
targetDirection = Camera.main.transform.TransformDirection(targetDirection);
targetDirection.y = 0.0f;
The first line is already in your existing code. I added the second two lines.
Thank you, When implementing this Im getting an error though:
"error CS1061: Type UnityEngine.Transform' does not contain a definition for
Transform' and no extension method Transform' of type
UnityEngine.Transform' could be found (are you missing a using directive or an assembly reference?)"
I should mention that my code is in C#, is this JS? Thanks for the help!
This is C#. I had an extra period in there. The method is 'TransformDirection()'.
http://docs.unity3d.com/ScriptReference/Transform.TransformDirection.html
I actualy just made this exact code and I found that there is a problem with it. Using TransformDirection you are translating the "local" transforms of the camera to be "global".
This is a problem if you use a camera that is looking almost straight down. If you were to move "forward" you would be trying to move your player into the ground, however since your canceling the y value your only left with the small x value used to make the diagonal line from the camera, this has lead to my player moving normally going side to side but incredibly slow when moving forward.
This is the same issue I am encountering. I don't know quite how to work around that. Did you ever find a solution?
Yes I did, what needs to be done is you have to normalize the vector to be a distance of 1, if you use this however you must use getaxisraw since it will do weird things with the sloping caused by getaxis.
Also to note is that if you base the movement direction only on the camera and ignoring the y value your (forward, back, left, right) will work fine after normalization but when you do diagonals it will not be at 45°. To fix this you need to calculate the forward movement, normalize, calculate the right movement, (normalize if you want), add them together, and then normalize again. This will give you perfect directional vectors separated by 45° increments.
if you dont understand I'll make an example code
thx, i couldn't get it
var faceCamDir = Camera.main.transform.forward;
faceCamDir.y = 0f;
now my character cant go running uphill
So it has been some time since I comented here and I dont know how your currently using your inputs to move your character but if it's any help I recomend you use Camera.main.transform.eulerAngles.y and rotate a vector2 that contains your forward/back and right/left inputs to world space. Then using the rotated inputs you can directly mover your character in the world
Your answer
![](https://koobas.hobune.stream/wayback/20220613164540im_/https://answers.unity.com/themes/thub/images/avi.jpg)
Follow this Question
Related Questions
How to make camera position relative to a specific target. 1 Answer
Changing Ortho Cam Size according to resolution 4 Answers
Camera and Target JS to CS converting 2 Answers
UNITY 3D: How to make the camera follow the player? Smoothly 2 Answers
Healthbar does not follow camera/appears behind gameObjects 0 Answers