Unity角色控制器修改(鼠标右键按住旋转视角)

发表于2018-06-27
评论0 4.3k浏览
角色控制器允许你在受制于碰撞的情况下很容易的进行运动,而不用处理刚体。Unity提供了一些游戏中控制角色的移动组件,可以帮助我们去协助做一些角色控制方面的修改工作,下面就和大家介绍如何实现鼠标右键按住旋转视角。

代码如下:
using System;  
using UnityEngine;  
using UnityStandardAssets.CrossPlatformInput;  
using UnityStandardAssets.Utility;  
using Random = UnityEngine.Random;  
namespace UnityStandardAssets.Characters.FirstPerson  
{  
    [RequireComponent(typeof (CharacterController))]  
    [RequireComponent(typeof (AudioSource))]  
    public class FirstPersonController : MonoBehaviour  
    {  
        [SerializeField]  
        private bool m_IsWalking;  
        public float m_WalkSpeed;  
        [SerializeField]  
        private float m_RunSpeed;  
        [SerializeField]  
        [Range(0f, 1f)]  
        private float m_RunstepLenghten;  
        [SerializeField]  
        private float m_JumpSpeed;  
        [SerializeField]  
        private float m_StickToGroundForce;  
        [SerializeField]  
        private float m_GravityMultiplier;  
        [SerializeField]  
        private MouseLook m_MouseLook;  
        [SerializeField]  
        private bool m_UseFovKick;  
        [SerializeField]  
        private FOVKick m_FovKick = new FOVKick();  
        [SerializeField]  
        private bool m_UseHeadBob;  
        [SerializeField]  
        private CurveControlledBob m_HeadBob = new CurveControlledBob();  
        [SerializeField]  
        private LerpControlledBob m_JumpBob = new LerpControlledBob();  
        [SerializeField]  
        private float m_StepInterval;  
        [SerializeField]  
        private AudioClip[] m_FootstepSounds;    // an array of footstep sounds that will be randomly selected from.  
        [SerializeField]  
        private AudioClip m_JumpSound;           // the sound played when character leaves the ground.  
        [SerializeField]  
        private AudioClip m_LandSound;           // the sound played when character touches back on ground.  
        private Camera m_Camera;  
        private bool m_Jump;  
        private float m_YRotation;  
        private Vector2 m_Input;  
        private Vector3 m_MoveDir = Vector3.zero;  
        private CharacterController m_CharacterController;  
        private CollisionFlags m_CollisionFlags;  
        private bool m_PreviouslyGrounded;  
        //private Vector3 m_OriginalCameraPosition;  
        private float m_StepCycle;  
        private float m_NextStep;  
        private bool m_Jumping;  
        private AudioSource m_AudioSource;  
        // Use this for initialization  
        private void Start()  
        {  
            m_CharacterController = GetComponent<CharacterController>();  
            m_Camera = Camera.main;  
            //m_OriginalCameraPosition = m_Camera.transform.localPosition;  
            m_FovKick.Setup(m_Camera);  
            m_HeadBob.Setup(m_Camera, m_StepInterval);  
            m_StepCycle = 0f;  
            m_NextStep = m_StepCycle / 2f;  
            m_Jumping = false;  
            m_AudioSource = GetComponent<AudioSource>();  
            m_MouseLook.Init(transform, m_Camera.transform);  
        }  
        // Update is called once per frame  
        private void Update()  
        {  
            RotateView();  
            // the jump state needs to read here to make sure it is not missed  
            if (!m_Jump)  
            {  
                m_Jump = CrossPlatformInputManager.GetButtonDown("Jump");  
            }  
            if (!m_PreviouslyGrounded && m_CharacterController.isGrounded)  
            {  
                StartCoroutine(m_JumpBob.DoBobCycle());  
                PlayLandingSound();  
                m_MoveDir.y = 0f;  
                m_Jumping = false;  
            }  
            if (!m_CharacterController.isGrounded && !m_Jumping && m_PreviouslyGrounded)  
            {  
                m_MoveDir.y = 0f;  
            }  
            m_PreviouslyGrounded = m_CharacterController.isGrounded;  
        }  
        private void PlayLandingSound()  
        {  
            m_AudioSource.clip = m_LandSound;  
            m_AudioSource.Play();  
            m_NextStep = m_StepCycle + .5f;  
        }  
        private void LateUpdate()  
        {  
            float speed;  
            GetInput(out speed);  
            if (m_Input.x != 0 || m_Input.y != 0)  
            {  
                transform.GetChild(0).localPosition = new Vector3(0, 0.8f, 0);  
            }  
            // always move along the camera forward as it is the direction that it being aimed at  
            Vector3 desiredMove = transform.forward * m_Input.y + transform.right * m_Input.x;  
            // get a normal for the surface that is being touched to move along it  
            RaycastHit hitInfo;  
            Physics.SphereCast(transform.position, m_CharacterController.radius, Vector3.down, out hitInfo,  
                               m_CharacterController.height / 2f, ~0, QueryTriggerInteraction.Ignore);  
            desiredMove = Vector3.ProjectOnPlane(desiredMove, hitInfo.normal).normalized;  
            m_MoveDir.x = desiredMove.x * speed;  
            m_MoveDir.z = desiredMove.z * speed;  
            if (m_CharacterController.isGrounded)  
            {  
                m_MoveDir.y = -m_StickToGroundForce;  
                if (m_Jump)  
                {  
                    m_MoveDir.y = m_JumpSpeed;  
                    PlayJumpSound();  
                    m_Jump = false;  
                    m_Jumping = true;  
                }  
            }  
            else  
            {  
                m_MoveDir += Physics.gravity * m_GravityMultiplier * Time.fixedDeltaTime;  
            }  
            m_CollisionFlags = m_CharacterController.Move(m_MoveDir * Time.fixedDeltaTime);  
            ProgressStepCycle(speed);  
            UpdateCameraPosition(speed);  
        }  
        private void PlayJumpSound()  
        {  
            m_AudioSource.clip = m_JumpSound;  
            m_AudioSource.Play();  
        }  
        private void ProgressStepCycle(float speed)  
        {  
            if (m_CharacterController.velocity.sqrMagnitude > 0 && (m_Input.x != 0 || m_Input.y != 0))  
            {  
                m_StepCycle += (m_CharacterController.velocity.magnitude + (speed * (m_IsWalking ? 1f : m_RunstepLenghten))) *  
                             Time.fixedDeltaTime;  
            }  
            if (!(m_StepCycle > m_NextStep))  
            {  
                return;  
            }  
            m_NextStep = m_StepCycle + m_StepInterval;  
            PlayFootStepAudio();  
        }  
        private void PlayFootStepAudio()  
        {  
            if (!m_CharacterController.isGrounded)  
            {  
                return;  
            }  
            // pick & play a random footstep sound from the array,  
            // excluding sound at index 0  
            int n = Random.Range(1, m_FootstepSounds.Length);  
            m_AudioSource.clip = m_FootstepSounds[n];  
            m_AudioSource.PlayOneShot(m_AudioSource.clip);  
            // move picked sound to index 0 so it's not picked next time  
            m_FootstepSounds[n] = m_FootstepSounds[0];  
            m_FootstepSounds[0] = m_AudioSource.clip;  
        }  
        private void UpdateCameraPosition(float speed)  
        {  
            //Vector3 newCameraPosition;  
            //if (!m_UseHeadBob)  
            //{  
            //    return;  
            //}  
            //if (m_CharacterController.velocity.magnitude > 0 && m_CharacterController.isGrounded)  
            //{  
            //    m_Camera.transform.localPosition =  
            //        m_HeadBob.DoHeadBob(m_CharacterController.velocity.magnitude +  
            //                          (speed*(m_IsWalking ? 1f : m_RunstepLenghten)));  
            //    newCameraPosition = m_Camera.transform.localPosition;  
            //    newCameraPosition.y = m_Camera.transform.localPosition.y - m_JumpBob.Offset();  
            //}  
            //else  
            //{  
            //    newCameraPosition = m_Camera.transform.localPosition;  
            //    newCameraPosition.y = m_OriginalCameraPosition.y - m_JumpBob.Offset();  
            //}  
            //m_Camera.transform.localPosition = newCameraPosition;  
        }  
        private void GetInput(out float speed)  
        {  
            // Read input  
            float horizontal = CrossPlatformInputManager.GetAxis("Horizontal");  
            float vertical = CrossPlatformInputManager.GetAxis("Vertical");  
            bool waswalking = m_IsWalking;  
#if !MOBILE_INPUT  
            // On standalone builds, walk/run speed is modified by a key press.  
            // keep track of whether or not the character is walking or running  
            m_IsWalking = !Input.GetKey(KeyCode.LeftShift);  
#endif  
            // set the desired speed to be walking or running  
            speed = m_IsWalking ? m_WalkSpeed : m_RunSpeed;  
            m_Input = new Vector2(horizontal, vertical);  
            // normalize input if it exceeds 1 in combined length:  
            if (m_Input.sqrMagnitude > 1)  
            {  
                m_Input.Normalize();  
            }  
            // handle speed change to give an fov kick  
            // only if the player is going to a run, is running and the fovkick is to be used  
            if (m_IsWalking != waswalking && m_UseFovKick && m_CharacterController.velocity.sqrMagnitude > 0)  
            {  
                StopAllCoroutines();  
                StartCoroutine(!m_IsWalking ? m_FovKick.FOVKickUp() : m_FovKick.FOVKickDown());  
            }  
        }  
        private void RotateView()  
        {  
            m_MouseLook.LookRotation(transform, m_Camera.transform);  
        }  
        private void OnControllerColliderHit(ControllerColliderHit hit)  
        {  
            Rigidbody body = hit.collider.attachedRigidbody;  
            //dont move the rigidbody if the character is on top of it  
            if (m_CollisionFlags == CollisionFlags.Below)  
            {  
                return;  
            }  
            if (body == null || body.isKinematic)  
            {  
                return;  
            }  
            body.AddForceAtPosition(m_CharacterController.velocity * 0.1f, hit.point, ForceMode.Impulse);  
        }  
    }  
}

