This commit is contained in:
2025-12-08 14:57:56 +01:00
20 changed files with 3166 additions and 2248 deletions

View File

@@ -172,6 +172,7 @@ SkinnedMeshRenderer:
m_SortingLayerID: 0 m_SortingLayerID: 0
m_SortingLayer: 0 m_SortingLayer: 0
m_SortingOrder: 0 m_SortingOrder: 0
m_MaskInteraction: 0
serializedVersion: 2 serializedVersion: 2
m_Quality: 0 m_Quality: 0
m_UpdateWhenOffscreen: 0 m_UpdateWhenOffscreen: 0
@@ -456,6 +457,7 @@ MeshRenderer:
m_SortingLayerID: 0 m_SortingLayerID: 0
m_SortingLayer: 0 m_SortingLayer: 0
m_SortingOrder: 0 m_SortingOrder: 0
m_MaskInteraction: 0
m_AdditionalVertexStreams: {fileID: 0} m_AdditionalVertexStreams: {fileID: 0}
--- !u!114 &1477914804333655978 --- !u!114 &1477914804333655978
MonoBehaviour: MonoBehaviour:
@@ -558,6 +560,7 @@ MeshRenderer:
m_SortingLayerID: 0 m_SortingLayerID: 0
m_SortingLayer: 0 m_SortingLayer: 0
m_SortingOrder: 0 m_SortingOrder: 0
m_MaskInteraction: 0
m_AdditionalVertexStreams: {fileID: 0} m_AdditionalVertexStreams: {fileID: 0}
--- !u!114 &6279009652162230510 --- !u!114 &6279009652162230510
MonoBehaviour: MonoBehaviour:
@@ -660,6 +663,7 @@ MeshRenderer:
m_SortingLayerID: 0 m_SortingLayerID: 0
m_SortingLayer: 0 m_SortingLayer: 0
m_SortingOrder: 0 m_SortingOrder: 0
m_MaskInteraction: 0
m_AdditionalVertexStreams: {fileID: 0} m_AdditionalVertexStreams: {fileID: 0}
--- !u!114 &7522599432703993887 --- !u!114 &7522599432703993887
MonoBehaviour: MonoBehaviour:
@@ -796,6 +800,7 @@ SkinnedMeshRenderer:
m_SortingLayerID: 0 m_SortingLayerID: 0
m_SortingLayer: 0 m_SortingLayer: 0
m_SortingOrder: 0 m_SortingOrder: 0
m_MaskInteraction: 0
serializedVersion: 2 serializedVersion: 2
m_Quality: 0 m_Quality: 0
m_UpdateWhenOffscreen: 0 m_UpdateWhenOffscreen: 0
@@ -912,6 +917,7 @@ MeshRenderer:
m_SortingLayerID: 0 m_SortingLayerID: 0
m_SortingLayer: 0 m_SortingLayer: 0
m_SortingOrder: 0 m_SortingOrder: 0
m_MaskInteraction: 0
m_AdditionalVertexStreams: {fileID: 0} m_AdditionalVertexStreams: {fileID: 0}
--- !u!114 &4521180984547725349 --- !u!114 &4521180984547725349
MonoBehaviour: MonoBehaviour:

View File

@@ -34,6 +34,7 @@ Transform:
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!212 &4110666412151536905 --- !u!212 &4110666412151536905
SpriteRenderer: SpriteRenderer:
serializedVersion: 2
m_ObjectHideFlags: 0 m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0} m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0} m_PrefabInstance: {fileID: 0}
@@ -79,6 +80,7 @@ SpriteRenderer:
m_SortingLayerID: 0 m_SortingLayerID: 0
m_SortingLayer: 0 m_SortingLayer: 0
m_SortingOrder: 1 m_SortingOrder: 1
m_MaskInteraction: 0
m_Sprite: {fileID: 0} m_Sprite: {fileID: 0}
m_Color: {r: 1, g: 1, b: 1, a: 1} m_Color: {r: 1, g: 1, b: 1, a: 1}
m_FlipX: 0 m_FlipX: 0
@@ -88,7 +90,6 @@ SpriteRenderer:
m_AdaptiveModeThreshold: 0.5 m_AdaptiveModeThreshold: 0.5
m_SpriteTileMode: 0 m_SpriteTileMode: 0
m_WasSpriteAssigned: 0 m_WasSpriteAssigned: 0
m_MaskInteraction: 0
m_SpriteSortPoint: 0 m_SpriteSortPoint: 0
--- !u!1 &7249528695393012044 --- !u!1 &7249528695393012044
GameObject: GameObject:
@@ -131,6 +132,7 @@ Transform:
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!212 &6258593095132504700 --- !u!212 &6258593095132504700
SpriteRenderer: SpriteRenderer:
serializedVersion: 2
m_ObjectHideFlags: 0 m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0} m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0} m_PrefabInstance: {fileID: 0}
@@ -176,6 +178,7 @@ SpriteRenderer:
m_SortingLayerID: 0 m_SortingLayerID: 0
m_SortingLayer: 0 m_SortingLayer: 0
m_SortingOrder: 0 m_SortingOrder: 0
m_MaskInteraction: 0
m_Sprite: {fileID: -8438005379329254897, guid: fe735eb4f8856904caec179520dcb92f, type: 3} m_Sprite: {fileID: -8438005379329254897, guid: fe735eb4f8856904caec179520dcb92f, type: 3}
m_Color: {r: 1, g: 1, b: 1, a: 1} m_Color: {r: 1, g: 1, b: 1, a: 1}
m_FlipX: 0 m_FlipX: 0
@@ -185,7 +188,6 @@ SpriteRenderer:
m_AdaptiveModeThreshold: 0.5 m_AdaptiveModeThreshold: 0.5
m_SpriteTileMode: 0 m_SpriteTileMode: 0
m_WasSpriteAssigned: 1 m_WasSpriteAssigned: 1
m_MaskInteraction: 0
m_SpriteSortPoint: 0 m_SpriteSortPoint: 0
--- !u!61 &5475802662781903683 --- !u!61 &5475802662781903683
BoxCollider2D: BoxCollider2D:

View File

@@ -121,6 +121,7 @@ MeshRenderer:
m_SortingLayerID: 0 m_SortingLayerID: 0
m_SortingLayer: 0 m_SortingLayer: 0
m_SortingOrder: 0 m_SortingOrder: 0
m_MaskInteraction: 0
m_AdditionalVertexStreams: {fileID: 0} m_AdditionalVertexStreams: {fileID: 0}
--- !u!114 &1799170203493421407 --- !u!114 &1799170203493421407
MonoBehaviour: MonoBehaviour:
@@ -169,6 +170,7 @@ Transform:
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!212 &2343214996212089369 --- !u!212 &2343214996212089369
SpriteRenderer: SpriteRenderer:
serializedVersion: 2
m_ObjectHideFlags: 0 m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0} m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0} m_PrefabInstance: {fileID: 0}
@@ -214,6 +216,7 @@ SpriteRenderer:
m_SortingLayerID: 0 m_SortingLayerID: 0
m_SortingLayer: 0 m_SortingLayer: 0
m_SortingOrder: 1 m_SortingOrder: 1
m_MaskInteraction: 0
m_Sprite: {fileID: -1125559343802010594, guid: 46b2fe6896b27cc4c8bd9f0da3f0de50, type: 3} m_Sprite: {fileID: -1125559343802010594, guid: 46b2fe6896b27cc4c8bd9f0da3f0de50, type: 3}
m_Color: {r: 1, g: 1, b: 1, a: 1} m_Color: {r: 1, g: 1, b: 1, a: 1}
m_FlipX: 0 m_FlipX: 0
@@ -223,7 +226,6 @@ SpriteRenderer:
m_AdaptiveModeThreshold: 0.5 m_AdaptiveModeThreshold: 0.5
m_SpriteTileMode: 0 m_SpriteTileMode: 0
m_WasSpriteAssigned: 1 m_WasSpriteAssigned: 1
m_MaskInteraction: 0
m_SpriteSortPoint: 1 m_SpriteSortPoint: 1
--- !u!61 &7660380594239590698 --- !u!61 &7660380594239590698
BoxCollider2D: BoxCollider2D:
@@ -360,6 +362,7 @@ MeshRenderer:
m_SortingLayerID: 0 m_SortingLayerID: 0
m_SortingLayer: 0 m_SortingLayer: 0
m_SortingOrder: 0 m_SortingOrder: 0
m_MaskInteraction: 0
m_AdditionalVertexStreams: {fileID: 0} m_AdditionalVertexStreams: {fileID: 0}
--- !u!114 &6348852419369233976 --- !u!114 &6348852419369233976
MonoBehaviour: MonoBehaviour:
@@ -407,6 +410,7 @@ Transform:
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!212 &7990414055343410434 --- !u!212 &7990414055343410434
SpriteRenderer: SpriteRenderer:
serializedVersion: 2
m_ObjectHideFlags: 0 m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0} m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0} m_PrefabInstance: {fileID: 0}
@@ -452,6 +456,7 @@ SpriteRenderer:
m_SortingLayerID: 0 m_SortingLayerID: 0
m_SortingLayer: 0 m_SortingLayer: 0
m_SortingOrder: 1 m_SortingOrder: 1
m_MaskInteraction: 0
m_Sprite: {fileID: 0} m_Sprite: {fileID: 0}
m_Color: {r: 1, g: 1, b: 1, a: 1} m_Color: {r: 1, g: 1, b: 1, a: 1}
m_FlipX: 0 m_FlipX: 0
@@ -461,7 +466,6 @@ SpriteRenderer:
m_AdaptiveModeThreshold: 0.5 m_AdaptiveModeThreshold: 0.5
m_SpriteTileMode: 0 m_SpriteTileMode: 0
m_WasSpriteAssigned: 0 m_WasSpriteAssigned: 0
m_MaskInteraction: 0
m_SpriteSortPoint: 0 m_SpriteSortPoint: 0
--- !u!1 &2265449145943364229 --- !u!1 &2265449145943364229
GameObject: GameObject:
@@ -552,6 +556,7 @@ MeshRenderer:
m_SortingLayerID: 0 m_SortingLayerID: 0
m_SortingLayer: 0 m_SortingLayer: 0
m_SortingOrder: 0 m_SortingOrder: 0
m_MaskInteraction: 0
m_AdditionalVertexStreams: {fileID: 0} m_AdditionalVertexStreams: {fileID: 0}
--- !u!114 &220335373367130193 --- !u!114 &220335373367130193
MonoBehaviour: MonoBehaviour:
@@ -685,6 +690,7 @@ MeshRenderer:
m_SortingLayerID: 0 m_SortingLayerID: 0
m_SortingLayer: 0 m_SortingLayer: 0
m_SortingOrder: 0 m_SortingOrder: 0
m_MaskInteraction: 0
m_AdditionalVertexStreams: {fileID: 0} m_AdditionalVertexStreams: {fileID: 0}
--- !u!114 &972451099498184359 --- !u!114 &972451099498184359
MonoBehaviour: MonoBehaviour:
@@ -790,6 +796,7 @@ SkinnedMeshRenderer:
m_SortingLayerID: 0 m_SortingLayerID: 0
m_SortingLayer: 0 m_SortingLayer: 0
m_SortingOrder: 0 m_SortingOrder: 0
m_MaskInteraction: 0
serializedVersion: 2 serializedVersion: 2
m_Quality: 0 m_Quality: 0
m_UpdateWhenOffscreen: 0 m_UpdateWhenOffscreen: 0
@@ -909,6 +916,7 @@ SkinnedMeshRenderer:
m_SortingLayerID: 0 m_SortingLayerID: 0
m_SortingLayer: 0 m_SortingLayer: 0
m_SortingOrder: 0 m_SortingOrder: 0
m_MaskInteraction: 0
serializedVersion: 2 serializedVersion: 2
m_Quality: 0 m_Quality: 0
m_UpdateWhenOffscreen: 0 m_UpdateWhenOffscreen: 0
@@ -1393,6 +1401,7 @@ Transform:
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!212 &5292193662800385283 --- !u!212 &5292193662800385283
SpriteRenderer: SpriteRenderer:
serializedVersion: 2
m_ObjectHideFlags: 0 m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0} m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0} m_PrefabInstance: {fileID: 0}
@@ -1438,6 +1447,7 @@ SpriteRenderer:
m_SortingLayerID: 0 m_SortingLayerID: 0
m_SortingLayer: 0 m_SortingLayer: 0
m_SortingOrder: 2 m_SortingOrder: 2
m_MaskInteraction: 0
m_Sprite: {fileID: 779209807, guid: b215bf5a0a0f5db4da48c686489d8cab, type: 3} m_Sprite: {fileID: 779209807, guid: b215bf5a0a0f5db4da48c686489d8cab, type: 3}
m_Color: {r: 1, g: 1, b: 1, a: 1} m_Color: {r: 1, g: 1, b: 1, a: 1}
m_FlipX: 0 m_FlipX: 0
@@ -1447,7 +1457,6 @@ SpriteRenderer:
m_AdaptiveModeThreshold: 0.5 m_AdaptiveModeThreshold: 0.5
m_SpriteTileMode: 0 m_SpriteTileMode: 0
m_WasSpriteAssigned: 1 m_WasSpriteAssigned: 1
m_MaskInteraction: 0
m_SpriteSortPoint: 0 m_SpriteSortPoint: 0
--- !u!95 &2858293142053250427 --- !u!95 &2858293142053250427
Animator: Animator:

