If i'm rotating my player on the Y-Axis and move it like
transform.Translate(Vector3.forward * Time.deltaTime)
it will move along the Z-Axis of the character (as expected).
If I used CharacterController.Move it will always move in the same direction, independent from its rotation.
How can I make the player follow it's rotation?
The problem is that you are translating the character forward on a global level. This means forward will always be in the same direction. Instead, use transform.forward. That way, you are translating the player on the forward vector on the player.
Another way to do it is using transform.rotation * Vector3.forward. This will rotate the global forward by the rotation of the player, returning the same thing as transform.forward.
Related
I am making a rolling ball game, and the way I want it to work is based on constant forward movement and rotation based turning.
I'm using force, which then has the ball roll forward.
My Issue here is that I would like the ball to move forward based on where it's "facing". Using Vector3.forward only moves it according to world space and transform.forward will start going backwards because the ball rolls over, upside down.
How can I make it so transform.forward ignores my forward turning, only being effected by the sideways turning?
"forward" is hard to imagine on a sphere.
You add speed when rotating around the X-axis (ball moves "forward")
For direction control, you rotate around global Y-axis.
The transform.forward will spin around the object. But the transform.right (local x-axis so to say) stays stable.
So we only need the Vector3.Cross Product of the transform.right and the global Vector3.Up.
Vector3 forward = Vector3.Cross(transform.right, Vector3.up);
You can use vector math for this. Take the cross product between the local right and the world up:
private static Vector3 GetRollingForward(Vector3 localRight)
{
return Vector3.Cross(localRight, Vector3.up);
}
// ...
void Update()
{
Debug.DrawLine(transform.position, transform.position
+ GetRollingForward(transform.right));
}
I have a spaceship which flies around planets orbit by this script:
Update() {
transform.RotateAround(planet.transform.position, Vector3.up, speed * Time.deltaTime);
}
But I don't understand how to add user inputs (Input.GetAxis("Horizontal") and Input.GetAxis("Vertical")) to this script so user can control spaceship's movement. How can I move spaceship around orbit using user input (arrows) ?
EDIT:
Camer follows ship from behind. Ship is moved forward by some force (speed) on planet's orbit (to simplify, it's just a circle). I want user to be able to change direction of movement (left\right) like in the pucture (from D1 to D2).
This task can be split into two parts. First is rotating the ship based on user input. The second is to change our method of orbiting to account for the rotation of the ship so that it moves in the direction that it is facing.
We can solve part one by using a Transform.Rotate call. Since we want the bottom of the ship to always face the planet, we want to rotate along the ship's "Up" axis. For our Input axis, the "Horizontal" will likely be the most intuitive. It will look something like this:
transform.Rotate(Vector3.forward, Input.GetAxis("Horizontal") * rotateSpeed * Time.deltaTime);
For part two, it is important to realize that Transform.RotateAround uses the world space, and not the local space. By making it use the local space of the ship, it will account for the ship's rotation such that the ship will move in the direction that it is facing, rather than moving in an independent direction. We can do this by using the Transform.TransformDirection function. It will look something like this:
transform.RotateAround(planet.transform.position, transform.TransformDirection(Vector3.up), speed * Time.deltaTime);
Combining these in an update function worked for me in a quick test.
In addition, if we want the ship to strafe from side to side without doing any local rotation of the ship, we can do it with another Transform.RotateAround call, like so:
transform.RotateAround(planet.transform.position, transform.TransformDirection(Vector3.right), Input.GetAxis("Horizontal") * strafeSpeed * Time.deltaTime);
(Answer edited for question edit)
I am working in unity trying to make a space shooter while watching the tutorial. The bolt is supposed to move on the z axis but it falls instead, and the ammo is not using gravity.
rb = GetComponent<Rigidbody>();
rb.velocity = transform.forward * speed;
what you see above is what the instructor told me to put into the script.
For the movement in the z axis, if the rotation of the bolt is zero in each of the vectors of the transform and it doesn't have a parent with any other non-zero rotation it should move in unity's z axis correctly with transform.forward. If that doesn't work then, instead of transform.forward you could use Vector3.up, or Vector3.forward instead.
The forward vector is the blue one in Unity editor. Check that your bolt goes in the direction of the blue arrow. It it doesn't, check that you correctly disabled gravity in the rigidbody of this object (be sure it is the right one). In the same way, be sure that you added your script in on the right object.
If you still can't figure out what goes wrong, give us more precision. Does your projectile go in a straight line, or is it still affected by gravity? What happens if you change the speed value, doesn't it work?
This is likely a problem in the setup in Unity's editor. The script is fine so we can't really know more without seeing the editor
I can show another object in front of my player using this simple line of code
newPosition =player.transform.position+player.transform.forward * distance
but how can i restrict it to always show in the same position(but in front of player) no matter what is the rotation of my player?
When you rotate gameobject transform.forward always changes.Because of you are using local values. But you need the use word values for this.
newPosition =player.transform.position+Vector3.forward * distance
I have balls falling (gravity) in my game, and in its Update method I've also added a slight pull, as the wind was blowing:
transform.Translate(new Vector3(sidewaysDrag,0));
Now, I want to rotate my GameOBject around the Z axis as well (its a 2D game), ive tried:
transform.Rotate(Vector3.forward * Time.deltaTime * 200);
But I guess my anchor is wrong, because instead of rotating around itself the whole object is rotating in a very big curve. The rotation is correct if I comment out the translation...
Put your ball object under another empty object(parent).
And translate parent, rotate ball.
or translate ball's world position, rotate ball's localRotation
It's because you are using Vector3.forward, which actually points to Z-axis in world space, you need Z-axis in local space, you can get that by doing transform.TransformDirection(Vector3.forward);