Unity基础包 FirstPersonController下的CurveControlledBob和LerpContolledBob 脚本研究
2016-11-08 14:22
381 查看
版本:unity 5.3.4 语言:C#
FirstPersonController的最后两个脚本,代码量不是很多,就一起贴上来了。
虽然这最后的两个脚本是比较容易的,不过它们跟之前的脚本融合起来,形成的一种分层而治的思想很有意思。
这跟没有锚点的话就多加一层的思想是类似的。
下面是脚本的解析,首先是控制头部镜头晃动的CurveControlledBob:
// 曲线摇晃控制器
// 该脚本主要处理头部的摇动,会在FirstPersonController脚本的FixedUpdate函数中调用该类中的DoHeadBob,获取镜头的偏移
[Serializable]
public class CurveControlledBob
{
public float HorizontalBobRange = 0.33f; //水平和垂直的摇动范围
public float VerticalBobRange = 0.33f;
public AnimationCurve Bobcurve = new AnimationCurve(new Keyframe(0f, 0f), new Keyframe(0.5f, 1f),
new Keyframe(1f, 0f), new Keyframe(1.5f, -1f),
new Keyframe(2f, 0f)); // 摇动曲线,默认为正弦函数
public float VerticaltoHorizontalRatio = 1f; //垂直跟水平的比例
private float m_CyclePositionX; //循环的x、y坐标,用于计算当前摇动曲线在哪个位置
private float m_CyclePositionY;
private float m_BobBaseInterval; //摇动的步伐间隔,单位是米
private Vector3 m_OriginalCameraPosition; //Camera的起源位置
private float m_Time;
// 设置Camera和步伐间隔,然而这边不像FOVKick做个null的判断
public void Setup(Camera camera, float bobBaseInterval)
{
m_BobBaseInterval = bobBaseInterval; //将步伐间隔赋值,这边就是跨一步的间隔,脚本默认设置了5米
m_OriginalCameraPosition = camera.transform.localPosition; //获取一次Camera的基础位置
// 获取摇动曲线一次的总时间,即这边最后一个key的时间
m_Time = Bobcurve[Bobcurve.length - 1].time;
}
// 摇动
public Vector3 DoHeadBob(float speed)
{
// 计算Camera新的位置,按照默认位置,相当于镜头右上到左下的的来回移动,产生一个头部晃动的效果
float xPos = m_OriginalCameraPosition.x + (Bobcurve.Evaluate(m_CyclePositionX)*HorizontalBobRange);
float yPos = m_OriginalCameraPosition.y + (Bobcurve.Evaluate(m_CyclePositionY)*VerticalBobRange);
// 增加循环x、y坐标
m_CyclePositionX += (speed*Time.deltaTime)/m_BobBaseInterval;
m_CyclePositionY += ((speed*Time.deltaTime)/m_BobBaseInterval)*VerticaltoHorizontalRatio; //VerticaltoHorizontalRatio默认设置为1,但如果大于1则垂直比水平摇晃的快,反之慢,只是缩小或增大一次摇晃的间隔距离
// 超过设置的一次摇晃时间后重置
if (m_CyclePositionX > m_Time)
{
m_CyclePositionX = m_CyclePositionX - m_Time;
}
if (m_CyclePositionY > m_Time)
{
m_CyclePositionY = m_CyclePositionY - m_Time;
}
return new Vector3(xPos, yPos, 0f); //返回镜头的位置
}
}
以上脚本主要实现了一个曲线的控制,下面的插值控制只是单坐标轴的LerpContolledBob,那就更容易了:
至此FirstPersonController脚本全部讲解完毕了。
总结:
第一人称控制的预制体中分为两层:FPSController角色层、FirstPersonCharacter镜头层。
FirstPersonController主脚本控制Character Controller组件,用以控制角色层的Position;
MouseLock脚本控制角色层的y轴旋转和镜头层的x轴旋转;
FovKick和这次两个摇晃脚本控制镜头层的x、y轴的移动(晃动)。
FirstPersonController的最后两个脚本,代码量不是很多,就一起贴上来了。
虽然这最后的两个脚本是比较容易的,不过它们跟之前的脚本融合起来,形成的一种分层而治的思想很有意思。
这跟没有锚点的话就多加一层的思想是类似的。
下面是脚本的解析,首先是控制头部镜头晃动的CurveControlledBob:
// 曲线摇晃控制器
// 该脚本主要处理头部的摇动,会在FirstPersonController脚本的FixedUpdate函数中调用该类中的DoHeadBob,获取镜头的偏移
[Serializable]
public class CurveControlledBob
{
public float HorizontalBobRange = 0.33f; //水平和垂直的摇动范围
public float VerticalBobRange = 0.33f;
public AnimationCurve Bobcurve = new AnimationCurve(new Keyframe(0f, 0f), new Keyframe(0.5f, 1f),
new Keyframe(1f, 0f), new Keyframe(1.5f, -1f),
new Keyframe(2f, 0f)); // 摇动曲线,默认为正弦函数
public float VerticaltoHorizontalRatio = 1f; //垂直跟水平的比例
private float m_CyclePositionX; //循环的x、y坐标,用于计算当前摇动曲线在哪个位置
private float m_CyclePositionY;
private float m_BobBaseInterval; //摇动的步伐间隔,单位是米
private Vector3 m_OriginalCameraPosition; //Camera的起源位置
private float m_Time;
// 设置Camera和步伐间隔,然而这边不像FOVKick做个null的判断
public void Setup(Camera camera, float bobBaseInterval)
{
m_BobBaseInterval = bobBaseInterval; //将步伐间隔赋值,这边就是跨一步的间隔,脚本默认设置了5米
m_OriginalCameraPosition = camera.transform.localPosition; //获取一次Camera的基础位置
// 获取摇动曲线一次的总时间,即这边最后一个key的时间
m_Time = Bobcurve[Bobcurve.length - 1].time;
}
// 摇动
public Vector3 DoHeadBob(float speed)
{
// 计算Camera新的位置,按照默认位置,相当于镜头右上到左下的的来回移动,产生一个头部晃动的效果
float xPos = m_OriginalCameraPosition.x + (Bobcurve.Evaluate(m_CyclePositionX)*HorizontalBobRange);
float yPos = m_OriginalCameraPosition.y + (Bobcurve.Evaluate(m_CyclePositionY)*VerticalBobRange);
// 增加循环x、y坐标
m_CyclePositionX += (speed*Time.deltaTime)/m_BobBaseInterval;
m_CyclePositionY += ((speed*Time.deltaTime)/m_BobBaseInterval)*VerticaltoHorizontalRatio; //VerticaltoHorizontalRatio默认设置为1,但如果大于1则垂直比水平摇晃的快,反之慢,只是缩小或增大一次摇晃的间隔距离
// 超过设置的一次摇晃时间后重置
if (m_CyclePositionX > m_Time)
{
m_CyclePositionX = m_CyclePositionX - m_Time;
}
if (m_CyclePositionY > m_Time)
{
m_CyclePositionY = m_CyclePositionY - m_Time;
}
return new Vector3(xPos, yPos, 0f); //返回镜头的位置
}
}
以上脚本主要实现了一个曲线的控制,下面的插值控制只是单坐标轴的LerpContolledBob,那就更容易了:
// 插值摇晃控制器 // 插值摇动的控制器,这个只要角色着陆就会开始计算,Update中调用DoBobCycle,FixedUpdate中调用Offset设置Camera的y坐标 [Serializable] public class LerpControlledBob { public float BobDuration; //摇晃到最大值的时间,默认这边是0.2,而完成一次摇晃需要一次下沉和上升,所以是0.4秒 public float BobAmount; //摇晃的最大值 private float m_Offset = 0f; //当前偏移值 // 提供偏移值供上层脚本使用 public float Offset() { return m_Offset; } // 计算一次偏移值 public IEnumerator DoBobCycle() { // 使用Camera轻微的下沉一些,以模拟人着陆的效果 float t = 0f; while (t < BobDuration) { m_Offset = Mathf.Lerp(0f, BobAmount, t/BobDuration); //根据时间,进行一个插值运算,计算当前需要下沉的y坐标值 t += Time.deltaTime; yield return new WaitForFixedUpdate(); //等待下一次FixedUpate更新完毕 } // 跟上面是一个相反的操作 t = 0f; while (t < BobDuration) { m_Offset = Mathf.Lerp(BobAmount, 0f, t/BobDuration); t += Time.deltaTime; yield return new WaitForFixedUpdate(); } m_Offset = 0f; //归零 } }
至此FirstPersonController脚本全部讲解完毕了。
总结:
第一人称控制的预制体中分为两层:FPSController角色层、FirstPersonCharacter镜头层。
FirstPersonController主脚本控制Character Controller组件,用以控制角色层的Position;
MouseLock脚本控制角色层的y轴旋转和镜头层的x轴旋转;
FovKick和这次两个摇晃脚本控制镜头层的x、y轴的移动(晃动)。
相关文章推荐
- Unity基础包 FirstPersonController下的MouseLook 脚本研究
- Unity基础包 FirstPersonController 脚本研究
- Unity基础包 刚体FPS RigidbodyFirstPersonController 脚本研究
- Unity基础包 FirstPersonController下的MouseLook 脚本研究
- Unity基础包 FirstPersonController下的FOVKick 脚本研究
- Unity基础包 刚体FPS HeadBob和CameraRefocus 脚本研究
- Unity第一人称控制器脚本解析-FPSCharacterController( FirstPersonController)
- Unity鲍勃曲线控制(CurveControlledBob)
- Unity基础包 刚体球类 Ball和BallUserControl 脚本研究
- unity自带脚本ThirdPersonController.cs(收藏)
- unity标准资源包FirstPersonController的分析
- Unity基础包 刚体TPS类 3个第三人称脚本的研究
- unity脚本基础
- Unity基础|Unity脚本创建与执行
- Unity基础 - 脚本入门
- unity自带脚本ThirdPersonCamera.cs(收藏)
- 【Unity3D基础教程】给初学者看的Unity教程(二):所有脚本组件的基类 -- MonoBehaviour的前世今生
- Unity基础包 工具类 FPSCounter脚本显示帧率
- Unity CharacterController带重力,并移动角色脚本
- Unity脚本基础知识思维导图1.0