Hi, I am attempting to make a third person shooter right now, I have gotten my camera and character movement setup however I am having issues trying to convert Rigidbody.Velocity into local space so it will move in the same direction as my player is facing. I am currently using the new input system which has made it pretty hard to really find an answer on how to do this correctly, any help would be appreciated!
I am also aware that some may ask why I am using velocity instead of addforce, it’s because I think it feels a lot better than addforce.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Animations;
using UnityEngine.InputSystem;
public class MovementController : MonoBehaviour
{
public InputAction moveAction;
public Rigidbody rb;
public float speed = 10f;
public float rotateSpeed = 1;
private Vector2 input;
private Vector2 look;
private Vector3 movement;
void OnEnable()
{
moveAction.Enable();
Cursor.lockState = CursorLockMode.Locked;
}
public void Update()
{
input = moveAction.ReadValue<Vector2>();
movement = new Vector3(-input.x, 0, -input.y) * speed;
movement.y = rb.velocity.y;
transform.Rotate(0, look.x, 0);
}
public void FixedUpdate()
{
rb.velocity = movement;
}
public void onLook(InputAction.CallbackContext context)
{
look = context.ReadValue<Vector2>() * rotateSpeed;
}
}
Hey @PixelPacker, you’re going to run into a number of problems with what it looks like you are trying, if I understand your question and sample code.
But first, the question of how to convert velocity to local space has been answered several times - in the recent past I’ve looked it up myself. So do a google search and you’ll find answers for that.
Also, transform direction vectors are all in World Space - even those of children. There are reasons to transform velocity to local space, but if you are just doing a one-shot velocity change to a Rigidbody, you should need no Local Space conversion.
That brings us to the problems:
-
Read Unity Rigidybody.velocity documentation: “Do not set the velocity of an object every physics step, this will lead to unrealistic physics simulation” You can set the velocity, but it should be for one-shot changes, not on a continuous basis.
-
If you are dealing with the physics engine - eg. a Rigidbody, do not attempt to modify the transform properties of the object. You’ll be fighting the physics engine calculations.
-
All calls to Rigidbody functions and properties need to happen within FixedUpdate. If the code does not, you will not get predictable results.
-
Do not put Rigidbodies on child objects whose parents have Rigidbodies. There will be conflicts between physics engine’s control over the child and parent. (It’s not even a good idea to parent child Rigidbodies to non-Rigidbody objects if you are going to modify the parent transform - you’ll run into problems.)
Physics engines are deterministic - that is for example, if you shoot a projectile and it bounces off a wall, it will do so in exactly the same way every time given the same set of input conditions, and environment object properties. The projectile will follow exactly the same path and stop in exactly the same place every time.
If you go outside the physics engine as it appears you are doing, you won’t get such consistency. And you are going to ask the system to waste clock cycles in conflict of what your code appears to be doing.
The upshot is, if you are going to use Rigidbodies, stick with AddForce, and do everything in FixedUpdate, and don’t touch the objects transform directly - e.g. use Rigidbody.position, not transform.position.
Or, dispense with the Rigidbody all together and write your own physics simulation. A lot of developers take this approach and you can find a number of resource that show you how.