Search code examples
c#unity-game-enginegame-physics

move object and _camera.TransformDirection(moveDirection)


i'm moving game object with this simple function which move body depends on camera view. The only problem that the camera X rotation isnt 0 and body tries to move into the ground but not clear forward and it makes movement slowly

void VerySimpleMove()
{
    if (_controllerBody.isGrounded)
    {
        _moveDirection.x = _mj.GetAxis("Horizontal");
        _moveDirection.y = 0;
        _moveDirection.z = _mj.GetAxis("Vertical");                  

        _moveDirection = _camera.TransformDirection(_moveDirection); 
        if (Mathf.Abs(_moveDirection.x) > 0 || Mathf.Abs(_moveDirection.y) > 0)
        {
            _body.rotation = Quaternion.LookRotation(_moveDirection);
        }
        if (_jumpButton)
        {
            _jumpButton = false;
            _moveDirection.y = _jumpHeight;
        }
    }
    _moveDirection.y -= _gravity * Time.deltaTime;
    _controllerBody.Move(_moveDirection * Time.deltaTime);
}

How is it possible to rotate _moveDirection by _camera.eulerAngle.x to make it real forward?


Solution

  • If I understand correctly, you need to make sure that _moveDirection is always parallel to XZ plane. One way to do it is instead of using _camera.TransformDirection, to calculate the projection of camera forward vector on XZ plane, then use LookRotation in that direction, like this:

    var forward = _camera.transform.forward; // Get camera forward vector
    forward.y = 0; // Project it on XZ plane
    _moveDirection =  Quaternion.LookRotation(forward) * _moveDirection; // Rotate
    

    Note that simply rotating the object by camera X angle as it was suggested won't always help here, since camera Z angle can cause the same effect.

    So final code would be:

    void VerySimpleMove()
    {
        if (_controllerBody.isGrounded)
        {
            _moveDirection.x = _mj.GetAxis("Horizontal");
            _moveDirection.y = 0;
            _moveDirection.z = _mj.GetAxis("Vertical");                  
    
            var forward = _camera.transform.forward; // Get camera forward vector
            forward.y = 0; // Project it on XZ plane
            _moveDirection =  Quaternion.LookRotation(forward) * _moveDirection; // Rotate
            if (Mathf.Abs(_moveDirection.x) > 0 || Mathf.Abs(_moveDirection.y) > 0)
            {
                _body.rotation = Quaternion.LookRotation(_moveDirection);
            }
            if (_jumpButton)
            {
                _jumpButton = false;
                _moveDirection.y = _jumpHeight;
            }
        }
        _moveDirection.y -= _gravity * Time.deltaTime;
        _controllerBody.Move(_moveDirection * Time.deltaTime);
    }