using System;  
using UnityEngine;  
using UnityStandardAssets.CrossPlatformInput;  
namespace UnityStandardAssets.Characters.FirstPerson  
{  
    [Serializable]  
    public class MouseLook  
    {  
        public float XSensitivity = 2f;  
        public float YSensitivity = 2f;  
        public bool clampVerticalRotation = true;  
        public float MinimumX = -90F;  
        public float MaximumX = 90F;  
        public bool smooth;  
        public float smoothTime = 5f;  
        //private Quaternion m_CharacterTargetRot;  
        //private Quaternion m_CameraTargetRot;  
        public void Init(Transform character, Transform camera)  
        {  
            //m_CharacterTargetRot = character.localRotation;  
            //m_CameraTargetRot = camera.localRotation;  
        }  
        public void LookRotation(Transform character, Transform camera)  
        {  
            if (!Input.GetMouseButton(1))  
                return;  
            //float yRot = CrossPlatformInputManager.GetAxis("Mouse X") * XSensitivity;  
            //float xRot = CrossPlatformInputManager.GetAxis("Mouse Y") * YSensitivity;  
            //m_CharacterTargetRot *= Quaternion.Euler(0f, yRot, 0f);  
            //m_CameraTargetRot *= Quaternion.Euler(-xRot, 0f, 0f);  
            //if (clampVerticalRotation)  
            //    m_CameraTargetRot = ClampRotationAroundXAxis(m_CameraTargetRot);  
            //if (smooth)  
            //{  
            //    character.localRotation = Quaternion.Slerp(character.localRotation, m_CharacterTargetRot, smoothTime * Time.deltaTime);  
            //    camera.localRotation = Quaternion.Slerp(camera.localRotation, m_CameraTargetRot, smoothTime * Time.deltaTime);  
            //    Debug.Log("跳转旋转----------》》》》 X");  
            //}  
            //else  
            //{  
            //    character.localRotation = m_CharacterTargetRot;  
            //    camera.localRotation = m_CameraTargetRot;  
            //    Debug.Log("---------- ++++ Y");  
            //}  
            float yRot = Input.GetAxis("Mouse X") * XSensitivity;  
            float xRot = Input.GetAxis("Mouse Y") * YSensitivity;  
            Vector3 yEuler = character.localEulerAngles + new Vector3(0, yRot, 0);  
            Vector3 xEuler = camera.localEulerAngles - new Vector3(xRot, 0, 0);  
            xEuler = ClampRotate(xEuler);  
            character.localEulerAngles = yEuler;  
            camera.localEulerAngles = xEuler;  
        }  
        Vector3 ClampRotate(Vector3 rotate)  
        {  
            if (rotate.x < 180)  
            {  
                rotate.x = Mathf.Clamp(rotate.x, -45, 45);  
            }  
            else  
            {  
                rotate.x = Mathf.Clamp(rotate.x, 315, 360);  
            }  
            return rotate;  
        }  
        Quaternion ClampRotationAroundXAxis(Quaternion q)  
        {  
            q.x /= q.w;  
            q.y /= q.w;  
            q.z /= q.w;  
            q.w = 1.0f;  
            float angleX = 2.0f * Mathf.Rad2Deg * Mathf.Atan(q.x);  
            angleX = Mathf.Clamp(angleX, MinimumX, MaximumX);  
            q.x = Mathf.Tan(0.5f * Mathf.Deg2Rad * angleX);  
            return q;  
        }  
    }  
}  

如社区发表内容存在侵权行为,您可以点击这里查看侵权投诉指引