View File

@@ -86,6 +86,7 @@ PolygonCollider2D:
m_UseDelaunayMesh: 0 m_UseDelaunayMesh: 0
--- !u!212 &2825253017896168654 --- !u!212 &2825253017896168654
SpriteRenderer: SpriteRenderer:
serializedVersion: 2
m_ObjectHideFlags: 0 m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0} m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0} m_PrefabInstance: {fileID: 0}
@@ -131,6 +132,7 @@ SpriteRenderer:
m_SortingLayerID: 0 m_SortingLayerID: 0
m_SortingLayer: 0 m_SortingLayer: 0
m_SortingOrder: 1 m_SortingOrder: 1
m_MaskInteraction: 0
m_Sprite: {fileID: -642587728066523507, guid: 95d6dbee5cb1f694c971791ee60cad14, type: 3} m_Sprite: {fileID: -642587728066523507, guid: 95d6dbee5cb1f694c971791ee60cad14, type: 3}
m_Color: {r: 1, g: 1, b: 1, a: 1} m_Color: {r: 1, g: 1, b: 1, a: 1}
m_FlipX: 0 m_FlipX: 0
@@ -140,7 +142,6 @@ SpriteRenderer:
m_AdaptiveModeThreshold: 0.5 m_AdaptiveModeThreshold: 0.5
m_SpriteTileMode: 0 m_SpriteTileMode: 0
m_WasSpriteAssigned: 1 m_WasSpriteAssigned: 1
m_MaskInteraction: 0
m_SpriteSortPoint: 1 m_SpriteSortPoint: 1
--- !u!1 &4316370833098727305 --- !u!1 &4316370833098727305
GameObject: GameObject:
@@ -176,6 +177,7 @@ Transform:
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!212 &3806274462998212361 --- !u!212 &3806274462998212361
SpriteRenderer: SpriteRenderer:
serializedVersion: 2
m_ObjectHideFlags: 0 m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0} m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0} m_PrefabInstance: {fileID: 0}
@@ -221,6 +223,7 @@ SpriteRenderer:
m_SortingLayerID: 0 m_SortingLayerID: 0
m_SortingLayer: 0 m_SortingLayer: 0
m_SortingOrder: 1 m_SortingOrder: 1
m_MaskInteraction: 0
m_Sprite: {fileID: 0} m_Sprite: {fileID: 0}
m_Color: {r: 1, g: 1, b: 1, a: 1} m_Color: {r: 1, g: 1, b: 1, a: 1}
m_FlipX: 0 m_FlipX: 0
@@ -230,7 +233,6 @@ SpriteRenderer:
m_AdaptiveModeThreshold: 0.5 m_AdaptiveModeThreshold: 0.5
m_SpriteTileMode: 0 m_SpriteTileMode: 0
m_WasSpriteAssigned: 0 m_WasSpriteAssigned: 0
m_MaskInteraction: 0
m_SpriteSortPoint: 1 m_SpriteSortPoint: 1
--- !u!1 &7145022056631397938 --- !u!1 &7145022056631397938
GameObject: GameObject:

View File

@@ -57,6 +57,7 @@ BoxCollider:
m_Center: {x: 0, y: 0, z: 0} m_Center: {x: 0, y: 0, z: 0}
--- !u!212 &4055726361761331703 --- !u!212 &4055726361761331703
SpriteRenderer: SpriteRenderer:
serializedVersion: 2
m_ObjectHideFlags: 0 m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0} m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0} m_PrefabInstance: {fileID: 0}
@@ -102,6 +103,7 @@ SpriteRenderer:
m_SortingLayerID: 0 m_SortingLayerID: 0
m_SortingLayer: 0 m_SortingLayer: 0
m_SortingOrder: 1 m_SortingOrder: 1
m_MaskInteraction: 0
m_Sprite: {fileID: -3019416885370694485, guid: ed57eef56cafff0428d08bce28798f58, type: 3} m_Sprite: {fileID: -3019416885370694485, guid: ed57eef56cafff0428d08bce28798f58, type: 3}
m_Color: {r: 1, g: 1, b: 1, a: 1} m_Color: {r: 1, g: 1, b: 1, a: 1}
m_FlipX: 0 m_FlipX: 0
@@ -111,7 +113,6 @@ SpriteRenderer:
m_AdaptiveModeThreshold: 0.5 m_AdaptiveModeThreshold: 0.5
m_SpriteTileMode: 0 m_SpriteTileMode: 0
m_WasSpriteAssigned: 1 m_WasSpriteAssigned: 1
m_MaskInteraction: 0
m_SpriteSortPoint: 1 m_SpriteSortPoint: 1
--- !u!114 &1226703179564388091 --- !u!114 &1226703179564388091
MonoBehaviour: MonoBehaviour:

View File

@@ -57,6 +57,7 @@ BoxCollider:
m_Center: {x: 0, y: 0, z: 0} m_Center: {x: 0, y: 0, z: 0}
--- !u!212 &4774534086162962138 --- !u!212 &4774534086162962138
SpriteRenderer: SpriteRenderer:
serializedVersion: 2
m_ObjectHideFlags: 0 m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0} m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0} m_PrefabInstance: {fileID: 0}
@@ -102,6 +103,7 @@ SpriteRenderer:
m_SortingLayerID: 0 m_SortingLayerID: 0
m_SortingLayer: 0 m_SortingLayer: 0
m_SortingOrder: 1 m_SortingOrder: 1
m_MaskInteraction: 0
m_Sprite: {fileID: 4799961156935096247, guid: 74289c1614ce2b2439a5d3ff60a90d66, type: 3} m_Sprite: {fileID: 4799961156935096247, guid: 74289c1614ce2b2439a5d3ff60a90d66, type: 3}
m_Color: {r: 1, g: 1, b: 1, a: 1} m_Color: {r: 1, g: 1, b: 1, a: 1}
m_FlipX: 0 m_FlipX: 0
@@ -111,7 +113,6 @@ SpriteRenderer:
m_AdaptiveModeThreshold: 0.5 m_AdaptiveModeThreshold: 0.5
m_SpriteTileMode: 0 m_SpriteTileMode: 0
m_WasSpriteAssigned: 1 m_WasSpriteAssigned: 1
m_MaskInteraction: 0
m_SpriteSortPoint: 1 m_SpriteSortPoint: 1
--- !u!114 &5483561632297398438 --- !u!114 &5483561632297398438
MonoBehaviour: MonoBehaviour:

