using System;
using System.Collections;
using System.Collections.Generic;
using Cinemachine;
using UnityEngine;
using UnityEngine.Rendering.HighDefinition;
///
/// Temporal effects needs to be reset in case of camera cut,
/// this is already handled in CinemachineVolumeSettings.OnCameraCut.
/// But Cinemachine cuts are not enough,
/// we are likely to see artefacts whenever the view changes abruptly
/// between two frames, and Cinemachine cut events only reflect virtual camera switches.
/// We must track camera movement ourselves and reset temporal effects based on camera motion
///
[RequireComponent(typeof(CinemachineBrain))]
public class AutoCameraCutController : MonoBehaviour
{
[SerializeField]
float m_Threshold;
CinemachineBrain m_Brain;
Vector3 m_PrevPosition;
const int k_WindowSize = 12;
float[] m_VelocityBuffer = new float[k_WindowSize];
int index;
void OnEnable()
{
m_Brain = GetComponent();
m_PrevPosition = m_Brain.transform.position;
index = 0;
// reset buffers
for (var i = 0; i != k_WindowSize; ++i)
m_VelocityBuffer[i] = 0;
}
void LateUpdate()
{
var position = m_Brain.OutputCamera.transform.position;
// compute current instantaneous value
var timeScale = 1.0f / Time.deltaTime;
var velocity = (position - m_PrevPosition).magnitude * timeScale;
// don't forget to update previous value
m_PrevPosition = position;
// compute average so that we can compare against it
var averageVelocity = 0f;
var mul = 1.0f / k_WindowSize;
for (var i = 0; i != k_WindowSize; ++i)
averageVelocity += m_VelocityBuffer[i];
averageVelocity /= (float)k_WindowSize;
// write current values to buffers
m_VelocityBuffer[index] = velocity;
index = (index + 1) % k_WindowSize; // circular buffer
// reset camera temporal effect on sudden motion
var velocityCrossesThreshold = velocity > averageVelocity * (1 + m_Threshold);
if (velocityCrossesThreshold)
{
// to prevent continuous firing related to buffer length,
// full buffer update on threshold cross, it forces averages up
for (var i = 0; i != k_WindowSize; ++i)
m_VelocityBuffer[i] = velocity;
Reset(m_Brain.OutputCamera);
Debug.Log("Automatic Temporal Effects Reset.");
}
}
static void Reset(Camera camera)
{
HDCamera hdCam = HDCamera.GetOrCreate(camera);
hdCam.volumetricHistoryIsValid = false;
hdCam.colorPyramidHistoryIsValid = false;
hdCam.Reset();
}
}