using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Cinemachine;
/// <summary>
/// 相机抖动
/// 一定要放在cinemachine brain 控件里面
/// </summary>
public class CinemachineController : MonoBehaviour
{
public static CinemachineController Instance { get; private set; }
public CinemachineVirtualCamera cinemachineVirtualCamera;
CinemachineBrain cinemachineBrain;//cm的核心
CinemachineVirtualCameraBase cinemachineVirtualCameraBase;//virtualcamera 的基类
CinemachineBasicMultiChannelPerlin[] cinemachineBasicMultiChannelPerlins;//这里是获取所有的rig来设置noise
float shakeTimer;//抖动时间
float shakeTimerTotal;//抖动总时间
float startingIntensity;//抖动强度
private void Awake()
{
cinemachineBrain = GetComponent<CinemachineBrain>();
Instance = this;
}
/// <summary>
/// 相机抖动
/// </summary>
/// <param name="intensity">强度 </param>
/// <param name="time">持续时间</param>
public void ShakeCamera(float intensity, float time)
{
if (cinemachineBrain.ActiveVirtualCamera != null)
{
//if (debug) cineName = cinemachineBrain.ActiveVirtualCamera.VirtualCameraGameObject.name + "[CinemachineShake.cs]";//deubug 相机名称
cinemachineVirtualCameraBase = cinemachineBrain.ActiveVirtualCamera.VirtualCameraGameObject.GetComponent<CinemachineVirtualCameraBase>();//获取当前虚拟相机的基类
cinemachineBasicMultiChannelPerlins = cinemachineVirtualCameraBase.GetComponentsInChildren<CinemachineBasicMultiChannelPerlin>();//获取该虚拟相机下的noise 设置
}
if (cinemachineBasicMultiChannelPerlins.Length > 0)
{
foreach (var item in cinemachineBasicMultiChannelPerlins)
{
item.m_AmplitudeGain = intensity;
}
startingIntensity = intensity;
shakeTimerTotal = time;
shakeTimer = time;
}
}
private void Update()
{
if (shakeTimer > 0)
{
shakeTimer -= Time.deltaTime;
float lerpValue = Mathf.Lerp(startingIntensity, 0f, shakeTimer / shakeTimerTotal); //线性方式慢慢减小
if (shakeTimer < 0)lerpValue = 0f;//这里会出现负数的情况,正常来说应该是为0,暂时用判断解决 20210802
foreach (var item in cinemachineBasicMultiChannelPerlins)
{
item.m_AmplitudeGain = lerpValue;
}
}
}
#region Soft
/// <summary>
/// 设置虚拟相机 soft值
/// </summary>
public void SetCameraSoft( )
{
if (cinemachineBrain.ActiveVirtualCamera != null)
{
StartCoroutine(Soft());
}
}
IEnumerator Soft()
{
var virtualcamera = cinemachineBrain.ActiveVirtualCamera.VirtualCameraGameObject.GetComponent<CinemachineVirtualCamera>();
if (virtualcamera == null)
{
yield return null;
}
else
{
var group = virtualcamera.GetCinemachineComponent<CinemachineGroupComposer>();
group.m_SoftZoneHeight = 0.8f;
group.m_SoftZoneWidth = 0.8f;
while (group.m_SoftZoneHeight + group.m_SoftZoneWidth > 0.01)
{
group.m_SoftZoneHeight = Mathf.Lerp(group.m_SoftZoneHeight, 0, .2f);
group.m_SoftZoneWidth = Mathf.Lerp(group.m_SoftZoneWidth, 0, .2f);
yield return null;
}
group.m_SoftZoneHeight = 0;
group.m_SoftZoneWidth = 0;
}
}
#endregion
#region 设置相机瞄准新对象
public void SetNewLookAt(Transform transform)
{
if (cinemachineBrain.ActiveVirtualCamera != null)
{
cinemachineVirtualCameraBase = cinemachineBrain.ActiveVirtualCamera.VirtualCameraGameObject.GetComponent<CinemachineVirtualCameraBase>();//获取当前虚拟相机的基类
cinemachineVirtualCameraBase.LookAt = transform;
}
}
#endregion
}
使用的方式
**获取到正在使用的相机,给每个相机增加nois效果**
CinemachineBrain cinemachineBrain;//cm的核心
cinemachineBrain.ActiveVirtualCamera.Name; //当前被激活的相机的名字
CinemachineVirtualCameraBase cinemachineVirtualCameraBase;//virtualcamera 的基类
虚拟相机继承于 CinemachineVirtualCameraBase
CinemachineFreeLook 中 三个节点 [ RigNames { "TopRig", "MiddleRig", "BottomRig" } ],每个rig 都包含了 CinemachineVirtualCamera ,而每个virtual camera 都会有 niose 组件。
cinemachineBasicMultiChannelPerlins = cinemachineVirtualCameraBase.GetComponentsInChildren<CinemachineBasicMultiChannelPerlin>();
获取到后就可以对每个相机进行操作了。
注意:该相机的noise设置为空的话,是获取不到任何值的,就不会有任何效果;可以尝试在代码中自定义添加个这个组件。
初学unity,在这里抛砖引玉,有更好的方式可以一起讨论
----------------------------------------------
2021-09-15
新增 虚拟相机 soft方法,用于virtualcamera。[锁定相机]