View File

@@ -57,6 +57,7 @@ BoxCollider:
m_Center: {x: 0, y: 0, z: 0} m_Center: {x: 0, y: 0, z: 0}
--- !u!212 &4986096986936361008 --- !u!212 &4986096986936361008
SpriteRenderer: SpriteRenderer:
serializedVersion: 2
m_ObjectHideFlags: 0 m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0} m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0} m_PrefabInstance: {fileID: 0}
@@ -102,6 +103,7 @@ SpriteRenderer:
m_SortingLayerID: 0 m_SortingLayerID: 0
m_SortingLayer: 0 m_SortingLayer: 0
m_SortingOrder: 1 m_SortingOrder: 1
m_MaskInteraction: 0
m_Sprite: {fileID: -2082989857396687135, guid: f106ad45f67e9e74895c64edbc1e4614, type: 3} m_Sprite: {fileID: -2082989857396687135, guid: f106ad45f67e9e74895c64edbc1e4614, type: 3}
m_Color: {r: 1, g: 1, b: 1, a: 1} m_Color: {r: 1, g: 1, b: 1, a: 1}
m_FlipX: 0 m_FlipX: 0
@@ -111,7 +113,6 @@ SpriteRenderer:
m_AdaptiveModeThreshold: 0.5 m_AdaptiveModeThreshold: 0.5
m_SpriteTileMode: 0 m_SpriteTileMode: 0
m_WasSpriteAssigned: 1 m_WasSpriteAssigned: 1
m_MaskInteraction: 0
m_SpriteSortPoint: 1 m_SpriteSortPoint: 1
--- !u!114 &2753389442270867527 --- !u!114 &2753389442270867527
MonoBehaviour: MonoBehaviour:

View File

@@ -57,6 +57,7 @@ BoxCollider:
m_Center: {x: 0, y: 0, z: 0} m_Center: {x: 0, y: 0, z: 0}
--- !u!212 &4266110216568578813 --- !u!212 &4266110216568578813
SpriteRenderer: SpriteRenderer:
serializedVersion: 2
m_ObjectHideFlags: 0 m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0} m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0} m_PrefabInstance: {fileID: 0}
@@ -102,6 +103,7 @@ SpriteRenderer:
m_SortingLayerID: 0 m_SortingLayerID: 0
m_SortingLayer: 0 m_SortingLayer: 0
m_SortingOrder: 1 m_SortingOrder: 1
m_MaskInteraction: 0
m_Sprite: {fileID: -4183208330383030991, guid: 26abd62d79d435f438c281aa83ee274a, type: 3} m_Sprite: {fileID: -4183208330383030991, guid: 26abd62d79d435f438c281aa83ee274a, type: 3}
m_Color: {r: 1, g: 1, b: 1, a: 1} m_Color: {r: 1, g: 1, b: 1, a: 1}
m_FlipX: 0 m_FlipX: 0
@@ -111,7 +113,6 @@ SpriteRenderer:
m_AdaptiveModeThreshold: 0.5 m_AdaptiveModeThreshold: 0.5
m_SpriteTileMode: 0 m_SpriteTileMode: 0
m_WasSpriteAssigned: 1 m_WasSpriteAssigned: 1
m_MaskInteraction: 0
m_SpriteSortPoint: 1 m_SpriteSortPoint: 1
--- !u!114 &1707774147108908574 --- !u!114 &1707774147108908574
MonoBehaviour: MonoBehaviour:

View File

