代码之家  ›  专栏  ›  技术社区  ›  ChriseNF

Unity 3人控制器摄像头动作怪异

  •  1
  • ChriseNF  · 技术社区  · 3 年前

    我是Unity和Stackowerflow的新手。如果我做错了什么,请不要评判我^^我在游戏中使用了Unity的TPS控制器资源。首先,它非常有效。但后来它坏了。但我什么也没做:((我甚至不碰脚本或预制件)。之后,我删除了资产并重新下载,但它不再工作。 Here is one example from my broken scene 这些是我控制器的代码。谢谢你的帮助。

    启动资产投入

    using UnityEngine;
    #if ENABLE_INPUT_SYSTEM && STARTER_ASSETS_PACKAGES_CHECKED
    using UnityEngine.InputSystem;
    #endif
    
    namespace StarterAssets
    {
        public class StarterAssetsInputs : MonoBehaviour
        {
            [Header("Character Input Values")]
            public Vector2 move;
            public Vector2 look;
            public bool jump;
            public bool sprint;
    
            [Header("Movement Settings")]
            public bool analogMovement;
    
    #if !UNITY_IOS || !UNITY_ANDROID
            [Header("Mouse Cursor Settings")]
            public bool cursorLocked = true;
            public bool cursorInputForLook = true;
    #endif
    
    #if ENABLE_INPUT_SYSTEM && STARTER_ASSETS_PACKAGES_CHECKED
            public void OnMove(InputValue value)
            {
                MoveInput(value.Get<Vector2>());
            }
    
            public void OnLook(InputValue value)
            {
                if(cursorInputForLook)
                {
                    LookInput(value.Get<Vector2>());
                }
            }
    
            public void OnJump(InputValue value)
            {
                JumpInput(value.isPressed);
            }
    
            public void OnSprint(InputValue value)
            {
                SprintInput(value.isPressed);
            }
    #else
        // old input sys if we do decide to have it (most likely wont)...
    #endif
    
    
            public void MoveInput(Vector2 newMoveDirection)
            {
                move = newMoveDirection;
                Debug.Log(move.magnitude);
                Debug.Log(move.normalized.magnitude);
            } 
    
            public void LookInput(Vector2 newLookDirection)
            {
                look = newLookDirection;
            }
    
            public void JumpInput(bool newJumpState)
            {
                jump = newJumpState;
            }
    
            public void SprintInput(bool newSprintState)
            {
                sprint = newSprintState;
            }
    
    #if !UNITY_IOS || !UNITY_ANDROID
    
            private void OnApplicationFocus(bool hasFocus)
            {
                SetCursorState(cursorLocked);
            }
    
            private void SetCursorState(bool newState)
            {
                Cursor.lockState = newState ? CursorLockMode.Locked : CursorLockMode.None;
            }
    
    #endif
    
        }
        
    }
    

    第三人控制器

    using UnityEngine;
    #if ENABLE_INPUT_SYSTEM && STARTER_ASSETS_PACKAGES_CHECKED
    using UnityEngine.InputSystem;
    #endif
    
    /* Note: animations are called via the controller for both the character and capsule using animator null checks
     */
    
    namespace StarterAssets
    {
        [RequireComponent(typeof(CharacterController))]
    #if ENABLE_INPUT_SYSTEM && STARTER_ASSETS_PACKAGES_CHECKED
        [RequireComponent(typeof(PlayerInput))]
    #endif
        public class ThirdPersonController : MonoBehaviour
        {
            [Header("Player")]
            [Tooltip("Move speed of the character in m/s")]
            public float MoveSpeed = 2.0f;
            [Tooltip("Sprint speed of the character in m/s")]
            public float SprintSpeed = 5.335f;
            [Tooltip("How fast the character turns to face movement direction")]
            [Range(0.0f, 0.3f)]
            public float RotationSmoothTime = 0.12f;
            [Tooltip("Acceleration and deceleration")]
            public float SpeedChangeRate = 10.0f;
    
            [Space(10)]
            [Tooltip("The height the player can jump")]
            public float JumpHeight = 1.2f;
            [Tooltip("The character uses its own gravity value. The engine default is -9.81f")]
            public float Gravity = -15.0f;
    
            [Space(10)]
            [Tooltip("Time required to pass before being able to jump again. Set to 0f to instantly jump again")]
            public float JumpTimeout = 0.50f;
            [Tooltip("Time required to pass before entering the fall state. Useful for walking down stairs")]
            public float FallTimeout = 0.15f;
    
            [Header("Player Grounded")]
            [Tooltip("If the character is grounded or not. Not part of the CharacterController built in grounded check")]
            public bool Grounded = true;
            [Tooltip("Useful for rough ground")]
            public float GroundedOffset = -0.14f;
            [Tooltip("The radius of the grounded check. Should match the radius of the CharacterController")]
            public float GroundedRadius = 0.28f;
            [Tooltip("What layers the character uses as ground")]
            public LayerMask GroundLayers;
    
            [Header("Cinemachine")]
            [Tooltip("The follow target set in the Cinemachine Virtual Camera that the camera will follow")]
            public GameObject CinemachineCameraTarget;
            [Tooltip("How far in degrees can you move the camera up")]
            public float TopClamp = 70.0f;
            [Tooltip("How far in degrees can you move the camera down")]
            public float BottomClamp = -30.0f;
            [Tooltip("Additional degress to override the camera. Useful for fine tuning camera position when locked")]
            public float CameraAngleOverride = 0.0f;
            [Tooltip("For locking the camera position on all axis")]
            public bool LockCameraPosition = false;
    
            // cinemachine
            private float _cinemachineTargetYaw;
            private float _cinemachineTargetPitch;
    
            // player
            private float _speed;
            private float _animationBlend;
            private float _targetRotation = 0.0f;
            private float _rotationVelocity;
            private float _verticalVelocity;
            private float _terminalVelocity = 53.0f;
    
            // timeout deltatime
            private float _jumpTimeoutDelta;
            private float _fallTimeoutDelta;
    
            // animation IDs
            private int _animIDSpeed;
            private int _animIDGrounded;
            private int _animIDJump;
            private int _animIDFreeFall;
            private int _animIDMotionSpeed;
    
            private Animator _animator;
            private CharacterController _controller;
            private StarterAssetsInputs _input;
            private GameObject _mainCamera;
    
            private const float _threshold = 0.01f;
    
            private bool _hasAnimator;
    
            private void Awake()
            {
                // get a reference to our main camera
                if (_mainCamera == null)
                {
                    _mainCamera = GameObject.FindGameObjectWithTag("MainCamera");
                }
            }
    
            private void Start()
            {
                _hasAnimator = TryGetComponent(out _animator);
                _controller = GetComponent<CharacterController>();
                _input = GetComponent<StarterAssetsInputs>();
    
                AssignAnimationIDs();
    
                // reset our timeouts on start
                _jumpTimeoutDelta = JumpTimeout;
                _fallTimeoutDelta = FallTimeout;
            }
    
            private void Update()
            {
                _hasAnimator = TryGetComponent(out _animator);
                
                JumpAndGravity();
                GroundedCheck();
                Move();
            }
    
            private void LateUpdate()
            {
                CameraRotation();
            }
    
            private void AssignAnimationIDs()
            {
                _animIDSpeed = Animator.StringToHash("Speed");
                _animIDGrounded = Animator.StringToHash("Grounded");
                _animIDJump = Animator.StringToHash("Jump");
                _animIDFreeFall = Animator.StringToHash("FreeFall");
                _animIDMotionSpeed = Animator.StringToHash("MotionSpeed");
            }
    
            private void GroundedCheck()
            {
                // set sphere position, with offset
                Vector3 spherePosition = new Vector3(transform.position.x, transform.position.y - GroundedOffset, transform.position.z);
                Grounded = Physics.CheckSphere(spherePosition, GroundedRadius, GroundLayers, QueryTriggerInteraction.Ignore);
    
                // update animator if using character
                if (_hasAnimator)
                {
                    _animator.SetBool(_animIDGrounded, Grounded);
                }
            }
    
            private void CameraRotation()
            {
                // if there is an input and camera position is not fixed
                if (_input.look.sqrMagnitude >= _threshold && !LockCameraPosition)
                {
                    _cinemachineTargetYaw += _input.look.x * Time.deltaTime;
                    _cinemachineTargetPitch += _input.look.y * Time.deltaTime;
                }
    
                // clamp our rotations so our values are limited 360 degrees
                _cinemachineTargetYaw = ClampAngle(_cinemachineTargetYaw, float.MinValue, float.MaxValue);
                _cinemachineTargetPitch = ClampAngle(_cinemachineTargetPitch, BottomClamp, TopClamp);
    
                // Cinemachine will follow this target
                CinemachineCameraTarget.transform.rotation = Quaternion.Euler(_cinemachineTargetPitch + CameraAngleOverride, _cinemachineTargetYaw, 0.0f);
            }
    
            private void Move()
            {
                // set target speed based on move speed, sprint speed and if sprint is pressed
                float targetSpeed = _input.sprint ? SprintSpeed : MoveSpeed;
    
                // a simplistic acceleration and deceleration designed to be easy to remove, replace, or iterate upon
    
                // note: Vector2's == operator uses approximation so is not floating point error prone, and is cheaper than magnitude
                // if there is no input, set the target speed to 0
                if (_input.move == Vector2.zero) targetSpeed = 0.0f;
    
                // a reference to the players current horizontal velocity
                float currentHorizontalSpeed = new Vector3(_controller.velocity.x, 0.0f, _controller.velocity.z).magnitude;
    
                float speedOffset = 0.1f;
                float inputMagnitude = _input.analogMovement ? _input.move.magnitude : 1f;
    
                // accelerate or decelerate to target speed
                if (currentHorizontalSpeed < targetSpeed - speedOffset || currentHorizontalSpeed > targetSpeed + speedOffset)
                {
                    // creates curved result rather than a linear one giving a more organic speed change
                    // note T in Lerp is clamped, so we don't need to clamp our speed
                    _speed = Mathf.Lerp(currentHorizontalSpeed, targetSpeed * inputMagnitude, Time.deltaTime * SpeedChangeRate);
    
                    // round speed to 3 decimal places
                    _speed = Mathf.Round(_speed * 1000f) / 1000f;
                }
                else
                {
                    _speed = targetSpeed;
                }
                _animationBlend = Mathf.Lerp(_animationBlend, targetSpeed, Time.deltaTime * SpeedChangeRate);
    
                // normalise input direction
                Vector3 inputDirection = new Vector3(_input.move.x, 0.0f, _input.move.y).normalized;
    
                // note: Vector2's != operator uses approximation so is not floating point error prone, and is cheaper than magnitude
                // if there is a move input rotate player when the player is moving
                if (_input.move != Vector2.zero)
                {
                    _targetRotation = Mathf.Atan2(inputDirection.x, inputDirection.z) * Mathf.Rad2Deg + _mainCamera.transform.eulerAngles.y;
                    float rotation = Mathf.SmoothDampAngle(transform.eulerAngles.y, _targetRotation, ref _rotationVelocity, RotationSmoothTime);
    
                    // rotate to face input direction relative to camera position
                    transform.rotation = Quaternion.Euler(0.0f, rotation, 0.0f);
                }
    
    
                Vector3 targetDirection = Quaternion.Euler(0.0f, _targetRotation, 0.0f) * Vector3.forward;
    
                // move the player
                _controller.Move(targetDirection.normalized * (_speed * Time.deltaTime) + new Vector3(0.0f, _verticalVelocity, 0.0f) * Time.deltaTime);
    
                // update animator if using character
                if (_hasAnimator)
                {
                    _animator.SetFloat(_animIDSpeed, _animationBlend);
                    _animator.SetFloat(_animIDMotionSpeed, inputMagnitude);
                }
            }
    
            private void JumpAndGravity()
            {
                if (Grounded)
                {
                    // reset the fall timeout timer
                    _fallTimeoutDelta = FallTimeout;
    
                    // update animator if using character
                    if (_hasAnimator)
                    {
                        _animator.SetBool(_animIDJump, false);
                        _animator.SetBool(_animIDFreeFall, false);
                    }
    
                    // stop our velocity dropping infinitely when grounded
                    if (_verticalVelocity < 0.0f)
                    {
                        _verticalVelocity = -2f;
                    }
    
                    // Jump
                    if (_input.jump && _jumpTimeoutDelta <= 0.0f)
                    {
                        // the square root of H * -2 * G = how much velocity needed to reach desired height
                        _verticalVelocity = Mathf.Sqrt(JumpHeight * -2f * Gravity);
    
                        // update animator if using character
                        if (_hasAnimator)
                        {
                            _animator.SetBool(_animIDJump, true);
                        }
                    }
    
                    // jump timeout
                    if (_jumpTimeoutDelta >= 0.0f)
                    {
                        _jumpTimeoutDelta -= Time.deltaTime;
                    }
                }
                else
                {
                    // reset the jump timeout timer
                    _jumpTimeoutDelta = JumpTimeout;
    
                    // fall timeout
                    if (_fallTimeoutDelta >= 0.0f)
                    {
                        _fallTimeoutDelta -= Time.deltaTime;
                    }
                    else
                    {
                        // update animator if using character
                        if (_hasAnimator)
                        {
                            _animator.SetBool(_animIDFreeFall, true);
                        }
                    }
    
                    // if we are not grounded, do not jump
                    _input.jump = false;
                }
    
                // apply gravity over time if under terminal (multiply by delta time twice to linearly speed up over time)
                if (_verticalVelocity < _terminalVelocity)
                {
                    _verticalVelocity += Gravity * Time.deltaTime;
                }
            }
    
            private static float ClampAngle(float lfAngle, float lfMin, float lfMax)
            {
                if (lfAngle < -360f) lfAngle += 360f;
                if (lfAngle > 360f) lfAngle -= 360f;
                return Mathf.Clamp(lfAngle, lfMin, lfMax);
            }
    
            private void OnDrawGizmosSelected()
            {
                Color transparentGreen = new Color(0.0f, 1.0f, 0.0f, 0.35f);
                Color transparentRed = new Color(1.0f, 0.0f, 0.0f, 0.35f);
    
                if (Grounded) Gizmos.color = transparentGreen;
                else Gizmos.color = transparentRed;
                
                // when selected, draw a gizmo in the position of, and matching radius of, the grounded collider
                Gizmos.DrawSphere(new Vector3(transform.position.x, transform.position.y - GroundedOffset, transform.position.z), GroundedRadius);
            }
        }
    }
    
    1 回复  |  直到 3 年前
        1
  •  1
  •   Emirhan Soylu    3 年前

    我也有同样的问题。 我研究了很多关于这方面的文件,最终解决了这个问题。 问题不在于你的代码、事件或其他方面。这个问题与团结有关。 我不知道问题的确切原因,但你可以这样解决: 首先,开始 编辑 &燃气轮机; 项目设置 然后选择 输入系统包 从左边的标签。 然后,改变 更新方法 具有 在动态更新中处理事件 .就这些! 动态更新是指脚本中常见的更新方法 无效更新() .

    图像

    enter image description here enter image description here