commit428243f4a6Author: AsanoRema <asanorema2036@gmail.com> Date: Sat Aug 29 13:43:13 2026 +0300 Squashed commit of the following: commit68e78fa464Author: AsanoRema <asanorema2036@gmail.com> Date: Sat Aug 29 13:41:49 2026 +0300 Updated .gitignore commit9f87122a34Author: AsanoRema <asanorema2036@gmail.com> Date: Sat Aug 29 13:34:57 2026 +0300 Added Dohya commitf6a7547e84Author: AsanoRema <asanorema2036@gmail.com> Date: Fri Aug 21 17:59:13 2026 +0300 Fixed commitb98901c366Author: AsanoRema <asanorema2036@gmail.com> Date: Tue Aug 18 17:37:22 2026 +0300 Added new particle Package commitbb2f4a3b16Author: AsanoRema <asanorema2036@gmail.com> Date: Tue Aug 18 17:17:48 2026 +0300 Map mehanic ready to multiplayer commitc01ff800f6Author: AsanoRema <asanorema2036@gmail.com> Date: Tue Aug 18 16:16:19 2026 +0300 Squashed commit of the following: commit173bbb165cAuthor: henjkey <henjkey@gmail.com> Date: Fri Aug 14 18:51:23 2026 +0500 Mappp commitd559ab338aAuthor: henjkey <henjkey@gmail.com> Date: Thu Aug 13 18:42:41 2026 +0500 Map Controller Coordinates Target System Crosshair System Radar System
183 lines
6.5 KiB
C#
183 lines
6.5 KiB
C#
using UnityEngine;
|
|
using UnityEngine.Serialization;
|
|
|
|
namespace VLB
|
|
{
|
|
[AddComponentMenu("")] // hide it from Component search
|
|
[DisallowMultipleComponent]
|
|
[RequireComponent(typeof(VolumetricLightBeam))]
|
|
public abstract class DynamicOcclusionAbstractBase : MonoBehaviour
|
|
{
|
|
public const string ClassName = "DynamicOcclusionAbstractBase";
|
|
|
|
/// <summary>
|
|
/// How often will the occlusion be processed?
|
|
/// Try to update the occlusion as rarely as possible to keep good performance.
|
|
/// </summary>
|
|
public DynamicOcclusionUpdateRate updateRate = Consts.DynOcclusion.UpdateRateDefault;
|
|
|
|
/// <summary>
|
|
/// How many frames we wait between 2 occlusion tests?
|
|
/// If you want your beam to be super responsive to the changes of your environment, update it every frame by setting 1.
|
|
/// If you want to save on performance, we recommend to wait few frames between each update by setting a higher value.
|
|
/// </summary>
|
|
[FormerlySerializedAs("waitFrameCount")]
|
|
public int waitXFrames = Consts.DynOcclusion.WaitFramesCountDefault;
|
|
|
|
/// <summary>
|
|
/// Manually process the occlusion.
|
|
/// You have to call this function in order to update the occlusion when using DynamicOcclusionUpdateRate.Never.
|
|
/// </summary>
|
|
public void ProcessOcclusionManually() { ProcessOcclusion(ProcessOcclusionSource.User); }
|
|
|
|
public event System.Action onOcclusionProcessed;
|
|
|
|
public static bool _INTERNAL_ApplyRandomFrameOffset = true;
|
|
|
|
|
|
protected enum ProcessOcclusionSource
|
|
{
|
|
RenderLoop,
|
|
OnEnable,
|
|
EditorUpdate,
|
|
User,
|
|
}
|
|
|
|
protected void ProcessOcclusion(ProcessOcclusionSource source)
|
|
{
|
|
if (!Config.Instance.featureEnabledDynamicOcclusion)
|
|
return;
|
|
|
|
Debug.Assert(!Application.isPlaying || m_LastFrameRendered != Time.frameCount, "ProcessOcclusion has been called twice on the same frame, which is forbidden");
|
|
Debug.Assert(m_Master);
|
|
|
|
bool occlusionSuccess = OnProcessOcclusion(source);
|
|
|
|
if(onOcclusionProcessed != null)
|
|
onOcclusionProcessed();
|
|
|
|
if (m_Master)
|
|
{
|
|
Debug.Assert(m_MaterialModifierCallbackCached != null);
|
|
m_Master._INTERNAL_SetDynamicOcclusionCallback(GetShaderKeyword(), occlusionSuccess ? m_MaterialModifierCallbackCached : (MaterialModifier.Callback)(null));
|
|
}
|
|
|
|
if (updateRate.HasFlag(DynamicOcclusionUpdateRate.OnBeamMove))
|
|
m_TransformPacked = transform.GetWorldPacked();
|
|
|
|
bool firstTime = m_LastFrameRendered < 0;
|
|
m_LastFrameRendered = Time.frameCount;
|
|
|
|
if (firstTime && _INTERNAL_ApplyRandomFrameOffset)
|
|
{
|
|
m_LastFrameRendered += Random.Range(0, waitXFrames); // add a random offset to prevent from updating texture for all beams having the same wait value
|
|
}
|
|
}
|
|
|
|
TransformUtils.Packed m_TransformPacked;
|
|
int m_LastFrameRendered = int.MinValue;
|
|
public int _INTERNAL_LastFrameRendered { get { return m_LastFrameRendered; } } // for unit tests
|
|
protected VolumetricLightBeam m_Master = null;
|
|
protected MaterialModifier.Callback m_MaterialModifierCallbackCached = null;
|
|
|
|
protected abstract string GetShaderKeyword();
|
|
protected abstract MaterialManager.DynamicOcclusion GetDynamicOcclusionMode();
|
|
|
|
protected abstract bool OnProcessOcclusion(ProcessOcclusionSource source);
|
|
protected abstract void OnModifyMaterialCallback(MaterialModifier.Interface owner);
|
|
protected abstract void OnEnablePostValidate();
|
|
|
|
|
|
protected virtual void OnValidateProperties()
|
|
{
|
|
waitXFrames = Mathf.Clamp(waitXFrames, 1, 60);
|
|
}
|
|
|
|
protected virtual void Awake()
|
|
{
|
|
m_Master = GetComponent<VolumetricLightBeam>();
|
|
Debug.Assert(m_Master);
|
|
|
|
m_Master._INTERNAL_DynamicOcclusionMode = GetDynamicOcclusionMode();
|
|
}
|
|
|
|
protected virtual void OnDestroy()
|
|
{
|
|
m_Master._INTERNAL_DynamicOcclusionMode = MaterialManager.DynamicOcclusion.Off;
|
|
DisableOcclusion();
|
|
}
|
|
|
|
protected virtual void OnEnable()
|
|
{
|
|
// cache the delegate to prevent from being inlined as '() => OnModifyMaterialCallback' when calling _INTERNAL_SetDynamicOcclusionCallback and from generating GC garbage
|
|
m_MaterialModifierCallbackCached = OnModifyMaterialCallback;
|
|
|
|
OnValidateProperties();
|
|
|
|
OnEnablePostValidate();
|
|
|
|
#if UNITY_EDITOR
|
|
if (Application.isPlaying)
|
|
#endif
|
|
{
|
|
m_Master.onWillCameraRenderThisBeam += OnWillCameraRender;
|
|
|
|
if (!updateRate.HasFlag(DynamicOcclusionUpdateRate.Never))
|
|
m_Master.RegisterOnBeamGeometryInitializedCallback(() => ProcessOcclusion(ProcessOcclusionSource.OnEnable));
|
|
}
|
|
}
|
|
|
|
protected virtual void OnDisable()
|
|
{
|
|
#if UNITY_EDITOR
|
|
if (Application.isPlaying)
|
|
#endif
|
|
{
|
|
m_Master.onWillCameraRenderThisBeam -= OnWillCameraRender;
|
|
}
|
|
|
|
DisableOcclusion();
|
|
}
|
|
|
|
#if UNITY_EDITOR
|
|
protected virtual void OnValidate()
|
|
{
|
|
OnValidateProperties();
|
|
}
|
|
#endif
|
|
|
|
|
|
void OnWillCameraRender(Camera cam)
|
|
{
|
|
Debug.Assert(Application.isPlaying);
|
|
|
|
if (cam != null && cam.enabled
|
|
&& Time.frameCount != m_LastFrameRendered) // prevent from updating multiple times if there are more than 1 camera
|
|
{
|
|
bool shouldUpdate = false;
|
|
|
|
if (!shouldUpdate && updateRate.HasFlag(DynamicOcclusionUpdateRate.OnBeamMove))
|
|
{
|
|
if (!m_TransformPacked.IsSame(transform))
|
|
shouldUpdate = true;
|
|
}
|
|
|
|
if (!shouldUpdate && updateRate.HasFlag(DynamicOcclusionUpdateRate.EveryXFrames))
|
|
{
|
|
if (Time.frameCount >= m_LastFrameRendered + waitXFrames)
|
|
shouldUpdate = true;
|
|
}
|
|
|
|
if (shouldUpdate)
|
|
ProcessOcclusion(ProcessOcclusionSource.RenderLoop);
|
|
}
|
|
}
|
|
|
|
void DisableOcclusion()
|
|
{
|
|
m_Master._INTERNAL_SetDynamicOcclusionCallback(GetShaderKeyword(), null);
|
|
}
|
|
}
|
|
}
|
|
|