This is the code I currently have to handle movement of a character:
if (Input.GetKey("w")){
transform.position = new Vector3 (transform.position.x, transform.position.y, transform.position.z + (float)0.1);
}
if (Input.GetKey("s")){
transform.position = new Vector3 (transform.position.x, transform.position.y, transform.position.z - (float)0.1);
}
if (Input.GetKey("a")){
transform.position = new Vector3 (transform.position.x-(float)0.1, transform.position.y, transform.position.z);
}
if (Input.GetKey("d")){
transform.position = new Vector3 (transform.position.x+(float)0.1, transform.position.y, transform.position.z);
}
However the character always faces the same direction and not where it goes.
For that I’m trying to use:
transform.LookAt(new Vector3());
However I can’t get it to work.
One of the ideas I had was to get vector coordinates of the current and the previous position of X and Z and put them inside that new Vector3 while Y=0 but I always get spazing out movement and weird physics.
hi there, instead of (float)0.1 use 0.1f and to make the character look at the direction he’s moving look into Transforms, Vector3’s Eulers and so on. The easiest way to do it in your case is to modify the transform’s rotation to make it look from 90 to 90 degrees to the direction it’s walking.
transform.eulerAngles = new Vector3(0, 90, 0);
//or
transform.eulerAngles = new Vector3(0, 0, 0);
//and so on
Also your movement it’s not FrameRate dependable, which means that on slow hardware it’ll move way slower than on other new devices. use Time.deltaTime as a multiplier for your movement modifications.
//add the rotation change here
transform.position = new Vector3 (transform.position.x-Speed, transform.position.y, transform.position.z) * Time.deltaTime;
At the beginning of the move calculate an angle between your forward vector and (position_you_are_moving_towards - position_of_your transform). See the code I usually use for that.
Rotate your transform by that angle. (transform.Rotate(up, angle_from_step_one)
public static float getAngle(Vector3 fr, Vector3 to, Vector3 up)
{
// http://answers.unity3d.com/questions/24983/how-to-calculate-the-angle-between-two-vectors.html
// the vector perpendicular to referenceForward (90 degrees clockwise)
// (used to determine if angle is positive or negative)
Vector3 referenceRight= Vector3.Cross(up, fr);
// Get the angle in degrees between 0 and 180
float angle = Vector3.Angle(to, fr);
// Determine if the degree value should be negative. Here, a positive value
// from the dot product means that our vector is the right of the reference vector
// whereas a negative value means we're on the left.
float sign = (Vector3.Dot(to, referenceRight) > 0.0f) ? 1.0f: -1.0f;
float finalAngle = sign * angle;
return finalAngle;
}
transform.Rotate(Vector3.up, Vector3.Angle(Vector3.forward, new Vector3(transform.position.x,transform.position.y,transform.position.z) - new Vector3(transform.position.x,transform.position.y,transform.position.z + (float)0.1)));
Sorry. I’m not sure I understand. Are you saying that when you try to move your character now it just goes to (0,0,0) and doesn’t move from there? If yes, can you post you current code that performs movement and rotation?
if I use your code or my version I get the same result but I tried to different things:
gravity on - when I move the character goes to (0,0,0) and then moves quickly in a random direction (probably has to do with the terrain been at (0,0,0) so the object get’s sliced by it)
gravity off - when I move the character it goes to (0,0,0) and stops.
My version:
if (Input.GetKey("w")){
transform.position = new Vector3 (transform.position.x, transform.position.y, transform.position.z + (float)0.1)* Time.deltaTime;
transform.Rotate(Vector3.up, Vector3.Angle(Vector3.forward, new Vector3(transform.position.x,transform.position.y,transform.position.z) - new Vector3(transform.position.x,transform.position.y,transform.position.z + (float)0.1)));
}
if (Input.GetKey("s")){
transform.position = new Vector3 (transform.position.x, transform.position.y, transform.position.z - (float)0.1)* Time.deltaTime;
transform.Rotate(Vector3.up, Vector3.Angle(Vector3.forward, new Vector3(transform.position.x,transform.position.y,transform.position.z) - new Vector3(transform.position.x,transform.position.y,transform.position.z - (float)0.1)));
}
if (Input.GetKey("a")){
transform.position = new Vector3 (transform.position.x-(float)0.1, transform.position.y, transform.position.z)* Time.deltaTime;
transform.Rotate(Vector3.up, Vector3.Angle(Vector3.forward, new Vector3(transform.position.x,transform.position.y,transform.position.z) - new Vector3(transform.position.x + (float)0.1,transform.position.y,transform.position.z )));
}
if (Input.GetKey("d")){
transform.position = new Vector3 (transform.position.x+(float)0.1, transform.position.y, transform.position.z)* Time.deltaTime;
transform.Rotate(Vector3.up, Vector3.Angle(Vector3.forward, new Vector3(transform.position.x,transform.position.y,transform.position.z) - new Vector3(transform.position.x - (float)0.1,transform.position.y,transform.position.z)));
}
12doze12 - the main problem with your code is that it multiplies your new position by deltaTime. That puts your position always very close to (0,0,0). Your code should look something like this (assuming 10 as your speed):
Why don’t you build a Vector3 instead of applying to transform.position at each step and then do a transform.LookAt(destination) before moving there?