wip : scarecrow fix & subtitle event implementation

This commit is contained in:
Ferlat Thibaud
2026-06-01 12:45:40 +02:00
parent fde7b39206
commit 28c951f50f
14 changed files with 1088 additions and 567 deletions
@@ -17,5 +17,5 @@ MonoBehaviour:
- English
- French
_values:
- 'What ? '
- 'Quoi ? '
- Where am I ?
- 'Ou suis je ? '
@@ -17,5 +17,5 @@ MonoBehaviour:
- English
- French
_values:
- 'It won''t stop ? '
- "Ca ne veut pas s'arr\xEAter ? "
- I don't understand ?
- 'Je ne comprends pas ? '
@@ -17,5 +17,5 @@ MonoBehaviour:
- English
- French
_values:
- The theatre ?
- 'Le theatre ? '
- 'He ? '
- 'Hein ? '
File diff suppressed because one or more lines are too long
@@ -132,7 +132,7 @@ Material:
- _Surface: 0
- _VignettePower: 4.92
- _VignetteStrength: 1
- _Weight: 0.08962297
- _Weight: 1
- _WorkflowMode: 1
- _XRMotionVectorsPass: 1
- _ZWrite: 1
+4 -15
View File
@@ -11,7 +11,6 @@ GameObject:
- component: {fileID: 688462554248565909}
- component: {fileID: 3502526413762748772}
- component: {fileID: 3666808908055770611}
- component: {fileID: 1386704396112132862}
m_Layer: 0
m_Name: Ray
m_TagString: Untagged
@@ -62,6 +61,8 @@ MeshRenderer:
m_RayTracingAccelStructBuildFlagsOverride: 0
m_RayTracingAccelStructBuildFlags: 1
m_SmallMeshCulling: 1
m_ForceMeshLod: -1
m_MeshLodSelectionBias: 0
m_RenderingLayerMask: 1
m_RendererPriority: 0
m_Materials:
@@ -83,21 +84,9 @@ MeshRenderer:
m_AutoUVMaxDistance: 0.5
m_AutoUVMaxAngle: 89
m_LightmapParameters: {fileID: 0}
m_GlobalIlluminationMeshLod: 0
m_SortingLayerID: 0
m_SortingLayer: 0
m_SortingOrder: 0
m_MaskInteraction: 0
m_AdditionalVertexStreams: {fileID: 0}
--- !u!114 &1386704396112132862
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 2541733693143394657}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: cc3f4e6ebaca477438c280760d2d2f16, type: 3}
m_Name:
m_EditorClassIdentifier:
MeshFilter: {fileID: 3502526413762748772}
Renderer: {fileID: 3666808908055770611}
+231 -189
View File
@@ -806,11 +806,11 @@ PrefabInstance:
objectReference: {fileID: 0}
- target: {fileID: 4440040250278121308, guid: 6493d77978c5c1246a0410d1f9204524, type: 3}
propertyPath: m_LocalRotation.w
value: 1
value: 0.9816273
objectReference: {fileID: 0}
- target: {fileID: 4440040250278121308, guid: 6493d77978c5c1246a0410d1f9204524, type: 3}
propertyPath: m_LocalRotation.x
value: 0
value: -0.19080894
objectReference: {fileID: 0}
- target: {fileID: 4440040250278121308, guid: 6493d77978c5c1246a0410d1f9204524, type: 3}
propertyPath: m_LocalRotation.y
@@ -822,7 +822,7 @@ PrefabInstance:
objectReference: {fileID: 0}
- target: {fileID: 4440040250278121308, guid: 6493d77978c5c1246a0410d1f9204524, type: 3}
propertyPath: m_LocalEulerAnglesHint.x
value: 0
value: -22
objectReference: {fileID: 0}
- target: {fileID: 4484393045093388587, guid: 6493d77978c5c1246a0410d1f9204524, type: 3}
propertyPath: _debugStressValue
@@ -1004,12 +1004,6 @@ PrefabInstance:
insertIndex: -1
addedObject: {fileID: 1918828521}
m_AddedComponents:
- targetCorrespondingSourceObject: {fileID: 5575782855984327677, guid: 6493d77978c5c1246a0410d1f9204524, type: 3}
insertIndex: -1
addedObject: {fileID: 130733312}
- targetCorrespondingSourceObject: {fileID: 5575782855984327677, guid: 6493d77978c5c1246a0410d1f9204524, type: 3}
insertIndex: -1
addedObject: {fileID: 130733313}
- targetCorrespondingSourceObject: {fileID: 2101508725665932610, guid: 6493d77978c5c1246a0410d1f9204524, type: 3}
insertIndex: -1
addedObject: {fileID: 126892899}
@@ -1072,102 +1066,6 @@ MonoBehaviour:
scalingFactor: 1
m_posOffsetData: {fileID: 0}
listenerMask: 1
--- !u!1 &130733311 stripped
GameObject:
m_CorrespondingSourceObject: {fileID: 5575782855984327677, guid: 6493d77978c5c1246a0410d1f9204524, type: 3}
m_PrefabInstance: {fileID: 126892893}
m_PrefabAsset: {fileID: 0}
--- !u!114 &130733312
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 130733311}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 0097589062bdfad4a96fa20e8effbe2f, type: 3}
m_Name:
m_EditorClassIdentifier: OctoCore.Runtime::OctoCore.Components.OctoProceduralAnimator
_settings:
Space: 0
Type: 3
Balance: 1
Curve:
serializedVersion: 2
m_Curve:
- serializedVersion: 3
time: 0
value: 0
inSlope: 0
outSlope: 0
tangentMode: 0
weightedMode: 0
inWeight: 0
outWeight: 0
- serializedVersion: 3
time: 1
value: 1
inSlope: 0
outSlope: 0
tangentMode: 0
weightedMode: 0
inWeight: 0
outWeight: 0
m_PreInfinity: 2
m_PostInfinity: 2
m_RotationOrder: 4
RandomOffset: 1
Duration: 15
CycleOffset: 0
Translation: {x: 0, y: 0, z: 0}
Rotation: {x: -22, y: 0, z: 0}
Scale: {x: 0, y: 0, z: 0}
_state:
CurrentTime: 0
IsFinished: 0
InitialPosition: {x: 0, y: 0, z: 0}
InitialRotation: {x: 0, y: 0, z: 0, w: 0}
InitialScale: {x: 0, y: 0, z: 0}
--- !u!114 &130733313
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 130733311}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 5170627695bd877419928fa9ca37865d, type: 3}
m_Name:
m_EditorClassIdentifier: OctoCore.Runtime::OctoCore.Components.OctoWorldEvent
_trigger: 2
_action: 0
_condition: 0
_tags: []
_targets: []
_tolerance: 0.5
_duration: 1
_execution: 1
_delay: 10
_onTrigger:
m_PersistentCalls:
m_Calls: []
_onTriggerDelayed:
m_PersistentCalls:
m_Calls:
- m_Target: {fileID: 130733312}
m_TargetAssemblyTypeName: OctoCore.Components.OctoProceduralAnimator, OctoCore.Runtime
m_MethodName: PlayAnimation
m_Mode: 1
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
--- !u!1 &166766592 stripped
GameObject:
m_CorrespondingSourceObject: {fileID: 8829451551789304542, guid: 8206b722d11501a449d6a278cca2adfa, type: 3}
@@ -1239,6 +1137,39 @@ Transform:
- {fileID: 498371833}
m_Father: {fileID: 0}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!1 &228353701
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 228353702}
m_Layer: 0
m_Name: 'FlamesReflections '
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!4 &228353702
Transform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 228353701}
serializedVersion: 2
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children:
- {fileID: 1879689922}
- {fileID: 1952597877}
m_Father: {fileID: 571823342}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!1001 &230644866
PrefabInstance:
m_ObjectHideFlags: 0
@@ -1249,23 +1180,23 @@ PrefabInstance:
m_Modifications:
- target: {fileID: 303326238445583123, guid: b235f6e405ca9644bb305756268ae07f, type: 3}
propertyPath: m_LocalScale.x
value: 4
value: 8
objectReference: {fileID: 0}
- target: {fileID: 303326238445583123, guid: b235f6e405ca9644bb305756268ae07f, type: 3}
propertyPath: m_LocalScale.y
value: 5.0204
value: 9.774718
objectReference: {fileID: 0}
- target: {fileID: 303326238445583123, guid: b235f6e405ca9644bb305756268ae07f, type: 3}
propertyPath: m_LocalScale.z
value: 4
value: 8
objectReference: {fileID: 0}
- target: {fileID: 303326238445583123, guid: b235f6e405ca9644bb305756268ae07f, type: 3}
propertyPath: m_LocalPosition.x
value: 12.46
value: 24
objectReference: {fileID: 0}
- target: {fileID: 303326238445583123, guid: b235f6e405ca9644bb305756268ae07f, type: 3}
propertyPath: m_LocalPosition.y
value: -3.094842
value: 8.6539
objectReference: {fileID: 0}
- target: {fileID: 303326238445583123, guid: b235f6e405ca9644bb305756268ae07f, type: 3}
propertyPath: m_LocalPosition.z
@@ -1301,7 +1232,7 @@ PrefabInstance:
objectReference: {fileID: 0}
- target: {fileID: 303326238445583123, guid: b235f6e405ca9644bb305756268ae07f, type: 3}
propertyPath: m_ConstrainProportionsScale
value: 1
value: 0
objectReference: {fileID: 0}
- target: {fileID: 787135931011508029, guid: b235f6e405ca9644bb305756268ae07f, type: 3}
propertyPath: m_Name
@@ -1719,7 +1650,7 @@ Transform:
m_ConstrainProportionsScale: 0
m_Children:
- {fileID: 1058633435}
- {fileID: 1879689922}
- {fileID: 228353702}
m_Father: {fileID: 0}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!1 &575144955
@@ -2007,51 +1938,6 @@ Transform:
m_CorrespondingSourceObject: {fileID: 2721267321453921552, guid: a4ca96f09a0c04645aa697def551b52d, type: 3}
m_PrefabInstance: {fileID: 620676192}
m_PrefabAsset: {fileID: 0}
--- !u!1 &658668483
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 658668485}
- component: {fileID: 658668484}
m_Layer: 0
m_Name: InputManager
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!114 &658668484
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 658668483}
m_Enabled: 0
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: e340839b22a784542ba8afdfde612c2e, type: 3}
m_Name:
m_EditorClassIdentifier: Assembly-CSharp::Unheimlich.Core.Input.InputManager
_currentContext: 3
--- !u!4 &658668485
Transform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 658668483}
serializedVersion: 2
m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
m_LocalPosition: {x: -1.32941, y: -1.014, z: 2.47307}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 1358231749}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!1 &832575517
GameObject:
m_ObjectHideFlags: 0
@@ -2455,23 +2341,23 @@ PrefabInstance:
m_Modifications:
- target: {fileID: 303326238445583123, guid: b235f6e405ca9644bb305756268ae07f, type: 3}
propertyPath: m_LocalScale.x
value: 4
value: 8
objectReference: {fileID: 0}
- target: {fileID: 303326238445583123, guid: b235f6e405ca9644bb305756268ae07f, type: 3}
propertyPath: m_LocalScale.y
value: 5.0204
value: 9.774718
objectReference: {fileID: 0}
- target: {fileID: 303326238445583123, guid: b235f6e405ca9644bb305756268ae07f, type: 3}
propertyPath: m_LocalScale.z
value: 4
value: 8
objectReference: {fileID: 0}
- target: {fileID: 303326238445583123, guid: b235f6e405ca9644bb305756268ae07f, type: 3}
propertyPath: m_LocalPosition.x
value: -12
value: -24
objectReference: {fileID: 0}
- target: {fileID: 303326238445583123, guid: b235f6e405ca9644bb305756268ae07f, type: 3}
propertyPath: m_LocalPosition.y
value: -3.094842
value: 8.6539
objectReference: {fileID: 0}
- target: {fileID: 303326238445583123, guid: b235f6e405ca9644bb305756268ae07f, type: 3}
propertyPath: m_LocalPosition.z
@@ -2507,7 +2393,7 @@ PrefabInstance:
objectReference: {fileID: 0}
- target: {fileID: 303326238445583123, guid: b235f6e405ca9644bb305756268ae07f, type: 3}
propertyPath: m_ConstrainProportionsScale
value: 1
value: 0
objectReference: {fileID: 0}
- target: {fileID: 787135931011508029, guid: b235f6e405ca9644bb305756268ae07f, type: 3}
propertyPath: m_Name
@@ -2843,7 +2729,6 @@ Transform:
m_ConstrainProportionsScale: 0
m_Children:
- {fileID: 1533276369}
- {fileID: 658668485}
- {fileID: 882795733}
m_Father: {fileID: 0}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
@@ -2875,8 +2760,8 @@ Transform:
m_GameObject: {fileID: 1520114605}
serializedVersion: 2
m_LocalRotation: {x: 0.7071068, y: -0, z: -0, w: 0.7071068}
m_LocalPosition: {x: 0, y: -16.294641, z: 0}
m_LocalScale: {x: 2.297417, y: 5, z: 4.9749117}
m_LocalPosition: {x: 0, y: -19.2968, z: 0}
m_LocalScale: {x: 5.169189, y: 11.250002, z: 10.593136}
m_ConstrainProportionsScale: 1
m_Children: []
m_Father: {fileID: 1527450886}
@@ -2928,7 +2813,7 @@ MeshRenderer:
m_RenderingLayerMask: 1
m_RendererPriority: 0
m_Materials:
- {fileID: 2100000, guid: 31321ba15b8f8eb4c954353edc038b1d, type: 2}
- {fileID: 2100000, guid: 5f465680b9c699e4a8e573e246fa1e9e, type: 2}
m_StaticBatchInfo:
firstSubMesh: 0
subMeshCount: 0
@@ -3116,9 +3001,12 @@ MonoBehaviour:
m_PreInfinity: 2
m_PostInfinity: 2
m_RotationOrder: 4
_heatMaterial: {fileID: 2100000, guid: 1daabe35e56c7bf41bb81f984e694029, type: 2}
_lightFlicker: {fileID: 0}
_targetLightIntensity: 15000
_heatMaterial: {fileID: 0}
_lights:
- Flicker: {fileID: 1879689923}
TargetIntensity: 15000
- Flicker: {fileID: 1952597878}
TargetIntensity: 300
--- !u!4 &1533276369
Transform:
m_ObjectHideFlags: 0
@@ -3720,7 +3608,7 @@ PrefabInstance:
objectReference: {fileID: 0}
- target: {fileID: 8829451551789304537, guid: 8206b722d11501a449d6a278cca2adfa, type: 3}
propertyPath: m_LocalScale.y
value: 9.897436
value: 9
objectReference: {fileID: 0}
- target: {fileID: 8829451551789304537, guid: 8206b722d11501a449d6a278cca2adfa, type: 3}
propertyPath: m_LocalScale.z
@@ -3732,7 +3620,7 @@ PrefabInstance:
objectReference: {fileID: 0}
- target: {fileID: 8829451551789304537, guid: 8206b722d11501a449d6a278cca2adfa, type: 3}
propertyPath: m_LocalPosition.y
value: 9.4512825
value: 8.44
objectReference: {fileID: 0}
- target: {fileID: 8829451551789304537, guid: 8206b722d11501a449d6a278cca2adfa, type: 3}
propertyPath: m_LocalPosition.z
@@ -3864,7 +3752,7 @@ GameObject:
- component: {fileID: 1879689922}
- component: {fileID: 1879689921}
- component: {fileID: 1879689920}
- component: {fileID: 1879689919}
- component: {fileID: 1879689923}
m_Layer: 0
m_Name: Point Light
m_TagString: Untagged
@@ -3872,18 +3760,6 @@ GameObject:
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!114 &1879689919
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1879689918}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: d4144428452c31843a84d459266f8212, type: 3}
m_Name:
m_EditorClassIdentifier: Assembly-CSharp::MonoLimboStudio.LightFlicker
--- !u!114 &1879689920
MonoBehaviour:
m_ObjectHideFlags: 0
@@ -3923,9 +3799,9 @@ Light:
m_Enabled: 1
serializedVersion: 12
m_Type: 2
m_Color: {r: 0.5471698, g: 0.2757114, b: 0.17722787, a: 1}
m_Color: {r: 0.9716981, g: 0.32118085, b: 0, a: 1}
m_Intensity: 5000
m_Range: 25.400116
m_Range: 32.184563
m_SpotAngle: 30
m_InnerSpotAngle: 21.80208
m_CookieSize2D: {x: 0.5, y: 0.5}
@@ -3987,12 +3863,31 @@ Transform:
m_GameObject: {fileID: 1879689918}
serializedVersion: 2
m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
m_LocalPosition: {x: 0.17059004, y: 10.366, z: -1.12693}
m_LocalPosition: {x: 0, y: 15.91, z: -1.3500001}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 571823342}
m_Father: {fileID: 228353702}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!114 &1879689923
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1879689918}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 1df1fd6452d396e4699ee7d8406130a2, type: 3}
m_Name:
m_EditorClassIdentifier: Assembly-CSharp::MonoLimboStudio.LightFlicker
targetLight: {fileID: 1879689921}
baseIntensity: 0
flickerRange: 0.4
flickerSpeed: 0.6
glitchChance: 0.15
glitchMinDuration: 0.1
glitchMaxDuration: 0.2
--- !u!1001 &1884628755
PrefabInstance:
m_ObjectHideFlags: 0
@@ -4201,6 +4096,153 @@ MeshFilter:
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1918828520}
m_Mesh: {fileID: 10209, guid: 0000000000000000e000000000000000, type: 0}
--- !u!1 &1952597876
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 1952597877}
- component: {fileID: 1952597880}
- component: {fileID: 1952597879}
- component: {fileID: 1952597878}
m_Layer: 0
m_Name: Point Light (1)
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!4 &1952597877
Transform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1952597876}
serializedVersion: 2
m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
m_LocalPosition: {x: 0, y: 15.91, z: 9.53}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 228353702}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!114 &1952597878
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1952597876}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 1df1fd6452d396e4699ee7d8406130a2, type: 3}
m_Name:
m_EditorClassIdentifier: Assembly-CSharp::MonoLimboStudio.LightFlicker
targetLight: {fileID: 1952597880}
baseIntensity: 0
flickerRange: 0.2
flickerSpeed: 0.4
glitchChance: 0
glitchMinDuration: 0
glitchMaxDuration: 0
--- !u!114 &1952597879
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1952597876}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 474bcb49853aa07438625e644c072ee6, type: 3}
m_Name:
m_EditorClassIdentifier: Unity.RenderPipelines.Universal.Runtime::UnityEngine.Rendering.Universal.UniversalAdditionalLightData
m_UsePipelineSettings: 1
m_AdditionalLightsShadowResolutionTier: 2
m_CustomShadowLayers: 0
m_LightCookieSize: {x: 1, y: 1}
m_LightCookieOffset: {x: 0, y: 0}
m_SoftShadowQuality: 0
m_RenderingLayersMask:
serializedVersion: 0
m_Bits: 1
m_ShadowRenderingLayersMask:
serializedVersion: 0
m_Bits: 1
m_Version: 4
m_LightLayerMask: 1
m_ShadowLayerMask: 1
m_RenderingLayers: 1
m_ShadowRenderingLayers: 1
--- !u!108 &1952597880
Light:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1952597876}
m_Enabled: 1
serializedVersion: 12
m_Type: 2
m_Color: {r: 0.972549, g: 0.17432763, b: 0, a: 1}
m_Intensity: 200
m_Range: 32.184563
m_SpotAngle: 30
m_InnerSpotAngle: 21.80208
m_CookieSize2D: {x: 0.5, y: 0.5}
m_Shadows:
m_Type: 0
m_Resolution: -1
m_CustomResolution: -1
m_Strength: 1
m_Bias: 0.05
m_NormalBias: 0.4
m_NearPlane: 0.2
m_CullingMatrixOverride:
e00: 1
e01: 0
e02: 0
e03: 0
e10: 0
e11: 1
e12: 0
e13: 0
e20: 0
e21: 0
e22: 1
e23: 0
e30: 0
e31: 0
e32: 0
e33: 1
m_UseCullingMatrixOverride: 0
m_Cookie: {fileID: 0}
m_DrawHalo: 0
m_Flare: {fileID: 0}
m_RenderMode: 0
m_CullingMask:
serializedVersion: 2
m_Bits: 4294967295
m_RenderingLayerMask: 1
m_Lightmapping: 4
m_LightShadowCasterMode: 0
m_AreaSize: {x: 1, y: 1}
m_BounceIntensity: 1
m_ColorTemperature: 6570
m_UseColorTemperature: 0
m_BoundingSphereOverride: {x: 0, y: 0, z: 0, w: 0}
m_UseBoundingSphereOverride: 0
m_UseViewFrustumForShadowCasterCull: 1
m_ForceVisible: 0
m_ShadowRadius: 0
m_ShadowAngle: 0
m_LightUnit: 1
m_LuxAtDistance: 1
m_EnableSpotReflector: 1
--- !u!1001 &1976921335
PrefabInstance:
m_ObjectHideFlags: 0
+223 -49
View File
@@ -1654,6 +1654,18 @@ MonoBehaviour:
m_StringArgument:
m_BoolArgument: 1
m_CallState: 2
- m_Target: {fileID: 625490235}
m_TargetAssemblyTypeName: Unheimlich.World.CameraSystem.LostFootageRig, Assembly-CSharp
m_MethodName: Enable
m_Mode: 1
m_Arguments:
m_ObjectArgument: {fileID: 0}
m_ObjectArgumentAssemblyTypeName: UnityEngine.Object, UnityEngine
m_IntArgument: 0
m_FloatArgument: 0
m_StringArgument:
m_BoolArgument: 1
m_CallState: 2
_onTriggerDelayed:
m_PersistentCalls:
m_Calls: []
@@ -4874,6 +4886,17 @@ Light:
m_LightUnit: 1
m_LuxAtDistance: 1
m_EnableSpotReflector: 1
--- !u!114 &625490235 stripped
MonoBehaviour:
m_CorrespondingSourceObject: {fileID: 1476756471834662335, guid: 6493d77978c5c1246a0410d1f9204524, type: 3}
m_PrefabInstance: {fileID: 1549040694}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 320cde26f18d40b40a31c85e85ee4e59, type: 3}
m_Name:
m_EditorClassIdentifier: Assembly-CSharp::Unheimlich.World.CameraSystem.LostFootageRig
--- !u!4 &638798851 stripped
Transform:
m_CorrespondingSourceObject: {fileID: -1693702828174715032, guid: 026d90e6b31bf0f47b6072ba92aef39a, type: 3}
@@ -8202,10 +8225,12 @@ GameObject:
- component: {fileID: 938880779}
- component: {fileID: 938880778}
- component: {fileID: 938880777}
- component: {fileID: 938880775}
- component: {fileID: 938880781}
- component: {fileID: 938880776}
- component: {fileID: 938880775}
- component: {fileID: 938880780}
m_Layer: 0
m_Name: DialogueOne
m_Name: DialogueA
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
@@ -8293,7 +8318,7 @@ MonoBehaviour:
m_Script: {fileID: 11500000, guid: 1023fdbb836c50f48bd4b52575ed3689, type: 3}
m_Name:
m_EditorClassIdentifier: OctoCore.Runtime::OctoCore.Localization.OctoLocalizedText
data: {fileID: 0}
data: {fileID: 11400000, guid: 973e511f44be1e7419527fbc54fa0bf1, type: 2}
text: {fileID: 0}
textMeshPro: {fileID: 0}
textMeshProUGUI: {fileID: 938880778}
@@ -8342,7 +8367,7 @@ MonoBehaviour:
m_OnCullStateChanged:
m_PersistentCalls:
m_Calls: []
m_text: 'Ou suis je ? '
m_text: Where am I ?
m_isRightToLeft: 0
m_fontAsset: {fileID: 11400000, guid: 9861d68f4cda1504f8e39cc1464e8bec, type: 2}
m_sharedMaterial: {fileID: -7153799593197912463, guid: 9861d68f4cda1504f8e39cc1464e8bec, type: 2}
@@ -8422,6 +8447,58 @@ CanvasRenderer:
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 938880773}
m_CullTransparentMesh: 1
--- !u!114 &938880780
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 938880773}
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: 1
_delay: 3
_onTrigger:
m_PersistentCalls:
m_Calls: []
_onTriggerDelayed:
m_PersistentCalls:
m_Calls:
- m_Target: {fileID: 681190132}
m_TargetAssemblyTypeName: Unheimlich.Features.Hallucination.HallucinationFlash,
Assembly-CSharp
m_MethodName: Play
m_Mode: 1
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
--- !u!114 &938880781
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 938880773}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: a2fcf97d75546f147adf431e737bce52, type: 3}
m_Name:
m_EditorClassIdentifier: Assembly-CSharp::Unheimlich.Features.Dialogue.LocalizedSubtitle
--- !u!1 &939771951
GameObject:
m_ObjectHideFlags: 0
@@ -10769,6 +10846,18 @@ MonoBehaviour:
m_StringArgument:
m_BoolArgument: 0
m_CallState: 2
- m_Target: {fileID: 625490235}
m_TargetAssemblyTypeName: Unheimlich.World.CameraSystem.LostFootageRig, Assembly-CSharp
m_MethodName: Disable
m_Mode: 1
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: []
@@ -10809,7 +10898,7 @@ GameObject:
- component: {fileID: 1161394551}
- component: {fileID: 1161394545}
m_Layer: 0
m_Name: DialogueThree
m_Name: DialogueC
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
@@ -12093,10 +12182,11 @@ GameObject:
- component: {fileID: 1221498299}
- component: {fileID: 1221498298}
- component: {fileID: 1221498297}
- component: {fileID: 1221498295}
- component: {fileID: 1221498300}
- component: {fileID: 1221498296}
- component: {fileID: 1221498295}
m_Layer: 0
m_Name: DialogueThree
m_Name: DialogueC
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
@@ -12148,7 +12238,7 @@ MonoBehaviour:
_onTriggerDelayed:
m_PersistentCalls:
m_Calls:
- m_Target: {fileID: 6305877997866428113}
- m_Target: {fileID: 477153748}
m_TargetAssemblyTypeName: Unheimlich.Features.Hallucination.HallucinationFlash,
Assembly-CSharp
m_MethodName: Play
@@ -12173,7 +12263,7 @@ MonoBehaviour:
m_Script: {fileID: 11500000, guid: 1023fdbb836c50f48bd4b52575ed3689, type: 3}
m_Name:
m_EditorClassIdentifier: OctoCore.Runtime::OctoCore.Localization.OctoLocalizedText
data: {fileID: 0}
data: {fileID: 11400000, guid: 1775f09327d76ab4eac9a8b4b75480ff, type: 2}
text: {fileID: 0}
textMeshPro: {fileID: 0}
textMeshProUGUI: {fileID: 1221498298}
@@ -12222,7 +12312,7 @@ MonoBehaviour:
m_OnCullStateChanged:
m_PersistentCalls:
m_Calls: []
m_text: 'Hein ? '
m_text: 'He ? '
m_isRightToLeft: 0
m_fontAsset: {fileID: 11400000, guid: 9861d68f4cda1504f8e39cc1464e8bec, type: 2}
m_sharedMaterial: {fileID: -7153799593197912463, guid: 9861d68f4cda1504f8e39cc1464e8bec, type: 2}
@@ -12302,6 +12392,18 @@ CanvasRenderer:
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1221498293}
m_CullTransparentMesh: 1
--- !u!114 &1221498300
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1221498293}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: a2fcf97d75546f147adf431e737bce52, type: 3}
m_Name:
m_EditorClassIdentifier: Assembly-CSharp::Unheimlich.Features.Dialogue.LocalizedSubtitle
--- !u!1 &1233009596
GameObject:
m_ObjectHideFlags: 0
@@ -12357,10 +12459,12 @@ GameObject:
- component: {fileID: 1270400839}
- component: {fileID: 1270400838}
- component: {fileID: 1270400837}
- component: {fileID: 1270400835}
- component: {fileID: 1270400841}
- component: {fileID: 1270400836}
- component: {fileID: 1270400835}
- component: {fileID: 1270400840}
m_Layer: 0
m_Name: DialogueTwo
m_Name: DialogueB
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
@@ -12448,7 +12552,7 @@ MonoBehaviour:
m_Script: {fileID: 11500000, guid: 1023fdbb836c50f48bd4b52575ed3689, type: 3}
m_Name:
m_EditorClassIdentifier: OctoCore.Runtime::OctoCore.Localization.OctoLocalizedText
data: {fileID: 0}
data: {fileID: 11400000, guid: 3c05ba91d318d524fbcf867fe886c553, type: 2}
text: {fileID: 0}
textMeshPro: {fileID: 0}
textMeshProUGUI: {fileID: 1270400838}
@@ -12497,7 +12601,7 @@ MonoBehaviour:
m_OnCullStateChanged:
m_PersistentCalls:
m_Calls: []
m_text: 'Je ne comprend pas ? '
m_text: I don't understand ?
m_isRightToLeft: 0
m_fontAsset: {fileID: 11400000, guid: 9861d68f4cda1504f8e39cc1464e8bec, type: 2}
m_sharedMaterial: {fileID: -7153799593197912463, guid: 9861d68f4cda1504f8e39cc1464e8bec, type: 2}
@@ -12577,6 +12681,58 @@ CanvasRenderer:
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1270400833}
m_CullTransparentMesh: 1
--- !u!114 &1270400840
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: 1
_delay: 3
_onTrigger:
m_PersistentCalls:
m_Calls: []
_onTriggerDelayed:
m_PersistentCalls:
m_Calls:
- m_Target: {fileID: 1916608619}
m_TargetAssemblyTypeName: Unheimlich.Features.Hallucination.HallucinationFlash,
Assembly-CSharp
m_MethodName: Play
m_Mode: 1
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
--- !u!114 &1270400841
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: a2fcf97d75546f147adf431e737bce52, type: 3}
m_Name:
m_EditorClassIdentifier: Assembly-CSharp::Unheimlich.Features.Dialogue.LocalizedSubtitle
--- !u!1 &1276767359
GameObject:
m_ObjectHideFlags: 0
@@ -13639,12 +13795,12 @@ GameObject:
- component: {fileID: 1385908343}
- component: {fileID: 1385908342}
- component: {fileID: 1385908341}
- component: {fileID: 1385908339}
- component: {fileID: 1385908345}
- component: {fileID: 1385908344}
- component: {fileID: 1385908339}
- component: {fileID: 1385908346}
m_Layer: 0
m_Name: DialogueTwo
m_Name: DialogueB
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
@@ -15223,8 +15379,44 @@ PrefabInstance:
propertyPath: m_Enabled
value: 1
objectReference: {fileID: 0}
- target: {fileID: 1476756471834662335, guid: 6493d77978c5c1246a0410d1f9204524, type: 3}
propertyPath: _isActive
value: 0
objectReference: {fileID: 0}
- target: {fileID: 1476756471834662335, guid: 6493d77978c5c1246a0410d1f9204524, type: 3}
propertyPath: m_Enabled
value: 1
objectReference: {fileID: 0}
- target: {fileID: 1476756471834662335, guid: 6493d77978c5c1246a0410d1f9204524, type: 3}
propertyPath: _stressLevel
value: 0.3
objectReference: {fileID: 0}
- target: {fileID: 1476756471834662335, guid: 6493d77978c5c1246a0410d1f9204524, type: 3}
propertyPath: _idleAmplitude
value: 0.5
objectReference: {fileID: 0}
- target: {fileID: 1476756471834662335, guid: 6493d77978c5c1246a0410d1f9204524, type: 3}
propertyPath: _walkAmplitude
value: 0.7
objectReference: {fileID: 0}
- target: {fileID: 1476756471834662335, guid: 6493d77978c5c1246a0410d1f9204524, type: 3}
propertyPath: _idleNoiseSpeed
value: 1.6
objectReference: {fileID: 0}
- target: {fileID: 1476756471834662335, guid: 6493d77978c5c1246a0410d1f9204524, type: 3}
propertyPath: _walkNoiseSpeed
value: 2
objectReference: {fileID: 0}
- target: {fileID: 1476756471834662335, guid: 6493d77978c5c1246a0410d1f9204524, type: 3}
propertyPath: _masterIntensity
value: 1.5
objectReference: {fileID: 0}
- target: {fileID: 1476756471834662335, guid: 6493d77978c5c1246a0410d1f9204524, type: 3}
propertyPath: _debugStressValue
value: 0
objectReference: {fileID: 0}
- target: {fileID: 1476756471834662335, guid: 6493d77978c5c1246a0410d1f9204524, type: 3}
propertyPath: _debugSustainStress
value: 0
objectReference: {fileID: 0}
- target: {fileID: 5295567073180248356, guid: 6493d77978c5c1246a0410d1f9204524, type: 3}
@@ -16518,6 +16710,19 @@ MonoBehaviour:
m_StringArgument:
m_BoolArgument: 1
m_CallState: 2
- m_Target: {fileID: 625490235}
m_TargetAssemblyTypeName: Unheimlich.World.CameraSystem.LostFootageRig,
Assembly-CSharp
m_MethodName: Enable
m_Mode: 1
m_Arguments:
m_ObjectArgument: {fileID: 0}
m_ObjectArgumentAssemblyTypeName: UnityEngine.Object, UnityEngine
m_IntArgument: 0
m_FloatArgument: 0
m_StringArgument:
m_BoolArgument: 1
m_CallState: 2
Triggered: 0
- Progression: 0.5
OnReached:
@@ -16629,37 +16834,6 @@ MonoBehaviour:
m_BoolArgument: 0
m_CallState: 2
Triggered: 0
- Progression: 0.9
OnReached:
m_PersistentCalls:
m_Calls:
- m_Target: {fileID: 2002434881}
m_TargetAssemblyTypeName: Unheimlich.Features.Hallucination.HallucinationPostProcess,
Assembly-CSharp
m_MethodName: AddSanityWrapper
m_Mode: 1
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
- m_Target: {fileID: 3473725938941227729}
m_TargetAssemblyTypeName: Unheimlich.Features.Hallucination.HallucinationFlash,
Assembly-CSharp
m_MethodName: Play
m_Mode: 1
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
Triggered: 0
--- !u!1 &1708782433
GameObject:
m_ObjectHideFlags: 0
@@ -22539,12 +22713,12 @@ GameObject:
- component: {fileID: 6820444050397160330}
- component: {fileID: 160056245658704172}
- component: {fileID: 6984622148685993083}
- component: {fileID: 6984622148685993084}
- component: {fileID: 6984622148685993087}
- component: {fileID: 6984622148685993085}
- component: {fileID: 6984622148685993084}
- component: {fileID: 6984622148685993088}
m_Layer: 0
m_Name: DialogueOne
m_Name: DialogueA
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
@@ -1,4 +1,6 @@
using System.Collections;
using System.Collections.Generic;
using Unheimlich.VFX;
using UnityEngine;
using UnityEngine.Rendering;
@@ -8,7 +10,6 @@ public class ScarecrowFire : MonoBehaviour
public class FireElement
{
public GameObject VFX;
/// <summary>Original scale captured at initialization, used as lerp target.</summary>
[HideInInspector] public Vector3 OriginalScale;
}
@@ -23,14 +24,9 @@ public class ScarecrowFire : MonoBehaviour
[SerializeField] private FireElement _fireBig;
[Header("Propagation Timings")]
[Tooltip("Duration of the scale lerp for each fire element (seconds).")]
[SerializeField] private float _growDuration = 3f;
[Tooltip("How early the next stage starts before the current one finishes (0 = no overlap, 1 = instant).")]
[Range(0f, 1f)]
[SerializeField] private float _overlapFactor = 0.4f;
[Tooltip("Curve driving the scale growth — tweak directly in the Inspector.")]
[SerializeField] private AnimationCurve _growCurve = new AnimationCurve(
new Keyframe(0f, 0f, 0f, 0f),
new Keyframe(0.3f, 0.1f, 0f, 2f),
@@ -39,10 +35,7 @@ public class ScarecrowFire : MonoBehaviour
);
[Header("Post Process")]
[Tooltip("Volume driving the heat haze effect — weight is driven up as fire spreads.")]
[SerializeField] private Volume _heatVolume;
[Tooltip("Curve driving all heat effects over the full sequence duration.")]
[SerializeField] private AnimationCurve _heatCurve = new AnimationCurve(
new Keyframe(0f, 0f, 0f, 0.5f),
new Keyframe(0.5f, 0.4f, 1f, 1f),
@@ -50,17 +43,18 @@ public class ScarecrowFire : MonoBehaviour
);
[Header("Heat Shader")]
[Tooltip("Material using the HeatHaze shader — _Weight property is driven from 0 to 1.")]
[SerializeField] private Material _heatMaterial;
[Header("Light")]
[Tooltip("LightFlicker component to drive — baseIntensity is ramped up with the fire.")]
[SerializeField] private MonoLimboStudio.LightFlicker _lightFlicker;
[Header("Lights")]
[SerializeField] private List<LightEntry> _lights = new List<LightEntry>();
[Tooltip("Final light intensity reached when the fire is fully ablaze.")]
[SerializeField] private float _targetLightIntensity = 3f;
[System.Serializable]
public class LightEntry
{
public LightFlicker Flicker;
public float TargetIntensity = 3f;
}
// Flag set when the last GrowFire completes — DriveHeatEffects waits on this
private bool _fireSequenceComplete = false;
private float _totalSequenceDuration = 0f;
@@ -77,16 +71,13 @@ public class ScarecrowFire : MonoBehaviour
InitElement(_fireHead);
InitElement(_fireBig);
// Used as a time reference for _heatCurve mapping — doesn't need to be exact
// since DriveHeatEffects now syncs to _fireSequenceComplete rather than this value
float overlapDelay = _growDuration * (1f - _overlapFactor);
_totalSequenceDuration = _growDuration + (7f * overlapDelay);
// Ensure everything starts at zero
SetHeatShaderWeight(0f);
if (_lightFlicker)
_lightFlicker.SetBaseIntensity(0f);
foreach (var entry in _lights)
if (entry.Flicker) entry.Flicker.SetBaseIntensity(0f);
}
void Start()
@@ -94,10 +85,6 @@ public class ScarecrowFire : MonoBehaviour
TriggerFire();
}
/// <summary>
/// Captures the original Inspector scale, then sets the starting scale to
/// (x * 0.2, y * 0.1, z * 0.2) so each element grows from near-nothing.
/// </summary>
private void InitElement(FireElement el)
{
if (!el.VFX) return;
@@ -113,51 +100,36 @@ public class ScarecrowFire : MonoBehaviour
// ─────────────────────────────────────────────────────────────────────────
/// <summary>Starts the full fire propagation sequence.</summary>
public void TriggerFire()
{
_fireSequenceComplete = false;
StartCoroutine(FireSequence());
}
/// <summary>
/// Propagates fire bottom-up with overlapping stages for an organic feel.
/// Sets _fireSequenceComplete when the last element finishes growing.
/// </summary>
private IEnumerator FireSequence()
{
float overlapDelay = _growDuration * (1f - _overlapFactor);
// Drive all heat effects independently — syncs via _fireSequenceComplete
StartCoroutine(DriveHeatEffects());
// Feet
StartCoroutine(GrowFire(_fireBase));
yield return new WaitForSeconds(overlapDelay);
// Torso overlaps with feet still growing
StartCoroutine(GrowFire(_fireTorso));
yield return new WaitForSeconds(overlapDelay);
// Both arms ignite simultaneously, each propagating from shoulder to tip
StartCoroutine(PropagateArm(_fireArmLeft, _fireArmLeftEnd, overlapDelay));
StartCoroutine(PropagateArm(_fireArmRight, _fireArmRightEnd, overlapDelay));
yield return new WaitForSeconds(overlapDelay * 2f);
// Head
StartCoroutine(GrowFire(_fireHead));
yield return new WaitForSeconds(overlapDelay);
// Full blaze — wait for it to fully complete before flagging done
yield return StartCoroutine(GrowFire(_fireBig));
_fireSequenceComplete = true;
}
/// <summary>
/// Propagates fire along one arm: shoulder ignites first,
/// then tip starts after overlapDelay rather than waiting for shoulder to finish.
/// </summary>
private IEnumerator PropagateArm(FireElement shoulder, FireElement tip, float overlapDelay)
{
StartCoroutine(GrowFire(shoulder));
@@ -165,10 +137,6 @@ public class ScarecrowFire : MonoBehaviour
yield return StartCoroutine(GrowFire(tip));
}
/// <summary>
/// Activates a fire element and lerps its scale from near-zero to its original
/// Inspector scale, driven by _growCurve for an organic progression.
/// </summary>
private IEnumerator GrowFire(FireElement el)
{
if (!el.VFX) yield break;
@@ -195,57 +163,54 @@ public class ScarecrowFire : MonoBehaviour
// ─────────────────────────────────────────────────────────────────────────
/// <summary>
/// Drives all heat effects (post-process volume, heat shader, light intensity)
/// using _heatCurve until _fireSequenceComplete is set, then snaps cleanly to 1.
/// Decoupled from individual fire element timing for smoother blending.
/// </summary>
private IEnumerator DriveHeatEffects()
{
float elapsed = 0f;
float elapsed = 0f;
float lastWeight = 0f;
// Phase 1 : monte avec la heatCurve jusqu'à ce que la séquence feu soit finie.
// On snapshote lastWeight à chaque frame pour partir de la vraie valeur courante
// en phase 2, évitant tout creux si la courbe redescend après t=1.
while (!_fireSequenceComplete)
{
elapsed += Time.deltaTime;
float t = elapsed / _totalSequenceDuration;
float weight = _heatCurve.Evaluate(Mathf.Min(t, 0.99f));
if (_heatVolume)
_heatVolume.weight = weight;
SetHeatShaderWeight(weight);
if (_lightFlicker)
_lightFlicker.SetBaseIntensity(_targetLightIntensity * weight);
float t = elapsed / _totalSequenceDuration;
lastWeight = _heatCurve.Evaluate(Mathf.Clamp01(t));
ApplyHeatWeight(lastWeight);
yield return null;
}
float lerpElapsed = 0f;
// Phase 2 : lerp propre de la valeur courante vers 1, sans jamais redescendre.
float lerpElapsed = 0f;
float lerpDuration = 8f;
float startWeight = _heatCurve.Evaluate(0.99f);
float startWeight = lastWeight; // ← valeur réelle au moment du flag, pas heatCurve(0.99)
while (lerpElapsed < lerpDuration)
{
lerpElapsed += Time.deltaTime;
float weight = Mathf.Lerp(startWeight, 1f, lerpElapsed / lerpDuration);
if (_heatVolume) _heatVolume.weight = weight;
SetHeatShaderWeight(weight);
if (_lightFlicker) _lightFlicker.SetBaseIntensity(_targetLightIntensity * weight);
ApplyHeatWeight(weight);
yield return null;
}
if (_heatVolume) _heatVolume.weight = 1f;
SetHeatShaderWeight(1f);
if (_lightFlicker) _lightFlicker.SetBaseIntensity(_targetLightIntensity);
// Phase 3 : maintien à 1 à l'infini.
ApplyHeatWeight(1f);
}
/// <summary>Applique un weight normalisé à tous les effets de chaleur + lumière.</summary>
private void ApplyHeatWeight(float weight)
{
if (_heatVolume) _heatVolume.weight = weight;
SetHeatShaderWeight(weight);
// ScarecrowFire pilote la base — LightFlicker applique le flicker par-dessus
// sans écrire directement sur targetLight.intensity.
foreach (var entry in _lights)
if (entry.Flicker) entry.Flicker.SetBaseIntensity(entry.TargetIntensity * weight);
}
/// <summary>
/// Drives the heat shader via a single normalized weight (0-1).
/// All visual parameters are tweaked directly on the material in the Inspector.
/// </summary>
private void SetHeatShaderWeight(float weight)
{
if (!_heatMaterial) return;
@@ -7,12 +7,15 @@ namespace Unheimlich.World.CameraSystem
/// Overlays a "lost footage / handheld camcorder" shake on a dedicated pivot
/// sitting between CameraPivot and Camera Player.
///
/// Layered in three passes:
/// Layered in four passes:
/// 1. Continuous Perlin drift — organic idle tremor, scales with movement and stress.
/// 2. Micro-jolts — randomised snap/recoil spikes, only fire when the camera
/// is steady (attenuated during active mouse look).
/// 2. Micro-jolts — randomised snap/recoil spikes, only fire when the
/// camera is steady (attenuated during active mouse look).
/// 3. Inertia swinging — the camera "lags" behind head rotation on all axes,
/// simulating the physical weight of a handheld camcorder.
/// 4. Spinning/dizzy drift — a slow, persistent rotational pull on Y (and a subtle
/// rolling tilt on Z) that builds with stress, simulating
/// a confused/disoriented head.
///
/// Hierarchy expected:
/// OctoPlayerFP (mouse-look root)
@@ -20,13 +23,32 @@ namespace Unheimlich.World.CameraSystem
/// └── LostFootagePivot ← this component
/// └── Camera Player
///
/// Mouse-look speed is sampled on OctoPlayerFP (grandparent) to avoid being
/// polluted by the continuous rotations CameraHeadBob writes on CameraPivot.
/// Movement blend (moveT) is smoothed to avoid noise amplitude spikes on
/// direction changes.
/// Quick setup:
/// • Toggle "Is Active" in the inspector (or call SetActive()) to enable/disable with fade.
/// • "Master Intensity" scales everything: noise, jolts, inertia and spin.
/// • "Stress Level" can be driven externally (e.g. by a StressController) or left at 0.
/// </summary>
public class LostFootageRig : MonoBehaviour
{
// ── Inspector — Global ────────────────────────────────────────────────────
[Header("Global")]
[Tooltip("Enable or disable the whole rig (with fade). Can also be toggled at runtime via SetActive().")]
[SerializeField] private bool _isActive = true;
[Tooltip("Master scale applied to ALL effects (noise amplitude, jolt amplitude, inertia strength, spin strength). 0 = off, 1 = nominal.")]
[SerializeField] [Range(0f, 3f)] private float _masterIntensity = 1f;
// ── Inspector — Stress ────────────────────────────────────────────────────
[Header("Stress")]
[Tooltip("Stress level in [0, 1]. Can be driven externally (StressController.Instance → rig.StressLevel = ...) or set manually here for testing.")]
[SerializeField] [Range(0f, 1f)] private float _stressLevel = 0f;
[Header("Stress — noise scale")]
[SerializeField] private float _stressAmplitudeMul = 2.5f;
[SerializeField] private float _stressSpeedMul = 1f;
// ── Inspector — Noise ─────────────────────────────────────────────────────
[Header("Noise — idle")]
@@ -41,12 +63,8 @@ namespace Unheimlich.World.CameraSystem
[SerializeField] private float _runAmplitude = 5f;
[SerializeField] private float _runNoiseSpeed = 0.6f;
[Header("Noise — stress scale")]
[SerializeField] private float _stressAmplitudeMul = 2.5f;
[SerializeField] private float _stressSpeedMul = 1f;
[Header("Noise — smoothing")]
[Tooltip("How fast the noise amplitude blends between idle/walk/run. Lower = smoother transitions.")]
[Tooltip("How fast the noise amplitude blends between idle/walk/run.")]
[SerializeField] private float _moveTSmoothSpeed = 4f;
// ── Inspector — Micro-jolts ───────────────────────────────────────────────
@@ -64,56 +82,73 @@ namespace Unheimlich.World.CameraSystem
[SerializeField] private Vector2 _runJoltIntervalRange = new Vector2(1f, 2f);
[Header("Micro-jolts — shared")]
[Tooltip("How fast the jolt snaps to its target (fraction of interval).")]
[SerializeField] private float _joltSnapFraction = 0.1f;
[Tooltip("Jolt interval is divided by this value when stress = 1.")]
[SerializeField] private float _stressJoltFreqMul = 2f;
[Tooltip("Jolt amplitude is multiplied by this value when stress = 1.")]
[SerializeField] private float _stressJoltAmpMul = 1.4f;
[Tooltip("Look speed (deg/s) above which jolts are fully suppressed. Sampled on OctoPlayerFP to bypass CameraHeadBob noise.")]
[SerializeField] private float _joltLookSuppressSpeed = 5f;
[SerializeField] private float _joltSnapFraction = 0.1f;
[SerializeField] private float _stressJoltFreqMul = 2f;
[SerializeField] private float _stressJoltAmpMul = 1.4f;
[Tooltip("Look speed (deg/s) above which jolts are fully suppressed.")]
[SerializeField] private float _joltLookSuppressSpeed = 5f;
// ── Inspector — Inertia swing ─────────────────────────────────────────────
[Header("Inertia swing")]
[Tooltip("How strongly the camera lags behind movement. Higher = more swing.")]
[SerializeField] private float _inertiaStrength = 4f;
[Tooltip("How fast the inertia offset returns to zero. Lower = longer swing tail.")]
[SerializeField] private float _inertiaDamping = 6f;
[Tooltip("Maximum swing angle (degrees) on each axis to avoid excessive drift.")]
[SerializeField] private float _inertiaMaxAngle = 8f;
// ── Inspector — Spinning / dizzy head ─────────────────────────────────────
[Header("Spinning / dizzy head")]
[Tooltip("Maximum Y-axis spin angle (degrees) at stress = 1 and masterIntensity = 1.")]
[SerializeField] private float _spinMaxYAngle = 6f;
[Tooltip("Maximum Z-axis roll angle (degrees) at stress = 1 — the subtle listing tilt.")]
[SerializeField] private float _spinMaxZAngle = 2.5f;
[Tooltip("Speed of the Perlin noise driving the spin drift. Lower = slower, more nauseating.")]
[SerializeField] private float _spinNoiseSpeed = 0.08f;
[Tooltip("How fast the spin offset interpolates toward its target. Lower = more sluggish/drunk.")]
[SerializeField] private float _spinDamping = 2f;
// ── Inspector — Fade ──────────────────────────────────────────────────────
[Header("Fade")]
[Tooltip("Duration (seconds) of the fade-in / fade-out when toggling the rig.")]
[SerializeField] private float _fadeDuration = 0.6f;
// ── Inspector — Debug ─────────────────────────────────────────────────────
[Header("Debug")]
[SerializeField] private bool _debugSustainStress;
[SerializeField] [Range(0f, 1f)] private float _debugStressValue;
[SerializeField] private bool _debugOverrideStress;
[SerializeField] [Range(0f, 1f)] private float _debugStressOverride;
// ── Runtime state ─────────────────────────────────────────────────────────
// ── Public API ────────────────────────────────────────────────────────────
/// <summary>Current stress level in [0, 1]. Driven by <see cref="StressController"/>.</summary>
public float StressLevel { get; set; }
/// <summary>
/// Current stress level in [0, 1].
/// Set this from an external controller (e.g. StressController) each frame,
/// or leave it at the inspector default.
/// </summary>
public float StressLevel
{
get => _stressLevel;
set => _stressLevel = Mathf.Clamp01(value);
}
/// <summary>Whether the rig is currently active (or fading in/out).</summary>
public bool IsActive { get; private set; }
// ── Runtime state ─────────────────────────────────────────────────────────
private float _weight;
private float _noiseTimer;
private float _initialMasterIntensity; // value set in inspector, restored on Enable()
private float _noiseTimer;
private float _spinTimer;
private Vector3 _noiseOffset;
private Vector3 _joltRotation;
private Vector3 _inertiaOffset;
private Vector3 _spinOffset; // current smoothed spin (Y, Z) rotation
private float _smoothMoveT;
// Smoothed movement blend — avoids amplitude spikes on direction changes.
private float _smoothMoveT;
// Mouse-look speed sampled on OctoPlayerFP (grandparent) — used to gate
// micro-jolts so they only fire when the player is not actively looking around.
private Quaternion _lastLookRootRotation;
private float _lookSpeed;
@@ -129,65 +164,87 @@ namespace Unheimlich.World.CameraSystem
Random.Range(0f, 100f),
Random.Range(0f, 100f)
);
// Spin uses its own offset to decouple from the main noise.
_spinTimer = Random.Range(0f, 100f);
}
private void Start()
{
// Store the inspector value so Enable() can restore it even if the rig
// started disabled (and _masterIntensity was faded to 0).
_initialMasterIntensity = _masterIntensity;
// Sync inspector toggle on first frame.
IsActive = _isActive;
_weight = _isActive ? 1f : 0f;
Transform lookRoot = transform.parent?.parent;
_lastLookRootRotation = lookRoot != null
? lookRoot.localRotation
: Quaternion.identity;
if (_isActive)
_joltCoroutine = StartCoroutine(JoltCoroutine());
}
private void OnValidate()
{
// Allow toggling _isActive from the inspector during Play mode.
if (!Application.isPlaying) return;
SetActive(_isActive);
}
private void Update()
{
if (_debugSustainStress)
StressLevel = _debugStressValue;
if (_debugOverrideStress)
_stressLevel = _debugStressOverride;
float stress = Mathf.Clamp01(_stressLevel);
float intensity = _masterIntensity;
UpdateInertia();
if (_weight <= 0f)
{
UpdateInertia();
transform.localRotation = Quaternion.identity;
return;
}
float stress = Mathf.Clamp01(StressLevel);
// ── 1. Resolve movement state ─────────────────────────────────────────
// ── 1. Movement state ─────────────────────────────────────────────────
float horizontalSpeed = 0f;
bool isRunning = false;
bool running = IsRunning();
if (Unheimlich.Features.Player.PlayerController.Instance?.CharController != null)
{
var vel = Unheimlich.Features.Player.PlayerController.Instance.CharController.velocity;
var vel = Unheimlich.Features.Player.PlayerController.Instance.CharController.velocity;
horizontalSpeed = new Vector3(vel.x, 0f, vel.z).magnitude;
isRunning = OctoCore.Components.OctoPlayer.Instance != null
&& OctoCore.Components.OctoPlayer.Instance.State.IsRunning;
}
const float WalkSpeedMs = 10f / 3.6f;
const float RunSpeedMs = 20f / 3.6f;
float maxSpeed = isRunning ? RunSpeedMs : WalkSpeedMs;
float rawMoveT = Mathf.Clamp01(horizontalSpeed / maxSpeed);
float maxSpeed = running ? RunSpeedMs : WalkSpeedMs;
float rawMoveT = Mathf.Clamp01(horizontalSpeed / maxSpeed);
_smoothMoveT = Mathf.Lerp(_smoothMoveT, rawMoveT, Time.deltaTime * _moveTSmoothSpeed);
// Smooth moveT to avoid abrupt amplitude jumps on direction changes.
_smoothMoveT = Mathf.Lerp(_smoothMoveT, rawMoveT, Time.deltaTime * _moveTSmoothSpeed);
// ── 2. Noise parameters ───────────────────────────────────────────────
// ── 2. Interpolate noise parameters from movement state ───────────────
float targetAmp = isRunning
float targetAmp = running
? Mathf.Lerp(_walkAmplitude, _runAmplitude, _smoothMoveT)
: Mathf.Lerp(_idleAmplitude, _walkAmplitude, _smoothMoveT);
float targetSpeed = isRunning
float targetSpeed = running
? Mathf.Lerp(_walkNoiseSpeed, _runNoiseSpeed, _smoothMoveT)
: Mathf.Lerp(_idleNoiseSpeed, _walkNoiseSpeed, _smoothMoveT);
float amp = (targetAmp + stress * _stressAmplitudeMul) * _weight;
float spd = (targetSpeed + stress * _stressSpeedMul);
float amp = (targetAmp + stress * _stressAmplitudeMul) * _weight * intensity;
float spd = targetSpeed + stress * _stressSpeedMul;
_noiseTimer += Time.deltaTime * spd;
if (_noiseTimer > 1000f) _noiseTimer -= 1000f; // wrap to avoid float precision loss
if (_noiseTimer > 1000f) _noiseTimer -= 1000f;
float t = _noiseTimer;
// ── 3. Perlin drift ───────────────────────────────────────────────────
@@ -198,74 +255,101 @@ namespace Unheimlich.World.CameraSystem
// ── 4. Inertia swing ──────────────────────────────────────────────────
UpdateInertia();
Vector3 swing = _inertiaOffset * _weight;
Vector3 swing = _inertiaOffset * _weight * intensity;
// ── 5. Compose and apply ──────────────────────────────────────────────
// ── 5. Spinning / dizzy drift ─────────────────────────────────────────
//
// Two independent Perlin channels drive a slow yaw drift (Y) and a
// listing roll (Z). Both scale with stress and masterIntensity.
// The offset is smoothed via _spinDamping so it feels heavy and sluggish
// rather than jittery — like a head that's struggling to stay level.
_spinTimer += Time.deltaTime * _spinNoiseSpeed;
if (_spinTimer > 1000f) _spinTimer -= 1000f;
float spinScale = stress * _weight * intensity;
float targetSpinY = (Mathf.PerlinNoise(_noiseOffset.x * 0.5f + _spinTimer, 10f) - 0.5f)
* _spinMaxYAngle * 2f * spinScale;
float targetSpinZ = (Mathf.PerlinNoise(_noiseOffset.z * 0.5f + _spinTimer, 20f) - 0.5f)
* _spinMaxZAngle * 2f * spinScale;
Vector3 targetSpin = new Vector3(0f, targetSpinY, targetSpinZ);
_spinOffset = Vector3.Lerp(_spinOffset, targetSpin, Time.deltaTime * _spinDamping);
// ── 6. Compose and apply ──────────────────────────────────────────────
transform.localRotation = Quaternion.Euler(
rx + _joltRotation.x + swing.x,
ry + _joltRotation.y + swing.y,
rz + _joltRotation.z + swing.z
ry + _joltRotation.y + swing.y + _spinOffset.y,
rz + _joltRotation.z + swing.z + _spinOffset.z
);
}
// ── Public API ────────────────────────────────────────────────────────────
/// <summary>UnityEvent-friendly wrapper — enables with the inspector master intensity.</summary>
public void Enable() => Enable(_initialMasterIntensity, _stressLevel);
/// <summary>UnityEvent-friendly wrapper — disables with a fade to 0.</summary>
public void Disable() => Disable(0f);
/// <summary>
/// Enables or disables the lost-footage effect with a smooth fade.
/// Safe to call multiple times — an in-progress fade is cancelled and reversed.
/// Enables the rig and lerps <see cref="_masterIntensity"/> toward
/// <paramref name="targetIntensity"/> and <see cref="_stressLevel"/> toward
/// <paramref name="targetStress"/> over <see cref="_fadeDuration"/> seconds.
/// Pass the values you want to reach — the current inspector values are left
/// untouched if you don't call this.
/// </summary>
public void SetActive(bool active)
public void Enable(float targetIntensity, float targetStress = 0f)
{
if (IsActive == active)
return;
_isActive = true;
IsActive = true;
IsActive = active;
if (_fadeCoroutine != null) StopCoroutine(_fadeCoroutine);
_fadeCoroutine = StartCoroutine(FadeCoroutine(true, targetIntensity, targetStress));
if (_fadeCoroutine != null)
StopCoroutine(_fadeCoroutine);
_fadeCoroutine = StartCoroutine(FadeCoroutine(active));
if (active)
{
if (_joltCoroutine != null)
StopCoroutine(_joltCoroutine);
_joltCoroutine = StartCoroutine(JoltCoroutine());
}
if (_joltCoroutine != null) StopCoroutine(_joltCoroutine);
_joltCoroutine = StartCoroutine(JoltCoroutine());
}
/// <summary>
/// Disables the rig, lerping <see cref="_masterIntensity"/> toward
/// <paramref name="targetIntensity"/> (default 0) over <see cref="_fadeDuration"/> seconds.
/// </summary>
public void Disable(float targetIntensity = 0f)
{
_isActive = false;
IsActive = false;
if (_fadeCoroutine != null) StopCoroutine(_fadeCoroutine);
_fadeCoroutine = StartCoroutine(FadeCoroutine(false, targetIntensity, _stressLevel));
}
/// <summary>Backwards-compatible toggle — calls Enable() or Disable().</summary>
public void SetActive(bool active) { if (active) Enable(); else Disable(); }
// ── Private helpers ───────────────────────────────────────────────────────
/// <summary>
/// Drives inertia swing from CharController velocity projected into local camera space,
/// avoiding the rotation-delta approach which caused spikes whenever CameraHeadBob
/// changed phase. Also samples OctoPlayerFP (grandparent) rotation delta to measure
/// true mouse-look speed for jolt gating.
/// </summary>
private void UpdateInertia()
{
// ── Inertia from CharController velocity ──────────────────────────────
Vector3 velocity = Vector3.zero;
if (Unheimlich.Features.Player.PlayerController.Instance?.CharController != null)
velocity = Unheimlich.Features.Player.PlayerController.Instance.CharController.velocity;
// Project velocity into local camera space so the swing feels attached to the view.
Vector3 localVel = transform.parent != null
Vector3 localVel = transform.parent != null
? transform.parent.InverseTransformDirection(velocity)
: velocity;
Vector3 targetInertia = new Vector3(-localVel.z, 0f, localVel.x) * (_inertiaStrength * 0.01f);
targetInertia = Vector3.ClampMagnitude(targetInertia, _inertiaMaxAngle);
Vector3 targetInertia = new Vector3(-localVel.z, 0f, localVel.x)
* (_inertiaStrength * _masterIntensity * 0.01f);
targetInertia = Vector3.ClampMagnitude(targetInertia, _inertiaMaxAngle);
_inertiaOffset = Vector3.Lerp(_inertiaOffset, targetInertia, _inertiaDamping * Time.deltaTime);
// ── Mouse-look speed from OctoPlayerFP (grandparent) ─────────────────
// Mouse-look speed from OctoPlayerFP (grandparent) — gates micro-jolts.
Transform lookRoot = transform.parent?.parent;
Quaternion lookRot = lookRoot != null ? lookRoot.localRotation : Quaternion.identity;
Quaternion lookDelta = lookRot * Quaternion.Inverse(_lastLookRootRotation);
@@ -277,21 +361,28 @@ namespace Unheimlich.World.CameraSystem
_lastLookRootRotation = lookRot;
}
private IEnumerator FadeCoroutine(bool fadeIn)
private IEnumerator FadeCoroutine(bool fadeIn, float targetIntensity, float targetStress)
{
float start = _weight;
float target = fadeIn ? 1f : 0f;
float elapsed = 0f;
float startIntensity = _masterIntensity;
float startStress = _stressLevel;
float elapsed = 0f;
if (fadeIn && _weight <= 0f) _weight = 0.001f;
while (elapsed < _fadeDuration)
{
elapsed += Time.deltaTime;
_weight = Mathf.Lerp(start, target, elapsed / _fadeDuration);
elapsed += Time.deltaTime;
float t = elapsed / _fadeDuration;
_masterIntensity = Mathf.Lerp(startIntensity, targetIntensity, t);
_stressLevel = Mathf.Lerp(startStress, targetStress, t);
_weight = _masterIntensity > 0f ? 1f : 0f;
yield return null;
}
_weight = target;
_fadeCoroutine = null;
_masterIntensity = targetIntensity;
_stressLevel = targetStress;
_weight = targetIntensity > 0f ? 1f : 0f;
_fadeCoroutine = null;
if (!fadeIn && _joltCoroutine != null)
{
@@ -304,14 +395,14 @@ namespace Unheimlich.World.CameraSystem
{
while (true)
{
float stress = Mathf.Clamp01(StressLevel);
float stress = Mathf.Clamp01(_stressLevel);
bool running = IsRunning();
// Use the same smoothed moveT as Update to keep jolt parameters consistent.
float joltAmp = isRunning()
float joltAmp = running
? Mathf.Lerp(_walkJoltAmplitude, _runJoltAmplitude, _smoothMoveT)
: Mathf.Lerp(_idleJoltAmplitude, _walkJoltAmplitude, _smoothMoveT);
Vector2 intervalRange = isRunning()
Vector2 intervalRange = running
? Vector2.Lerp(_walkJoltIntervalRange, _runJoltIntervalRange, _smoothMoveT)
: Vector2.Lerp(_idleJoltIntervalRange, _walkJoltIntervalRange, _smoothMoveT);
@@ -320,10 +411,8 @@ namespace Unheimlich.World.CameraSystem
yield return new WaitForSeconds(interval);
// Jolts only fire when the camera is steady — steadyFactor is 1 when still,
// 0 when the player is actively looking around.
float steadyFactor = 1f - Mathf.Clamp01(_lookSpeed / _joltLookSuppressSpeed);
float ampScale = (1f + stress * _stressJoltAmpMul) * _weight * steadyFactor;
float ampScale = (1f + stress * _stressJoltAmpMul) * _weight * _masterIntensity * steadyFactor;
Vector3 target = new Vector3(
Random.Range(-1f, 1f) * joltAmp * ampScale,
@@ -335,17 +424,12 @@ namespace Unheimlich.World.CameraSystem
}
}
/// <summary>Returns true if the player is currently running.</summary>
private bool isRunning()
private bool IsRunning()
{
return OctoCore.Components.OctoPlayer.Instance != null
&& OctoCore.Components.OctoPlayer.Instance.State.IsRunning;
}
/// <summary>
/// Snaps to <paramref name="target"/> in the first fraction of the interval,
/// then eases back to zero for the remainder — simulating a hand recoil.
/// </summary>
private IEnumerator ApplyJolt(Vector3 target, float totalDuration)
{
float snapDur = totalDuration * _joltSnapFraction;
@@ -1,74 +1,39 @@
using System.Collections;
using UnityEngine;
using UnityEngine.Rendering;
namespace MonoLimboStudio
namespace Unheimlich.VFX
{
public class LightFlicker : MonoBehaviour
{
[Header("Light Settings")]
public Light targetLight;
[Tooltip("Base intensity set externally (e.g. by ScarecrowFire). Flicker oscillates around this value.")]
public float baseIntensity = 1f;
[Tooltip("Flicker oscillates around this value. Driven each frame by ScarecrowFire.")]
public float baseIntensity = 0f;
[Tooltip("Flicker range applied relative to baseIntensity (e.g. 0.3 = ±30%).")]
[Range(0f, 1f)]
public float flickerRange = 0.3f;
[Header("Perlin Flicker (smooth)")]
[Range(0f, 1f)] public float flickerRange = 0.3f;
public float flickerSpeed = 5f;
[Header("Glitch Flicker (bursts)")]
[Range(0f, 1f)] public float glitchChance = 0.15f;
public float glitchMinDuration = 0.02f;
public float glitchMaxDuration = 0.12f;
[Range(0f, 1f)] public float glitchChance = 0.15f;
public float glitchMinDuration = 0.02f;
public float glitchMaxDuration = 0.12f;
[Header("Material Settings")]
public Renderer targetRenderer;
public string opacityProperty = "_Opacity";
[Range(0f, 1f)] public float minOpacity = 0.2f;
[Range(0f, 1f)] public float maxOpacity = 1.0f;
private Material _materialInstance;
private float _randomOffset;
// ─────────────────────────────────────────────────────────────────────
private float _randomOffset;
void Start()
{
_randomOffset = Random.Range(0f, 1000f);
if (targetRenderer != null)
{
_materialInstance = targetRenderer.material;
if (!_materialInstance.HasProperty(opacityProperty))
Debug.LogWarning($"Property '{opacityProperty}' not found on material.");
}
StartCoroutine(FlickerRoutine());
}
// ─────────────────────────────────────────────────────────────────────
/// <summary>
/// Sets the base intensity that the flicker oscillates around.
/// Called each frame by ScarecrowFire as the fire grows.
/// </summary>
public void SetBaseIntensity(float value)
{
baseIntensity = value;
}
// ─────────────────────────────────────────────────────────────────────
/// <summary>Called each frame by ScarecrowFire to update the base the flicker oscillates around.</summary>
public void SetBaseIntensity(float value) => baseIntensity = value;
private IEnumerator FlickerRoutine()
{
while (true)
{
float perlinValue = Mathf.PerlinNoise(Time.time * flickerSpeed + _randomOffset, 0f);
ApplyFlicker(perlinValue);
float t = Mathf.PerlinNoise(Time.time * flickerSpeed + _randomOffset, 0f);
ApplyFlicker(t);
if (Random.value < glitchChance)
yield return StartCoroutine(GlitchBurst());
@@ -79,8 +44,8 @@ namespace MonoLimboStudio
private IEnumerator GlitchBurst()
{
float duration = Random.Range(glitchMinDuration, glitchMaxDuration);
float elapsed = 0f;
float duration = Random.Range(glitchMinDuration, glitchMaxDuration);
while (elapsed < duration)
{
@@ -90,26 +55,12 @@ namespace MonoLimboStudio
}
}
/// <summary>
/// Applies flicker as an offset around baseIntensity rather than
/// absolute min/max, so external intensity control stays intact.
/// </summary>
private void ApplyFlicker(float t)
{
if (targetLight != null)
{
float offset = Mathf.Lerp(-flickerRange, flickerRange, t);
targetLight.intensity = Mathf.Max(0f, baseIntensity + offset);
}
if (_materialInstance != null && _materialInstance.HasProperty(opacityProperty))
_materialInstance.SetFloat(opacityProperty, Mathf.Lerp(minOpacity, maxOpacity, t));
}
void OnDestroy()
{
if (_materialInstance != null)
Destroy(_materialInstance);
if (targetLight == null) return;
float offset = Mathf.Lerp(-baseIntensity * flickerRange,
baseIntensity * flickerRange, t);
targetLight.intensity = Mathf.Max(0f, baseIntensity + offset);
}
}
}