@@ -69,10 +69,14 @@ MonoBehaviour:
itemData: {fileID: 11400000, guid: ea20e322caf6eb441b580775bf1bf2c8, type: 2} itemData: {fileID: 11400000, guid: ea20e322caf6eb441b580775bf1bf2c8, type: 2}
iconRenderer: {fileID: 1311388821310946158} iconRenderer: {fileID: 1311388821310946158}
slottedItemRenderers: slottedItemRenderers:
- {fileID: 4363732810493563330} - renderer: {fileID: 4363732810493563330}
- {fileID: 4765283125670404640} assignedItem: {fileID: 11400000, guid: f5a6df00a3840924a8e5b5052a8c9b05, type: 2}
- {fileID: 6453868228671073978} - renderer: {fileID: 4765283125670404640}
- {fileID: 5502334101811892095} assignedItem: {fileID: 11400000, guid: 0f94d1cbd3735424ea37b6125154ed37, type: 2}
- renderer: {fileID: 6453868228671073978}
assignedItem: {fileID: 11400000, guid: d0e8554a0463a924e803732e9209c92a, type: 2}
- renderer: {fileID: 5502334101811892095}
assignedItem: {fileID: 11400000, guid: 45c190ffad50b994ba53f64a9838751d, type: 2}
onItemSlotted: onItemSlotted:
m_PersistentCalls: m_PersistentCalls:
m_Calls: [] m_Calls: []

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 8ad71c1dc8542e54494a857fa06095fb
PrefabImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -34,6 +34,7 @@ Transform:
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!212 &3593498626556091915 --- !u!212 &3593498626556091915
SpriteRenderer: SpriteRenderer:
serializedVersion: 2
m_ObjectHideFlags: 0 m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0} m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0} m_PrefabInstance: {fileID: 0}
@@ -79,6 +80,7 @@ SpriteRenderer:
m_SortingLayerID: 0 m_SortingLayerID: 0
m_SortingLayer: 0 m_SortingLayer: 0
m_SortingOrder: 1 m_SortingOrder: 1
m_MaskInteraction: 0
m_Sprite: {fileID: 277634131431117102, guid: 2cf4a5af200e48347b7dcd0dbd84d9ca, type: 3} m_Sprite: {fileID: 277634131431117102, guid: 2cf4a5af200e48347b7dcd0dbd84d9ca, type: 3}
m_Color: {r: 1, g: 1, b: 1, a: 1} m_Color: {r: 1, g: 1, b: 1, a: 1}
m_FlipX: 0 m_FlipX: 0
@@ -88,7 +90,6 @@ SpriteRenderer:
m_AdaptiveModeThreshold: 0.5 m_AdaptiveModeThreshold: 0.5
m_SpriteTileMode: 0 m_SpriteTileMode: 0
m_WasSpriteAssigned: 1 m_WasSpriteAssigned: 1
m_MaskInteraction: 0
m_SpriteSortPoint: 0 m_SpriteSortPoint: 0
--- !u!1 &563765657355903966 --- !u!1 &563765657355903966
GameObject: GameObject:
@@ -454,6 +455,7 @@ Transform:
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!212 &4677446939953396014 --- !u!212 &4677446939953396014
SpriteRenderer: SpriteRenderer:
serializedVersion: 2
m_ObjectHideFlags: 0 m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0} m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0} m_PrefabInstance: {fileID: 0}
@@ -499,6 +501,7 @@ SpriteRenderer:
m_SortingLayerID: 0 m_SortingLayerID: 0
m_SortingLayer: 0 m_SortingLayer: 0
m_SortingOrder: 1 m_SortingOrder: 1
m_MaskInteraction: 0
m_Sprite: {fileID: -2418630947029704618, guid: fbbc627f5a8f06e47a23369fd19f3998, type: 3} m_Sprite: {fileID: -2418630947029704618, guid: fbbc627f5a8f06e47a23369fd19f3998, type: 3}
m_Color: {r: 1, g: 1, b: 1, a: 1} m_Color: {r: 1, g: 1, b: 1, a: 1}
m_FlipX: 0 m_FlipX: 0
@@ -508,7 +511,6 @@ SpriteRenderer:
m_AdaptiveModeThreshold: 0.5 m_AdaptiveModeThreshold: 0.5
m_SpriteTileMode: 0 m_SpriteTileMode: 0
m_WasSpriteAssigned: 1 m_WasSpriteAssigned: 1
m_MaskInteraction: 0
m_SpriteSortPoint: 0 m_SpriteSortPoint: 0
--- !u!1 &2312511629901843318 --- !u!1 &2312511629901843318
GameObject: GameObject:
@@ -544,6 +546,7 @@ Transform:
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!212 &5126475362876787783 --- !u!212 &5126475362876787783
SpriteRenderer: SpriteRenderer:
serializedVersion: 2
m_ObjectHideFlags: 0 m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0} m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0} m_PrefabInstance: {fileID: 0}
@@ -589,6 +592,7 @@ SpriteRenderer:
m_SortingLayerID: 0 m_SortingLayerID: 0
m_SortingLayer: 0 m_SortingLayer: 0
m_SortingOrder: 1 m_SortingOrder: 1
m_MaskInteraction: 0
m_Sprite: {fileID: 277634131431117102, guid: 2cf4a5af200e48347b7dcd0dbd84d9ca, type: 3} m_Sprite: {fileID: 277634131431117102, guid: 2cf4a5af200e48347b7dcd0dbd84d9ca, type: 3}
m_Color: {r: 1, g: 1, b: 1, a: 1} m_Color: {r: 1, g: 1, b: 1, a: 1}
m_FlipX: 0 m_FlipX: 0
@@ -598,7 +602,6 @@ SpriteRenderer:
m_AdaptiveModeThreshold: 0.5 m_AdaptiveModeThreshold: 0.5
m_SpriteTileMode: 0 m_SpriteTileMode: 0
m_WasSpriteAssigned: 1 m_WasSpriteAssigned: 1
m_MaskInteraction: 0
m_SpriteSortPoint: 0 m_SpriteSortPoint: 0
--- !u!1 &2391935521422290070 --- !u!1 &2391935521422290070
GameObject: GameObject:
@@ -637,6 +640,7 @@ Transform:
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!212 &6338084184716153992 --- !u!212 &6338084184716153992
SpriteRenderer: SpriteRenderer:
serializedVersion: 2
m_ObjectHideFlags: 0 m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0} m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0} m_PrefabInstance: {fileID: 0}
@@ -682,6 +686,7 @@ SpriteRenderer:
m_SortingLayerID: 0 m_SortingLayerID: 0
m_SortingLayer: 0 m_SortingLayer: 0
m_SortingOrder: 1 m_SortingOrder: 1
m_MaskInteraction: 0
m_Sprite: {fileID: -3811075571101519331, guid: cf5af87e6a25e9442b89f069b894a5fd, type: 3} m_Sprite: {fileID: -3811075571101519331, guid: cf5af87e6a25e9442b89f069b894a5fd, type: 3}
m_Color: {r: 1, g: 1, b: 1, a: 1} m_Color: {r: 1, g: 1, b: 1, a: 1}
m_FlipX: 0 m_FlipX: 0
@@ -691,7 +696,6 @@ SpriteRenderer:
m_AdaptiveModeThreshold: 0.5 m_AdaptiveModeThreshold: 0.5
m_SpriteTileMode: 0 m_SpriteTileMode: 0
m_WasSpriteAssigned: 1 m_WasSpriteAssigned: 1
m_MaskInteraction: 0
m_SpriteSortPoint: 0 m_SpriteSortPoint: 0
--- !u!61 &253472492358066383 --- !u!61 &253472492358066383
BoxCollider2D: BoxCollider2D:
@@ -813,6 +817,7 @@ Transform:
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!212 &1081162597868568544 --- !u!212 &1081162597868568544
SpriteRenderer: SpriteRenderer:
serializedVersion: 2
m_ObjectHideFlags: 0 m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0} m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0} m_PrefabInstance: {fileID: 0}
@@ -858,6 +863,7 @@ SpriteRenderer:
m_SortingLayerID: 0 m_SortingLayerID: 0
m_SortingLayer: 0 m_SortingLayer: 0
m_SortingOrder: 0 m_SortingOrder: 0
m_MaskInteraction: 0
m_Sprite: {fileID: 9105513792776133627, guid: 140f82f54aeb07e409575fe55dc6df14, type: 3} m_Sprite: {fileID: 9105513792776133627, guid: 140f82f54aeb07e409575fe55dc6df14, type: 3}
m_Color: {r: 1, g: 1, b: 1, a: 1} m_Color: {r: 1, g: 1, b: 1, a: 1}
m_FlipX: 0 m_FlipX: 0
@@ -867,7 +873,6 @@ SpriteRenderer:
m_AdaptiveModeThreshold: 0.5 m_AdaptiveModeThreshold: 0.5
m_SpriteTileMode: 0 m_SpriteTileMode: 0
m_WasSpriteAssigned: 1 m_WasSpriteAssigned: 1
m_MaskInteraction: 0
m_SpriteSortPoint: 0 m_SpriteSortPoint: 0
--- !u!60 &4857176284453307382 --- !u!60 &4857176284453307382
PolygonCollider2D: PolygonCollider2D:
@@ -955,6 +960,7 @@ Transform:
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!212 &7072755111968586092 --- !u!212 &7072755111968586092
SpriteRenderer: SpriteRenderer:
serializedVersion: 2
m_ObjectHideFlags: 0 m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0} m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0} m_PrefabInstance: {fileID: 0}
@@ -1000,6 +1006,7 @@ SpriteRenderer:
m_SortingLayerID: 0 m_SortingLayerID: 0
m_SortingLayer: 0 m_SortingLayer: 0
m_SortingOrder: 0 m_SortingOrder: 0
m_MaskInteraction: 0
m_Sprite: {fileID: 9105513792776133627, guid: 140f82f54aeb07e409575fe55dc6df14, type: 3} m_Sprite: {fileID: 9105513792776133627, guid: 140f82f54aeb07e409575fe55dc6df14, type: 3}
m_Color: {r: 1, g: 1, b: 1, a: 1} m_Color: {r: 1, g: 1, b: 1, a: 1}
m_FlipX: 0 m_FlipX: 0
@@ -1009,7 +1016,6 @@ SpriteRenderer:
m_AdaptiveModeThreshold: 0.5 m_AdaptiveModeThreshold: 0.5
m_SpriteTileMode: 0 m_SpriteTileMode: 0
m_WasSpriteAssigned: 1 m_WasSpriteAssigned: 1
m_MaskInteraction: 0
m_SpriteSortPoint: 0 m_SpriteSortPoint: 0
--- !u!1 &8095936409589519396 --- !u!1 &8095936409589519396
GameObject: GameObject:
@@ -1045,6 +1051,7 @@ Transform:
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!212 &7713018619525726688 --- !u!212 &7713018619525726688
SpriteRenderer: SpriteRenderer:
serializedVersion: 2
m_ObjectHideFlags: 0 m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0} m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0} m_PrefabInstance: {fileID: 0}
@@ -1090,6 +1097,7 @@ SpriteRenderer:
m_SortingLayerID: 0 m_SortingLayerID: 0
m_SortingLayer: 0 m_SortingLayer: 0
m_SortingOrder: 1 m_SortingOrder: 1
m_MaskInteraction: 0
m_Sprite: {fileID: -2418630947029704618, guid: fbbc627f5a8f06e47a23369fd19f3998, type: 3} m_Sprite: {fileID: -2418630947029704618, guid: fbbc627f5a8f06e47a23369fd19f3998, type: 3}
m_Color: {r: 1, g: 1, b: 1, a: 1} m_Color: {r: 1, g: 1, b: 1, a: 1}
m_FlipX: 0 m_FlipX: 0
@@ -1099,7 +1107,6 @@ SpriteRenderer:
m_AdaptiveModeThreshold: 0.5 m_AdaptiveModeThreshold: 0.5
m_SpriteTileMode: 0 m_SpriteTileMode: 0
m_WasSpriteAssigned: 1 m_WasSpriteAssigned: 1
m_MaskInteraction: 0
m_SpriteSortPoint: 0 m_SpriteSortPoint: 0
--- !u!1 &8607415572972099566 --- !u!1 &8607415572972099566
GameObject: GameObject:

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -17,6 +17,17 @@ namespace Interactions
Forbidden Forbidden
} }
/// <summary>
/// Maps a sprite renderer to an optional item assignment
/// </summary>
[Serializable]
public class SlotRendererMapping
{
public SpriteRenderer renderer;
[Tooltip("Optional: If set, this renderer slot is dedicated to this specific item. Leave null for flexible slots.")]
public PickupItemData assignedItem;
}
/// <summary> /// <summary>
/// Saveable data for ItemSlot state /// Saveable data for ItemSlot state
/// </summary> /// </summary>
@@ -41,7 +52,7 @@ namespace Interactions
// Multi-slot item tracking // Multi-slot item tracking
private List<PickupItemData> slottedItemsData = new List<PickupItemData>(); private List<PickupItemData> slottedItemsData = new List<PickupItemData>();
public SpriteRenderer[] slottedItemRenderers; // Array of renderers for multiple items public SlotRendererMapping[] slottedItemRenderers; // Array of renderers with optional item assignments
private List<GameObject> slottedItemObjects = new List<GameObject>(); private List<GameObject> slottedItemObjects = new List<GameObject>();
private List<bool> slottedItemCorrectness = new List<bool>(); // Track which items are correct private List<bool> slottedItemCorrectness = new List<bool>(); // Track which items are correct
@@ -63,12 +74,24 @@ namespace Interactions
/// <summary> /// <summary>
/// Number of items currently slotted (correct or incorrect) /// Number of items currently slotted (correct or incorrect)
/// </summary> /// </summary>
public int CurrentSlottedCount => slottedItemObjects.Count; public int CurrentSlottedCount => slottedItemObjects.Count(obj => obj != null);
/// <summary> /// <summary>
/// Number of CORRECT items currently slotted /// Number of CORRECT items currently slotted
/// </summary> /// </summary>
public int CurrentCorrectCount => slottedItemCorrectness.Count(correct => correct); public int CurrentCorrectCount
{
get
{
int count = 0;
for (int i = 0; i < slottedItemCorrectness.Count; i++)
{
if (i < slottedItemObjects.Count && slottedItemObjects[i] != null && slottedItemCorrectness[i])
count++;
}
return count;
}
}
/// <summary> /// <summary>
/// Number of items required to complete this slot /// Number of items required to complete this slot
@@ -288,16 +311,44 @@ namespace Interactions
// For multi-slots: only allow swap if not complete yet (allows fixing mistakes) // For multi-slots: only allow swap if not complete yet (allows fixing mistakes)
if (!IsMultiSlot || !IsComplete) if (!IsMultiSlot || !IsComplete)
{ {
// LIFO swap - swap with the last item // Determine target index for the new item
int lastIndex = CurrentSlottedCount - 1; int targetIndex = GetTargetSlotIndexForItem(heldItemData);
var itemToReturn = slottedItemObjects[lastIndex];
var itemDataToReturn = slottedItemsData[lastIndex]; int indexToSwap;
if (targetIndex >= 0 && targetIndex < slottedItemObjects.Count && slottedItemObjects[targetIndex] != null)
{
// Swap with the item in the assigned slot
indexToSwap = targetIndex;
}
else
{
// LIFO swap - swap with the last non-null item
indexToSwap = -1;
for (int i = slottedItemObjects.Count - 1; i >= 0; i--)
{
if (slottedItemObjects[i] != null)
{
indexToSwap = i;
break;
}
}
if (indexToSwap < 0)
{
// No items to swap (shouldn't happen, but fallback)
SlotItem(heldItemObj, heldItemData);
return false;
}
}
var itemToReturn = slottedItemObjects[indexToSwap];
var itemDataToReturn = slottedItemsData[indexToSwap];
// Step 1: Give old item to follower // Step 1: Give old item to follower
FollowerController.TryPickupItem(itemToReturn, itemDataToReturn, dropItem: false); FollowerController.TryPickupItem(itemToReturn, itemDataToReturn, dropItem: false);
// Step 2: Remove old item from slot // Step 2: Remove old item from slot
RemoveItemAtIndex(lastIndex); RemoveItemAtIndex(indexToSwap);
// Step 3: Slot the new item // Step 3: Slot the new item
SlotItem(heldItemObj, heldItemData); SlotItem(heldItemObj, heldItemData);
@@ -317,15 +368,28 @@ namespace Interactions
// Pickup from slot (empty hands) - LIFO removal // Pickup from slot (empty hands) - LIFO removal
if (heldItemData == null) if (heldItemData == null)
{ {
int lastIndex = CurrentSlottedCount - 1; // Find last non-null item
var itemToPickup = slottedItemObjects[lastIndex]; int lastIndex = -1;
var itemDataToPickup = slottedItemsData[lastIndex]; for (int i = slottedItemObjects.Count - 1; i >= 0; i--)
{
if (slottedItemObjects[i] != null)
{
lastIndex = i;
break;
}
}
// Try to give item to follower if (lastIndex >= 0)
FollowerController.TryPickupItem(itemToPickup, itemDataToPickup, dropItem: false); {
var itemToPickup = slottedItemObjects[lastIndex];
var itemDataToPickup = slottedItemsData[lastIndex];
// Remove from slot // Try to give item to follower
RemoveItemAtIndex(lastIndex); FollowerController.TryPickupItem(itemToPickup, itemDataToPickup, dropItem: false);
// Remove from slot
RemoveItemAtIndex(lastIndex);
}
// Just picked up from slot - not a success // Just picked up from slot - not a success
return false; return false;
@@ -343,7 +407,16 @@ namespace Interactions
/// </summary> /// </summary>
private void ClearSlot() private void ClearSlot()
{ {
var previousData = slottedItemsData.Count > 0 ? slottedItemsData[0] : null; // Find first non-null data for event
PickupItemData previousData = null;
foreach (var data in slottedItemsData)
{
if (data != null)
{
previousData = data;
break;
}
}
// Clear all pickup's OwningSlot references // Clear all pickup's OwningSlot references
foreach (var itemObj in slottedItemObjects) foreach (var itemObj in slottedItemObjects)
@@ -375,7 +448,7 @@ namespace Interactions
/// </summary> /// </summary>
private void RemoveItemAtIndex(int index) private void RemoveItemAtIndex(int index)
{ {
if (index < 0 || index >= CurrentSlottedCount) if (index < 0 || index >= slottedItemObjects.Count)
return; return;
var itemObj = slottedItemObjects[index]; var itemObj = slottedItemObjects[index];
@@ -391,9 +464,10 @@ namespace Interactions
} }
} }
slottedItemObjects.RemoveAt(index); // Set to null instead of removing to maintain sparse storage
slottedItemsData.RemoveAt(index); slottedItemObjects[index] = null;
slottedItemCorrectness.RemoveAt(index); // Also remove correctness tracking slottedItemsData[index] = null;
slottedItemCorrectness[index] = false;
if (CurrentSlottedCount == 0) if (CurrentSlottedCount == 0)
{ {
@@ -412,6 +486,74 @@ namespace Interactions
#region Visual Updates #region Visual Updates
/// <summary>
/// Determines the best slot index for an item based on assignments and availability.
/// Returns -1 if no mappings are configured (uses append behavior).
/// </summary>
private int GetTargetSlotIndexForItem(PickupItemData itemData)
{
if (slottedItemRenderers == null || slottedItemRenderers.Length == 0)
return -1;
// Check if any renderer has assignments configured
bool hasAnyAssignments = false;
for (int i = 0; i < slottedItemRenderers.Length; i++)
{
if (slottedItemRenderers[i]?.assignedItem != null)
{
hasAnyAssignments = true;
break;
}
}
// If no assignments configured, use append behavior (backward compatible)
if (!hasAnyAssignments)
return -1;
// Step 1: Check if this item has a dedicated assigned slot
for (int i = 0; i < slottedItemRenderers.Length; i++)
{
var mapping = slottedItemRenderers[i];
if (mapping?.assignedItem != null && PickupItemData.AreEquivalent(mapping.assignedItem, itemData))
{
// This is the assigned slot for this item
return i;
}
}
// Step 2: Item is not assigned to a specific slot - find best available slot
// Ensure lists are large enough to check
while (slottedItemObjects.Count < slottedItemRenderers.Length)
{
slottedItemObjects.Add(null);
slottedItemsData.Add(null);
slottedItemCorrectness.Add(false);
}
// Prefer unassigned empty slots first
for (int i = 0; i < slottedItemRenderers.Length; i++)
{
var mapping = slottedItemRenderers[i];
if (mapping?.assignedItem == null && slottedItemObjects[i] == null)
{
return i; // Empty unassigned slot
}
}
// Then try assigned but empty slots
for (int i = 0; i < slottedItemRenderers.Length; i++)
{
var mapping = slottedItemRenderers[i];
if (mapping?.assignedItem != null && slottedItemObjects[i] == null)
{
return i; // Empty assigned slot
}
}
// All slots full - return -1 to trigger swap logic
return -1;
}
/// <summary> /// <summary>
/// Updates the sprite and scale for all slotted items. /// Updates the sprite and scale for all slotted items.
/// </summary> /// </summary>
@@ -423,10 +565,12 @@ namespace Interactions
// Update each renderer based on slotted items // Update each renderer based on slotted items
for (int i = 0; i < slottedItemRenderers.Length; i++) for (int i = 0; i < slottedItemRenderers.Length; i++)
{ {
var slotRenderer = slottedItemRenderers[i]; var mapping = slottedItemRenderers[i];
if (slotRenderer == null) if (mapping == null || mapping.renderer == null)
continue; continue;
var slotRenderer = mapping.renderer;
// If we have an item at this index, show it // If we have an item at this index, show it
if (i < slottedItemsData.Count && slottedItemsData[i] != null) if (i < slottedItemsData.Count && slottedItemsData[i] != null)
{ {
@@ -645,7 +789,7 @@ namespace Interactions
/// <summary> /// <summary>
/// Public API for slotting items during gameplay. /// Public API for slotting items during gameplay.
/// Adds item to the slot (multi-slot support). /// Adds item to the slot (multi-slot support with positional awareness).
/// Caller is responsible for managing follower's held item state. /// Caller is responsible for managing follower's held item state.
/// </summary> /// </summary>
public void SlotItem(GameObject itemToSlot, PickupItemData itemToSlotData) public void SlotItem(GameObject itemToSlot, PickupItemData itemToSlotData)
@@ -661,10 +805,31 @@ namespace Interactions
var allowed = config?.allowedItems ?? new List<PickupItemData>(); var allowed = config?.allowedItems ?? new List<PickupItemData>();
bool isCorrectItem = PickupItemData.ListContainsEquivalent(allowed, itemToSlotData); bool isCorrectItem = PickupItemData.ListContainsEquivalent(allowed, itemToSlotData);
// Add to lists // Determine target slot index
slottedItemObjects.Add(itemToSlot); int targetIndex = GetTargetSlotIndexForItem(itemToSlotData);
slottedItemsData.Add(itemToSlotData);
slottedItemCorrectness.Add(isCorrectItem); // Track correctness if (targetIndex >= 0)
{
// Positional slotting - ensure lists are large enough
while (slottedItemObjects.Count <= targetIndex)
{
slottedItemObjects.Add(null);
slottedItemsData.Add(null);
slottedItemCorrectness.Add(false);
}
// Place at specific index
slottedItemObjects[targetIndex] = itemToSlot;
slottedItemsData[targetIndex] = itemToSlotData;
slottedItemCorrectness[targetIndex] = isCorrectItem;
}
else
{
// Append behavior (backward compatible or when all slots full)
slottedItemObjects.Add(itemToSlot);
slottedItemsData.Add(itemToSlotData);
slottedItemCorrectness.Add(isCorrectItem);
}
// Deactivate item and set pickup state // Deactivate item and set pickup state
itemToSlot.SetActive(false); itemToSlot.SetActive(false);

View File

@@ -26,6 +26,10 @@ namespace Minigames.StatueDressup.Controllers
[SerializeField] private GameObject statue; [SerializeField] private GameObject statue;
[SerializeField] private DecorationDraggableInstance draggablePrefab; // Prefab for spawning decorations [SerializeField] private DecorationDraggableInstance draggablePrefab; // Prefab for spawning decorations
[Header("Edit UI")]
[SerializeField] private UI.DecorationEditUI editUIPrefab; // Prefab for edit UI
private UI.DecorationEditUI _editUIInstance;
[Header("UI Pages")] [Header("UI Pages")]
[SerializeField] private UI.PlayAreaPage playAreaPage; [SerializeField] private UI.PlayAreaPage playAreaPage;
[SerializeField] private UI.PhotoGalleryPage photoGalleryPage; [SerializeField] private UI.PhotoGalleryPage photoGalleryPage;
@@ -37,8 +41,8 @@ namespace Minigames.StatueDressup.Controllers
[Header("Photo Settings")] [Header("Photo Settings")]
[SerializeField] private RectTransform photoArea; // Area to capture [SerializeField] private RectTransform photoArea; // Area to capture
private List<DecorationDraggableInstance> placedDecorations = new List<DecorationDraggableInstance>(); private List<DecorationDraggableInstance> _placedDecorations = new List<DecorationDraggableInstance>();
private bool minigameCompleted; private bool _minigameCompleted;
// Public properties // Public properties
public Transform StatueParent => statueParent; public Transform StatueParent => statueParent;
@@ -127,9 +131,9 @@ namespace Minigames.StatueDressup.Controllers
/// </summary> /// </summary>
public void RegisterDecoration(DecorationDraggableInstance decoration) public void RegisterDecoration(DecorationDraggableInstance decoration)
{ {
if (decoration != null && !placedDecorations.Contains(decoration)) if (decoration != null && !_placedDecorations.Contains(decoration))
{ {
placedDecorations.Add(decoration); _placedDecorations.Add(decoration);
Logging.Debug($"[StatueDecorationController] Decoration placed: {decoration.Data?.DecorationName}"); Logging.Debug($"[StatueDecorationController] Decoration placed: {decoration.Data?.DecorationName}");
// Auto-save state // Auto-save state
@@ -142,9 +146,9 @@ namespace Minigames.StatueDressup.Controllers
/// </summary> /// </summary>
public void UnregisterDecoration(DecorationDraggableInstance decoration) public void UnregisterDecoration(DecorationDraggableInstance decoration)
{ {
if (decoration != null && placedDecorations.Contains(decoration)) if (decoration != null && _placedDecorations.Contains(decoration))
{ {
placedDecorations.Remove(decoration); _placedDecorations.Remove(decoration);
Logging.Debug($"[StatueDecorationController] Decoration removed: {decoration.Data?.DecorationName}"); Logging.Debug($"[StatueDecorationController] Decoration removed: {decoration.Data?.DecorationName}");
// Auto-save state // Auto-save state
@@ -157,7 +161,7 @@ namespace Minigames.StatueDressup.Controllers
/// </summary> /// </summary>
private void OnTakePhoto() private void OnTakePhoto()
{ {
if (minigameCompleted) if (_minigameCompleted)
{ {
Logging.Debug("[StatueDecorationController] Minigame already completed"); Logging.Debug("[StatueDecorationController] Minigame already completed");
return; return;
@@ -174,7 +178,7 @@ namespace Minigames.StatueDressup.Controllers
/// </summary> /// </summary>
private System.Collections.IEnumerator CapturePhotoCoroutine() private System.Collections.IEnumerator CapturePhotoCoroutine()
{ {
int decorationCount = placedDecorations.Count; int decorationCount = _placedDecorations.Count;
bool captureSuccess = false; bool captureSuccess = false;
string savedPhotoId = null; string savedPhotoId = null;
@@ -222,7 +226,7 @@ namespace Minigames.StatueDressup.Controllers
// Show completion feedback // Show completion feedback
ShowCompletionFeedback(); ShowCompletionFeedback();
minigameCompleted = true; _minigameCompleted = true;
} }
/// <summary> /// <summary>
@@ -290,7 +294,7 @@ namespace Minigames.StatueDressup.Controllers
}; };
// Collect all decoration placements // Collect all decoration placements
foreach (var decoration in placedDecorations) foreach (var decoration in _placedDecorations)
{ {
if (decoration == null || decoration.Data == null) continue; if (decoration == null || decoration.Data == null) continue;
@@ -455,6 +459,38 @@ namespace Minigames.StatueDressup.Controllers
return true; return true;
} }
/// <summary>
/// Show edit UI for a placed decoration
/// </summary>
public void ShowEditUI(DecorationDraggableInstance decoration)
{
if (decoration == null)
{
Logging.Warning("[StatueDecorationController] Cannot show edit UI - decoration is null");
return;
}
// Create edit UI instance if needed
if (_editUIInstance == null)
{
if (editUIPrefab == null)
{
Logging.Error("[StatueDecorationController] Edit UI prefab is not assigned!");
return;
}
// Instantiate as child of canvas (find appropriate parent)
Transform canvasTransform = statueArea != null ? statueArea.root : transform.root;
_editUIInstance = Instantiate(editUIPrefab, canvasTransform);
_editUIInstance.transform.SetAsLastSibling(); // Ensure it's on top
Logging.Debug("[StatueDecorationController] Created edit UI instance");
}
// Show the UI
_editUIInstance.Show(decoration);
}
/// <summary> /// <summary>
/// Cleanup when controller is destroyed /// Cleanup when controller is destroyed
/// </summary> /// </summary>

View File

@@ -21,36 +21,36 @@ namespace Minigames.StatueDressup.DragDrop
[SerializeField] private Image decorationImage; [SerializeField] private Image decorationImage;
[SerializeField] private CanvasGroup canvasGroup; [SerializeField] private CanvasGroup canvasGroup;
private DecorationData decorationData; private DecorationData _decorationData;
private RectTransform rectTransform; private RectTransform _rectTransform;
private Canvas canvas; private Canvas _canvas;
private Transform canvasParent; // Parent transform for dragging (usually canvas or draggable container) private Transform _canvasParent; // Parent transform for dragging (usually canvas or draggable container)
private RectTransform statueOutline; private RectTransform _statueOutline;
private Transform statueParent; private Transform _statueParent;
private StatueDecorationController controller; private StatueDecorationController _controller;
private AppleHills.Core.Settings.IStatueDressupSettings settings; private AppleHills.Core.Settings.IStatueDressupSettings _settings;
private System.Action onFinishedCallback; private System.Action _onFinishedCallback;
private System.Action onShowOutlineCallback; private System.Action _onShowOutlineCallback;
private System.Action onHideOutlineCallback; private System.Action _onHideOutlineCallback;
private bool isDragging; private bool _isDragging;
private bool isPlacedOnStatue; private bool _isPlacedOnStatue;
private Vector3 dragOffset; private Vector3 _dragOffset;
private bool dragStarted; // Track if drag actually started (vs just a click) private bool _dragStarted; // Track if drag actually started (vs just a click)
// Properties // Properties
public DecorationData Data => decorationData; public DecorationData Data => _decorationData;
public bool IsPlacedOnStatue => isPlacedOnStatue; public bool IsPlacedOnStatue => _isPlacedOnStatue;
private void Awake() private void Awake()
{ {
rectTransform = GetComponent<RectTransform>(); _rectTransform = GetComponent<RectTransform>();
canvas = GetComponentInParent<Canvas>(); _canvas = GetComponentInParent<Canvas>();
// Store initial parent for dragging context // Store initial parent for dragging context
if (transform.parent != null) if (transform.parent != null)
{ {
canvasParent = transform.parent; _canvasParent = transform.parent;
} }
if (canvasGroup == null) if (canvasGroup == null)
@@ -76,24 +76,24 @@ namespace Minigames.StatueDressup.DragDrop
return; return;
} }
decorationData = context.Data; _decorationData = context.Data;
statueOutline = context.StatueOutline; _statueOutline = context.StatueOutline;
statueParent = context.StatueParent; _statueParent = context.StatueParent;
controller = context.Controller; _controller = context.Controller;
settings = context.Settings; _settings = context.Settings;
onFinishedCallback = context.OnFinished; _onFinishedCallback = context.OnFinished;
onShowOutlineCallback = context.OnShowOutline; _onShowOutlineCallback = context.OnShowOutline;
onHideOutlineCallback = context.OnHideOutline; _onHideOutlineCallback = context.OnHideOutline;
// Handle placed vs new drag // Handle placed vs new drag
if (context.IsPlaced) if (context.IsPlaced)
{ {
isPlacedOnStatue = true; _isPlacedOnStatue = true;
isDragging = false; _isDragging = false;
statueParent = transform.parent; // Already parented to statue _statueParent = transform.parent; // Already parented to statue
if (context.CanvasParent != null) if (context.CanvasParent != null)
{ {
canvasParent = context.CanvasParent; _canvasParent = context.CanvasParent;
} }
} }
@@ -104,9 +104,9 @@ namespace Minigames.StatueDressup.DragDrop
} }
// Set authored size // Set authored size
if (rectTransform != null && context.Data != null) if (_rectTransform != null && context.Data != null)
{ {
rectTransform.sizeDelta = context.Data.AuthoredSize; _rectTransform.sizeDelta = context.Data.AuthoredSize;
} }
// Make interactive if placed (so it can be picked up) // Make interactive if placed (so it can be picked up)
@@ -154,22 +154,22 @@ namespace Minigames.StatueDressup.DragDrop
/// </summary> /// </summary>
public void StartDragFromIcon(PointerEventData eventData) public void StartDragFromIcon(PointerEventData eventData)
{ {
isDragging = true; _isDragging = true;
// Broadcast started dragging event (from grid) // Broadcast started dragging event (from grid)
var eventDataObj = new DecorationEventData(decorationData, gameObject, transform.position, fromStatue: false); var eventDataObj = new DecorationEventData(_decorationData, gameObject, transform.position, fromStatue: false);
DecorationEventsManager.BroadcastDecorationStartedDragging(eventDataObj); DecorationEventsManager.BroadcastDecorationStartedDragging(eventDataObj);
// Calculate offset from cursor to object center // Calculate offset from cursor to object center
RectTransformUtility.ScreenPointToLocalPointInRectangle( RectTransformUtility.ScreenPointToLocalPointInRectangle(
canvas.transform as RectTransform, _canvas.transform as RectTransform,
eventData.position, eventData.position,
eventData.pressEventCamera, eventData.pressEventCamera,
out Vector2 localPoint); out Vector2 localPoint);
dragOffset = rectTransform.localPosition - (Vector3)localPoint; _dragOffset = _rectTransform.localPosition - (Vector3)localPoint;
Logging.Debug($"[DecorationDraggableInstance] Started drag from icon: {decorationData?.DecorationName}"); Logging.Debug($"[DecorationDraggableInstance] Started drag from icon: {_decorationData?.DecorationName}");
} }
/// <summary> /// <summary>
@@ -177,16 +177,16 @@ namespace Minigames.StatueDressup.DragDrop
/// </summary> /// </summary>
public void ContinueDrag(PointerEventData eventData) public void ContinueDrag(PointerEventData eventData)
{ {
if (!isDragging) return; if (!_isDragging) return;
// Update position to follow cursor // Update position to follow cursor
RectTransformUtility.ScreenPointToLocalPointInRectangle( RectTransformUtility.ScreenPointToLocalPointInRectangle(
canvas.transform as RectTransform, _canvas.transform as RectTransform,
eventData.position, eventData.position,
eventData.pressEventCamera, eventData.pressEventCamera,
out Vector2 localPoint); out Vector2 localPoint);
rectTransform.localPosition = localPoint + (Vector2)dragOffset; _rectTransform.localPosition = localPoint + (Vector2)_dragOffset;
} }
/// <summary> /// <summary>
@@ -194,12 +194,12 @@ namespace Minigames.StatueDressup.DragDrop
/// </summary> /// </summary>
public void EndDrag(PointerEventData eventData) public void EndDrag(PointerEventData eventData)
{ {
isDragging = false; _isDragging = false;
Logging.Debug($"[DecorationDraggableInstance] Drag ended: {decorationData?.DecorationName}"); Logging.Debug($"[DecorationDraggableInstance] Drag ended: {_decorationData?.DecorationName}");
// Broadcast finished dragging event // Broadcast finished dragging event
var eventDataObj = new DecorationEventData(decorationData, gameObject, transform.position, fromStatue: isPlacedOnStatue); var eventDataObj = new DecorationEventData(_decorationData, gameObject, transform.position, fromStatue: _isPlacedOnStatue);
DecorationEventsManager.BroadcastDecorationFinishedDragging(eventDataObj); DecorationEventsManager.BroadcastDecorationFinishedDragging(eventDataObj);
// Check if overlapping with statue // Check if overlapping with statue
@@ -218,20 +218,20 @@ namespace Minigames.StatueDressup.DragDrop
/// </summary> /// </summary>
private bool IsOverlappingStatue() private bool IsOverlappingStatue()
{ {
if (statueOutline == null || rectTransform == null) if (_statueOutline == null || _rectTransform == null)
{ {
Logging.Warning($"[DecorationDraggableInstance] Cannot check overlap - statueOutline or RectTransform is null"); Logging.Warning($"[DecorationDraggableInstance] Cannot check overlap - statueOutline or RectTransform is null");
return false; return false;
} }
// Get bounds of this item in world space // Get bounds of this item in world space
Rect itemRect = GetWorldRect(rectTransform); Rect itemRect = GetWorldRect(_rectTransform);
Rect outlineRect = GetWorldRect(statueOutline); Rect outlineRect = GetWorldRect(_statueOutline);
// Check for any overlap // Check for any overlap
bool overlaps = itemRect.Overlaps(outlineRect); bool overlaps = itemRect.Overlaps(outlineRect);
Logging.Debug($"[DecorationDraggableInstance] Overlap check: {decorationData?.DecorationName}, overlaps={overlaps}"); Logging.Debug($"[DecorationDraggableInstance] Overlap check: {_decorationData?.DecorationName}, overlaps={overlaps}");
return overlaps; return overlaps;
} }
@@ -255,28 +255,28 @@ namespace Minigames.StatueDressup.DragDrop
/// </summary> /// </summary>
private void PlaceOnStatue() private void PlaceOnStatue()
{ {
Logging.Debug($"[DecorationDraggableInstance] Placing on statue: {decorationData?.DecorationName}"); Logging.Debug($"[DecorationDraggableInstance] Placing on statue: {_decorationData?.DecorationName}");
isPlacedOnStatue = true; _isPlacedOnStatue = true;
// Broadcast dropped on statue event // Broadcast dropped on statue event
var eventDataObj = new DecorationEventData(decorationData, gameObject, transform.position, fromStatue: false); var eventDataObj = new DecorationEventData(_decorationData, gameObject, transform.position, fromStatue: false);
DecorationEventsManager.BroadcastDecorationDroppedOnStatue(eventDataObj); DecorationEventsManager.BroadcastDecorationDroppedOnStatue(eventDataObj);
// Move to statue parent if specified // Move to statue parent if specified
if (statueParent != null && transform.parent != statueParent) if (_statueParent != null && transform.parent != _statueParent)
{ {
transform.SetParent(statueParent, true); // Keep world position transform.SetParent(_statueParent, true); // Keep world position
} }
// Register with controller // Register with controller
if (controller != null) if (_controller != null)
{ {
controller.RegisterDecoration(this); _controller.RegisterDecoration(this);
} }
// Notify menu controller to hide outline // Notify menu controller to hide outline
onFinishedCallback?.Invoke(); _onFinishedCallback?.Invoke();
} }
/// <summary> /// <summary>
@@ -284,22 +284,22 @@ namespace Minigames.StatueDressup.DragDrop
/// </summary> /// </summary>
private void PlayPopOutAndDestroy() private void PlayPopOutAndDestroy()
{ {
Logging.Debug($"[DecorationDraggableInstance] Pop-out and destroy: {decorationData?.DecorationName}"); Logging.Debug($"[DecorationDraggableInstance] Pop-out and destroy: {_decorationData?.DecorationName}");
// Broadcast dropped out event (animation starting) // Broadcast dropped out event (animation starting)
var eventDataObj = new DecorationEventData(decorationData, gameObject, transform.position, fromStatue: false); var eventDataObj = new DecorationEventData(_decorationData, gameObject, transform.position, fromStatue: false);
DecorationEventsManager.BroadcastDecorationDroppedOut(eventDataObj); DecorationEventsManager.BroadcastDecorationDroppedOut(eventDataObj);
// Notify menu controller to hide outline immediately // Notify menu controller to hide outline immediately
onFinishedCallback?.Invoke(); _onFinishedCallback?.Invoke();
float duration = settings?.PlacementAnimationDuration ?? StatueDressupConstants.DefaultAnimationDuration; float duration = _settings?.PlacementAnimationDuration ?? StatueDressupConstants.DefaultAnimationDuration;
// Play pop-out with fade animation // Play pop-out with fade animation
TweenAnimationUtility.PopOutWithFade(transform, canvasGroup, duration, () => TweenAnimationUtility.PopOutWithFade(transform, canvasGroup, duration, () =>
{ {
// Broadcast finished dropping out event (animation complete) // Broadcast finished dropping out event (animation complete)
var finalEventData = new DecorationEventData(decorationData, gameObject, transform.position, fromStatue: false); var finalEventData = new DecorationEventData(_decorationData, gameObject, transform.position, fromStatue: false);
DecorationEventsManager.BroadcastDecorationFinishedDroppingOut(finalEventData); DecorationEventsManager.BroadcastDecorationFinishedDroppingOut(finalEventData);
Destroy(gameObject); Destroy(gameObject);
@@ -311,26 +311,26 @@ namespace Minigames.StatueDressup.DragDrop
/// </summary> /// </summary>
public void StartDragFromStatue(PointerEventData eventData) public void StartDragFromStatue(PointerEventData eventData)
{ {
Logging.Debug($"[DecorationDraggableInstance] StartDragFromStatue called for: {decorationData?.DecorationName}"); Logging.Debug($"[DecorationDraggableInstance] StartDragFromStatue called for: {_decorationData?.DecorationName}");
Logging.Debug($"[DecorationDraggableInstance] Show outline callback is null: {onShowOutlineCallback == null}"); Logging.Debug($"[DecorationDraggableInstance] Show outline callback is null: {_onShowOutlineCallback == null}");
if (controller != null) if (_controller != null)
{ {
controller.UnregisterDecoration(this); _controller.UnregisterDecoration(this);
} }
isPlacedOnStatue = false; _isPlacedOnStatue = false;
isDragging = true; _isDragging = true;
// Broadcast started dragging event (from statue) // Broadcast started dragging event (from statue)
var eventDataObj = new DecorationEventData(decorationData, gameObject, transform.position, fromStatue: true); var eventDataObj = new DecorationEventData(_decorationData, gameObject, transform.position, fromStatue: true);
DecorationEventsManager.BroadcastDecorationStartedDragging(eventDataObj); DecorationEventsManager.BroadcastDecorationStartedDragging(eventDataObj);
// Show statue outline when picking up from statue // Show statue outline when picking up from statue
if (onShowOutlineCallback != null) if (_onShowOutlineCallback != null)
{ {
Logging.Debug("[DecorationDraggableInstance] Invoking show outline callback"); Logging.Debug("[DecorationDraggableInstance] Invoking show outline callback");
onShowOutlineCallback.Invoke(); _onShowOutlineCallback.Invoke();
} }
else else
{ {
@@ -338,24 +338,24 @@ namespace Minigames.StatueDressup.DragDrop
} }
// Reparent to canvas for dragging (so coordinates work correctly) // Reparent to canvas for dragging (so coordinates work correctly)
if (canvasParent != null && transform.parent != canvasParent) if (_canvasParent != null && transform.parent != _canvasParent)
{ {
// Store world position before reparenting // Store world position before reparenting
Vector3 worldPos = transform.position; Vector3 worldPos = transform.position;
transform.SetParent(canvasParent, false); transform.SetParent(_canvasParent, false);
transform.position = worldPos; // Restore world position transform.position = worldPos; // Restore world position
} }
// Calculate offset using proper camera // Calculate offset using proper camera
RectTransformUtility.ScreenPointToLocalPointInRectangle( RectTransformUtility.ScreenPointToLocalPointInRectangle(
canvas.transform as RectTransform, _canvas.transform as RectTransform,
eventData.position, eventData.position,
eventData.pressEventCamera, eventData.pressEventCamera,
out Vector2 localPoint); out Vector2 localPoint);
dragOffset = rectTransform.localPosition - (Vector3)localPoint; _dragOffset = _rectTransform.localPosition - (Vector3)localPoint;
Logging.Debug($"[DecorationDraggableInstance] Started drag from statue: {decorationData?.DecorationName}"); Logging.Debug($"[DecorationDraggableInstance] Started drag from statue: {_decorationData?.DecorationName}");
} }
#region Pointer Event Handlers #region Pointer Event Handlers
@@ -366,15 +366,23 @@ namespace Minigames.StatueDressup.DragDrop
public void OnPointerClick(PointerEventData eventData) public void OnPointerClick(PointerEventData eventData)
{ {
// Only handle clicks when placed on statue and not currently dragging // Only handle clicks when placed on statue and not currently dragging
if (!isPlacedOnStatue || dragStarted) return; if (!_isPlacedOnStatue || _dragStarted) return;
Logging.Debug($"[DecorationDraggableInstance] Decoration tapped: {decorationData?.DecorationName}"); Logging.Debug($"[DecorationDraggableInstance] Decoration tapped: {_decorationData?.DecorationName}");
// Broadcast tap event // Broadcast tap event
var eventDataObj = new DecorationEventData(decorationData, gameObject, transform.position, fromStatue: true); var eventDataObj = new DecorationEventData(_decorationData, gameObject, transform.position, fromStatue: true);
DecorationEventsManager.BroadcastDecorationTappedOnStatue(eventDataObj); DecorationEventsManager.BroadcastDecorationTappedOnStatue(eventDataObj);
// Future: Open detail view, play sound effect, show info popup, etc. // Show edit UI
if (_controller != null)
{
_controller.ShowEditUI(this);
}
else
{
Logging.Warning("[DecorationDraggableInstance] Cannot show edit UI - controller reference is null");
}
} }
/// <summary> /// <summary>
@@ -383,9 +391,9 @@ namespace Minigames.StatueDressup.DragDrop
public void OnBeginDrag(PointerEventData eventData) public void OnBeginDrag(PointerEventData eventData)
{ {
// Only handle drag from statue if already placed // Only handle drag from statue if already placed
if (!isPlacedOnStatue) return; if (!_isPlacedOnStatue) return;
dragStarted = true; _dragStarted = true;
StartDragFromStatue(eventData); StartDragFromStatue(eventData);
} }
@@ -394,7 +402,7 @@ namespace Minigames.StatueDressup.DragDrop
/// </summary> /// </summary>
public void OnDrag(PointerEventData eventData) public void OnDrag(PointerEventData eventData)
{ {
if (!isDragging) return; if (!_isDragging) return;
ContinueDrag(eventData); ContinueDrag(eventData);
} }
@@ -404,9 +412,9 @@ namespace Minigames.StatueDressup.DragDrop
/// </summary> /// </summary>
public void OnEndDrag(PointerEventData eventData) public void OnEndDrag(PointerEventData eventData)
{ {
if (!isDragging) return; if (!_isDragging) return;
dragStarted = false; _dragStarted = false;
EndDrag(eventData); EndDrag(eventData);
} }

View File

@@ -0,0 +1,288 @@
using Core;
using UnityEngine;
using UnityEngine.UI;
using Minigames.StatueDressup.DragDrop;
namespace Minigames.StatueDressup.UI
{
/// <summary>
/// UI panel for editing a placed decoration's scale and rotation.
/// Shows sliders for scale (0.1x - 2x) and rotation (-180° to 180°).
/// Changes are applied immediately to the decoration's transform.
/// </summary>
public class DecorationEditUI : MonoBehaviour
{
[Header("UI References")]
[SerializeField] private Slider scaleSlider;
[SerializeField] private Slider rotationSlider;
[SerializeField] private Button confirmButton;
[SerializeField] private Button resetButton;
[SerializeField] private CanvasGroup canvasGroup;
[Header("Slider Ranges")]
[SerializeField] private float minScale = 0.1f;
[SerializeField] private float maxScale = 2.0f;
[SerializeField] private float minRotation = -180f;
[SerializeField] private float maxRotation = 180f;
private DecorationDraggableInstance _targetDecoration;
private RectTransform _rectTransform;
private float _originalRotation;
private bool _isInitialized;
private void Awake()
{
// Get RectTransform
_rectTransform = GetComponent<RectTransform>();
// Ensure canvas group exists
if (canvasGroup == null)
{
canvasGroup = GetComponent<CanvasGroup>();
if (canvasGroup == null)
{
canvasGroup = gameObject.AddComponent<CanvasGroup>();
}
}
// Setup slider ranges
if (scaleSlider != null)
{
scaleSlider.minValue = minScale;
scaleSlider.maxValue = maxScale;
scaleSlider.onValueChanged.AddListener(OnScaleChanged);
}
if (rotationSlider != null)
{
rotationSlider.minValue = minRotation;
rotationSlider.maxValue = maxRotation;
rotationSlider.onValueChanged.AddListener(OnRotationChanged);
}
// Setup buttons
if (confirmButton != null)
{
confirmButton.onClick.AddListener(OnConfirm);
}
if (resetButton != null)
{
resetButton.onClick.AddListener(OnReset);
}
// Start hidden
gameObject.SetActive(false);
_isInitialized = true;
}
private void OnDestroy()
{
// Clean up listeners
if (scaleSlider != null)
{
scaleSlider.onValueChanged.RemoveListener(OnScaleChanged);
}
if (rotationSlider != null)
{
rotationSlider.onValueChanged.RemoveListener(OnRotationChanged);
}
if (confirmButton != null)
{
confirmButton.onClick.RemoveListener(OnConfirm);
}
if (resetButton != null)
{
resetButton.onClick.RemoveListener(OnReset);
}
}
/// <summary>
/// Show the edit UI for the given decoration
/// </summary>
public void Show(DecorationDraggableInstance decoration)
{
if (!_isInitialized)
{
Logging.Error("[DecorationEditUI] Attempted to show before initialization!");
return;
}
if (decoration == null)
{
Logging.Error("[DecorationEditUI] Cannot show edit UI - decoration is null!");
return;
}
_targetDecoration = decoration;
// Store original rotation for reference
_originalRotation = decoration.transform.localEulerAngles.z;
// Normalize rotation to -180 to 180 range
if (_originalRotation > 180f)
{
_originalRotation -= 360f;
}
// Initialize sliders from current transform values
if (scaleSlider != null)
{
// Use X component for uniform scale
float currentScale = decoration.transform.localScale.x;
scaleSlider.value = Mathf.Clamp(currentScale, minScale, maxScale);
}
if (rotationSlider != null)
{
rotationSlider.value = Mathf.Clamp(_originalRotation, minRotation, maxRotation);
}
// Disable decoration raycasts during editing
CanvasGroup decorationCanvasGroup = decoration.GetComponent<CanvasGroup>();
if (decorationCanvasGroup != null)
{
decorationCanvasGroup.blocksRaycasts = false;
}
// Position UI centered over the decoration (context menu style)
PositionOverDecoration(decoration);
// Show UI immediately
gameObject.SetActive(true);
if (canvasGroup != null)
{
canvasGroup.alpha = 1f;
}
Logging.Debug($"[DecorationEditUI] Showing edit UI for: {decoration.Data?.DecorationName}");
}
/// <summary>
/// Position the UI centered over the decoration (context menu style)
/// </summary>
private void PositionOverDecoration(DecorationDraggableInstance decoration)
{
if (_rectTransform == null || decoration == null) return;
// Get decoration's world position
Vector3 decorationWorldPos = decoration.transform.position;
// Convert to canvas space if using screen space overlay
Canvas canvas = GetComponentInParent<Canvas>();
if (canvas != null && canvas.renderMode == RenderMode.ScreenSpaceOverlay)
{
// For overlay canvas, world position is already correct
_rectTransform.position = decorationWorldPos;
}
else if (canvas != null)
{
// For other canvas modes, convert properly
RectTransformUtility.ScreenPointToLocalPointInRectangle(
canvas.transform as RectTransform,
RectTransformUtility.WorldToScreenPoint(canvas.worldCamera, decorationWorldPos),
canvas.worldCamera,
out Vector2 localPoint
);
_rectTransform.localPosition = localPoint;
}
Logging.Debug($"[DecorationEditUI] Positioned at decoration location: {decorationWorldPos}");
}
/// <summary>
/// Hide the edit UI
/// </summary>
public void Hide()
{
if (_targetDecoration != null)
{
// Re-enable decoration raycasts
CanvasGroup decorationCanvasGroup = _targetDecoration.GetComponent<CanvasGroup>();
if (decorationCanvasGroup != null)
{
decorationCanvasGroup.blocksRaycasts = true;
}
}
_targetDecoration = null;
gameObject.SetActive(false);
Logging.Debug("[DecorationEditUI] Edit UI hidden");
}
/// <summary>
/// Handle scale slider change
/// </summary>
private void OnScaleChanged(float value)
{
if (_targetDecoration == null) return;
// Apply uniform scale (X, Y, Z all the same)
_targetDecoration.transform.localScale = Vector3.one * value;
}
/// <summary>
/// Handle rotation slider change
/// </summary>
private void OnRotationChanged(float value)
{
if (_targetDecoration == null) return;
// Apply Z rotation only
_targetDecoration.transform.localEulerAngles = new Vector3(0f, 0f, value);
}
/// <summary>
/// Handle confirm button - save changes and close
/// </summary>
private void OnConfirm()
{
if (_targetDecoration != null)
{
// Trigger auto-save through the controller
var controller = Controllers.StatueDecorationController.Instance;
if (controller != null)
{
// The controller's RegisterDecoration already triggers SaveStatueState
// Since the decoration is already registered, we just need to trigger a save
// This happens automatically on the next RegisterDecoration/UnregisterDecoration call
Logging.Debug("[DecorationEditUI] Changes confirmed - will be auto-saved");
}
}
Hide();
}
/// <summary>
/// Handle reset button - restore original values
/// </summary>
private void OnReset()
{
if (_targetDecoration == null) return;
// Reset to authored size (scale 1.0) and 0 rotation
float defaultScale = 1.0f;
float defaultRotation = 0f;
if (scaleSlider != null)
{
scaleSlider.value = defaultScale;
}
if (rotationSlider != null)
{
rotationSlider.value = defaultRotation;
}
// Values are applied through the slider callbacks
Logging.Debug("[DecorationEditUI] Reset to defaults");
}
}
}

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 7f3e2a1b9c4d5e6f7a8b9c0d1e2f3a4b
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant: