diff --git a/Assets/OctoCore/Prefabs/OctoCore.prefab b/Assets/OctoCore/Prefabs/OctoCore.prefab
index 2444f5e3..ddbd1505 100644
--- a/Assets/OctoCore/Prefabs/OctoCore.prefab
+++ b/Assets/OctoCore/Prefabs/OctoCore.prefab
@@ -29,10 +29,10 @@ RectTransform:
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children:
- - {fileID: 3245798801699784922}
- - {fileID: 8809334315617690044}
- {fileID: 82148688982910463}
- {fileID: 3074494267237045658}
+ - {fileID: 3245798801699784922}
+ - {fileID: 8809334315617690044}
m_Father: {fileID: 7468471552496634669}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0.5, y: 0.5}
@@ -195,7 +195,7 @@ RectTransform:
- {fileID: 1658671424626357336}
- {fileID: 2821496700537645326}
- {fileID: 5059971830852439863}
- m_Father: {fileID: 2859689488225106521}
+ m_Father: {fileID: 6194350059673118374}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0}
m_AnchorMax: {x: 0, y: 0}
@@ -446,7 +446,7 @@ VideoPlayer:
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 2863700951379057923}
m_Enabled: 1
- m_VideoClip: {fileID: 32900000, guid: b0bcfa0c7d8546f41bbf6c37042457ef, type: 3}
+ m_VideoClip: {fileID: 0}
m_TargetCameraAlpha: 1
m_TargetCamera3DLayout: 0
m_TargetCamera: {fileID: 0}
@@ -640,8 +640,7 @@ Transform:
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
- m_Children:
- - {fileID: 7468471552496634669}
+ m_Children: []
m_Father: {fileID: 6194350059673118374}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!114 &1464817219593818183
@@ -1120,7 +1119,7 @@ MonoBehaviour:
m_EditorClassIdentifier: UnityEngine.UI::UnityEngine.UI.Image
m_Material: {fileID: 0}
m_Color: {r: 0, g: 0, b: 0, a: 1}
- m_RaycastTarget: 1
+ m_RaycastTarget: 0
m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0}
m_Maskable: 1
m_OnCullStateChanged:
@@ -1195,7 +1194,7 @@ MonoBehaviour:
m_EditorClassIdentifier: UnityEngine.UI::UnityEngine.UI.RawImage
m_Material: {fileID: 2100000, guid: ee02f227a2ef9c146a9e3df7f47442ce, type: 2}
m_Color: {r: 1, g: 1, b: 1, a: 1}
- m_RaycastTarget: 1
+ m_RaycastTarget: 0
m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0}
m_Maskable: 1
m_OnCullStateChanged:
@@ -1441,7 +1440,7 @@ MonoBehaviour:
m_EditorClassIdentifier: UnityEngine.UI::UnityEngine.UI.Image
m_Material: {fileID: 0}
m_Color: {r: 0, g: 0, b: 0, a: 1}
- m_RaycastTarget: 1
+ m_RaycastTarget: 0
m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0}
m_Maskable: 1
m_OnCullStateChanged:
@@ -1467,7 +1466,7 @@ GameObject:
m_Component:
- component: {fileID: 6194350059673118374}
- component: {fileID: 4562949134636194362}
- - component: {fileID: 8418726451754860477}
+ - component: {fileID: 1519536274667175428}
m_Layer: 0
m_Name: OctoCore
m_TagString: Untagged
@@ -1488,6 +1487,7 @@ Transform:
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children:
+ - {fileID: 7468471552496634669}
- {fileID: 2859689488225106521}
m_Father: {fileID: 0}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
@@ -1526,7 +1526,7 @@ MonoBehaviour:
PendingTeleporter: {fileID: 0}
_development:
Log: 0
---- !u!114 &8418726451754860477
+--- !u!114 &1519536274667175428
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
diff --git a/Assets/_Content/Models/VFX/Rain/Rain.vfx b/Assets/_Content/Models/VFX/Rain/Rain.vfx
index c82cabb9..0a546955 100644
--- a/Assets/_Content/Models/VFX/Rain/Rain.vfx
+++ b/Assets/_Content/Models/VFX/Rain/Rain.vfx
@@ -547,7 +547,7 @@ MonoBehaviour:
- {fileID: 8926484042661614583}
- {fileID: 8926484042661614585}
dataType: 0
- capacity: 30000
+ capacity: 100000
stripCapacity: 16
particlePerStripCount: 16
needsComputeBounds: 0
diff --git a/Assets/_Content/Scenes/Theatre.unity b/Assets/_Content/Scenes/Theatre.unity
index ce2d63da..d8030c29 100644
--- a/Assets/_Content/Scenes/Theatre.unity
+++ b/Assets/_Content/Scenes/Theatre.unity
@@ -4579,7 +4579,7 @@ PrefabInstance:
objectReference: {fileID: 0}
- target: {fileID: 3976092107026356747, guid: a4ca96f09a0c04645aa697def551b52d, type: 3}
propertyPath: m_Enabled
- value: 0
+ value: 1
objectReference: {fileID: 0}
- target: {fileID: 3976092107026356747, guid: a4ca96f09a0c04645aa697def551b52d, type: 3}
propertyPath: m_Center.y
@@ -14993,8 +14993,10 @@ MonoBehaviour:
_closeDuration: 0.1
_holdClosed: 0.05
_openDuration: 0.15
- _visibleHold: 0.5
+ _visibleHold: 0
_showVideoAtCloseProgress: 0.5
+ _swapLayerOrderOnTransition: 1
+ _logCallers: 0
--- !u!1 &477778557
GameObject:
m_ObjectHideFlags: 0
@@ -16949,7 +16951,7 @@ GameObject:
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
- m_IsActive: 1
+ m_IsActive: 0
--- !u!224 &528711171
RectTransform:
m_ObjectHideFlags: 0
@@ -1228550,7 +1228552,7 @@ MonoBehaviour:
_fadeInEvent:
idInternal: 0
valueGuidInternal:
- WwiseObjectReference: {fileID: 11400000, guid: cb7005361d4283844bb30f03e0a63a83, type: 2}
+ WwiseObjectReference: {fileID: 11400000, guid: b403a2d1f9899dc43b13a3bb41020a2f, type: 2}
--- !u!1001 &669525208
PrefabInstance:
m_ObjectHideFlags: 0
@@ -1229151,8 +1229153,10 @@ MonoBehaviour:
_closeDuration: 0.1
_holdClosed: 0.05
_openDuration: 0.15
- _visibleHold: 0.5
+ _visibleHold: 0
_showVideoAtCloseProgress: 0.5
+ _swapLayerOrderOnTransition: 1
+ _logCallers: 0
--- !u!4 &681655009 stripped
Transform:
m_CorrespondingSourceObject: {fileID: 992638687589661580, guid: 8a998c00fc583a54082d05343d747b99, type: 3}
@@ -1250596,7 +1250600,7 @@ GameObject:
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
- m_IsActive: 1
+ m_IsActive: 0
--- !u!224 &823286597
RectTransform:
m_ObjectHideFlags: 0
@@ -1250661,7 +1250665,7 @@ MonoBehaviour:
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 823286596}
- m_Enabled: 1
+ m_Enabled: 0
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 3aa8c513a3632aa4aa3b8ca2da6ca926, type: 3}
m_Name:
@@ -1250671,8 +1250675,10 @@ MonoBehaviour:
_closeDuration: 0.1
_holdClosed: 0.05
_openDuration: 0.15
- _visibleHold: 0.5
+ _visibleHold: 0
_showVideoAtCloseProgress: 0.5
+ _swapLayerOrderOnTransition: 0
+ _logCallers: 0
--- !u!1 &825450534
GameObject:
m_ObjectHideFlags: 0
@@ -1259529,7 +1259535,7 @@ MonoBehaviour:
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1075395951}
- m_Enabled: 1
+ m_Enabled: 0
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 5170627695bd877419928fa9ca37865d, type: 3}
m_Name:
@@ -1788630,7 +1788636,7 @@ MonoBehaviour:
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1161394543}
- m_Enabled: 1
+ m_Enabled: 0
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 5170627695bd877419928fa9ca37865d, type: 3}
m_Name:
@@ -1793390,6 +1793396,7 @@ GameObject:
- component: {fileID: 1270400838}
- component: {fileID: 1270400837}
- component: {fileID: 1270400841}
+ - component: {fileID: 1270400842}
- component: {fileID: 1270400835}
- component: {fileID: 1270400840}
m_Layer: 0
@@ -1793647,6 +1793654,45 @@ MonoBehaviour:
m_Name:
m_EditorClassIdentifier: Assembly-CSharp::Unheimlich.Features.Dialogue.LocalizedSubtitle
_data: {fileID: 11400000, guid: 3c05ba91d318d524fbcf867fe886c553, type: 2}
+--- !u!114 &1270400842
+MonoBehaviour:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 1270400833}
+ m_Enabled: 1
+ m_EditorHideFlags: 0
+ m_Script: {fileID: 11500000, guid: 5170627695bd877419928fa9ca37865d, type: 3}
+ m_Name:
+ m_EditorClassIdentifier: OctoCore.Runtime::OctoCore.Components.OctoWorldEvent
+ _trigger: 3
+ _action: 0
+ _condition: 0
+ _tags: []
+ _targets: []
+ _tolerance: 0.5
+ _duration: 1
+ _execution: 0
+ _delay: 1
+ _onTrigger:
+ m_PersistentCalls:
+ m_Calls:
+ - m_Target: {fileID: 938880773}
+ m_TargetAssemblyTypeName: UnityEngine.GameObject, UnityEngine
+ m_MethodName: SetActive
+ m_Mode: 6
+ m_Arguments:
+ m_ObjectArgument: {fileID: 0}
+ m_ObjectArgumentAssemblyTypeName: UnityEngine.Object, UnityEngine
+ m_IntArgument: 0
+ m_FloatArgument: 0
+ m_StringArgument:
+ m_BoolArgument: 0
+ m_CallState: 2
+ _onTriggerDelayed:
+ m_PersistentCalls:
+ m_Calls: []
--- !u!64 &1271053080
MeshCollider:
m_ObjectHideFlags: 0
@@ -1793816,7 +1793862,7 @@ GameObject:
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
- m_IsActive: 1
+ m_IsActive: 0
--- !u!224 &1276767360
RectTransform:
m_ObjectHideFlags: 0
@@ -1793881,7 +1793927,7 @@ MonoBehaviour:
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1276767359}
- m_Enabled: 1
+ m_Enabled: 0
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 3aa8c513a3632aa4aa3b8ca2da6ca926, type: 3}
m_Name:
@@ -1793891,8 +1793937,10 @@ MonoBehaviour:
_closeDuration: 0.1
_holdClosed: 0.05
_openDuration: 0.15
- _visibleHold: 0.5
+ _visibleHold: 0
_showVideoAtCloseProgress: 0.5
+ _swapLayerOrderOnTransition: 0
+ _logCallers: 0
--- !u!1 &1277811577 stripped
GameObject:
m_CorrespondingSourceObject: {fileID: 472138041468068150, guid: 8a998c00fc583a54082d05343d747b99, type: 3}
@@ -1796692,8 +1796740,8 @@ MonoBehaviour:
_clustersToDraw: []
_radii: []
sourceObjectBounds:
- m_Center: {x: -0.085959435, y: 1.7420399, z: 5.2234697}
- m_Extent: {x: 5.6247444, y: 0.88517404, z: 0.606534}
+ m_Center: {x: -100.02052, y: 1.7420399, z: 5.2138634}
+ m_Extent: {x: 5.6236115, y: 0.88517404, z: 0.5528393}
prefabOptions_outputFolder:
prefabOptions_autoGeneratePrefabs: 0
prefabOptions_mergeOutputIntoSinglePrefab: 0
@@ -1797971,7 +1798019,7 @@ MonoBehaviour:
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1385908337}
- m_Enabled: 1
+ m_Enabled: 0
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 5170627695bd877419928fa9ca37865d, type: 3}
m_Name:
@@ -3476700,7 +3476748,7 @@ GameObject:
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
- m_IsActive: 1
+ m_IsActive: 0
--- !u!224 &1708782434
RectTransform:
m_ObjectHideFlags: 0
@@ -3476765,7 +3476813,7 @@ MonoBehaviour:
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1708782433}
- m_Enabled: 1
+ m_Enabled: 0
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 3aa8c513a3632aa4aa3b8ca2da6ca926, type: 3}
m_Name:
@@ -3476775,8 +3476823,10 @@ MonoBehaviour:
_closeDuration: 0.1
_holdClosed: 0.05
_openDuration: 0.15
- _visibleHold: 0.5
+ _visibleHold: 0
_showVideoAtCloseProgress: 0.5
+ _swapLayerOrderOnTransition: 0
+ _logCallers: 0
--- !u!114 &1710639304
MonoBehaviour:
m_ObjectHideFlags: 0
@@ -3483422,8 +3483472,10 @@ MonoBehaviour:
_closeDuration: 0.1
_holdClosed: 0.05
_openDuration: 0.15
- _visibleHold: 0.5
+ _visibleHold: 0
_showVideoAtCloseProgress: 0.5
+ _swapLayerOrderOnTransition: 1
+ _logCallers: 0
--- !u!1 &1918993959
GameObject:
m_ObjectHideFlags: 0
@@ -3503122,12 +3503174,14 @@ MonoBehaviour:
m_Name:
m_EditorClassIdentifier: Assembly-CSharp::Unheimlich.Features.Hallucination.HallucinationFlash
_clip: {fileID: 32900000, guid: b0bcfa0c7d8546f41bbf6c37042457ef, type: 3}
- _material: {fileID: 0}
+ _material: {fileID: 2100000, guid: ee02f227a2ef9c146a9e3df7f47442ce, type: 2}
_closeDuration: 0.06
_holdClosed: 0.1
_openDuration: 0.1
_visibleHold: 1
- _showVideoAtCloseProgress: 1
+ _showVideoAtCloseProgress: 0.2
+ _swapLayerOrderOnTransition: 0
+ _logCallers: 0
--- !u!1 &3474206300861930777
GameObject:
m_ObjectHideFlags: 0
@@ -3513843,13 +3513897,15 @@ MonoBehaviour:
m_Script: {fileID: 11500000, guid: 3aa8c513a3632aa4aa3b8ca2da6ca926, type: 3}
m_Name:
m_EditorClassIdentifier: Assembly-CSharp::Unheimlich.Features.Hallucination.HallucinationFlash
- _clip: {fileID: 0}
- _material: {fileID: 0}
+ _clip: {fileID: 32900000, guid: 110592976a5654240b144bf3c05cf16e, type: 3}
+ _material: {fileID: 2100000, guid: c2467417522efbe448119480d4daff9f, type: 2}
_closeDuration: 0.06
_holdClosed: 0.1
_openDuration: 0.1
_visibleHold: 0.8
- _showVideoAtCloseProgress: 1
+ _showVideoAtCloseProgress: 0.2
+ _swapLayerOrderOnTransition: 0
+ _logCallers: 0
--- !u!1 &6309718822811934455
GameObject:
m_ObjectHideFlags: 0
@@ -3515099,13 +3515155,15 @@ MonoBehaviour:
m_Script: {fileID: 11500000, guid: 3aa8c513a3632aa4aa3b8ca2da6ca926, type: 3}
m_Name:
m_EditorClassIdentifier: Assembly-CSharp::Unheimlich.Features.Hallucination.HallucinationFlash
- _clip: {fileID: 0}
- _material: {fileID: 0}
+ _clip: {fileID: 32900000, guid: ba3c91ef4865d7c4aa179bac9d7a1e69, type: 3}
+ _material: {fileID: 2100000, guid: e8cd122788852424cbc5436633400b2e, type: 2}
_closeDuration: 0.06
_holdClosed: 0.1
_openDuration: 0.1
- _visibleHold: 1.5
- _showVideoAtCloseProgress: 1
+ _visibleHold: 2
+ _showVideoAtCloseProgress: 0.2
+ _swapLayerOrderOnTransition: 0
+ _logCallers: 0
--- !u!33 &6816362058036913435
MeshFilter:
m_ObjectHideFlags: 0
@@ -3516202,7 +3516260,7 @@ MonoBehaviour:
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1011309933828299120}
- m_Enabled: 1
+ m_Enabled: 0
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 5170627695bd877419928fa9ca37865d, type: 3}
m_Name:
diff --git a/Assets/_Content/Scripts/Features/Hallucination/Runtime/HallucinationFlash.cs b/Assets/_Content/Scripts/Features/Hallucination/Runtime/HallucinationFlash.cs
index 09a42439..09cf9fc7 100644
--- a/Assets/_Content/Scripts/Features/Hallucination/Runtime/HallucinationFlash.cs
+++ b/Assets/_Content/Scripts/Features/Hallucination/Runtime/HallucinationFlash.cs
@@ -6,8 +6,10 @@ using Unheimlich.Transitions;
namespace Unheimlich.Features.Hallucination
{
///
- /// Scene-local trigger for a double-blink hallucination sequence. Delegates all
- /// visual work to the persistent OctoEyelidBlink singleton.
+ /// Scene-local trigger for a hallucination blink. Delegates all visual work to the
+ /// persistent OctoEyelidBlink singleton. Runs as a single close-hold-open cycle when
+ /// the layer swap is enabled (the correct video/eyelid z-order makes one blink enough),
+ /// or as the classic double close-hold-open-hold-close-hold-open sequence otherwise.
///
public class HallucinationFlash : MonoBehaviour
{
@@ -18,12 +20,45 @@ namespace Unheimlich.Features.Hallucination
[SerializeField, Min(0f)] private float _closeDuration = 0.1f;
[SerializeField, Min(0f)] private float _holdClosed = 0.05f;
[SerializeField, Min(0f)] private float _openDuration = 0.15f;
+ [Tooltip("How long the video stays visible after the eyes have fully reopened, before it's hidden.")]
[SerializeField, Min(0f)] private float _visibleHold = 0.5f;
[SerializeField, Range(0f, 1f)] private float _showVideoAtCloseProgress = 0.25f;
- /// Triggers the hallucination sequence. No-op if the singleton is missing or busy.
+ [Header("Layering")]
+ [Tooltip("If enabled, the eyelid bars render behind the video overlay while closing (video shows on top of them), then swap to render in front of it while opening (video disappears behind the still-closed-looking bars instead of staying visible during the reveal).")]
+ [SerializeField] private bool _swapLayerOrderOnTransition = false;
+
+ [Header("Debug")]
+ [Tooltip("Logs the full call stack every time Play() is triggered, so you can trace who requested this hallucination.")]
+ [SerializeField] private bool _logCallers = false;
+
+ ///
+ /// Starts warming up this hallucination's video clip ahead of time, without triggering
+ /// the blink sequence. Call this in advance (e.g. when the player enters a trigger volume
+ /// near the hallucination point) so the video is ready the moment Play() is actually called,
+ /// instead of racing the warm-up against the eyelid close animation.
+ ///
+ public void Prewarm()
+ {
+ OctoEyelidBlink blink = OctoEyelidBlink.Instance;
+
+ if (blink == null)
+ return;
+
+ blink.SetClip(_clip, _material);
+ }
+
+ ///
+ /// Triggers the hallucination blink. If the layer swap is enabled, runs a single
+ /// close-hold-open cycle with the video revealed partway through closing and hidden
+ /// after the configured hold once reopened. If disabled, runs the classic double
+ /// blink instead. No-op if the singleton is missing or already busy.
+ ///
public void Play()
{
+ if (_logCallers)
+ Debug.LogError($"[HallucinationFlash] Play() called on '{gameObject.name}' at t={Time.time:F2}\n{StackTraceUtility.ExtractStackTrace()}");
+
OctoEyelidBlink blink = OctoEyelidBlink.Instance;
if (blink == null)
@@ -36,7 +71,45 @@ namespace Unheimlich.Features.Hallucination
return;
blink.SetClip(_clip, _material);
+ blink.SetLayerSwapEnabled(_swapLayerOrderOnTransition);
+ if (_swapLayerOrderOnTransition)
+ PlaySingleBlink(blink);
+ else
+ PlayDoubleBlink(blink);
+
+ blink.ShowVideoAfterDelay(_closeDuration * _showVideoAtCloseProgress);
+ }
+
+ ///
+ /// Single close-hold-open cycle: video is revealed partway through closing and hidden
+ /// after staying visible for _visibleHold once the eyes are back open. Relies on the
+ /// eyelid/video layer swap being correctly set beforehand for the reveal to look right.
+ ///
+ private void PlaySingleBlink(OctoEyelidBlink blink)
+ {
+ blink.CloseEyes(_closeDuration, () =>
+ {
+ blink.Hold(_holdClosed, () =>
+ {
+ blink.OpenEyes(_openDuration, () =>
+ {
+ blink.Hold(_visibleHold, () =>
+ {
+ blink.HideVideo();
+ });
+ });
+ });
+ });
+ }
+
+ ///
+ /// Classic double blink: close, reveal video, open, hold visible, close again,
+ /// hide video, hold, open. Used when the layer swap is disabled, since without the
+ /// correct z-order a single blink wouldn't hide the video cleanly on its own.
+ ///
+ private void PlayDoubleBlink(OctoEyelidBlink blink)
+ {
blink.CloseEyes(_closeDuration, () =>
{
blink.Hold(_holdClosed, () =>
@@ -57,8 +130,6 @@ namespace Unheimlich.Features.Hallucination
});
});
});
-
- blink.ShowVideoAfterDelay(_closeDuration * _showVideoAtCloseProgress);
}
}
}
\ No newline at end of file
diff --git a/Assets/_Content/Scripts/Features/Hallucination/Runtime/OctoEyelidBlink.cs b/Assets/_Content/Scripts/Features/Hallucination/Runtime/OctoEyelidBlink.cs
index ef93dfcd..5bb5a1f0 100644
--- a/Assets/_Content/Scripts/Features/Hallucination/Runtime/OctoEyelidBlink.cs
+++ b/Assets/_Content/Scripts/Features/Hallucination/Runtime/OctoEyelidBlink.cs
@@ -32,6 +32,11 @@ namespace Unheimlich.Transitions
[SerializeField] private float _openOffset = 600f;
[SerializeField] private float _closedOffset = 0f;
+ // Set per-call via SetLayerSwapEnabled() rather than serialized here, since this
+ // is a shared singleton: different callers (HallucinationFlash instances, scene
+ // transitions) may want different behavior for the same shared component.
+ private bool _swapLayerOrderOnTransition;
+
/// True while a blink sequence is currently animating.
public bool IsBusy { get; private set; }
@@ -42,11 +47,36 @@ namespace Unheimlich.Transitions
private bool _isWarmedUp;
private bool _videoShown;
+ private bool _showRequested;
private VideoClip _pendingClip;
private Material _defaultMaterial;
private bool HasVideo => _videoPlayer != null && _videoDisplay != null && _videoPlayer.clip != null;
+ ///
+ /// Logs the individual state of every condition HasVideo depends on, plus the
+ /// warm-up/shown flags. Use this to pinpoint exactly why the video overlay isn't
+ /// appearing (missing reference, clip not assigned, warm-up not finished, etc.).
+ ///
+ private void LogVideoState(string context)
+ {
+ if (!_logVideoDebug)
+ return;
+
+ Debug.LogError(
+ $"[OctoEyelidBlink] VideoState @ {context}"
+ + $" | _videoPlayer={(_videoPlayer != null ? "OK" : "NULL")}"
+ + $" | _videoDisplay={(_videoDisplay != null ? "OK" : "NULL")}"
+ + $" | clip={(_videoPlayer != null && _videoPlayer.clip != null ? _videoPlayer.clip.name : "NULL")}"
+ + $" | HasVideo={HasVideo}"
+ + $" | _isWarmedUp={_isWarmedUp}"
+ + $" | _videoShown={_videoShown}"
+ + $" | _videoDisplay.enabled={(_videoDisplay != null ? _videoDisplay.enabled.ToString() : "N/A")}"
+ + $" | _videoPlayer.isPrepared={(_videoPlayer != null ? _videoPlayer.isPrepared.ToString() : "N/A")}"
+ + $" | _videoPlayer.isPlaying={(_videoPlayer != null ? _videoPlayer.isPlaying.ToString() : "N/A")}"
+ );
+ }
+
protected override void OnAwake()
{
OctoTransitionProvider.Current = this;
@@ -92,14 +122,40 @@ namespace Unheimlich.Transitions
if (_videoPlayer == null)
return;
+ // Avoid restarting an already-completed or in-progress warm-up for the same clip.
+ // This lets a caller pre-warm a clip early (e.g. HallucinationFlash.Prewarm()) and
+ // then safely call SetClip again with the same clip right before CloseEyes without
+ // losing the warm-up progress already made.
+ if (clip == _pendingClip && _videoPlayer.clip == clip)
+ {
+ LogVideoState("SetClip (skipped, same clip already set)");
+ return;
+ }
+
_isWarmedUp = false;
_pendingClip = clip;
_videoPlayer.clip = clip;
+ LogVideoState("SetClip");
+
if (clip != null)
StartCoroutine(WarmUpVideo());
}
+ ///
+ /// Enables or disables the eyelid/video layer swap for the next CloseEyes()/OpenEyes()
+ /// sequence: when enabled, the eyelid bars render behind the video overlay while closing
+ /// (video shows on top), then swap to render in front of it while opening (video
+ /// disappears behind the still-closed-looking bars instead of staying visible during
+ /// the reveal). Call this before CloseEyes() to opt a specific sequence in; it resets
+ /// to disabled automatically once the sequence finishes opening, so it never leaks into
+ /// unrelated callers (e.g. scene transitions) that don't set it explicitly.
+ ///
+ public void SetLayerSwapEnabled(bool enabled)
+ {
+ _swapLayerOrderOnTransition = enabled;
+ }
+
/// Closes the eyelids over the given duration and invokes the callback on completion.
public void CloseEyes(float duration, Action onComplete)
{
@@ -107,6 +163,10 @@ namespace Unheimlich.Transitions
CancelCurrent();
ResetVideoToStart();
_videoShown = false;
+ _showRequested = false;
+
+ if (_swapLayerOrderOnTransition)
+ SetEyelidsBehindVideo();
RectTransform top = _topEyelid.rectTransform;
RectTransform bottom = _bottomEyelid.rectTransform;
@@ -129,6 +189,9 @@ namespace Unheimlich.Transitions
/// Opens the eyelids over the given duration and invokes the callback on completion.
public void OpenEyes(float duration, Action onComplete)
{
+ if (_swapLayerOrderOnTransition)
+ SetEyelidsInFrontOfVideo();
+
RectTransform top = _topEyelid.rectTransform;
RectTransform bottom = _bottomEyelid.rectTransform;
@@ -147,16 +210,28 @@ namespace Unheimlich.Transitions
{
_bottomTweenId = -1;
IsBusy = false;
+ _swapLayerOrderOnTransition = false;
})
.id;
}
+ ///
+ /// True if the given clip is the one currently assigned and has finished warming up.
+ /// Lets a caller (e.g. HallucinationFlash) check readiness after calling Prewarm-style
+ /// SetClip ahead of time, without having to guess a fixed delay.
+ ///
+ public bool IsClipReady(VideoClip clip)
+ {
+ return _isWarmedUp && _pendingClip == clip;
+ }
+
/// Stops playback, resets the video to its first frame, and hides the overlay.
public void HideVideo()
{
if (!HasVideo)
return;
+ _showRequested = false;
_videoPlayer.Pause();
_videoPlayer.time = 0.0;
SetVideoVisible(false);
@@ -166,6 +241,8 @@ namespace Unheimlich.Transitions
/// Reveals and plays the video overlay after the given delay, once warm-up has completed.
public void ShowVideoAfterDelay(float delay)
{
+ LogVideoState("ShowVideoAfterDelay (before HasVideo check)");
+
if (!HasVideo)
return;
@@ -236,28 +313,46 @@ namespace Unheimlich.Transitions
_isWarmedUp = true;
if (_logVideoDebug)
- Debug.Log($"[OctoEyelidBlink] Warm-up complete for clip: {_pendingClip?.name}");
+ Debug.LogError($"[OctoEyelidBlink] Warm-up complete for clip: {_pendingClip?.name}");
+
+ // The requested reveal may have fired before warm-up finished and bailed out.
+ // Catch up now instead of leaving the overlay stuck hidden for the whole sequence.
+ if (_showRequested && !_videoShown)
+ {
+ if (_logVideoDebug)
+ Debug.LogError("[OctoEyelidBlink] Warm-up finished after a pending show request, showing video now.");
+
+ ShowVideo();
+ }
}
private void ShowVideo()
{
+ LogVideoState("ShowVideo (entry)");
+
if (!HasVideo || _videoShown)
return;
- // Safety check: if warm-up hasn't completed yet (e.g. clip assigned too late),
- // skip showing the video rather than risk a corrupted first frame. The eyelid
- // blink itself remains unaffected.
+ _showRequested = true;
+
+ // Safety check: if warm-up hasn't completed yet (e.g. clip assigned too late,
+ // or the reveal delay is shorter than warm-up takes), skip showing the video for
+ // now rather than risk a corrupted first frame. WarmUpVideo() will catch up and
+ // call ShowVideo() again as soon as it finishes, since _showRequested is still set.
if (!_isWarmedUp)
{
if (_logVideoDebug)
- Debug.LogWarning("[OctoEyelidBlink] Video not warmed up in time, skipping display.");
+ Debug.LogError("[OctoEyelidBlink] Video not warmed up in time, skipping display for now (will retry once warm-up completes).");
return;
}
+ _showRequested = false;
_videoShown = true;
SetVideoVisible(true);
_videoPlayer.Play();
+
+ LogVideoState("ShowVideo (after SetVideoVisible(true))");
}
private void ResetVideoToStart()
@@ -271,8 +366,43 @@ namespace Unheimlich.Transitions
private void SetVideoVisible(bool visible)
{
- if (_videoDisplay != null)
- _videoDisplay.enabled = visible;
+ if (_videoDisplay == null)
+ {
+ if (_logVideoDebug)
+ Debug.LogError("[OctoEyelidBlink] SetVideoVisible called but _videoDisplay is NULL.");
+
+ return;
+ }
+
+ _videoDisplay.enabled = visible;
+
+ if (_logVideoDebug)
+ Debug.LogError($"[OctoEyelidBlink] SetVideoVisible({visible}) applied. _videoDisplay.enabled is now {_videoDisplay.enabled} on '{_videoDisplay.gameObject.name}'.");
+ }
+
+ // ---------- Layering internals ----------
+
+ ///
+ /// Moves both eyelid bars to the first sibling position, so any other UI element
+ /// under the same parent (in particular the video overlay) renders on top of them.
+ /// Used when closing, so the video appears layered above the bars.
+ ///
+ private void SetEyelidsBehindVideo()
+ {
+ _topEyelid.transform.SetAsFirstSibling();
+ _bottomEyelid.transform.SetAsFirstSibling();
+ }
+
+ ///
+ /// Moves both eyelid bars to the last sibling position, so they render in front of
+ /// any other UI element under the same parent (in particular the video overlay).
+ /// Used when opening, so the video disappears behind the still-closed-looking bars
+ /// instead of staying visible while the scene is revealed.
+ ///
+ private void SetEyelidsInFrontOfVideo()
+ {
+ _topEyelid.transform.SetAsLastSibling();
+ _bottomEyelid.transform.SetAsLastSibling();
}
// ---------- Eyelid internals ----------
diff --git a/Assets/_Content/Settings/DefaultVolumeProfile.asset b/Assets/_Content/Settings/DefaultVolumeProfile.asset
index 560e2220..d1a75bd9 100644
--- a/Assets/_Content/Settings/DefaultVolumeProfile.asset
+++ b/Assets/_Content/Settings/DefaultVolumeProfile.asset
@@ -121,6 +121,31 @@ MonoBehaviour:
m_PreInfinity: 2
m_PostInfinity: 2
m_RotationOrder: 4
+--- !u!114 &-6525128945574694045
+MonoBehaviour:
+ m_ObjectHideFlags: 3
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 0}
+ m_Enabled: 1
+ m_EditorHideFlags: 0
+ m_Script: {fileID: 11500000, guid: ccf1aba9553839d41ae37dd52e9ebcce, type: 3}
+ m_Name: MotionBlur
+ m_EditorClassIdentifier: Unity.RenderPipelines.Universal.Runtime::UnityEngine.Rendering.Universal.MotionBlur
+ active: 1
+ mode:
+ m_OverrideState: 1
+ m_Value: 0
+ quality:
+ m_OverrideState: 1
+ m_Value: 0
+ intensity:
+ m_OverrideState: 1
+ m_Value: 0
+ clamp:
+ m_OverrideState: 1
+ m_Value: 0.05
--- !u!114 &-6335409530604852063
MonoBehaviour:
m_ObjectHideFlags: 3
@@ -442,6 +467,7 @@ MonoBehaviour:
- {fileID: -6288072647309666549}
- {fileID: 7518938298396184218}
- {fileID: -1410297666881709256}
+ - {fileID: -6525128945574694045}
--- !u!114 &853819529557874667
MonoBehaviour:
m_ObjectHideFlags: 3
diff --git a/Assets/_Content/Settings/PC_RPAsset.asset b/Assets/_Content/Settings/PC_RPAsset.asset
index 6cbff50f..410916b9 100644
--- a/Assets/_Content/Settings/PC_RPAsset.asset
+++ b/Assets/_Content/Settings/PC_RPAsset.asset
@@ -47,7 +47,7 @@ MonoBehaviour:
m_AdditionalLightsRenderingMode: 1
m_AdditionalLightsPerObjectLimit: 8
m_AdditionalLightShadowsSupported: 1
- m_AdditionalLightsShadowmapResolution: 4096
+ m_AdditionalLightsShadowmapResolution: 8192
m_AdditionalLightsShadowResolutionTierLow: 256
m_AdditionalLightsShadowResolutionTierMedium: 512
m_AdditionalLightsShadowResolutionTierHigh: 4096
diff --git a/Assets/_Content/UI/FlashHallus/Stairs/RT_houseOfLeaves.renderTexture b/Assets/_Content/UI/FlashHallus/Stairs/RT_houseOfLeaves.renderTexture
deleted file mode 100644
index 4bbf467c..00000000
--- a/Assets/_Content/UI/FlashHallus/Stairs/RT_houseOfLeaves.renderTexture
+++ /dev/null
@@ -1,39 +0,0 @@
-%YAML 1.1
-%TAG !u! tag:unity3d.com,2011:
---- !u!84 &8400000
-RenderTexture:
- m_ObjectHideFlags: 0
- m_CorrespondingSourceObject: {fileID: 0}
- m_PrefabInstance: {fileID: 0}
- m_PrefabAsset: {fileID: 0}
- m_Name: RT_houseOfLeaves
- m_ImageContentsHash:
- serializedVersion: 2
- Hash: 00000000000000000000000000000000
- m_IsAlphaChannelOptional: 0
- serializedVersion: 6
- m_Width: 1920
- m_Height: 1080
- m_AntiAliasing: 1
- m_MipCount: -1
- m_DepthStencilFormat: 94
- m_ColorFormat: 8
- m_MipMap: 0
- m_GenerateMips: 1
- m_SRGB: 0
- m_UseDynamicScale: 0
- m_UseDynamicScaleExplicit: 0
- m_BindMS: 0
- m_EnableCompatibleFormat: 1
- m_EnableRandomWrite: 0
- m_TextureSettings:
- serializedVersion: 2
- m_FilterMode: 1
- m_Aniso: 0
- m_MipBias: 0
- m_WrapU: 1
- m_WrapV: 1
- m_WrapW: 1
- m_Dimension: 2
- m_VolumeDepth: 1
- m_ShadowSamplingMode: 2
diff --git a/Assets/_Content/UI/FlashHallus/Stairs/RT_omnissiah.renderTexture.meta b/Assets/_Content/UI/FlashHallus/Stairs/RT_omnissiah.renderTexture.meta
deleted file mode 100644
index 36ab30e7..00000000
--- a/Assets/_Content/UI/FlashHallus/Stairs/RT_omnissiah.renderTexture.meta
+++ /dev/null
@@ -1,8 +0,0 @@
-fileFormatVersion: 2
-guid: 5e7d07b5b87049e439bc686fef1c54f0
-NativeFormatImporter:
- externalObjects: {}
- mainObjectFileID: 8400000
- userData:
- assetBundleName:
- assetBundleVariant:
diff --git a/Assets/_Content/UI/FlashHallus/Stairs/RT_omnissiah.renderTexture b/Assets/_Content/UI/FlashHallus/Stairs/RT_stairsHallu.renderTexture
similarity index 97%
rename from Assets/_Content/UI/FlashHallus/Stairs/RT_omnissiah.renderTexture
rename to Assets/_Content/UI/FlashHallus/Stairs/RT_stairsHallu.renderTexture
index 48ad6f3a..f784fc56 100644
--- a/Assets/_Content/UI/FlashHallus/Stairs/RT_omnissiah.renderTexture
+++ b/Assets/_Content/UI/FlashHallus/Stairs/RT_stairsHallu.renderTexture
@@ -6,7 +6,7 @@ RenderTexture:
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
- m_Name: RT_omnissiah
+ m_Name: RT_stairsHallu
m_ImageContentsHash:
serializedVersion: 2
Hash: 00000000000000000000000000000000
diff --git a/Assets/_Content/UI/FlashHallus/Stairs/RT_houseOfLeaves.renderTexture.meta b/Assets/_Content/UI/FlashHallus/Stairs/RT_stairsHallu.renderTexture.meta
similarity index 100%
rename from Assets/_Content/UI/FlashHallus/Stairs/RT_houseOfLeaves.renderTexture.meta
rename to Assets/_Content/UI/FlashHallus/Stairs/RT_stairsHallu.renderTexture.meta
diff --git a/Assets/_Content/UI/FlashHallus/Stairs/RT_theater.renderTexture b/Assets/_Content/UI/FlashHallus/Stairs/RT_theater.renderTexture
deleted file mode 100644
index f68e5a30..00000000
--- a/Assets/_Content/UI/FlashHallus/Stairs/RT_theater.renderTexture
+++ /dev/null
@@ -1,39 +0,0 @@
-%YAML 1.1
-%TAG !u! tag:unity3d.com,2011:
---- !u!84 &8400000
-RenderTexture:
- m_ObjectHideFlags: 0
- m_CorrespondingSourceObject: {fileID: 0}
- m_PrefabInstance: {fileID: 0}
- m_PrefabAsset: {fileID: 0}
- m_Name: RT_theater
- m_ImageContentsHash:
- serializedVersion: 2
- Hash: 00000000000000000000000000000000
- m_IsAlphaChannelOptional: 0
- serializedVersion: 6
- m_Width: 1920
- m_Height: 1080
- m_AntiAliasing: 1
- m_MipCount: -1
- m_DepthStencilFormat: 94
- m_ColorFormat: 8
- m_MipMap: 0
- m_GenerateMips: 1
- m_SRGB: 0
- m_UseDynamicScale: 0
- m_UseDynamicScaleExplicit: 0
- m_BindMS: 0
- m_EnableCompatibleFormat: 1
- m_EnableRandomWrite: 0
- m_TextureSettings:
- serializedVersion: 2
- m_FilterMode: 1
- m_Aniso: 0
- m_MipBias: 0
- m_WrapU: 1
- m_WrapV: 1
- m_WrapW: 1
- m_Dimension: 2
- m_VolumeDepth: 1
- m_ShadowSamplingMode: 2
diff --git a/Assets/_Content/UI/FlashHallus/Stairs/RT_theater.renderTexture.meta b/Assets/_Content/UI/FlashHallus/Stairs/RT_theater.renderTexture.meta
deleted file mode 100644
index 7d8120af..00000000
--- a/Assets/_Content/UI/FlashHallus/Stairs/RT_theater.renderTexture.meta
+++ /dev/null
@@ -1,8 +0,0 @@
-fileFormatVersion: 2
-guid: 725048bdfff10644eb1cae1916817e85
-NativeFormatImporter:
- externalObjects: {}
- mainObjectFileID: 8400000
- userData:
- assetBundleName:
- assetBundleVariant:
diff --git a/Packages/OctoCore/Runtime/Scripts/Navigation/OctoNavigation.cs b/Packages/OctoCore/Runtime/Scripts/Navigation/OctoNavigation.cs
index c4f989b5..b4f03455 100644
--- a/Packages/OctoCore/Runtime/Scripts/Navigation/OctoNavigation.cs
+++ b/Packages/OctoCore/Runtime/Scripts/Navigation/OctoNavigation.cs
@@ -110,6 +110,9 @@ namespace OctoCore.Navigation
return;
}
+ if (OctoCore.Instance.Development.Log)
+ Debug.LogError($"[OctoNavigation] LoadScene({sceneData.name}) called at t={Time.time:F2}\n{StackTraceUtility.ExtractStackTrace()}");
+
_loadingCoroutine = OctoCore.Instance.StartCoroutine(LoadSceneCoroutine(sceneData));
}
@@ -124,6 +127,9 @@ namespace OctoCore.Navigation
return;
}
+ if (OctoCore.Instance.Development.Log)
+ Debug.LogError($"[OctoNavigation] Teleport({teleporter.name}) called at t={Time.time:F2}\n{StackTraceUtility.ExtractStackTrace()}");
+
OnTeleportStarted?.Invoke(null, teleporter);
// Same scene teleport