- Home /
How to make an object go the direction it is facing?
I have a cube that is my player and I can move it with WASD. I can also rotate it with QE. When I rotate it though, it still goes the the same direction when I press a directional button. It doesn't matter what direction it is facing. So how can I make it always go forward based on the front of the cube? Any help would be much appreciated.
Script:
using UnityEngine;
using System.Collections;
[RequireComponent (typeof(Rigidbody))]
public class Movement : MonoBehaviour {
public float movementSpeed = 5.0f;
public float clockwise = 1000.0f;
public float counterClockwise = -5.0f;
void Start () {
}
void Update () {
if(Input.GetKey(KeyCode.W)) {
transform.position += Vector3.forward * Time.deltaTime * movementSpeed;
}
else if(Input.GetKey(KeyCode.S)) {
rigidbody.position += Vector3.back * Time.deltaTime * movementSpeed;
}
else if(Input.GetKey(KeyCode.A)) {
rigidbody.position += Vector3.left * Time.deltaTime * movementSpeed;
}
else if(Input.GetKey(KeyCode.D)) {
rigidbody.position += Vector3.right * Time.deltaTime * movementSpeed;
}
if(Input.GetKey(KeyCode.E)) {
transform.Rotate(0, Time.deltaTime * clockwise, 0);
}
else if(Input.GetKey(KeyCode.Q)) {
transform.Rotate(0, Time.deltaTime * counterClockwise, 0);
}
}
}
Answer by GameVortex · Jan 14, 2014 at 07:35 AM
Vector3.forward and the others are in world space, so they will always move you in the same direction no matter which direction your character is in. To fix this you can replace the Vector3.forward with transform.forward. transform.forward is the forward direction of the transform, taking rotation into account.
So you change this:
transform.position += Vector3.forward * Time.deltaTime * movementSpeed;
Into this:
transform.position += transform.forward * Time.deltaTime * movementSpeed;
Transform does not have the variables left and back though, so you use the negative version of right and forward instead. Or simply subtract movement instead of adding it.
Move Back:
transform.position -= transform.forward * Time.deltaTime * movementSpeed;
Sorry for late response. This worked perfectly. Thank you.
$$anonymous$$aybe you can help me too. I'm making a 2D game right now and this was my first script for a bullet: movement_vector = new Vector2(1, 0); rbody.$$anonymous$$ovePosition(rbody.position + movement_vector * Time.deltaTime * Speed);
So now I'm trying to make it move into the direction that it's facing: Attempt 1: rbody.$$anonymous$$ovePosition((Vector2)transform.forward * Time.deltaTime * Speed);
Attempt 2: rbody.position += (Vector2)transform.forward * Time.deltaTime * Speed;
I'm sorry if my question seems extremely stupid as I'm relatively new to unity. Neither of my attempts seem to work as the bullet isn't moving. $$anonymous$$aybe someone can help me?
Edit: Fixed it
transform.Translate(transform.right * Speed * Time.smoothDeltaTime);
You are casting a Vector3 (transform.forward) into a Vector2 which basically just removes the Z value of the Vector3. In 2D you cannot move forward because forward is in the direction of the Z Axis which is into the screen. So in 2D you want to use the UP or Right direction ins$$anonymous$$d: transform.up. In 2D the Up and Right direction will always have a Z value of 0 which means that it can safely be ignored and passed into the $$anonymous$$ovePosition function.
If you are new to Unity and want to make a 2D game I recommend you to start with some of the 2D tutorials which covers many of these things: https://unity3d.com/learn/tutorials/topics/2d-game-creation
It is also generally better to ask a new question ins$$anonymous$$d of commenting on an answer on another if you need help. Also remember to search for your issue, searching for "Unity 2D Forward" came up with this helpful answer: http://answers.unity3d.com/questions/797202/finding-forward-in-2d-rigid-body.html
Answer by arul20 · Oct 23, 2017 at 08:20 AM
Use AddRelativeForce - which adds a force to the rigidbody relative to its / local coordinate system, rather than AddForce which adds based on the world's coordinate system.
E.g: If the spaceship is rotated away from the station, pressing forward with AddRelativeForce will use the ship's position and rotation, moving the ship forward in the correct direction. AddForce will use the station's / world's coordinates and ignore the ship's rotation - so when you press forward, the ship will move backward, towards the station.
Answer by morbidcamel · Jan 14, 2014 at 05:05 AM
If you're movement is physics based you can calculate the angular velocity... I use this in movement of some robot characters and needed more than just a simple Lerp. Here's a typical rigidbody movement motor.. Assuming you have 2 vectors, point a the position of the game object, b the position of the target to move to...
// First calculate the force - ...
...
Vector3 nextDirection = (b - a).normalized;
Vector3 targetVelocity = nextDirection * speed;
Vector3 deltaVelocity = targetVelocity - thisRigidbody.velocity;
if (thisRigidbody.useGravity)
deltaVelocity.y = 0;
force = deltaVelocity * accelerationRate;
// Then we can calculate the angular velocity
// Make the character rotate towards the target rotation
var turnDir = nextDirection;
if (turnDir == Vector3.zero)
{
angularVelocity = Vector3.zero;
}
else
{
var rotationAngle = AngleAroundAxis (transform.forward, turnDir, Vector3.up);
angularVelocity = (Vector3.up * rotationAngle * turningSmoothing);
}
Then you can set the rigidbody --
thisRigidbody.AddForce (force, ForceMode.Acceleration);
thisRigidbody.angularVelocity = angularVelocity;
Here is how to calculate the angle around an axis (make it turn around its head y axis)
public static float AngleAroundAxis (Vector3 dirA, Vector3 dirB, Vector3 axis)
{
// Project A and B onto the plane orthogonal target axis
dirA = dirA - Vector3.Project (dirA, axis);
dirB = dirB - Vector3.Project (dirB, axis);
// Find (positive) angle between A and B
float angle = Vector3.Angle (dirA, dirB);
// Return angle multiplied with 1 or -1
return angle * (Vector3.Dot (axis, Vector3.Cross (dirA, dirB)) < 0 ? -1 : 1);
}
To make sure it doesn't overshoot make use of a in range calculation and the adjust the speed for the component above. You can do this with ( b - a).magnitude or Vector3.Distance. The trick is to calculate the gradual deceleration or you can just make it stop with a speed = 0. Let me know if you need more help.
Answer by hari2015 · Feb 12, 2018 at 06:02 PM
transform.Translate(Vector3.forward*speed*time.dealtatime);
Answer by NFad · Apr 27, 2018 at 05:53 AM
I would certainly advise against setting (adding in this case) the position every time you move the player. Please either use transform.Translate() as the replies above suggest, or go all the way and add a rigidbody and use GetComponent().AddForce(Vector3.forward Time.deltaTime movementSpeed) in order to also give unity the power to also calculate collisions (if you have a collider attached) and physics if necessary.