版本:unity 5.3.4  语言:C#

 

有段时间没写了,主要在忙考核期的任务,可能还是不是很适应公司的环境,最近负能量有点多,不过我已经把那些悲情的歌删除了,应该没事了。

 

之前一段时间迷上了RimWorld,玩到了4点半,第二天精神饱满的上班了,不过这是在玩命吧。但总是学习的话感觉给自己压力太大了,所以是养成习惯,而不是逼出习惯来吧?总之我还是抱着能改善自己生活的想法来工作和学习,希望哪天自己也能成个学霸。

 

还有最近比较关心的是FF15和PS4 Pro了,英亚上好便宜啊,就是暂时买不起,希望过一两个月不要涨价,没涨就入了。

 

好了,正题了,工作上的事情差不多就抽空写写,这些脚本反复接触的话,我觉得自己在解决问题的时候思路也会广很多。

 

今天主要带来两个脚本,一个脚本其实在某脚本中有集成,只不过基础包为刚体FPS新建了一个,思路是一样的,那就是HeadBob,主要控制镜头的摇动:

// 镜头摇动脚本,之前的非刚体FPS脚本是直接集成在脚本中的
public class HeadBob : MonoBehaviour
{
    public Camera Camera;   //当前使用的Camera
    public CurveControlledBob motionBob = new CurveControlledBob(); //曲线摇动控制器,主要控制移动时相机的x、y轴移动
    public LerpControlledBob jumpAndLandingBob = new LerpControlledBob();   //插值摇动控制器,跳跃着陆时y轴的下降和还原
    public RigidbodyFirstPersonController rigidbodyFirstPersonController;   //刚体FPS脚本
    public float StrideInterval;    //步伐的间隔
    [Range(0f, 1f)] public float RunningStrideLengthen; //奔跑步伐延长

    //private CameraRefocus m_CameraRefocus;    //重调相机聚焦,这个脚本主要用于如果看到物体,则强制往前看,不允许镜头上下移动,感觉没什么用,所以注释了吧
    private bool m_PreviouslyGrounded;  //之前的状态是否在地上
    private Vector3 m_OriginalCameraPosition;   //相机的起源位置

    // 初始化
    private void Start()
    {
        motionBob.Setup(Camera, StrideInterval);
        m_OriginalCameraPosition = Camera.transform.localPosition;
        //m_CameraRefocus = new CameraRefocus(Camera, transform.root.transform, Camera.transform.localPosition);
    }


    private void Update()
    {
        //m_CameraRefocus.GetFocusPoint();
        Vector3 newCameraPosition;
        if (rigidbodyFirstPersonController.Velocity.magnitude > 0 && rigidbodyFirstPersonController.Grounded)
        {
            // 在陆地上并且在移动时,根据镜头摇动计算出新的坐标
            Camera.transform.localPosition = motionBob.DoHeadBob(rigidbodyFirstPersonController.Velocity.magnitude*(rigidbodyFirstPersonController.Running ? RunningStrideLengthen : 1f));  //这边如果在奔跑状态下,步伐长度增加
            newCameraPosition = Camera.transform.localPosition;
            newCameraPosition.y = Camera.transform.localPosition.y - jumpAndLandingBob.Offset();    //减去一个跳跃后下沉的值
        }
        else
        {
            // 其他情况
            newCameraPosition = Camera.transform.localPosition;
            newCameraPosition.y = m_OriginalCameraPosition.y - jumpAndLandingBob.Offset();
        }
        Camera.transform.localPosition = newCameraPosition;

        // 刚着陆,开始下沉的计算
        if (!m_PreviouslyGrounded && rigidbodyFirstPersonController.Grounded)
        {
            StartCoroutine(jumpAndLandingBob.DoBobCycle());
        }

        m_PreviouslyGrounded = rigidbodyFirstPersonController.Grounded; //把是否着陆的状态存储
        //m_CameraRefocus.SetFocusPoint();
    }
}



是否注意到unity团队把CameraRefocus注释了,然后我就打开了,对比了一下前后的结果,然后去分析了一下,哈哈,这就是下一个要说的脚本:



// 相机重聚焦脚本,在HeadBob中是被注释掉的,不清楚有什么历史渊源
public class CameraRefocus
{
    public Camera Camera;   //相机
    public Vector3 Lookatpoint; //观察对象坐标
    public Transform Parent;    //父对象的坐标,这边传入的就是角色层的坐标

    private Vector3 m_OrigCameraPos;    //相机的起源坐标
    private bool m_Refocus; //是否重聚焦

    // 初始化,这边的parent传入的是transform.root即最上层节点,就是相机层的父节点
    public CameraRefocus(Camera camera, Transform parent, Vector3 origCameraPos)
    {
        m_OrigCameraPos = origCameraPos;    //相机起源坐标
        Camera = camera;    //相机层和角色层
        Parent = parent;
    }

    // 相机和父节点的改变
    public void ChangeCamera(Camera camera)
    {
        Camera = camera;
    }

    public void ChangeParent(Transform parent)
    {
        Parent = parent;
    }

    // 获取聚焦点
    public void GetFocusPoint()
    {
        RaycastHit hitInfo;
        if (Physics.Raycast(Parent.transform.position + m_OrigCameraPos, Parent.transform.forward, out hitInfo, //从相机的坐标往角色的前方放出一条射线
                            100f))
        {
            Lookatpoint = hitInfo.point;    //记录碰到的物体上坐标
            m_Refocus = true;
            return;
        }
        m_Refocus = false;
    }

    // 设置聚焦点
    // 如果看到物体,则强制往前看,不允许镜头上下移动
    public void SetFocusPoint()
    {
        if (m_Refocus)
        {
            Camera.transform.LookAt(Lookatpoint);
        }
    }
}



反正是我上面注释所说的效果,不过我不太清楚在什么情况下会用到,限定镜头角度范围的话,也不会这么做吧。