刚体字符控制器

时间:2019-03-06 08:58:27

标签: unity3d

我正在使用字符控制器,除两件事外,其他所有东西都工作正常,我找不到解决此问题的方法:( 这是我的控制器脚本的代码:

using UnityEngine;

public class ControlsManager : MonoBehaviour
{
    public Transform playerBody;
    private Rigidbody _rigidbody;

    private Transform _playerCamera;

    private Vector2 _mousePosition;
    private Vector2 _precMousePosition;
    private float _rJoystickX;
    private float _rJoystickY;

    private float _sprint;
    private bool _jump;

    private Vector3 _bodyTranslation;
    private bool _bodyTranslationChange;
    private Vector3 _bodyRotation;
    private bool _bodyRotationChange;
    private Vector3 _cameraRotation;
    private bool _cameraRotationChange;


    private void Awake()
    {
        _rigidbody = playerBody.GetComponent<Rigidbody>();
        _playerCamera = Utilities.mainCamera.transform;
        _mousePosition = Input.mousePosition;
    }

    private void Update()
    {
        _sprint = 1;

        // Cursor lock for camera rotation
        if (Input.GetKeyDown(Utilities.controls.lockCursorMouse))
        {
            if (Cursor.lockState == CursorLockMode.None)
            {
                Cursor.visible = false;
                Cursor.lockState = CursorLockMode.Locked;
            }
            else
            {
                Cursor.visible = true;
                Cursor.lockState = CursorLockMode.None;
            }
        }


        if (!Utilities.isGamePaused)
        {

            if (Input.GetJoystickNames().Length > 0 && Input.GetJoystickNames()[0] != "")
            {
                // Camera rotation for controller
                _rJoystickX = Input.GetAxis("RJoystickX");
                _rJoystickY = Input.GetAxis("RJoystickY");

                if (_rJoystickX != 0) {
                    _bodyRotation.y += Utilities.controls.controllerSens * _rJoystickX * Time.deltaTime;
                    _bodyRotationChange = true;
                }
                if (_rJoystickY != 0)
                {
                    _cameraRotation.x += Utilities.controls.controllerSens * _rJoystickY * Time.deltaTime;
                    _cameraRotationChange = true;
                }

                // Movements for controller
                if(Input.GetKey(Utilities.controls.sprintController))
                {
                    _sprint = 1.6f;
                }

                if (Input.GetAxis("LJoystickY") > 0)
                {
                    _bodyTranslation += playerBody.forward * _sprint * Time.deltaTime;
                    _bodyTranslationChange = true;
                }
                if (Input.GetAxis("LJoystickY") < 0)
                {
                    _bodyTranslation -= playerBody.forward * Time.deltaTime;
                    _bodyTranslationChange = true;
                }
                if (Input.GetAxis("LJoystickX") < 0)
                {
                    _bodyTranslation -= playerBody.right * Time.deltaTime;
                    _bodyTranslationChange = true;
                }
                if (Input.GetAxis("LJoystickX") > 0)
                {
                    _bodyTranslation += playerBody.right * Time.deltaTime;
                    _bodyTranslationChange = true;
                }
            }


            if (Cursor.lockState == CursorLockMode.Locked)
            {
                // Camera rotation for mouse
                _precMousePosition = _mousePosition;
                _mousePosition.x = Input.GetAxis("Mouse X");
                _mousePosition.y = Input.GetAxis("Mouse Y");

                if (_mousePosition.x != _precMousePosition.x)
                {
                    _bodyRotation.y += _mousePosition.x * Utilities.controls.mouseSens;
                    _bodyRotationChange = true;
                }
                if (_mousePosition.y != _precMousePosition.y)
                {
                    _cameraRotation.x += -_mousePosition.y * Utilities.controls.mouseSens;
                    _cameraRotationChange = true;
                }

                // Movements for mouse

                _sprint = 1;
                if(Input.GetKey(KeyCode.LeftShift))
                {
                    _sprint = 1.6f;
                }

                if (Input.GetKeyDown(KeyCode.Space))
                {
                    _jump = true;
                }

                if (Input.GetKey(Utilities.controls.forward))
                {
                    _bodyTranslation += playerBody.forward * (_sprint * Time.deltaTime);
                    _bodyTranslationChange = true;
                }
                if (Input.GetKey(Utilities.controls.backward))
                {
                    _bodyTranslation -= playerBody.forward * Time.deltaTime;
                    _bodyTranslationChange = true;
                }
                if (Input.GetKey(Utilities.controls.left))
                {
                    _bodyTranslation -= playerBody.right * Time.deltaTime;
                    _bodyTranslationChange = true;
                }
                if (Input.GetKey(Utilities.controls.right))
                {
                    _bodyTranslation += playerBody.right * Time.deltaTime;
                    _bodyTranslationChange = true;
                }

                ///////////////////////////////// Debug
                if (Input.GetKey(KeyCode.DownArrow))
                {
                    _bodyTranslation -= playerBody.up * Time.deltaTime;
                    _bodyTranslationChange = true;
                }
                if (Input.GetKey(KeyCode.UpArrow))
                {
                    _bodyTranslation += playerBody.up * Time.deltaTime;
                    _bodyTranslationChange = true;
                }

            }
        }

        // Rotations
        if (_bodyRotationChange)
        {
            playerBody.localRotation *= Quaternion.Euler(_bodyRotation);
        }
        _bodyRotationChange = false;
        _bodyRotation = Vector3.zero;
        if (_cameraRotationChange)
        {
            _playerCamera.localRotation *= Quaternion.Euler(_cameraRotation);
        }
        _cameraRotationChange = false;
        _cameraRotation = Vector3.zero;

        if (Input.GetKeyDown(KeyCode.Escape))
        {
            Application.Quit();
        }

    }

    private void FixedUpdate()
    {

        if (_bodyTranslationChange)
        {
            _rigidbody.AddForce(_bodyTranslation * Utilities.controls.playerSpeed, ForceMode.VelocityChange);
        }

        if (_jump)
        {
            _jump = false;
            _rigidbody.AddForce(playerBody.up * 500, ForceMode.Impulse);
        }

        _rigidbody.drag = playerBody.position.y > -0.6f ? 1 : 8;

        _bodyTranslationChange = false;
        _bodyTranslation = Vector3.zero;
    }    
}

主要的两个问题是:

  1. 当我在Update中进行旋转,并在FixedUpdates中进行移动时,当我同时移动和旋转时会有一些烦人的抖动。我试图以gif格式显示此内容,但一切似乎都比较滞后,因此我无法真正显示。
  2. 当我使用AddForce()移动角色时,我不得不增加刚体的阻力(最大为8),因为当您停止运动时它不会“滑动”。这很好用,但是由于这个原因我现在不能正常跳。我找到了一种解决方法,就是在空中时将阻力重新设置为1,但是如果我跳跃并移动,那么在空中的移动速度就会快8倍,这也很烦人。

我认为完全错误吗?我首先没有使用AddForce,而是使用普通的矢量翻译来移动角色,但是碰撞就像地狱般的越野车,我可以穿过大多数墙壁,物体...等等

感谢您阅读所有内容!

2 个答案:

答案 0 :(得分:-1)

使用Pyhsics(RB)时,切勿直接更改变换,也永远不要在Update中对此进行更改!所有更改都必须在FixedUpdate中进行!

playerBody.localRotation * =四元数.Euler(_bodyRotation); <-在更新中。

也可以使用Rigidbody.MoveRotation代替直接更改值。 发生这种情况是因为pyhsics将在不同的更新过程中工作,并且当您在此过程中更改值时,单位会感到困惑,并且会破坏物理原理->抖动

答案 1 :(得分:-1)

好吧,在尝试使用Rigidbody进行平滑处理几个小时后,我无法获得完美的东西。

我将只使用基本的Character控制器并自己处理碰撞。

仍然感谢!