加载中…
个人资料
  • 博客等级:
  • 博客积分:
  • 博客访问:
  • 关注人气:
  • 获赠金笔:0支
  • 赠出金笔:0支
  • 荣誉徽章:
正文 字体大小:

Unity基础包 FirstPersonController下的MouseLook 脚本研究

(2016-11-07 16:59:35)
标签:

unity3d

unity

脚本

mouselook

基础包

分类: Unity起航

版本:unity 5.3.4  语言:C#

 

又不知道要做什么了,这周周末把Animator的基础部分刷了,跟模型结合的比较紧密,代码其实没什么,就是非常羡慕熟练操作3dsmax的美工们。

 

反正看看基础包吧,上一次的FirstPersonController写的不是很详细,这次我尽量写的详细一点,只是四元数这个玩意我还是不太理解,还是Euler角容易一些。

 

看看这里面的代码,虽然半蒙半猜还算看得懂,但什么时候自己也能写出如此优秀的代码呢?

 

今天分析了一下MouseLook,主要是处理人物和镜头的旋转:

public class MouseLook

{

    public float XSensitivity = 2f; //x轴和y轴的灵敏度

    public float YSensitivity = 2f;

 

    public bool clampVerticalRotation = true;   //是否锁定x轴的旋转角度,旋转的解释见下

    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;   //当前鼠标指针是否锁定,只有lockCursor为true的时候,该值才会有效

 

    // 初始化,传入角色和相机的旋转角度

    public void Init(Transform character, Transform camera)

    {

        m_CharacterTargetRot = character.localRotation; //角色的旋转角度

        m_CameraTargetRot = camera.localRotation;   //相机的旋转角度

    }

 

    // FirstPersonController每帧会调用

    // 根据鼠标移动的位置调整镜头的旋转

    public void LookRotation(Transform character, Transform camera)

    {

        // 获取鼠标的位置,乘以灵敏度,获取x轴y轴的旋转

        // 注意这边的位置是相对位置,也就是这一帧和上一帧的相对移动位置

        float yRot = CrossPlatformInputManager.GetAxis("Mouse X") * XSensitivity;   

        float xRot = CrossPlatformInputManager.GetAxis("Mouse Y") * YSensitivity;

 

        // 旋转,y轴旋转角色,x轴旋转镜头,也就是说横向的旋转是旋转的角色,而纵向的旋转是旋转镜头。

        // 这里有个好处,就是镜头Camera节点是在FPC节点下面的,所以旋转了角色的同时也会旋转镜头,同时兼顾了旋转角色的正方向。

        // 而纵向的旋转,其实对实际角色而言没有任何影响,所以只要旋转镜头即可,这种分层次的旋转十分有用。

        m_CharacterTargetRot *= Quaternion.Euler (0f, yRot, 0f);    //然后说一下这边API的使用,大家刚看到一个乘法,可能跟我一样有些懵逼,不过这边乘以一个欧拉角,相当于旋转增加该值,而增加的就是Transform面板上Rotation的值了,所以要使用面板Rotation值的话一定要记住使用欧拉角,而不是普通的创建,普通的创建那是四元数

        m_CameraTargetRot *= Quaternion.Euler(-xRot, 0f, 0f);

 

        // 锁定x轴的旋转角度

        if(clampVerticalRotation)

            m_CameraTargetRot = ClampRotationAroundXAxis (m_CameraTargetRot);

 

        if(smooth)  //使用插值运算平滑旋转速度,不过我打开了感觉头晕,不知道为什么。第三人称用这类插值运算应该很舒服。

        {

            // Slerp使用球形进行插值

            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();

    }

 

    public void SetCursorLock(bool value)

    {

        lockCursor = value;

        if(!lockCursor)

        {

            // 如果用户主动设置lockCursor,即InternalLockUpdate不会影响是否锁定指针,则我们强制解锁指针

            // 也就是说,lockCursor为true时快捷键影响锁定指针,lockCursor为false的时候快捷键不影响,并强制不锁指针

            Cursor.lockState = CursorLockMode.None;

            Cursor.visible = true;

        }

    }

 

    // 鼠标指针锁定有关,FirstPersonController的Update中会调用一次外,MouseLook的LookRotation中也会调用一次

    public void UpdateCursorLock()

    {

        //如果设置lockCursor,则检查确认是否要锁定指针

        if (lockCursor)

            InternalLockUpdate();

    }

 

    private void InternalLockUpdate()

    {

        if(Input.GetKeyUp(KeyCode.Escape))  //按下esc,退出指针锁定

        {

            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;

        }

    }

 

    // 锁定镜头的旋转角度,镜头只跟X轴旋转有关

    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;

    }

 

}

 

OK,我会继续分析基础包中剩下的代码的,同时也会加把劲把Unity书中基础部分给刷掉。

0

阅读 收藏 喜欢 打印举报/Report
  

新浪BLOG意见反馈留言板 欢迎批评指正

新浪简介 | About Sina | 广告服务 | 联系我们 | 招聘信息 | 网站律师 | SINA English | 产品答疑

新浪公司 版权所有