今天实现的内容:
震屏效果逻辑
震屏效果,也就是射击时给予摄像机的旋转一个偏移量,再逐渐复原。我们写了一个弹簧工具来帮助实现上述效果。
这个工具主要是用来将产生偏移后的摄像机逐渐归正。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
// 摄像机弹簧工具 用于帮助实现摄像机震屏效果
public class CameraSpringUtility
{
// 震屏强度参数
[HideInInspector]
public Vector3 value;
// 频率
private float m_frequence;
// 阻尼
private Vector3 m_damp;
// 阻尼大小
private float m_dampValue;
// 构造函数
public CameraSpringUtility(float _frequence, float _dampValue)
{
m_frequence = _frequence;
m_dampValue = _dampValue;
}
// 运用阻尼 更新value
public void UpdateSpring(float _deltaTime, Vector3 _target) //_target是指阻尼要恢复到的位置 一般是zero
{
// 运用阻尼
value -= _deltaTime * m_frequence * m_damp;
// 计算阻尼
m_damp = Vector3.Lerp(m_damp, value - _target, m_dampValue * _deltaTime);
}
}
其中,m_frequence用于振动频率的控制,越大抖的越快,但是好像没什么具体作用,毕竟抖动频率应该只和开火频率有关,m_frequence这样用应该也只是又一个用于调整归正速度的参数。m_dampValue才是我们真正想要用来调整归正速度的参数,其控制插值的t大小。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
// 相机弹簧 用于实现相机震屏功能
public class CameraSpring : MonoBehaviour
{
// Y轴、Z轴的最小反冲范围
public Vector2 minRecoilRange;
// Y轴、Z轴的最大反冲范围
public Vector2 maxRecoilRange;
// 振动频率
[Tooltip("振动频率")]
public float frequence = 25f;
// 阻尼大小
[Tooltip("阻尼大小")]
public float dampValue = 15f;
// 摄像机弹簧工具
private CameraSpringUtility springUtility;
// 缓存摄像机的Transform
private Transform cameraSpringTransform;
// 开始震屏
public void StartCameraSpring()
{
// 将一个随机的震屏强度赋给springUtility.value
springUtility.value = new Vector3(0,
Random.Range(minRecoilRange.x, maxRecoilRange.x),
Random.Range(minRecoilRange.y, maxRecoilRange.y));
}
private void Start()
{
springUtility = new CameraSpringUtility(frequence, dampValue);
cameraSpringTransform = this.transform;
}
private void Update()
{
springUtility.UpdateSpring(Time.deltaTime, Vector3.zero);
cameraSpringTransform.localRotation = Quaternion.Slerp(
cameraSpringTransform.localRotation,
Quaternion.Euler(springUtility.value),
Time.deltaTime * 10f);
}
}
以上代码将一个随机的旋转偏移量运用到摄像机来达到震屏效果,再调用springUtility.UpdateSpring(Time.deltaTime, Vector3.zero);来归正摄像机。
// 使用后坐力 交给外部枪械脚本来使用
public void DoRecoil()
{
m_currentRecoil += recoilRange;
m_currentRecoilTime = 0; //将开枪时间设置为0
cameraSpring.StartCameraSpring();
}
脚本的运用
由于摄像机震屏和后坐力的产生原因都是因为开火,所以在运用后坐力的函数DoRecoil中调用cameraSpring.StartCameraSpring();就可以实现效果。
最后,将CameraSpring脚本挂到一个作为摄像机的节点之下的一个节点,如果你愿意,可以让振动只作用于摄像机,我这里振动依旧会作用到枪上。
BUG以及缺陷:
暂无
值得注意的:
将这个CameraVibrationHolder放到真正的摄像机的上一级就行了,这样就只会作用到摄像机。
如果你的项目单独设置了一个GunCamera,也可以将GunCamera也放到Holder下面。