第一人称FPS视角跟随(Unity3D官方script)

Unity官方版本都已经更新的2017.2的了,官方的案例和使用脚本还是挺给力的,而且还经常有更新优化脚本。今天把官方的一个FPS视角脚本贴出来,同时加上了自己的一些理解注释。
想要获得完整的官方案例([Standard Assets Example](https://unity3d.com/cn/get-unity/download/archive?_ga=2.42565285.10319038.1509089568-1430363113.1505441910))的可以自己去官网下载,如果你嫌麻烦的话也可以给我评论,我到时放到网盘上。

![这里写图片描述](https://img-blog.csdn.net/20171027155652190?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvSm9leUh1YW5neng=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
代码送上
using System;
using UnityEngine;
using UnityStandardAssets.CrossPlatformInput;

namespace UnityStandardAssets.Characters.FirstPerson
{
    //序列化,显示在Inspector里
    [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;
        public bool lockCursor = true;


        private Quaternion m_CharacterTargetRot;
        private Quaternion m_CameraTargetRot;
        private bool m_cursorIsLocked = true;

        public void Init(Transform character, Transform camera)
        {
            m_CharacterTargetRot = character.localRotation;
            m_CameraTargetRot = camera.localRotation;
        }


        public void LookRotation(Transform character, Transform camera)
        {
            //float yRot = CrossPlatformInputManager.GetAxis("Mouse X") * XSensitivity;
            //float xRot = CrossPlatformInputManager.GetAxis("Mouse Y") * YSensitivity;

            float yRot = Input.GetAxis("Mouse X") * XSensitivity;
            float xRot = Input.GetAxis("Mouse Y") * YSensitivity;

            //返回围绕着Y轴旋转的一个旋转
            m_CharacterTargetRot *= Quaternion.Euler (0f, yRot, 0f);
            //返回围绕着X轴旋转的一个旋转
            m_CameraTargetRot *= Quaternion.Euler (-xRot, 0f, 0f);

            //限制X轴的旋转范围
            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);
            }
            else
            {
                character.localRotation = m_CharacterTargetRot;
                camera.localRotation = m_CameraTargetRot;
            }

            UpdateCursorLock();
        }

        /// <summary>
        /// 保证在绕X轴选择的角度值在限制范围内
        /// </summary>
        /// <param name="q"></param>
        /// <returns></returns>
        Quaternion ClampRotationAroundXAxis(Quaternion q)
        {
            //根据四元数的公式,这个运算得出来一个tan(angle)值
            //q.x=n* sin(angle/2) 在这里sin里面是一个弧度值
            //q.w=cos(angle/2)
            //q.x=sin(angle/2)/cos(angle/2)=tan(angle/2)
            q.x /= q.w;
            q.y /= q.w;
            q.z /= q.w;
            q.w = 1.0f;

            //q.x=tan(angle/2);
            //angle= 2*Atan(q.x)(弧度,要转角度)=2 * Mathf.Rad2Deg * Mathf.Atan (q.x);
            float angleX = 2.0f * Mathf.Rad2Deg * Mathf.Atan(q.x);

            angleX = Mathf.Clamp(angleX, MinimumX, MaximumX);
            //如果angle的值没有超过min,max,那转换前后的值是一样的。
            //如果angle的值小于min或者大于max了,那么angle的取值就发送了变化,这时候就又要重新转换下
            //这个就是上面那个angle公式的逆运算了
            q.x = Mathf.Tan(0.5f * Mathf.Deg2Rad * angleX);

            return q;
        }

        public void SetCursorLock(bool value)
        {
            lockCursor = value;
            if(!lockCursor)
            {//we force unlock the cursor if the user disable the cursor locking helper
                Cursor.lockState = CursorLockMode.None;
                Cursor.visible = true;
            }
        }

        public void UpdateCursorLock()
        {
            //if the user set "lockCursor" we check & properly lock the cursos
            if (lockCursor)
                InternalLockUpdate();
        }

        /// <summary>
        /// 鼠标的状态
        /// </summary>
        private void InternalLockUpdate()
        {
            if(Input.GetKeyUp(KeyCode.Escape))
            {
                m_cursorIsLocked = false;
            }
            else if(Input.GetMouseButtonUp(0))
            {
                m_cursorIsLocked = true;
            }

            if (m_cursorIsLocked)
            {
                Cursor.lockState = CursorLockMode.Locked;
                Cursor.visible = false;
            }
            else if (!m_cursorIsLocked)
            {
                Cursor.lockState = CursorLockMode.None;
                Cursor.visible = true;
            }
        }
    }
}

然后我们给场景加个“人物”,人物上挂个脚本,在人物GameObject下面我们把相机放到这里,脚本上控制MouseLook初始化和在Update里实时调用旋转函数就可以了。
这里写图片描述

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Joey;
using UnityStandardAssets.Characters.FirstPerson;

public class Controller : MonoBehaviour {
    [SerializeField]
    private MouseLook ml;
    public Camera mCamera;

    // Use this for initialization
    void Start () {
        mCamera = Camera.main;
        ml.Init(transform,mCamera.transform);
    }

    // Update is called once per frame
    void Update () {

        ml.LookRotation(transform, mCamera.transform);
    }
}

其实我觉得官方一些视频教程非常不错的,学会了那些基本的Unity3D基础就会了,只是要翻墙,因为里面的视频都是挂在youtube上的,还是英文的。很后悔当初没有学好英文啊。

官方视频教程链接:https://unity3d.com/cn/learn/tutorials

发布了6 篇原创文章 · 获赞 3 · 访问量 6665

猜你喜欢

转载自blog.csdn.net/JoeyHuangzx/article/details/78365815