(client) feat:实现掉落物,UI显示,维度

This commit is contained in:
m0_75251201
2025-08-27 13:56:22 +08:00
parent f04c89046b
commit 0c99e2beee
46 changed files with 6150 additions and 1809 deletions

View File

@ -76,6 +76,7 @@ PrefabInstance:
- {fileID: 7300440714681954677, guid: 6cd8b01a0f57372438dc30c864ae1530, type: 3}
- {fileID: 1724818962207668775, guid: 6cd8b01a0f57372438dc30c864ae1530, type: 3}
- {fileID: 1550000129210799929, guid: 6cd8b01a0f57372438dc30c864ae1530, type: 3}
- {fileID: 5281521133329697568, guid: 6cd8b01a0f57372438dc30c864ae1530, type: 3}
m_RemovedGameObjects: []
m_AddedGameObjects: []
m_AddedComponents:
@ -89,17 +90,6 @@ PrefabInstance:
insertIndex: 4
addedObject: {fileID: 6245381882962021176}
m_SourcePrefab: {fileID: 100100000, guid: 6cd8b01a0f57372438dc30c864ae1530, type: 3}
--- !u!114 &473404334762913218 stripped
MonoBehaviour:
m_CorrespondingSourceObject: {fileID: 7296562035276564141, guid: 6cd8b01a0f57372438dc30c864ae1530, type: 3}
m_PrefabInstance: {fileID: 7193170239846001519}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: e33d58195dd8450a9ec468ede64c8635, type: 3}
m_Name:
m_EditorClassIdentifier:
--- !u!114 &1196523683669800718 stripped
MonoBehaviour:
m_CorrespondingSourceObject: {fileID: 8307348883874536545, guid: 6cd8b01a0f57372438dc30c864ae1530, type: 3}
@ -116,6 +106,17 @@ GameObject:
m_CorrespondingSourceObject: {fileID: 2838206730318674270, guid: 6cd8b01a0f57372438dc30c864ae1530, type: 3}
m_PrefabInstance: {fileID: 7193170239846001519}
m_PrefabAsset: {fileID: 0}
--- !u!114 &5615006624229444611 stripped
MonoBehaviour:
m_CorrespondingSourceObject: {fileID: 3332598847335032684, guid: 6cd8b01a0f57372438dc30c864ae1530, type: 3}
m_PrefabInstance: {fileID: 7193170239846001519}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 8035315966857772658}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: b20b1846b9ef47db83c2ac8c4c4e82cb, type: 3}
m_Name:
m_EditorClassIdentifier:
--- !u!212 &6103973223718413091 stripped
SpriteRenderer:
m_CorrespondingSourceObject: {fileID: 3992139212329961548, guid: 6cd8b01a0f57372438dc30c864ae1530, type: 3}
@ -141,11 +142,12 @@ MonoBehaviour:
animatorPrefab: {fileID: 2113064398104960506, guid: ea9af70ce0f4c8b4a9de58ac63074156, type: 3}
imagePrefab: {fileID: 1922746734790246249, guid: a6657f26d735fab4690c8185980fda29, type: 3}
healthBarPrefab: {fileID: 1196523683669800718}
visionRangeDetector: {fileID: 473404334762913218}
entityPrefab: {fileID: 5615006624229444611}
direction: {x: 0, y: 0, z: 0}
body: {fileID: 4949477718940635697}
affiliation:
canSelect: 1
currentDimensionId:
_hitBarUIShowTime: 5
--- !u!114 &6487788869574860317
MonoBehaviour:

View File

@ -71,6 +71,7 @@ PrefabInstance:
m_RemovedComponents:
- {fileID: 7300440714681954677, guid: 6cd8b01a0f57372438dc30c864ae1530, type: 3}
- {fileID: 4717642781780051128, guid: 6cd8b01a0f57372438dc30c864ae1530, type: 3}
- {fileID: 5281521133329697568, guid: 6cd8b01a0f57372438dc30c864ae1530, type: 3}
m_RemovedGameObjects:
- {fileID: 1328271255896522146, guid: 6cd8b01a0f57372438dc30c864ae1530, type: 3}
- {fileID: 6276067436382167109, guid: 6cd8b01a0f57372438dc30c864ae1530, type: 3}
@ -100,10 +101,12 @@ MonoBehaviour:
animatorPrefab: {fileID: 2113064398104960506, guid: ea9af70ce0f4c8b4a9de58ac63074156, type: 3}
imagePrefab: {fileID: 1922746734790246249, guid: a6657f26d735fab4690c8185980fda29, type: 3}
healthBarPrefab: {fileID: 0}
entityPrefab: {fileID: 8687677644466399534}
direction: {x: 0, y: 0, z: 0}
body: {fileID: 8200005766896563996}
affiliation:
canSelect: 1
currentDimensionId:
_hitBarUIShowTime: 5
bulletSource: {fileID: 0}
lifeTime: 10
@ -112,3 +115,14 @@ GameObject:
m_CorrespondingSourceObject: {fileID: 2838206730318674270, guid: 6cd8b01a0f57372438dc30c864ae1530, type: 3}
m_PrefabInstance: {fileID: 6246229038671744578}
m_PrefabAsset: {fileID: 0}
--- !u!114 &8687677644466399534 stripped
MonoBehaviour:
m_CorrespondingSourceObject: {fileID: 3332598847335032684, guid: 6cd8b01a0f57372438dc30c864ae1530, type: 3}
m_PrefabInstance: {fileID: 6246229038671744578}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 6557095110834133855}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: b20b1846b9ef47db83c2ac8c4c4e82cb, type: 3}
m_Name:
m_EditorClassIdentifier:

View File

@ -60,7 +60,8 @@ PrefabInstance:
propertyPath: entity
value:
objectReference: {fileID: 1108911649520063592}
m_RemovedComponents: []
m_RemovedComponents:
- {fileID: 5281521133329697568, guid: 6cd8b01a0f57372438dc30c864ae1530, type: 3}
m_RemovedGameObjects: []
m_AddedGameObjects: []
m_AddedComponents:
@ -88,26 +89,27 @@ MonoBehaviour:
animatorPrefab: {fileID: 2113064398104960506, guid: ea9af70ce0f4c8b4a9de58ac63074156, type: 3}
imagePrefab: {fileID: 1922746734790246249, guid: a6657f26d735fab4690c8185980fda29, type: 3}
healthBarPrefab: {fileID: 8215007830330368681}
visionRangeDetector: {fileID: 7208762515041450085}
entityPrefab: {fileID: 3420474218334607780}
direction: {x: 0, y: 0, z: 0}
body: {fileID: 2750404322221410198}
affiliation:
canSelect: 1
currentDimensionId:
_hitBarUIShowTime: 5
--- !u!1 &2750404322221410198 stripped
GameObject:
m_CorrespondingSourceObject: {fileID: 2838206730318674270, guid: 6cd8b01a0f57372438dc30c864ae1530, type: 3}
m_PrefabInstance: {fileID: 92380775595425480}
m_PrefabAsset: {fileID: 0}
--- !u!114 &7208762515041450085 stripped
--- !u!114 &3420474218334607780 stripped
MonoBehaviour:
m_CorrespondingSourceObject: {fileID: 7296562035276564141, guid: 6cd8b01a0f57372438dc30c864ae1530, type: 3}
m_CorrespondingSourceObject: {fileID: 3332598847335032684, guid: 6cd8b01a0f57372438dc30c864ae1530, type: 3}
m_PrefabInstance: {fileID: 92380775595425480}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 0}
m_GameObject: {fileID: 943601596972592085}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: e33d58195dd8450a9ec468ede64c8635, type: 3}
m_Script: {fileID: 11500000, guid: b20b1846b9ef47db83c2ac8c4c4e82cb, type: 3}
m_Name:
m_EditorClassIdentifier:
--- !u!114 &8215007830330368681 stripped

View File

@ -98,6 +98,7 @@ GameObject:
- component: {fileID: 697189026367054479}
- component: {fileID: 3332598847335032684}
- component: {fileID: 1550000129210799929}
- component: {fileID: 5281521133329697568}
- component: {fileID: 1724818962207668775}
- component: {fileID: 4717642781780051128}
m_Layer: 6
@ -137,7 +138,7 @@ MonoBehaviour:
m_Script: {fileID: 11500000, guid: b20b1846b9ef47db83c2ac8c4c4e82cb, type: 3}
m_Name:
m_EditorClassIdentifier:
entity: {fileID: 0}
entity: {fileID: 5281521133329697568}
outline: {fileID: 1550000129210799929}
--- !u!114 &1550000129210799929
MonoBehaviour:
@ -156,7 +157,29 @@ MonoBehaviour:
outlineRenderer: {fileID: 3992139212329961548}
outlineCollider: {fileID: 1724818962207668775}
progressBarPrefab: {fileID: 8307348883874536545}
entity: {fileID: 0}
entity: {fileID: 5281521133329697568}
--- !u!114 &5281521133329697568
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 887327274103887133}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: fbde354e0bcc4409b3378ee9b698ddc0, type: 3}
m_Name:
m_EditorClassIdentifier:
animatorPrefab: {fileID: 2113064398104960506, guid: ea9af70ce0f4c8b4a9de58ac63074156, type: 3}
imagePrefab: {fileID: 1922746734790246249, guid: a6657f26d735fab4690c8185980fda29, type: 3}
healthBarPrefab: {fileID: 8307348883874536545}
entityPrefab: {fileID: 3332598847335032684}
direction: {x: 0, y: 0, z: 0}
body: {fileID: 2838206730318674270}
affiliation:
canSelect: 1
currentDimensionId:
_hitBarUIShowTime: 5
--- !u!70 &1724818962207668775
CapsuleCollider2D:
m_ObjectHideFlags: 0

View File

@ -0,0 +1,123 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!1001 &2380275988296954650
PrefabInstance:
m_ObjectHideFlags: 0
serializedVersion: 2
m_Modification:
serializedVersion: 3
m_TransformParent: {fileID: 0}
m_Modifications:
- target: {fileID: 697189026367054479, guid: 6cd8b01a0f57372438dc30c864ae1530, type: 3}
propertyPath: m_LocalPosition.x
value: 0
objectReference: {fileID: 0}
- target: {fileID: 697189026367054479, guid: 6cd8b01a0f57372438dc30c864ae1530, type: 3}
propertyPath: m_LocalPosition.y
value: 0
objectReference: {fileID: 0}
- target: {fileID: 697189026367054479, guid: 6cd8b01a0f57372438dc30c864ae1530, type: 3}
propertyPath: m_LocalPosition.z
value: 0
objectReference: {fileID: 0}
- target: {fileID: 697189026367054479, guid: 6cd8b01a0f57372438dc30c864ae1530, type: 3}
propertyPath: m_LocalRotation.w
value: 1
objectReference: {fileID: 0}
- target: {fileID: 697189026367054479, guid: 6cd8b01a0f57372438dc30c864ae1530, type: 3}
propertyPath: m_LocalRotation.x
value: 0
objectReference: {fileID: 0}
- target: {fileID: 697189026367054479, guid: 6cd8b01a0f57372438dc30c864ae1530, type: 3}
propertyPath: m_LocalRotation.y
value: 0
objectReference: {fileID: 0}
- target: {fileID: 697189026367054479, guid: 6cd8b01a0f57372438dc30c864ae1530, type: 3}
propertyPath: m_LocalRotation.z
value: 0
objectReference: {fileID: 0}
- target: {fileID: 697189026367054479, guid: 6cd8b01a0f57372438dc30c864ae1530, type: 3}
propertyPath: m_LocalEulerAnglesHint.x
value: 0
objectReference: {fileID: 0}
- target: {fileID: 697189026367054479, guid: 6cd8b01a0f57372438dc30c864ae1530, type: 3}
propertyPath: m_LocalEulerAnglesHint.y
value: 0
objectReference: {fileID: 0}
- target: {fileID: 697189026367054479, guid: 6cd8b01a0f57372438dc30c864ae1530, type: 3}
propertyPath: m_LocalEulerAnglesHint.z
value: 0
objectReference: {fileID: 0}
- target: {fileID: 887327274103887133, guid: 6cd8b01a0f57372438dc30c864ae1530, type: 3}
propertyPath: m_Name
value: PickupPrefab Variant
objectReference: {fileID: 0}
- target: {fileID: 1550000129210799929, guid: 6cd8b01a0f57372438dc30c864ae1530, type: 3}
propertyPath: entity
value:
objectReference: {fileID: 3102709554251180267}
- target: {fileID: 1550000129210799929, guid: 6cd8b01a0f57372438dc30c864ae1530, type: 3}
propertyPath: progressBarPrefab
value:
objectReference: {fileID: 0}
- target: {fileID: 1724818962207668775, guid: 6cd8b01a0f57372438dc30c864ae1530, type: 3}
propertyPath: m_IsTrigger
value: 1
objectReference: {fileID: 0}
- target: {fileID: 3332598847335032684, guid: 6cd8b01a0f57372438dc30c864ae1530, type: 3}
propertyPath: entity
value:
objectReference: {fileID: 3102709554251180267}
m_RemovedComponents:
- {fileID: 5281521133329697568, guid: 6cd8b01a0f57372438dc30c864ae1530, type: 3}
m_RemovedGameObjects:
- {fileID: 1328271255896522146, guid: 6cd8b01a0f57372438dc30c864ae1530, type: 3}
m_AddedGameObjects: []
m_AddedComponents:
- targetCorrespondingSourceObject: {fileID: 887327274103887133, guid: 6cd8b01a0f57372438dc30c864ae1530, type: 3}
insertIndex: 3
addedObject: {fileID: 3102709554251180267}
m_SourcePrefab: {fileID: 100100000, guid: 6cd8b01a0f57372438dc30c864ae1530, type: 3}
--- !u!1 &462504746097347140 stripped
GameObject:
m_CorrespondingSourceObject: {fileID: 2838206730318674270, guid: 6cd8b01a0f57372438dc30c864ae1530, type: 3}
m_PrefabInstance: {fileID: 2380275988296954650}
m_PrefabAsset: {fileID: 0}
--- !u!114 &1096543602564338806 stripped
MonoBehaviour:
m_CorrespondingSourceObject: {fileID: 3332598847335032684, guid: 6cd8b01a0f57372438dc30c864ae1530, type: 3}
m_PrefabInstance: {fileID: 2380275988296954650}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 3267391294614185479}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: b20b1846b9ef47db83c2ac8c4c4e82cb, type: 3}
m_Name:
m_EditorClassIdentifier:
--- !u!1 &3267391294614185479 stripped
GameObject:
m_CorrespondingSourceObject: {fileID: 887327274103887133, guid: 6cd8b01a0f57372438dc30c864ae1530, type: 3}
m_PrefabInstance: {fileID: 2380275988296954650}
m_PrefabAsset: {fileID: 0}
--- !u!114 &3102709554251180267
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 3267391294614185479}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 4e65cb3d0f8440c599399cefd9a3a5d7, type: 3}
m_Name:
m_EditorClassIdentifier:
animatorPrefab: {fileID: 2113064398104960506, guid: ea9af70ce0f4c8b4a9de58ac63074156, type: 3}
imagePrefab: {fileID: 1922746734790246249, guid: a6657f26d735fab4690c8185980fda29, type: 3}
healthBarPrefab: {fileID: 0}
entityPrefab: {fileID: 1096543602564338806}
direction: {x: 0, y: 0, z: 0}
body: {fileID: 462504746097347140}
affiliation:
canSelect: 0
currentDimensionId:
_hitBarUIShowTime: 5

View File

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

View File

@ -0,0 +1,565 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!1 &1030546024980288463
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 1157947551238829547}
- component: {fileID: 5463992534135031964}
- component: {fileID: 4239866054256778730}
- component: {fileID: 39290904923667451}
- component: {fileID: 9024135780612969828}
m_Layer: 5
m_Name: Equipment
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!224 &1157947551238829547
RectTransform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1030546024980288463}
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: 3019988288342535868}
- {fileID: 7721553852364159343}
- {fileID: 5107399522308016876}
- {fileID: 8656654474110430578}
m_Father: {fileID: 0}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0}
m_AnchorMax: {x: 0, y: 0}
m_AnchoredPosition: {x: 0, y: 0}
m_SizeDelta: {x: 44, y: 44}
m_Pivot: {x: 0.5, y: 0.5}
--- !u!222 &5463992534135031964
CanvasRenderer:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1030546024980288463}
m_CullTransparentMesh: 1
--- !u!114 &4239866054256778730
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1030546024980288463}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3}
m_Name:
m_EditorClassIdentifier:
m_Material: {fileID: 0}
m_Color: {r: 0.26415092, g: 0.26415092, b: 0.26415092, a: 1}
m_RaycastTarget: 1
m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0}
m_Maskable: 1
m_OnCullStateChanged:
m_PersistentCalls:
m_Calls: []
m_Sprite: {fileID: 0}
m_Type: 0
m_PreserveAspect: 0
m_FillCenter: 1
m_FillMethod: 4
m_FillAmount: 1
m_FillClockwise: 1
m_FillOrigin: 0
m_UseSpriteMesh: 0
m_PixelsPerUnitMultiplier: 1
--- !u!114 &39290904923667451
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1030546024980288463}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 7d651a3517184abcb4aff78629eb7946, type: 3}
m_Name:
m_EditorClassIdentifier:
textureUI: {fileID: 4546646434353196358}
countUI: {fileID: 2838284958729559819}
nameUI: {fileID: 7621879387603348285}
selectedOutline: {fileID: 8911733408486196626}
--- !u!114 &9024135780612969828
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1030546024980288463}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 4e29b1a8efbd4b44bb3f3716e73f07ff, type: 3}
m_Name:
m_EditorClassIdentifier:
m_Navigation:
m_Mode: 3
m_WrapAround: 0
m_SelectOnUp: {fileID: 0}
m_SelectOnDown: {fileID: 0}
m_SelectOnLeft: {fileID: 0}
m_SelectOnRight: {fileID: 0}
m_Transition: 1
m_Colors:
m_NormalColor: {r: 1, g: 1, b: 1, a: 1}
m_HighlightedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1}
m_PressedColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1}
m_SelectedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1}
m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608}
m_ColorMultiplier: 1
m_FadeDuration: 0.1
m_SpriteState:
m_HighlightedSprite: {fileID: 0}
m_PressedSprite: {fileID: 0}
m_SelectedSprite: {fileID: 0}
m_DisabledSprite: {fileID: 0}
m_AnimationTriggers:
m_NormalTrigger: Normal
m_HighlightedTrigger: Highlighted
m_PressedTrigger: Pressed
m_SelectedTrigger: Selected
m_DisabledTrigger: Disabled
m_Interactable: 1
m_TargetGraphic: {fileID: 4239866054256778730}
m_OnClick:
m_PersistentCalls:
m_Calls: []
--- !u!1 &1322051136596624039
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 7721553852364159343}
- component: {fileID: 2363982704846067834}
- component: {fileID: 7621879387603348285}
m_Layer: 5
m_Name: name
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!224 &7721553852364159343
RectTransform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1322051136596624039}
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: []
m_Father: {fileID: 1157947551238829547}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0.5, y: 1}
m_AnchorMax: {x: 0.5, y: 1}
m_AnchoredPosition: {x: 0, y: 0}
m_SizeDelta: {x: 40, y: 20}
m_Pivot: {x: 0.5, y: 0.5}
--- !u!222 &2363982704846067834
CanvasRenderer:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1322051136596624039}
m_CullTransparentMesh: 1
--- !u!114 &7621879387603348285
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1322051136596624039}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: f4688fdb7df04437aeb418b961361dc5, type: 3}
m_Name:
m_EditorClassIdentifier:
m_Material: {fileID: 0}
m_Color: {r: 1, g: 1, b: 1, a: 1}
m_RaycastTarget: 1
m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0}
m_Maskable: 1
m_OnCullStateChanged:
m_PersistentCalls:
m_Calls: []
m_text: "\u7269\u54C1\u540D\u79F0"
m_isRightToLeft: 0
m_fontAsset: {fileID: 11400000, guid: 317edb274e9c5144a9916937bdbf7716, type: 2}
m_sharedMaterial: {fileID: -1361428157011412921, guid: 317edb274e9c5144a9916937bdbf7716, type: 2}
m_fontSharedMaterials: []
m_fontMaterial: {fileID: 0}
m_fontMaterials: []
m_fontColor32:
serializedVersion: 2
rgba: 4292598747
m_fontColor: {r: 0.8584906, g: 0.8584906, b: 0.8584906, a: 1}
m_enableVertexGradient: 0
m_colorMode: 3
m_fontColorGradient:
topLeft: {r: 1, g: 1, b: 1, a: 1}
topRight: {r: 1, g: 1, b: 1, a: 1}
bottomLeft: {r: 1, g: 1, b: 1, a: 1}
bottomRight: {r: 1, g: 1, b: 1, a: 1}
m_fontColorGradientPreset: {fileID: 0}
m_spriteAsset: {fileID: 0}
m_tintAllSprites: 0
m_StyleSheet: {fileID: 0}
m_TextStyleHashCode: -1183493901
m_overrideHtmlColors: 0
m_faceColor:
serializedVersion: 2
rgba: 4294967295
m_fontSize: 12
m_fontSizeBase: 12
m_fontWeight: 400
m_enableAutoSizing: 0
m_fontSizeMin: 18
m_fontSizeMax: 72
m_fontStyle: 0
m_HorizontalAlignment: 2
m_VerticalAlignment: 512
m_textAlignment: 65535
m_characterSpacing: 0
m_wordSpacing: 0
m_lineSpacing: 0
m_lineSpacingMax: 0
m_paragraphSpacing: 0
m_charWidthMaxAdj: 0
m_TextWrappingMode: 0
m_wordWrappingRatios: 0.4
m_overflowMode: 0
m_linkedTextComponent: {fileID: 0}
parentLinkedComponent: {fileID: 0}
m_enableKerning: 0
m_ActiveFontFeatures: 6e72656b
m_enableExtraPadding: 0
checkPaddingRequired: 0
m_isRichText: 1
m_EmojiFallbackSupport: 1
m_parseCtrlCharacters: 1
m_isOrthographic: 1
m_isCullingEnabled: 0
m_horizontalMapping: 0
m_verticalMapping: 0
m_uvLineOffset: 0
m_geometrySortingOrder: 0
m_IsTextObjectScaleStatic: 0
m_VertexBufferAutoSizeReduction: 0
m_useMaxVisibleDescender: 1
m_pageToDisplay: 1
m_margin: {x: 0, y: 0, z: 0, w: 0}
m_isUsingLegacyAnimationComponent: 0
m_isVolumetricText: 0
m_hasFontAssetChanged: 0
m_baseMaterial: {fileID: 0}
m_maskOffset: {x: 0, y: 0, z: 0, w: 0}
--- !u!1 &3209011714410963536
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 3019988288342535868}
- component: {fileID: 7568224505238899076}
- component: {fileID: 4546646434353196358}
m_Layer: 5
m_Name: texture
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!224 &3019988288342535868
RectTransform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 3209011714410963536}
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: []
m_Father: {fileID: 1157947551238829547}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0}
m_AnchorMax: {x: 1, y: 1}
m_AnchoredPosition: {x: 0, y: 0}
m_SizeDelta: {x: -4, y: -4}
m_Pivot: {x: 0.5, y: 0.5}
--- !u!222 &7568224505238899076
CanvasRenderer:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 3209011714410963536}
m_CullTransparentMesh: 1
--- !u!114 &4546646434353196358
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 3209011714410963536}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3}
m_Name:
m_EditorClassIdentifier:
m_Material: {fileID: 0}
m_Color: {r: 1, g: 1, b: 1, a: 1}
m_RaycastTarget: 1
m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0}
m_Maskable: 1
m_OnCullStateChanged:
m_PersistentCalls:
m_Calls: []
m_Sprite: {fileID: 21300000, guid: 620e16cb0aec3684db9ef80bdcc85695, type: 3}
m_Type: 0
m_PreserveAspect: 0
m_FillCenter: 1
m_FillMethod: 4
m_FillAmount: 1
m_FillClockwise: 1
m_FillOrigin: 0
m_UseSpriteMesh: 0
m_PixelsPerUnitMultiplier: 1
--- !u!1 &8911733408486196626
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 8656654474110430578}
- component: {fileID: 407204586558773978}
- component: {fileID: 1196719146505742501}
m_Layer: 5
m_Name: select
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!224 &8656654474110430578
RectTransform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 8911733408486196626}
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: []
m_Father: {fileID: 1157947551238829547}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0}
m_AnchorMax: {x: 1, y: 1}
m_AnchoredPosition: {x: 0, y: 0}
m_SizeDelta: {x: 2, y: 2}
m_Pivot: {x: 0.5, y: 0.5}
--- !u!222 &407204586558773978
CanvasRenderer:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 8911733408486196626}
m_CullTransparentMesh: 1
--- !u!114 &1196719146505742501
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 8911733408486196626}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3}
m_Name:
m_EditorClassIdentifier:
m_Material: {fileID: 0}
m_Color: {r: 1, g: 1, b: 1, a: 1}
m_RaycastTarget: 1
m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0}
m_Maskable: 1
m_OnCullStateChanged:
m_PersistentCalls:
m_Calls: []
m_Sprite: {fileID: 21300000, guid: 811d3d3bfa653494784ee8ed56956471, type: 3}
m_Type: 1
m_PreserveAspect: 0
m_FillCenter: 1
m_FillMethod: 4
m_FillAmount: 1
m_FillClockwise: 1
m_FillOrigin: 0
m_UseSpriteMesh: 0
m_PixelsPerUnitMultiplier: 1
--- !u!1 &9083725956021694610
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 5107399522308016876}
- component: {fileID: 3215760353359771558}
- component: {fileID: 2838284958729559819}
m_Layer: 5
m_Name: count
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!224 &5107399522308016876
RectTransform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 9083725956021694610}
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: []
m_Father: {fileID: 1157947551238829547}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 1, y: 0}
m_AnchorMax: {x: 1, y: 0}
m_AnchoredPosition: {x: -10, y: 5}
m_SizeDelta: {x: 20, y: 15}
m_Pivot: {x: 0.5, y: 0.5}
--- !u!222 &3215760353359771558
CanvasRenderer:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 9083725956021694610}
m_CullTransparentMesh: 1
--- !u!114 &2838284958729559819
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 9083725956021694610}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: f4688fdb7df04437aeb418b961361dc5, type: 3}
m_Name:
m_EditorClassIdentifier:
m_Material: {fileID: 0}
m_Color: {r: 1, g: 1, b: 1, a: 1}
m_RaycastTarget: 1
m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0}
m_Maskable: 1
m_OnCullStateChanged:
m_PersistentCalls:
m_Calls: []
m_text: 1
m_isRightToLeft: 0
m_fontAsset: {fileID: 11400000, guid: 317edb274e9c5144a9916937bdbf7716, type: 2}
m_sharedMaterial: {fileID: -1361428157011412921, guid: 317edb274e9c5144a9916937bdbf7716, type: 2}
m_fontSharedMaterials: []
m_fontMaterial: {fileID: 0}
m_fontMaterials: []
m_fontColor32:
serializedVersion: 2
rgba: 4292598747
m_fontColor: {r: 0.8584906, g: 0.8584906, b: 0.8584906, a: 1}
m_enableVertexGradient: 0
m_colorMode: 3
m_fontColorGradient:
topLeft: {r: 0, g: 0.16973758, b: 1, a: 1}
topRight: {r: 1, g: 1, b: 1, a: 1}
bottomLeft: {r: 1, g: 1, b: 1, a: 1}
bottomRight: {r: 1, g: 1, b: 1, a: 1}
m_fontColorGradientPreset: {fileID: 0}
m_spriteAsset: {fileID: 0}
m_tintAllSprites: 0
m_StyleSheet: {fileID: 0}
m_TextStyleHashCode: -1183493901
m_overrideHtmlColors: 0
m_faceColor:
serializedVersion: 2
rgba: 4294967295
m_fontSize: 12
m_fontSizeBase: 12
m_fontWeight: 400
m_enableAutoSizing: 0
m_fontSizeMin: 18
m_fontSizeMax: 72
m_fontStyle: 0
m_HorizontalAlignment: 4
m_VerticalAlignment: 512
m_textAlignment: 65535
m_characterSpacing: 0
m_wordSpacing: 0
m_lineSpacing: 0
m_lineSpacingMax: 0
m_paragraphSpacing: 0
m_charWidthMaxAdj: 0
m_TextWrappingMode: 1
m_wordWrappingRatios: 0.4
m_overflowMode: 0
m_linkedTextComponent: {fileID: 0}
parentLinkedComponent: {fileID: 0}
m_enableKerning: 0
m_ActiveFontFeatures: 6e72656b
m_enableExtraPadding: 0
checkPaddingRequired: 0
m_isRichText: 1
m_EmojiFallbackSupport: 1
m_parseCtrlCharacters: 1
m_isOrthographic: 1
m_isCullingEnabled: 0
m_horizontalMapping: 0
m_verticalMapping: 0
m_uvLineOffset: 0
m_geometrySortingOrder: 0
m_IsTextObjectScaleStatic: 0
m_VertexBufferAutoSizeReduction: 0
m_useMaxVisibleDescender: 1
m_pageToDisplay: 1
m_margin: {x: 0, y: 0, z: 0, w: 0}
m_isUsingLegacyAnimationComponent: 0
m_isVolumetricText: 0
m_hasFontAssetChanged: 0
m_baseMaterial: {fileID: 0}
m_maskOffset: {x: 0, y: 0, z: 0, w: 0}

View File

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

View File

@ -569,6 +569,81 @@ MonoBehaviour:
m_PersistentCalls:
m_Calls: []
m_IsOn: 1
--- !u!1 &675834759292362998
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 3807220599302013032}
- component: {fileID: 3166955263631569040}
- component: {fileID: 8009962731176257063}
m_Layer: 5
m_Name: Checkmark
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!224 &3807220599302013032
RectTransform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 675834759292362998}
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: []
m_Father: {fileID: 1368576192826021356}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0.5, y: 0.5}
m_AnchorMax: {x: 0.5, y: 0.5}
m_AnchoredPosition: {x: 0, y: 0}
m_SizeDelta: {x: 30, y: 30}
m_Pivot: {x: 0.5, y: 0.5}
--- !u!222 &3166955263631569040
CanvasRenderer:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 675834759292362998}
m_CullTransparentMesh: 1
--- !u!114 &8009962731176257063
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 675834759292362998}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3}
m_Name:
m_EditorClassIdentifier:
m_Material: {fileID: 0}
m_Color: {r: 1, g: 1, b: 1, a: 1}
m_RaycastTarget: 1
m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0}
m_Maskable: 1
m_OnCullStateChanged:
m_PersistentCalls:
m_Calls: []
m_Sprite: {fileID: 10901, guid: 0000000000000000f000000000000000, type: 0}
m_Type: 0
m_PreserveAspect: 0
m_FillCenter: 1
m_FillMethod: 4
m_FillAmount: 1
m_FillClockwise: 1
m_FillOrigin: 0
m_UseSpriteMesh: 0
m_PixelsPerUnitMultiplier: 1
--- !u!1 &731014230302852672
GameObject:
m_ObjectHideFlags: 0
@ -745,6 +820,7 @@ RectTransform:
- {fileID: 5250766324582680904}
- {fileID: 63467561189681800}
- {fileID: 588209722058685216}
- {fileID: 4382446647419696272}
- {fileID: 8372402552497025236}
- {fileID: 3582015553262914482}
- {fileID: 8669098655635635614}
@ -1857,6 +1933,82 @@ RectTransform:
m_AnchoredPosition: {x: 0, y: 0}
m_SizeDelta: {x: 0, y: 28}
m_Pivot: {x: 0.5, y: 1}
--- !u!1 &2003844502392795890
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 1368576192826021356}
- component: {fileID: 4535216129726192708}
- component: {fileID: 8370016880625545629}
m_Layer: 5
m_Name: Background
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!224 &1368576192826021356
RectTransform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 2003844502392795890}
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: 3807220599302013032}
m_Father: {fileID: 1387738332983915429}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0.5}
m_AnchorMax: {x: 0, y: 0.5}
m_AnchoredPosition: {x: 15, y: 0}
m_SizeDelta: {x: 30, y: 30}
m_Pivot: {x: 0.5, y: 0.5}
--- !u!222 &4535216129726192708
CanvasRenderer:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 2003844502392795890}
m_CullTransparentMesh: 1
--- !u!114 &8370016880625545629
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 2003844502392795890}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3}
m_Name:
m_EditorClassIdentifier:
m_Material: {fileID: 0}
m_Color: {r: 1, g: 1, b: 1, a: 1}
m_RaycastTarget: 1
m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0}
m_Maskable: 1
m_OnCullStateChanged:
m_PersistentCalls:
m_Calls: []
m_Sprite: {fileID: 10905, guid: 0000000000000000f000000000000000, type: 0}
m_Type: 1
m_PreserveAspect: 0
m_FillCenter: 1
m_FillMethod: 4
m_FillAmount: 1
m_FillClockwise: 1
m_FillOrigin: 0
m_UseSpriteMesh: 0
m_PixelsPerUnitMultiplier: 1
--- !u!1 &2521308813618324157
GameObject:
m_ObjectHideFlags: 0
@ -2291,6 +2443,128 @@ MonoBehaviour:
m_OnValueChanged:
m_PersistentCalls:
m_Calls: []
--- !u!1 &3316031743481732750
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 4382446647419696272}
m_Layer: 5
m_Name: showMiniMap
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!224 &4382446647419696272
RectTransform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 3316031743481732750}
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: 4154665771205055467}
- {fileID: 1387738332983915429}
m_Father: {fileID: 8058820546803683956}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0}
m_AnchorMax: {x: 0, y: 0}
m_AnchoredPosition: {x: 0, y: 0}
m_SizeDelta: {x: 0, y: 30}
m_Pivot: {x: 0.5, y: 0.5}
--- !u!1 &4272417468456359236
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 1387738332983915429}
- component: {fileID: 2665600169125004565}
m_Layer: 5
m_Name: Toggle
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!224 &1387738332983915429
RectTransform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 4272417468456359236}
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: 1368576192826021356}
m_Father: {fileID: 4382446647419696272}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0}
m_AnchorMax: {x: 0, y: 1}
m_AnchoredPosition: {x: 200, y: 0}
m_SizeDelta: {x: 0, y: -10}
m_Pivot: {x: 0.5, y: 0.5}
--- !u!114 &2665600169125004565
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 4272417468456359236}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 9085046f02f69544eb97fd06b6048fe2, type: 3}
m_Name:
m_EditorClassIdentifier:
m_Navigation:
m_Mode: 3
m_WrapAround: 0
m_SelectOnUp: {fileID: 0}
m_SelectOnDown: {fileID: 0}
m_SelectOnLeft: {fileID: 0}
m_SelectOnRight: {fileID: 0}
m_Transition: 1
m_Colors:
m_NormalColor: {r: 1, g: 1, b: 1, a: 1}
m_HighlightedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1}
m_PressedColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1}
m_SelectedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1}
m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608}
m_ColorMultiplier: 1
m_FadeDuration: 0.1
m_SpriteState:
m_HighlightedSprite: {fileID: 0}
m_PressedSprite: {fileID: 0}
m_SelectedSprite: {fileID: 0}
m_DisabledSprite: {fileID: 0}
m_AnimationTriggers:
m_NormalTrigger: Normal
m_HighlightedTrigger: Highlighted
m_PressedTrigger: Pressed
m_SelectedTrigger: Selected
m_DisabledTrigger: Disabled
m_Interactable: 1
m_TargetGraphic: {fileID: 8370016880625545629}
toggleTransition: 1
graphic: {fileID: 8009962731176257063}
m_Group: {fileID: 0}
onValueChanged:
m_PersistentCalls:
m_Calls: []
m_IsOn: 1
--- !u!1 &4720486499607599114
GameObject:
m_ObjectHideFlags: 0
@ -5870,6 +6144,137 @@ RectTransform:
m_CorrespondingSourceObject: {fileID: 632585612639644796, guid: 4572fd0db4eb91d4588451064f59c91b, type: 3}
m_PrefabInstance: {fileID: 3460623932033366543}
m_PrefabAsset: {fileID: 0}
--- !u!1001 &3562122742722363287
PrefabInstance:
m_ObjectHideFlags: 0
serializedVersion: 2
m_Modification:
serializedVersion: 3
m_TransformParent: {fileID: 4382446647419696272}
m_Modifications:
- target: {fileID: 27210933623785530, guid: 4572fd0db4eb91d4588451064f59c91b, type: 3}
propertyPath: m_Name
value: TextTemplate
objectReference: {fileID: 0}
- target: {fileID: 632585612639644796, guid: 4572fd0db4eb91d4588451064f59c91b, type: 3}
propertyPath: m_Pivot.x
value: 0.5
objectReference: {fileID: 0}
- target: {fileID: 632585612639644796, guid: 4572fd0db4eb91d4588451064f59c91b, type: 3}
propertyPath: m_Pivot.y
value: 1
objectReference: {fileID: 0}
- target: {fileID: 632585612639644796, guid: 4572fd0db4eb91d4588451064f59c91b, type: 3}
propertyPath: m_AnchorMax.x
value: 0
objectReference: {fileID: 0}
- target: {fileID: 632585612639644796, guid: 4572fd0db4eb91d4588451064f59c91b, type: 3}
propertyPath: m_AnchorMax.y
value: 1
objectReference: {fileID: 0}
- target: {fileID: 632585612639644796, guid: 4572fd0db4eb91d4588451064f59c91b, type: 3}
propertyPath: m_AnchorMin.x
value: 0
objectReference: {fileID: 0}
- target: {fileID: 632585612639644796, guid: 4572fd0db4eb91d4588451064f59c91b, type: 3}
propertyPath: m_AnchorMin.y
value: 0
objectReference: {fileID: 0}
- target: {fileID: 632585612639644796, guid: 4572fd0db4eb91d4588451064f59c91b, type: 3}
propertyPath: m_SizeDelta.x
value: 200
objectReference: {fileID: 0}
- target: {fileID: 632585612639644796, guid: 4572fd0db4eb91d4588451064f59c91b, type: 3}
propertyPath: m_SizeDelta.y
value: 0
objectReference: {fileID: 0}
- target: {fileID: 632585612639644796, guid: 4572fd0db4eb91d4588451064f59c91b, type: 3}
propertyPath: m_LocalPosition.x
value: 0
objectReference: {fileID: 0}
- target: {fileID: 632585612639644796, guid: 4572fd0db4eb91d4588451064f59c91b, type: 3}
propertyPath: m_LocalPosition.y
value: 0
objectReference: {fileID: 0}
- target: {fileID: 632585612639644796, guid: 4572fd0db4eb91d4588451064f59c91b, type: 3}
propertyPath: m_LocalPosition.z
value: 0
objectReference: {fileID: 0}
- target: {fileID: 632585612639644796, guid: 4572fd0db4eb91d4588451064f59c91b, type: 3}
propertyPath: m_LocalRotation.w
value: 1
objectReference: {fileID: 0}
- target: {fileID: 632585612639644796, guid: 4572fd0db4eb91d4588451064f59c91b, type: 3}
propertyPath: m_LocalRotation.x
value: 0
objectReference: {fileID: 0}
- target: {fileID: 632585612639644796, guid: 4572fd0db4eb91d4588451064f59c91b, type: 3}
propertyPath: m_LocalRotation.y
value: 0
objectReference: {fileID: 0}
- target: {fileID: 632585612639644796, guid: 4572fd0db4eb91d4588451064f59c91b, type: 3}
propertyPath: m_LocalRotation.z
value: 0
objectReference: {fileID: 0}
- target: {fileID: 632585612639644796, guid: 4572fd0db4eb91d4588451064f59c91b, type: 3}
propertyPath: m_AnchoredPosition.x
value: 100
objectReference: {fileID: 0}
- target: {fileID: 632585612639644796, guid: 4572fd0db4eb91d4588451064f59c91b, type: 3}
propertyPath: m_AnchoredPosition.y
value: 0
objectReference: {fileID: 0}
- target: {fileID: 632585612639644796, guid: 4572fd0db4eb91d4588451064f59c91b, type: 3}
propertyPath: m_LocalEulerAnglesHint.x
value: 0
objectReference: {fileID: 0}
- target: {fileID: 632585612639644796, guid: 4572fd0db4eb91d4588451064f59c91b, type: 3}
propertyPath: m_LocalEulerAnglesHint.y
value: 0
objectReference: {fileID: 0}
- target: {fileID: 632585612639644796, guid: 4572fd0db4eb91d4588451064f59c91b, type: 3}
propertyPath: m_LocalEulerAnglesHint.z
value: 0
objectReference: {fileID: 0}
- target: {fileID: 7303780691383776844, guid: 4572fd0db4eb91d4588451064f59c91b, type: 3}
propertyPath: m_text
value: "\u663E\u793A\u5C0F\u5730\u56FE"
objectReference: {fileID: 0}
- target: {fileID: 7303780691383776844, guid: 4572fd0db4eb91d4588451064f59c91b, type: 3}
propertyPath: m_fontSize
value: 25
objectReference: {fileID: 0}
- target: {fileID: 7303780691383776844, guid: 4572fd0db4eb91d4588451064f59c91b, type: 3}
propertyPath: m_fontColor.b
value: 1
objectReference: {fileID: 0}
- target: {fileID: 7303780691383776844, guid: 4572fd0db4eb91d4588451064f59c91b, type: 3}
propertyPath: m_fontColor.g
value: 1
objectReference: {fileID: 0}
- target: {fileID: 7303780691383776844, guid: 4572fd0db4eb91d4588451064f59c91b, type: 3}
propertyPath: m_fontColor.r
value: 1
objectReference: {fileID: 0}
- target: {fileID: 7303780691383776844, guid: 4572fd0db4eb91d4588451064f59c91b, type: 3}
propertyPath: m_fontSizeBase
value: 25
objectReference: {fileID: 0}
- target: {fileID: 7303780691383776844, guid: 4572fd0db4eb91d4588451064f59c91b, type: 3}
propertyPath: m_fontColor32.rgba
value: 4294967295
objectReference: {fileID: 0}
m_RemovedComponents:
- {fileID: -6983149199180571386, guid: 4572fd0db4eb91d4588451064f59c91b, type: 3}
m_RemovedGameObjects: []
m_AddedGameObjects: []
m_AddedComponents: []
m_SourcePrefab: {fileID: 100100000, guid: 4572fd0db4eb91d4588451064f59c91b, type: 3}
--- !u!224 &4154665771205055467 stripped
RectTransform:
m_CorrespondingSourceObject: {fileID: 632585612639644796, guid: 4572fd0db4eb91d4588451064f59c91b, type: 3}
m_PrefabInstance: {fileID: 3562122742722363287}
m_PrefabAsset: {fileID: 0}
--- !u!1001 &4124528537733325346
PrefabInstance:
m_ObjectHideFlags: 0

File diff suppressed because it is too large Load Diff

View File

@ -1801,6 +1801,7 @@ MonoBehaviour:
characterPrefab: {fileID: 3420474218334607780, guid: 5218adfb8e855a9459df63de8b2f323c, type: 3}
buildingPrefab: {fileID: 5615006624229444611, guid: d7b9277d8e6ac4541800044bdb0da063, type: 3}
bulletPrefab: {fileID: 8687677644466399534, guid: 29b2450a8636a104586e36333878f4d9, type: 3}
pickupPrefab: {fileID: 1096543602564338806, guid: ec84100729cd1bd4699fc15b3a09134c, type: 3}
defaultEntityPrefab: {fileID: 7975757421877276383, guid: 89661daa5f100c64783f0ad9cd37a7ff, type: 3}
--- !u!4 &2131333544
Transform:

View File

@ -1,5 +1,7 @@
using System.Collections.Generic;
using Base;
using Data;
using Managers;
using Prefab;
using Unity.VisualScripting;
using UnityEngine;
@ -74,5 +76,22 @@ namespace AI
}
}
public class AttackJob : JobBase
{
private Entity.Entity attackTarget;
protected override void UpdateJob()
{
entity.TryMove();
}
override public void StartJob(Entity.Entity target)
{
base.StartJob(target);
attackTarget =
EntityManage.Instance
.FindNearestEntityByRelation(target.currentDimensionId, target.entityPrefab, Relation.Hostile)
?.entity;
}
}
}

View File

@ -15,6 +15,7 @@ namespace Base
public float exitAnimationDuration = 1f;
public bool developerMode = false;
public bool friendlyFire = false;
public bool showMiniMap = true;
public float globalVolume = 1.0f;
public WindowMode currentWindowMode = WindowMode.Fullscreen;
public Vector2Int windowResolution = new(1920, 1080);

View File

@ -7,13 +7,18 @@ namespace CameraControl
public class CameraControl : Utils.MonoSingleton<CameraControl>, ITick, ITickUI
{
// Camera movement variables
[SerializeField] private float _zoomSpeed = 5f;
[SerializeField] private float _minZoom = 2f;
[SerializeField] private float _maxZoom = 20f;
[SerializeField] private float _focusLerpSpeed = 5f;
private Vector3 _dragOrigin;
private bool _isDragging = false;
private float _zoomSpeed = 5f;
private float _minZoom = 2f;
private float _maxZoom = 20f;
private Camera _camera;
private int dimensionId;
private string[] dimensionList;
private void OnDestroy()
@ -24,69 +29,180 @@ namespace CameraControl
protected override void OnStart()
{
// 注册场景加载事件
// 注册场景加载事件。请注意MonoSingleton中的OnStart通常由Awake调用。
// 真正的Init调用已移至Start方法以确保Program.Instance已完成其Awake阶段的初始化。
SceneManager.sceneLoaded += OnSceneLoaded;
}
// 初始化时调用一次
private void Start()
{
// 在Start中调用Init确保所有依赖的单例如Program.Instance已完成Awake阶段的初始化。
Init();
}
private void OnSceneLoaded(Scene scene, LoadSceneMode mode)
{
// 场景加载完成后调用 Init 方法
// 场景加载完成后调用 Init 方法,重新获取相机引用并初始化维度状态。
// 这确保了如果CameraControl是DontDestroyOnLoad在切换场景后也能正确工作。
Init();
}
private void Init()
{
_camera = Camera.main;
// 确保相机引用有效
if (_camera == null)
{
_camera = FindFirstObjectByType<Camera>();
_camera = Camera.main;
if (_camera == null)
{
_camera = FindFirstObjectByType<Camera>();
}
}
if (_camera == null)
{
Debug.LogError("No Camera found in the scene! CameraControl functionalities will be limited.");
return; // 如果没有相机,则无法进行后续初始化
}
// 初始化维度数据 (假设 Program.Instance 总是已初始化)
dimensionId = 0; // 默认从第一个维度开始
dimensionList = Program.Instance.Dimensions;
if (dimensionList != null && dimensionList.Length > 0)
{
SetCameraPositionForDimension(0);
}
else
{
Debug.LogWarning("Dimension list is empty or null from Program.Instance. Cannot set initial camera position for dimensions.");
}
}
public void NextDimension()
{
if (_camera == null)
{
Debug.LogWarning("Camera reference is null, cannot switch dimensions.");
return;
}
if (dimensionList == null || dimensionList.Length == 0)
{
Debug.LogWarning("Dimension list is empty.");
return;
}
// 1. 保存当前相机的真实位置到当前维度 (假设 Program.Instance 总是已初始化)
// 维度ID范围检查仍然保留因为这是数组访问的安全保障
if (dimensionId >= 0 && dimensionId < dimensionList.Length)
{
// Program.Instance 假设不会为 null
var currentDimension = Program.Instance.GetDimension(dimensionList[dimensionId]);
if (currentDimension != null)
{
currentDimension.cameraPosition = _camera.transform.position;
// Debug.Log($"Saved camera position {currentDimension.cameraPosition} for dimension {dimensionList[dimensionId]} (ID: {dimensionId})");
}
else
{
Debug.LogWarning($"Could not find dimension object for ID {dimensionId} ({dimensionList[dimensionId]}) to save camera position.");
}
}
else
{
Debug.LogWarning($"Current dimensionId ({dimensionId}) is out of bounds for saving camera position (dimensionList length: {dimensionList.Length}).");
}
// 2. 更新 dimensionId形成循环
dimensionId = (dimensionId + 1) % dimensionList.Length;
// 3. 更新相机位置到新维度
SetCameraPositionForDimension(dimensionId);
}
private void SetCameraPositionForDimension(int id)
{
if (_camera == null)
{
Debug.LogWarning("Camera reference is null, cannot set camera position.");
return;
}
if (dimensionList == null || id < 0 || id >= dimensionList.Length)
{
Debug.LogWarning($"Dimension ID {id} is out of bounds or dimension list is null/empty.");
return;
}
// Program.Instance 假设不会为 null
// 确保获取到的 Dimension 对象不为 null
var dimension = Program.Instance.GetDimension(dimensionList[id]);
if (dimension)
{
Vector3 cameraPosition = dimension.cameraPosition;
_camera.transform.position = cameraPosition;
}
else
{
Debug.LogWarning($"Dimension object for ID {id} ({dimensionList[id]}) is null. Cannot set camera position.");
}
}
public void Tick()
{
if (Program.Instance.focusedEntity)
if (_camera == null) return; // 确保相机存在
// 假设 Program.Instance 总是已初始化
if (Program.Instance.FocusedEntity)
{
// Follow the focused entity's position
var targetPosition = new Vector3(
Program.Instance.focusedEntity.Position.x,
Program.Instance.focusedEntity.Position.y,
Program.Instance.FocusedEntity.Position.x,
Program.Instance.FocusedEntity.Position.y,
_camera.transform.position.z);
// 使用 deltaTime 进行平滑的相机跟随
_camera.transform.position = Vector3.Lerp(
_camera.transform.position,
targetPosition,
Time.fixedDeltaTime * 5f);
Time.deltaTime * _focusLerpSpeed);
}
if (Input.GetKeyDown(KeyCode.Tab))
{
NextDimension();
}
}
public void TickUI()
{
if (!_camera)
if (!_camera) // 确保相机存在
return;
HandleMiddleMouseDrag();
HandleMouseZoom();
// HandleMouseZoom();
}
public void SetPosition(Vector3 position)
{
if (_camera)
_camera.transform.position = position;
else
Debug.LogWarning("Camera reference is null, cannot set position.");
}
private void HandleMiddleMouseDrag()
{
if (_camera == null) return; // 确保相机存在
// Start drag
if (Input.GetMouseButtonDown(2)) // Middle mouse button
{
_dragOrigin = _camera.ScreenToWorldPoint(Input.mousePosition);
_isDragging = true;
if (Program.Instance.focusedEntity)
// 假设 Program.Instance 总是已初始化
if (Program.Instance.FocusedEntity)
{
Program.Instance.focusedEntity.PlayerControlled = false;
Program.Instance.focusedEntity = null; // Clear focus when manually moving camera
Program.Instance.FocusedEntity.PlayerControlled = false;
Program.Instance.SetFocusedEntity(null);
}
}
@ -106,13 +222,12 @@ namespace CameraControl
private void HandleMouseZoom()
{
if (_camera == null) return; // 确保相机存在
var scroll = Input.GetAxis("Mouse ScrollWheel");
if (scroll == 0) return;
var newSize = _camera.orthographicSize - scroll * _zoomSpeed;
_camera.orthographicSize = Mathf.Clamp(newSize, _minZoom, _maxZoom);
}
}
}
}

View File

@ -6,9 +6,9 @@ namespace CameraControl
{
public void Tick()
{
if (Program.Instance.focusedEntity)
if (Program.Instance.FocusedEntity)
{
transform.position = Program.Instance.focusedEntity.transform.position + new Vector3(0, 0, -10);
transform.position = Program.Instance.FocusedEntity.transform.position + new Vector3(0, 0, -10);
}
}
}

View File

@ -0,0 +1,21 @@
namespace Data
{
public enum EventType
{
None,
SpawnCharacter,
SpawnBuilding,
SpawnBullet,
SpawnPickup,
SpawnDefaultEntity,
}
public class EventDef : Define
{
public EventType eventType = EventType.None;
public EntityDef entityDef_Character; // 用于 EventType.SpawnCharacter
public BuildingDef entityDef_Building; // 用于 EventType.SpawnBuilding
public BulletDef entityDef_Bullet; // 用于 EventType.SpawnBullet
public ItemDef entityDef_Pickup; // 用于 EventType.SpawnPickup
public EventDef() { }
}
}

View File

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 70b8a820a04c4cafad4c9b91b9d3b01d
timeCreated: 1756267922

View File

@ -10,7 +10,8 @@ namespace Data
}
public class ItemDef : Define
{
public ImageDef texture;
public float FPS = 0;
public string[] textures;
public ItemRarity rarity = ItemRarity.Common;
public int maxStack = 10; // 最大堆叠数量默认为10
public bool ssEquippable = false; // 是否可装备

View File

@ -30,7 +30,7 @@ namespace Entity
private void OnTriggerEnter2D(Collider2D other)
{
var entity = other.GetComponent<Entity>();
if (!entity || entity == bulletSource) return;
if (!entity || entity == bulletSource || entity is Pickup) return;
if (Managers.AffiliationManager.Instance.GetRelation(bulletSource.affiliation, entity.affiliation) != Relation.Friendly)
{
entity.OnHit(this);

View File

@ -1,89 +1,110 @@
using System;
using System.Linq;
using Data;
using Item;
using Managers;
using UnityEngine;
using Utils;
// 添加 System 命名空间以使用 Action
namespace Entity
{
public class Character : Entity
{
// ------------- 新增 / 修改部分 START -------------
private int _currentSelected; // 私有字段用于存储实际值
// 声明 Inventory 字段。更改为 private set 以确保 Inventory 实例只能在 Character 内部设置。
public Inventory Inventory { get; private set; }
/// <summary>
/// 当前选中的背包槽位索引。
/// 当此值被设置时,如果与旧值不同,将触发 OnCurrentSelectedChanged 事件。
/// </summary>
public int currentSelected
{
get => _currentSelected;
set
{
var maxIndex = Inventory != null && Inventory.Capacity > 0 ? Inventory.Capacity - 1 : 0;
var clampedValue = Mathf.Clamp(value, 0, maxIndex);
if (_currentSelected != clampedValue)
{
_currentSelected = clampedValue;
OnCurrentSelectedChanged?.Invoke(_currentSelected); // 触发事件
}
}
}
public Inventory Inventory { get; private set; }
/// <summary>
/// 当当前选中的槽位索引改变时触发的事件。
/// 参数:新的选中索引。
/// </summary>
public event Action<int> OnCurrentSelectedChanged;
public override void Init(EntityDef entityDef)
{
base.Init(entityDef);
// 1. 初始化背包:
// 在这里创建并初始化 Inventory 实例。
// 'this' 指的是当前 Character 实例,作为 Inventory 的拥有者。
// 容量可以根据 entityDef 或一个默认值来设定。这里使用默认值 20。
Inventory = new Inventory(this, 3);
Inventory = new Inventory(this, 3);
// (可选) 可以在此订阅背包事件,以便 Character 对背包变化做出响应,
// 例如更新角色状态、播放音效或更新UI
// Inventory.OnItemAdded += HandleItemAddedToInventory;
// Inventory.OnItemRemoved += HandleItemRemovedFromInventory;
// Inventory.OnInventoryChanged += HandleInventoryChanged;
// 初始化 currentSelected。
// 使用属性来设置,确保触发事件和范围检查
// 如果Inventory.Capacity为0则currentSelected会被钳制到0。
// 如果Inventory.Capacity为3currentSelected=0是有效值。
currentSelected = 0;
}
/// <summary>
/// 尝试将指定物品添加到角色的背包中。
/// 尝试将指定物品添加到角色的背包中。
/// </summary>
/// <param name="itemResource">要尝试添加的物品资源。</param>
/// <param name="quantity">要尝试添加的数量。</param>
/// <returns>未成功添加到背包的物品数量。
/// 如果返回0表示所有物品都成功添加
/// 如果返回quantity表示未能添加任何物品
/// 如果返回一个介于0和quantity之间的值表示部分物品被添加。</returns>
public int TryPickupItem(Item.ItemResource itemResource, int quantity)
/// <returns>
/// 未成功添加到背包的物品数量。
/// 如果返回0表示所有物品都成功添加
/// 如果返回quantity表示未能添加任何物品
/// 如果返回一个介于0和quantity之间的值表示部分物品被添加。
/// </returns>
public int TryPickupItem(ItemResource itemResource, int quantity)
{
if (Inventory == null)
{
Debug.LogError($"Character '{this.name}' inventory is not initialized. Cannot pickup item.");
Debug.LogError($"Character '{name}' inventory is not initialized. Cannot pickup item.");
return quantity; // 如果背包未初始化,则视为未能添加任何物品
}
// 直接调用 Inventory 实例的 AddItem 方法。
// AddItem 方法已经包含了严谨的逻辑来处理物品堆叠、新槽位分配、容量检查以及无效输入的警告。
int remainingQuantity = Inventory.AddItem(itemResource, quantity);
var remainingQuantity = Inventory.AddItem(itemResource, quantity);
return remainingQuantity;
}
// (可选) 示例事件处理方法,用于展示如何响应背包事件
// private void HandleItemAddedToInventory(Item.ItemResource item, int count)
// {
// Debug.Log($"{DefName} picked up {count} x {item.Name}. Current total: {Inventory.GetItemCount(item)}");
// // 例如更新UI、播放音效、完成任务等
// }
// private void HandleItemRemovedFromInventory(Item.ItemResource item, int count)
// {
// Debug.Log($"{DefName} removed {count} x {item.Name}. Current total: {Inventory.GetItemCount(item)}");
// // 例如更新UI、播放音效、更新制作状态等
// }
// private void HandleInventoryChanged()
// {
// Debug.Log($"{DefName}'s inventory changed. Occupied slots: {Inventory.OccupiedSlotsCount}/{Inventory.Capacity}");
// // 例如通知背包UI刷新显示
// }
// ------------- 新增 / 修改部分 END -------------
public override void TryAttack()
{
if (IsAttacking)
return;
if (!Managers.DefineManager.Instance.defines.TryGetValue(nameof(BulletDef), out var def))
if (!DefineManager.Instance.defines.TryGetValue(nameof(BulletDef), out var def))
return;
var buttonDef = def.Values.First();
Vector3 dir = Utils.MousePosition.GetWorldPosition();
Managers.EntityManage.Instance.GenerateBulletEntity(Program.Instance.focuseDimensionId,(BulletDef)buttonDef, Position,
// 修正First() 可能会在一个空的 Values 集合上抛出异常。
// 更好的做法是使用 TryGetValue 或 FirstOrDefault 并检查结果。
// 这里假设至少有一个 BulletDef 存在,如果不是,需要更复杂的错误处理。
var bulletDefEntry = def.Values.FirstOrDefault();
if (bulletDefEntry == null)
{
Debug.LogError("No BulletDef found in DefineManager. Cannot attack.");
return;
}
var bulletDef = (BulletDef)bulletDefEntry;
Vector3 dir = MousePosition.GetWorldPosition();
EntityManage.Instance.GenerateBulletEntity(Program.Instance.FocusedDimensionId, bulletDef, Position,
dir - Position, this);
}
public override WeaponResource GetCurrentWeapon()
{
var currentSelectItem = Inventory.GetSlot(currentSelected);
return (WeaponResource)currentSelectItem.Item;
}
}
}
}

View File

@ -5,6 +5,7 @@ using System.Linq;
using AI;
using Base;
using Data;
using Item;
using Prefab;
using UnityEngine;
@ -86,19 +87,19 @@ namespace Entity
IsChase = true;
currentJob = null;
// 逻辑修改只有当存在一个不同的焦点实体时才将其PlayerControlled设为false
if (Program.Instance.focusedEntity && Program.Instance.focusedEntity != this)
if (Program.Instance.FocusedEntity && Program.Instance.FocusedEntity != this)
{
Program.Instance.focusedEntity.PlayerControlled = false;
Program.Instance.FocusedEntity.PlayerControlled = false;
}
Program.Instance.focusedEntity = this;
Program.Instance.SetFocusedEntity(this);
}
// 逻辑修改:确保只有当自身是焦点实体时才取消焦点,避免不必要的逻辑执行
else if (Program.Instance.focusedEntity == this)
else if (Program.Instance.FocusedEntity == this)
{
Program.Instance.focusedEntity = null;
Program.Instance.SetFocusedEntity(null);
}
}
get => Program.Instance.focusedEntity == this;
get => Program.Instance.FocusedEntity == this;
}
@ -115,18 +116,27 @@ namespace Entity
public bool IsDead => attributes.health <= 0;
public bool IsShowingHealthBarUI=>_hitBarUIShowTimer > 0;
public bool IsAttacking => _attackCoroutine != null;
/// <summary>
/// 当实体受到伤害时触发的事件。
/// 可以订阅此事件来响应实体的生命值变化例如更新UI或播放受击特效。
/// </summary>
public event Action<EntityHitEventArgs> OnEntityHit;
/// <summary>
/// 当实体死亡时触发的事件。
/// 只在实体首次进入死亡状态时触发一次。
/// </summary>
public event Action<Entity> OnEntityDied;
private bool _warning = false;
/// <summary>
/// 存储不同朝向下的动画节点集合。
/// </summary>
public Dictionary<EntityState, Dictionary<Orientation, List<ITick>>> bodyAnimationNode = new();
private List<ITick> _currentAnimatorCache=new ();
public Dictionary<EntityState, Dictionary<Orientation, ITick[]>> bodyAnimationNode = new();
private ITick[] _currentAnimatorCache;
/// <summary>
/// 存储不同朝向下的身体节点对象。
/// </summary>
private Dictionary<EntityState, Dictionary<Orientation,GameObject>> bodyNodes = new();
protected Dictionary<EntityState, Dictionary<Orientation,GameObject>> bodyNodes = new();
/// <summary>
/// 当前实体的朝向。
@ -186,7 +196,7 @@ namespace Entity
foreach (var state in states)
{
bodyNodes.TryAdd(state, new Dictionary<Orientation, GameObject>());
bodyAnimationNode.TryAdd(state, new Dictionary<Orientation, List<ITick>>());
bodyAnimationNode.TryAdd(state, new Dictionary<Orientation, ITick[]>());
}
// 主初始化逻辑
@ -229,7 +239,7 @@ namespace Entity
{
animatorsForOrientation.AddRange(animators);
}
stateAnimNodes[orientation] = animatorsForOrientation;
stateAnimNodes[orientation] = animatorsForOrientation.ToArray();
}
}
@ -472,7 +482,7 @@ namespace Entity
}
else
{
_currentAnimatorCache = new List<ITick>(); // 如果没有找到动画,则使用空列表
_currentAnimatorCache = new ITick[]{}; // 如果没有找到动画,则使用空列表
}
}
@ -487,19 +497,38 @@ namespace Entity
SetBodyTexture(EntityState.Walking,_currentOrientation);
_walkingTimer = 2;
}
/// <summary>
/// 处理实体受到攻击的逻辑。
/// </summary>
/// <param name="from">攻击来源实体。</param>
public virtual void OnHit(Entity from)
{
// MODIFIED: 收到攻击时触发回调
if (IsDead) // 如果已经死亡,则不再处理伤害 nor 触发事件
{
return;
}
var hit = from.attributes.attack - attributes.defense;
if (hit < 0)
hit = from.attributes.attack / 100;
// 确保伤害不为负最小为0
hit = Mathf.Max(0, hit);
attributes.health -= hit;
var wasFatal = IsDead; // 检查这次攻击是否导致实体死亡
// 触发 OnEntityHit 事件
OnEntityHit?.Invoke(new EntityHitEventArgs(
this, from, hit, attributes.health, entityDef.attributes.health, wasFatal));
currentJob?.StopJob();
ShowHealthBar();
if (wasFatal)
{
// 如果是首次死亡,则触发 OnEntityDied 事件
// MODIFIED: 停止所有活动,包括当前工作
currentJob = null; // 清除当前工作
OnEntityDied?.Invoke(this);
}
ShowHealthBar(); // 无论是否死亡都更新血条UI
}
public void ShowHealthBar()
@ -523,7 +552,17 @@ namespace Entity
/// </summary>
public virtual void Kill()
{
attributes.health = 0;
if (IsDead)
{
return;
}
attributes.health = 0; // 直接设置生命值为0
// MODIFIED: 停止所有活动,包括当前工作
currentJob?.StopJob();
currentJob = null; // 清除当前工作
// 触发 OnEntityDied 事件
OnEntityDied?.Invoke(this);
ShowHealthBar();
}
/// <summary>
@ -684,5 +723,10 @@ namespace Entity
attackCount--;
}
}
public virtual WeaponResource GetCurrentWeapon()
{
return null;
}
}
}

View File

@ -0,0 +1,25 @@
using System;
namespace Entity
{
public class EntityHitEventArgs : EventArgs
{
public Entity AttackedEntity { get; } // 被攻击的实体
public Entity AttackerEntity { get; } // 攻击者
public int DamageDealt { get; } // 这次攻击造成的实际伤害
public float CurrentHealth { get; } // 攻击后的当前生命值
public float MaxHealth { get; } // 最大生命值
public bool WasFatal { get; } // 这次攻击是否致命(导致死亡)
public EntityHitEventArgs(Entity attacked, Entity attacker, int damage, float currentHealth, float maxHealth, bool wasFatal)
{
AttackedEntity = attacked;
AttackerEntity = attacker;
DamageDealt = damage;
CurrentHealth = currentHealth;
MaxHealth = maxHealth;
WasFatal = wasFatal;
}
}
}

View File

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 5d160d50370b46b299421e6c05a83beb
timeCreated: 1756199871

View File

@ -142,6 +142,25 @@ namespace Entity
{
return _slots.AsReadOnly();
}
public InventorySlot GetSlot(Item.ItemResource itemResource)
{
if (itemResource == null) return null;
foreach (var slot in _slots)
{
if (slot.Item != null && slot.Item.DefName == itemResource.DefName)
{
return slot;
}
}
return null;
}
public InventorySlot GetSlot(int i)
{
i = Mathf.Clamp(i, 0, Capacity - 1);
return _slots[i];
}
public int OccupiedSlotsCount => _slots.Count;
public int AvailableSlotsCount => Capacity - _slots.Count;

View File

@ -116,7 +116,7 @@ namespace Entity
private void BecomeDefault()
{
entity.Kill();
EntityManage.Instance.GenerateDefaultEntity(Program.Instance.focuseDimensionId,entity.Position);
EntityManage.Instance.GenerateDefaultEntity(Program.Instance.FocusedDimensionId,entity.Position);
}
private void StartControl()

View File

@ -1,6 +1,10 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Base;
using Data;
using Item;
using Prefab;
using UnityEngine;
namespace Entity
@ -11,6 +15,48 @@ namespace Entity
protected override void AutoBehave()
{
}
public override void SetTarget(Vector3 pos)
{
}
public void Init(ItemDef itemDef)
{
itemResource = Managers.ItemResourceManager.Instance.GetItem(itemDef.defName);
// 预缓存枚举值(避免每次循环重复调用 Enum.GetValues
var states = Enum.GetValues(typeof(EntityState)).Cast<EntityState>().ToArray();
// 预初始化字典结构(减少内层循环的字典检查)
foreach (var state in states)
{
bodyNodes.TryAdd(state, new Dictionary<Orientation, GameObject>());
bodyAnimationNode.TryAdd(state, new Dictionary<Orientation, ITick[]>());
}
var texture = itemResource.Icon;
if (texture.Count == 1)
{
var imageObj = Instantiate(imagePrefab.gameObject, body.transform);
imageObj.transform.localPosition = Vector3.zero;
bodyNodes[EntityState.Idle][Orientation.Down] = imageObj;
var image = imageObj.GetComponent<ImagePrefab>();
image.SetSprite(texture[0]);
}
else if (texture.Count > 1)
{
var animatorObj = Instantiate(animatorPrefab.gameObject, body.transform);
animatorObj.transform.localPosition = Vector3.zero;
bodyNodes[EntityState.Idle][Orientation.Down] = animatorObj;
var animator = animatorObj.GetComponent<SpriteAnimator>();
animator.SetSprites(texture.ToArray());
ITick[] ticks = { animator };
bodyAnimationNode[EntityState.Idle][Orientation.Down] = ticks;
}
SetBodyTexture(EntityState.Idle, Orientation.Down);
}
private void OnTriggerEnter2D(Collider2D other)
{
var entity = other.GetComponent<Character>();

View File

@ -1,4 +1,5 @@
using System;
using System.Collections.Generic;
using Data;
using Managers;
using UnityEngine;
@ -6,66 +7,98 @@ using UnityEngine;
namespace Item
{
/// <summary>
/// 表示游戏中的一个物品资源,包含了物品的各项基本属性和数据。
/// 这是一个只读的数据结构,用于存储物品的定义信息。
/// 表示游戏中的一个物品资源,包含了物品的各项基本属性和数据。
/// 这是一个只读的数据结构,用于存储物品的定义信息。
/// </summary>
public class ItemResource
{
/// <summary>
/// 物品的定义名称,通常作为其唯一标识符
/// </summary>
public string DefName { get; protected set; }
/// <summary>
/// 物品的显示名称例如在UI中显示的名称
/// </summary>
public string Name { get; protected set; }
/// <summary>
/// 物品的描述文本。
/// </summary>
public string Description { get; protected set; }
/// <summary>
/// 物品的图标精灵。
/// </summary>
public Sprite Icon { get; protected set; }
/// <summary>
/// 物品的稀有度。
/// </summary>
public ItemRarity Rarity { get; protected set; }
/// <summary>
/// 物品的最大堆叠数量。
/// </summary>
public int MaxStack { get; protected set; }
/// <summary>
/// 指示物品是否可以被装备。
/// </summary>
public bool IsEquippable { get; protected set; }
/// <summary>
/// 构造函数:通过 ItemDef 对象初始化 ItemResource。
/// 构造函数:通过 ItemDef 对象初始化 ItemResource
/// </summary>
/// <param name="def">物品的定义对象。</param>
/// <exception cref="ArgumentNullException">如果传入的 ItemDef 为 null则抛出此异常。</exception>
public ItemResource(ItemDef def)
{
// 参数校验:在构造函数中进行参数非空检查至关重要,避免空引用异常。
if (def == null)
{
throw new ArgumentNullException(nameof(def), "创建 ItemResource 时ItemDef 不能为 null。");
}
if (def == null) throw new ArgumentNullException(nameof(def), "创建 ItemResource 时ItemDef 不能为 null。");
// 从 ItemDef 对象中直接赋值 ItemResource 的所有属性。
// 这将创建 ItemResource 的逻辑完全封装在类内部,外部调用方无需关心具体属性的提取过程。
DefName = def.defName;
Name = def.label;
Description = def.description;
Icon = PackagesImageManager.Instance.GetSprite(def.texture);
Rarity = def.rarity;
MaxStack = def.maxStack;
IsEquippable = def.ssEquippable;
if (!Icon && def.texture == null)
FPS = def.FPS;
var sprites = new List<Sprite>();
var packID = def.packID;
// 逻辑修改:添加对 def.textures 的非空检查,避免 NullReferenceException
if (def.textures != null)
{
Debug.LogWarning($"ItemResource: Failed to load sprite for texture '{def.texture}' for item '{def.defName}'. Icon will be null.");
foreach (var texture in def.textures)
{
var spr = PackagesImageManager.Instance.GetSprite(packID, texture);
if (spr)
sprites.Add(spr);
else
// 统一日志信息,说明哪个纹理加载失败
Debug.LogWarning(
$"ItemResource: Failed to load sprite for texture '{texture}' for item '{def.defName}'.");
}
}
else
{
// 仅当 textures 为 null 时警告,因为它可能是预期的数据状态(无图标)
Debug.LogWarning(
$"ItemResource: ItemDef '{def.defName}' has a null textures array. No icons will be loaded.");
}
// 逻辑修改Icon 属性现在是 IReadOnlyList<Sprite> 类型,确保外部只读访问
Icon = sprites.AsReadOnly(); // 使用 AsReadOnly() 获得一个只读包装器
}
/// <summary>
/// 物品的定义名称,通常作为其唯一标识符。
/// </summary>
public string DefName { get; protected set; }
/// <summary>
/// 物品的显示名称例如在UI中显示的名称
/// </summary>
public string Name { get; protected set; }
/// <summary>
/// 物品的描述文本。
/// </summary>
public string Description { get; protected set; }
/// <summary>
/// 物品的图标精灵集合。提供只读访问以保持数据结构不变性。
/// </summary>
// 逻辑修改Icon 属性更改为 IReadOnlyList<Sprite>
public IReadOnlyList<Sprite> Icon { get; protected set; }
/// <summary>
/// 物品的稀有度。
/// </summary>
public ItemRarity Rarity { get; protected set; }
/// <summary>
/// 物品的最大堆叠数量。
/// </summary>
public int MaxStack { get; protected set; }
/// <summary>
/// 指示物品是否可以被装备。
/// </summary>
public bool IsEquippable { get; protected set; }
/// <summary>
/// 物品的帧率(如果适用)。
/// </summary>
public float FPS { get; protected set; }
}
}

View File

@ -4,7 +4,6 @@ using System.Linq;
using Base;
using Data;
using Entity;
using Map;
using Prefab;
using UnityEngine;
using UnityEngine.SceneManagement;
@ -46,11 +45,12 @@ namespace Managers
/// <summary> 子弹实体的预制体。 </summary>
public EntityPrefab bulletPrefab;
public EntityPrefab pickupPrefab;
/// <summary> 默认实体的预制体,用于生成失败时的回退。 </summary>
public EntityPrefab defaultEntityPrefab;
// 已移除RegisterDimension 和 UnregisterDimension 方法的相关注释,因为这些方法已不存在且与逻辑无关。
/// <summary>
/// 在指定维度中,根据派系键查找所有实体。
@ -238,7 +238,7 @@ namespace Managers
string dimensionId,
GameObject prefab,
Vector3 pos,
Data.EntityDef def,
EntityDef def,
Action<EntityPrefab> extraInit = null)
{
// 验证维度是否活跃 (通过 Program)。
@ -277,7 +277,7 @@ namespace Managers
_pendingAdditions.Add(Tuple.Create(dimensionId, factionKey, entityComponent));
return entityComponent;
}
catch (System.Exception ex)
catch (Exception ex)
{
if (instantiatedEntity) Destroy(instantiatedEntity);
Debug.LogError($"实体管理器:在维度 '{dimensionId}' 中生成实体失败:{ex.Message}\n{ex.StackTrace}");
@ -345,7 +345,7 @@ namespace Managers
/// <param name="dimensionId">实体所属的维度ID。</param>
/// <param name="entityDef">实体定义对象。</param>
/// <param name="pos">生成位置。</param>
public void GenerateEntity(string dimensionId, Data.EntityDef entityDef, Vector3 pos)
public void GenerateEntity(string dimensionId, EntityDef entityDef, Vector3 pos)
{
if (!characterPrefab)
{
@ -376,7 +376,7 @@ namespace Managers
/// <param name="dimensionId">实体所属的维度ID。</param>
/// <param name="buildingDef">建筑定义对象。</param>
/// <param name="pos">网格位置。</param>
public void GenerateBuildingEntity(string dimensionId, Data.BuildingDef buildingDef, Vector3Int pos)
public void GenerateBuildingEntity(string dimensionId, BuildingDef buildingDef, Vector3Int pos)
{
if (!buildingPrefab)
{
@ -410,7 +410,7 @@ namespace Managers
/// <param name="pos">生成位置。</param>
/// <param name="dir">子弹的初始方向。</param>
/// <param name="source">发射子弹的源实体。</param>
public void GenerateBulletEntity(string dimensionId, Data.BulletDef bulletDef, Vector3 pos, Vector3 dir,
public void GenerateBulletEntity(string dimensionId, BulletDef bulletDef, Vector3 pos, Vector3 dir,
Entity.Entity source = null)
{
if (!bulletPrefab)
@ -453,7 +453,27 @@ namespace Managers
if (result == null) GenerateDefaultEntity(dimensionId, pos);
}
public void GeneratePickupEntity(string dimensionId, ItemDef itemDef, Vector3 pos)
{
if (!pickupPrefab)
{
Debug.LogError("实体管理器pickupPrefab 为空!请分配一个有效的预制体。");
GenerateDefaultEntity(dimensionId, pos);
return;
}
if (itemDef == null)
{
Debug.LogError("实体管理器itemDef 为空!无法生成子弹。");
GenerateDefaultEntity(dimensionId, pos);
return;
}
var result=Instantiate(pickupPrefab, pos, Quaternion.identity);
var pickup = result.GetComponent<Pickup>();
pickup.Init(itemDef);
if (result == null) GenerateDefaultEntity(dimensionId, pos);
}
/// <summary>
/// 在指定维度和位置生成一个默认实体(通常作为回退选项)。
/// </summary>
@ -616,7 +636,7 @@ namespace Managers
// 关系判断:判断当前实体与源实体是否为“敌对”关系。
if (affiliationManager.GetRelation(sourceEntityPrefab.entity, currentEntityPrefab.entity) ==
Data.Relation.Hostile)
Relation.Hostile)
{
return true; // 找到第一个敌对实体即返回 true提高效率。
}
@ -682,7 +702,7 @@ namespace Managers
// 关系判断:判断当前实体与源实体是否为“敌对”关系。
if (affiliationManager.GetRelation(sourceEntityPrefab.entity, currentEntityPrefab.entity) ==
Data.Relation.Hostile)
Relation.Hostile)
{
// 距离判断:如果关系敌对,进一步判断其是否在视野范围内。
var distanceSqr = Vector3.SqrMagnitude(currentEntityPrefab.transform.position - sourcePos);

View File

@ -0,0 +1,181 @@
using System.Collections.Generic;
using Data;
using UnityEngine;
using EventType = Data.EventType;
namespace Managers
{
// 新增私有结构体,用于在事件队列中存储事件定义及其运行时上下文
public struct EventPayload // Make it public if EventManager exposes it directly
{
public string DimensionId;
public EventDef EventDefinition;
public Vector3 Position; // 适用于 Character, Bullet, Pickup, DefaultEntity
public Vector3 Direction; // 仅适用于 Bullet
public Entity.Entity SourceEntity; // 仅适用于 Bullet (发射源)
public Vector3Int GridPosition; // 仅适用于 Building
}
public class EventManager : Utils.MonoSingleton<EventManager>
{
private Queue<EventPayload> _eventQueue = new Queue<EventPayload>();
private EventManager()
{
/* Private constructor for singleton */
}
// ===================================
// 公共入队方法
// ===================================
public void EnqueueCharacterSpawnEvent(string dimensionId, EventDef eventDef, Vector3 pos)
{
if (eventDef == null || eventDef.eventType != EventType.SpawnCharacter ||
eventDef.entityDef_Character == null)
{
Debug.LogError(
$"EnqueueCharacterSpawnEvent: Invalid EventDef, mismatched EventType ({eventDef?.eventType}), or missing characterDef for event '{eventDef?.defName ?? "Unknown"}'.");
return;
}
_eventQueue.Enqueue(new EventPayload
{
DimensionId = dimensionId,
EventDefinition = eventDef,
Position = pos,
});
Debug.Log($"Event '{eventDef.defName}' (SpawnCharacter) enqueued for dimension {dimensionId} at {pos}.");
}
public void EnqueueBuildingSpawnEvent(string dimensionId, EventDef eventDef, Vector3Int gridPos)
{
if (eventDef == null || eventDef.eventType != EventType.SpawnBuilding ||
eventDef.entityDef_Building == null)
{
Debug.LogError(
$"EnqueueBuildingSpawnEvent: Invalid EventDef, mismatched EventType ({eventDef?.eventType}), or missing buildingDef for event '{eventDef?.defName ?? "Unknown"}'.");
return;
}
_eventQueue.Enqueue(new EventPayload
{
DimensionId = dimensionId,
EventDefinition = eventDef,
GridPosition = gridPos,
});
Debug.Log($"Event '{eventDef.defName}' (SpawnBuilding) enqueued for dimension {dimensionId} at grid {gridPos}.");
}
public void EnqueueBulletSpawnEvent(string dimensionId, EventDef eventDef, Vector3 pos, Vector3 dir,
Entity.Entity source = null)
{
if (eventDef == null || eventDef.eventType != EventType.SpawnBullet || eventDef.entityDef_Bullet == null)
{
Debug.LogError(
$"EnqueueBulletSpawnEvent: Invalid EventDef, mismatched EventType ({eventDef?.eventType}), or missing bulletDef for event '{eventDef?.defName ?? "Unknown"}'.");
return;
}
_eventQueue.Enqueue(new EventPayload
{
DimensionId = dimensionId,
EventDefinition = eventDef,
Position = pos,
Direction = dir,
SourceEntity = source,
});
Debug.Log($"Event '{eventDef.defName}' (SpawnBullet) enqueued for dimension {dimensionId} at {pos}, dir {dir}.");
}
public void EnqueuePickupSpawnEvent(string dimensionId, EventDef eventDef, Vector3 pos)
{
if (eventDef == null || eventDef.eventType != EventType.SpawnPickup || eventDef.entityDef_Pickup == null)
{
Debug.LogError(
$"EnqueuePickupSpawnEvent: Invalid EventDef, mismatched EventType ({eventDef?.eventType}), or missing itemDef for event '{eventDef?.defName ?? "Unknown"}'.");
return;
}
_eventQueue.Enqueue(new EventPayload
{
DimensionId = dimensionId,
EventDefinition = eventDef,
Position = pos,
});
Debug.Log($"Event '{eventDef.defName}' (SpawnPickup) enqueued for dimension {dimensionId} at {pos}.");
}
public void EnqueueDefaultEntitySpawnEvent(string dimensionId, EventDef eventDef, Vector3 pos)
{
if (eventDef == null || eventDef.eventType != EventType.SpawnDefaultEntity)
{
Debug.LogError(
$"EnqueueDefaultEntitySpawnEvent: Invalid EventDef or mismatched EventType ({eventDef?.eventType}) for event '{eventDef?.defName ?? "Unknown"}'.");
return;
}
_eventQueue.Enqueue(new EventPayload
{
DimensionId = dimensionId,
EventDefinition = eventDef,
Position = pos,
});
Debug.Log($"Event '{eventDef.defName}' (SpawnDefaultEntity) enqueued for dimension {dimensionId} at {pos}.");
}
// ===================================
// 事件处理方法
// ===================================
/// <summary>
/// 处理所有在队列中的待处理事件。
/// </summary>
public void ProcessEvents()
{
while (_eventQueue.Count > 0)
{
EventPayload eventData = _eventQueue.Dequeue();
if (!Program.Instance.GetDimension(eventData.DimensionId))
{
Debug.LogWarning(
$"Event '{eventData.EventDefinition.defName}' for dimension {eventData.DimensionId} dropped as dimension is no longer active.");
continue;
}
// 核心:调用 EntityManage.Instance 的现有公共方法
switch (eventData.EventDefinition.eventType)
{
case EventType.SpawnCharacter:
EntityManage.Instance.GenerateEntity(eventData.DimensionId,
eventData.EventDefinition.entityDef_Character, eventData.Position);
break;
case EventType.SpawnBuilding:
EntityManage.Instance.GenerateBuildingEntity(eventData.DimensionId,
eventData.EventDefinition.entityDef_Building, eventData.GridPosition);
break;
case EventType.SpawnBullet:
EntityManage.Instance.GenerateBulletEntity(eventData.DimensionId,
eventData.EventDefinition.entityDef_Bullet, eventData.Position, eventData.Direction,
eventData.SourceEntity);
break;
case EventType.SpawnPickup:
EntityManage.Instance.GeneratePickupEntity(eventData.DimensionId,
eventData.EventDefinition.entityDef_Pickup, eventData.Position);
break;
case EventType.SpawnDefaultEntity:
EntityManage.Instance.GenerateDefaultEntity(eventData.DimensionId, eventData.Position);
break;
case EventType.None:
default:
Debug.LogWarning(
$"EventManager: Unhandled or invalid event type: {eventData.EventDefinition.eventType} for event '{eventData.EventDefinition.defName}'.");
break;
}
}
}
protected override void OnStart()
{
throw new System.NotImplementedException();
}
}
}

View File

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: fe7c735088384400a50b418f85252c70
timeCreated: 1756268066

View File

@ -16,7 +16,8 @@ namespace Map
private string _dimensionId;
[SerializeField] public MapGenerator mapGenerator;
public Vector3 cameraPosition;
/// <summary>
/// 获取此维度的唯一标识符。
/// </summary>
@ -73,6 +74,12 @@ namespace Map
}
private void Start()
{
var size = mapGenerator.baseMap.GetSize();
cameraPosition = new Vector3(size.x / 2f, size.y / 2f, -10)+transform.position;
}
private void OnDestroy()
{
// 当 Dimension 对象被销毁时(例如,场景卸载),从 Program 和 EntityManage 注销

View File

@ -10,32 +10,10 @@ namespace Map
{
public class DoubleMap : MonoBehaviour
{
private List<List<int>> mapData = new();
public List<List<int>> mapData = new();
public Tilemap textureLevel;
// public Vector2Int dataOffset = Vector2Int.zero; // 数据起始点偏移变量 - 已删除
private void Start()
{
Managers.DefineManager.Instance.Init();
Managers.PackagesImageManager.Instance.Init();
Managers.TileManager.Instance.Init();
var size = 100;
InitializeData(size, size);
for (var i = 0; i < size; i++)
{
for (var j = 0; j < size; j++)
{
var dx = i - size / 2;
var dy = j - size / 2;
mapData[i][j] = (int)(Math.Sqrt(dx * dx + dy * dy) / 5) & 1;
}
}
RefreshAllTiles();
CameraControl.CameraControl.Instance.SetPosition(new Vector3(size * 0.5f, size * 0.5f, -10));
}
// 初始化地图数据大小
public void InitializeData(int width, int height, int defaultValue = 0)
@ -186,6 +164,16 @@ namespace Map
Debug.LogError($"未找到对应瓦片: {key}");
return null;
}
public Vector2Int GetSize()
{
if (!mapData.Any() || mapData[0].Count == 0)
{
return new Vector2Int(0, 0);
}
return new Vector2Int(mapData.Count, mapData[0].Count);
}
}
}

View File

@ -6,6 +6,29 @@ namespace Map
{
public class MapGenerator:MonoBehaviour
{
public DoubleMap baseMap;
private void Awake()
{
Managers.DefineManager.Instance.Init();
Managers.PackagesImageManager.Instance.Init();
Managers.TileManager.Instance.Init();
var size = 100;
baseMap.InitializeData(size, size);
for (var i = 0; i < size; i++)
{
for (var j = 0; j < size; j++)
{
var dx = i - size / 2;
var dy = j - size / 2;
baseMap.mapData[i][j] = (int)(Math.Sqrt(dx * dx + dy * dy) / 5) & 1;
}
}
baseMap.RefreshAllTiles();
CameraControl.CameraControl.Instance.SetPosition(new Vector3(size * 0.5f, size * 0.5f, -10));
}
}
}

View File

@ -1,10 +1,22 @@
using Base;
using UnityEngine;
using UnityEngine.UI;
namespace Map
{
public class MiniMap : MonoBehaviour
public class MiniMap : MonoBehaviour,ITickUI
{
public RawImage texture;
private bool _show = true;
public void TickUI()
{
if (_show != Setting.Instance.CurrentSettings.showMiniMap)
{
_show = Setting.Instance.CurrentSettings.showMiniMap;
texture.gameObject.SetActive(_show);
}
}
}
}

View File

@ -38,10 +38,10 @@ namespace Prefab
public void DefaultInit()
{
var animator = GetComponentsInChildren<SpriteAnimator>();
var inf = animator.Cast<ITick>().ToList();
var inf = animator.Cast<ITick>().ToArray();
foreach (EntityState state in Enum.GetValues(typeof(EntityState)))
{
var orientationDict = new Dictionary<Orientation, List<ITick>>();
var orientationDict = new Dictionary<Orientation, ITick[]>();
foreach (Orientation orientation in Enum.GetValues(typeof(Orientation)))
{
orientationDict[orientation] = inf; // 所有值都指向同一个列表

View File

@ -1,5 +1,6 @@
using System; // 添加引用,用于 Action 委托
using System;
using System.Collections.Generic;
using System.Linq;
using Map;
using UnityEngine;
using Utils;
@ -16,18 +17,26 @@ public class Program : Singleton<Program>
public bool needLoad = true;
/// <summary>
/// 当前聚焦的实体对象,可能为空
/// 当前聚焦的实体对象。
/// 变更为属性并私有化setter确保通过 SetFocusedEntity 方法集中管理其更新和事件触发。
/// </summary>
public Entity.Entity focusedEntity = null;
public Entity.Entity FocusedEntity { get; private set; } = null;
/// <summary>
/// 当焦点实体发生变化时触发的事件。
/// 事件参数为新的焦点 Entity 实例,如果焦点被清除则为 null。
/// </summary>
public event Action<Entity.Entity> OnFocusedEntityChanged;
/// <summary>
/// 当前活跃焦点的维度唯一标识符,可能为空。
/// 变更为属性并私有化setter确保通过 SetFocusedDimension 方法集中管理其更新。
/// </summary>
public string focuseDimensionId { get; private set; } = null;
// 逻辑修改1修正属性名 'focuseDimensionId' 为 'focusedDimensionId'
public string FocusedDimensionId { get; private set; } = null;
/// <summary>
/// 当前聚焦的维度对象实例。当 <see cref="focuseDimensionId"/> 不为空时,此属性指向对应的维度实例。
/// 当前聚焦的维度对象实例。当 <see cref="FocusedDimensionId"/> 不为空时,此属性指向对应的维度实例。
/// </summary>
public Dimension FocusedDimension { get; private set; }
@ -47,6 +56,9 @@ public class Program : Singleton<Program>
/// </summary>
public event Action<Dimension> OnFocusedDimensionChanged;
public int DimensionCount => _registeredDimensions.Count;
public string[] Dimensions => _registeredDimensions.Keys.ToArray();
/// <summary>
/// 注册一个维度实例到 Program。
/// </summary>
@ -71,10 +83,13 @@ public class Program : Singleton<Program>
}
_registeredDimensions.Add(id, dimension);
// 修改理由:确保任何对焦点的潜在更新都通过 SetFocusedDimension 进行,
// 逻辑修改此处不需要if语句包裹_registeredDimensions.Add因为前置的ContainsKey已确保不会抛异常。
// 确保任何对焦点的潜在更新都通过 SetFocusedDimension 进行,
// 从而集中管理焦点状态的同步和事件的触发。
// 如果注册的维度恰好是当前 focuseDimensionId SetFocusedDimension(id) 将负责更新 FocusedDimension 并触发事件。
if (focuseDimensionId == id)
// 如果注册的维度恰好是当前 focusedDimensionId SetFocusedDimension(id) 将负责更新 FocusedDimension 并触发事件。
// 并且由于SetFocusedDimension会清空FocusedEntity这也符合新维度的行为。
// 逻辑修改1修正属性名 'focuseDimensionId' 为 'focusedDimensionId'
if (FocusedDimensionId == id)
{
SetFocusedDimension(id);
}
@ -94,10 +109,11 @@ public class Program : Singleton<Program>
var id = dimension.DimensionId;
if (_registeredDimensions.Remove(id))
{
// 修改理由:确保任何对焦点的潜在更新都通过 SetFocusedDimension 进行,
// 确保任何对焦点的潜在更新都通过 SetFocusedDimension 进行,
// 从而集中管理焦点状态的同步和事件的触发。
// 如果注销的维度是当前焦点维度,则调用 SetFocusedDimension(null) 清除焦点并触发事件。
if (focuseDimensionId == id)
// 逻辑修改1修正属性名 'focuseDimensionId' 为 'focusedDimensionId'
if (FocusedDimensionId == id)
{
SetFocusedDimension(null); // 清除焦点
}
@ -128,13 +144,13 @@ public class Program : Singleton<Program>
{
// 1. 确定新的焦点维度及其ID
Dimension newFocusedDimension = null; // 默认为清除焦点
string newFocuseDimensionId = null;
string newFocusedDimensionId = null; // 逻辑修改1修正属性名 'newFocuseDimensionId' 为 'newFocusedDimensionId'
if (!string.IsNullOrEmpty(dimensionId))
{
if (_registeredDimensions.TryGetValue(dimensionId, out var foundDimension))
{
newFocuseDimensionId = dimensionId;
newFocusedDimensionId = dimensionId; // 逻辑修改1修正属性名
newFocusedDimension = foundDimension;
}
else
@ -144,26 +160,53 @@ public class Program : Singleton<Program>
return;
}
}
// 如果 dimensionId 为 null 或空, newFocusedDimension 和 newFocuseDimensionId 将保持为 null表示清除焦点。
// 如果 dimensionId 为 null 或空, newFocusedDimension 和 newFocusedDimensionId 将保持为 null表示清除焦点。
// 2. 优化:检查是否实际发生变化,避免不必要的更新和事件触发
// 只有当新的ID或新的维度对象引用与当前的不一致时才执行更新。
// 例如,如果 focuseDimensionId 已经是 "someId"FocusedDimension 已经是 "someDimensionObject"
// 再次调用 SetFocusedDimension("someId") 不会触发事件。
// 但如果 focuseDimensionId 是 "someId"FocusedDimension 是 null (因为维度还未注册)
// 而此时注册了 "someId" 对应的维度并调用 SetFocusedDimension("someId")FocusedDimension 将从 null 变为实际对象,
// 这算作一次变化,会触发事件。
if (focuseDimensionId == newFocuseDimensionId && FocusedDimension == newFocusedDimension)
// 逻辑修改1修正属性名 'focuseDimensionId' 为 'focusedDimensionId'
// 逻辑修改1修正局部变量名 'newFocuseDimensionId' 为 'newFocusedDimensionId'
if (FocusedDimensionId == newFocusedDimensionId && FocusedDimension == newFocusedDimension)
{
// Debug.Log($"[Program] SetFocusedDimension: ID '{dimensionId}' already current. No change needed.");
return;
}
if (FocusedEntity != null)
{
FocusedEntity.PlayerControlled = false;
}
// 3. 更新内部状态
focuseDimensionId = newFocuseDimensionId;
FocusedDimensionId = newFocusedDimensionId; // 逻辑修改1修正属性名
FocusedDimension = newFocusedDimension;
// 逻辑修改2功能缺失修复 - 切换维度时,焦点实体应该置为空
// 确保功能一致性:当维度焦点改变(或被清除)时,任何实体焦点也应被清除。
SetFocusedEntity(null);
// 4. 触发事件
OnFocusedDimensionChanged?.Invoke(FocusedDimension);
}
/// <summary>
/// 设置当前聚焦的实体。
/// 这是更改焦点实体的唯一官方入口,并会在实体改变时触发 OnFocusedEntityChanged 事件。
/// </summary>
/// <param name="entity">要设置为焦点的实体实例。如果传入null将清除当前焦点实体。</param>
public void SetFocusedEntity(Entity.Entity entity)
{
// 优化:检查是否实际发生变化,避免不必要的更新和事件触发。
// 如果新的实体与当前焦点实体相同(按引用比较),则不执行任何操作。
if (FocusedEntity == entity)
{
// Debug.Log($"[Program] SetFocusedEntity: Entity '{entity?.name ?? "null"}' already current. No change needed.");
return;
}
// 更新内部状态
FocusedEntity = entity;
// 触发事件,将新的焦点实体(或 null作为参数传递。
OnFocusedEntityChanged?.Invoke(FocusedEntity);
}
}

View File

@ -1,10 +1,7 @@
using System.Collections.Generic;
using System.Linq;
using Base;
using Data;
using Data; // 确保 Data 命名空间包含 DefBase, CharacterDef, MonsterDef, BuildingDef, ItemDef, EventDef
using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.UI;
namespace UI
{
@ -29,6 +26,7 @@ namespace UI
InitCharacter();
InitMonster();
InitBuilding();
InitItem();
}
private void InitReloadGameButton()
@ -38,89 +36,101 @@ namespace UI
button.AddListener(HotReload);
}
private void InitEvent()
/// <summary>
/// 通用的初始化定义按钮的方法。
/// </summary>
/// <typeparam name="TDef">定义的类型,必须继承自 Data.DefBase。</typeparam>
/// <param name="titleLabel">菜单部分的标题。</param>
/// <param name="noDefMessage">当没有定义时显示的提示信息。</param>
/// <param name="buttonTextSelector">用于从 TDef 获取按钮显示文本的函数。</param>
/// <param name="buttonAction">点击按钮时执行的动作,传入对应的 TDef 对象。</param>
private void InitDefineButtons<TDef>(string titleLabel, string noDefMessage, System.Func<TDef, string> buttonTextSelector, System.Action<TDef> buttonAction) where TDef : Define
{
var title = InstantiatePrefab(textTemplate, menuContent.transform);
title.Label = "事件菜单";
title = InstantiatePrefab(textTemplate, menuContent.transform);
title.Label = "未定义任何事件";
title.text.color = Color.red;
// for (int i = 0; i < 30; i++)
// {
// var button= InstantiatePrefab(buttonTemplate, menuContent.transform);
// button.text.text = i.ToString();
// }
title.Label = titleLabel;
var defList = Managers.DefineManager.Instance.QueryNamedDefinesByType<TDef>();
if (defList == null || defList.Length == 0)
{
var noDefTitle = InstantiatePrefab(textTemplate, menuContent.transform);
noDefTitle.Label = noDefMessage;
noDefTitle.text.color = Color.red;
}
else
{
foreach (var def in defList)
{
var button = InstantiatePrefab(buttonTemplate, menuContent.transform);
button.Label = buttonTextSelector(def);
// 确保 lambda 捕获的是循环当前迭代的 def 变量,而不是循环变量本身
var currentDef = def;
button.AddListener(() => buttonAction(currentDef));
}
}
}
private void InitEvent()
{
// 假设存在 Data.EventDef 类型,且它继承自 Data.DefBase并包含一个可作为标签的字段。
// 如果事件触发逻辑不同于生成实体,需要在此处定义相应的回调。
InitDefineButtons<EventDef>(
"事件菜单",
"未定义任何事件",
// 假设 EventDef 也有 label 字段作为按钮文本
def => def.label,
eventDef =>
{
// TODO: 在这里实现事件触发逻辑
Debug.Log($"触发事件: {eventDef.label}");
// 示例: Managers.EventManager.Instance.TriggerEvent(eventDef.id);
});
}
private void InitCharacter()
{
var title = InstantiatePrefab(textTemplate, menuContent.transform);
title.Label = "生成人物";
var defList = Managers.DefineManager.Instance.QueryNamedDefinesByType<Data.CharacterDef>();
if (defList == null || defList.Length == 0)
{
title = InstantiatePrefab(textTemplate, menuContent.transform);
title.Label = "未定义任何角色";
title.text.color = Color.red;
}
else
foreach (var def in defList)
{
var button = InstantiatePrefab(buttonTemplate, menuContent.transform);
button.Label = def.label;
var pawnDef = def;
button.AddListener(() => GenerateEntityCallback(pawnDef));
}
InitDefineButtons<CharacterDef>(
"生成人物",
"未定义任何角色",
def => def.label,
GenerateEntityCallback);
}
private void InitMonster()
{
var title = InstantiatePrefab(textTemplate, menuContent.transform);
title.Label = "生成怪物";
var defList = Managers.DefineManager.Instance.QueryNamedDefinesByType<Data.MonsterDef>();
if (defList == null || defList.Length == 0)
{
title = InstantiatePrefab(textTemplate, menuContent.transform);
title.Label = "未定义任何怪物";
title.text.color = Color.red;
}
else
foreach (var def in defList)
{
var button = InstantiatePrefab(buttonTemplate, menuContent.transform);
button.Label = def.label;
var pawnDef = def;
button.AddListener(() => GenerateEntityCallback(pawnDef));
}
InitDefineButtons<MonsterDef>(
"生成怪物",
"未定义任何怪物",
def => def.label,
GenerateEntityCallback);
}
private void InitBuilding()
{
var title = InstantiatePrefab(textTemplate, menuContent.transform);
title.Label = "生成建筑";
var defList = Managers.DefineManager.Instance.QueryNamedDefinesByType<Data.BuildingDef>();
if (defList == null || defList.Length == 0)
{
title = InstantiatePrefab(textTemplate, menuContent.transform);
title.Label = "未定义任何建筑";
title.text.color = Color.red;
}
else
foreach (var def in defList)
{
var button = InstantiatePrefab(buttonTemplate, menuContent.transform);
button.Label = def.label;
var pawnDef = def;
button.AddListener(() => GenerateBuildingCallback(pawnDef));
}
InitDefineButtons<BuildingDef>(
"生成建筑",
"未定义任何建筑",
def => def.label,
GenerateBuildingCallback);
}
private void InitItem()
{
InitDefineButtons<ItemDef>(
"生成掉落物",
"未定义任何物品",
def => def.label,
GeneratePickupCallback);
}
private void InitWeapon()
{
InitDefineButtons<WeaponDef>(
"生成武器",
"未定义任何武器",
def => def.label,
GeneratePickupCallback);
}
/// <summary>
/// 通用的实例化函数,返回实例化的预制件脚本组件。
/// </summary>
@ -154,24 +164,33 @@ namespace UI
{
entityPlacementUI.currentAction = () =>
{
Managers.EntityManage.Instance.GenerateEntity(Program.Instance.focuseDimensionId,entityDef, Utils.MousePosition.GetWorldPosition());
Managers.EntityManage.Instance.GenerateEntity(Program.Instance.FocusedDimensionId,entityDef, Utils.MousePosition.GetWorldPosition());
};
entityPlacementUI.Prompt = $"当前生成器:\n名称{entityDef.label}\n描述{entityDef.description}";
entityPlacementUI.snapEnabled = false;
Base.UIInputControl.Instance.Show(entityPlacementUI);
UIInputControl.Instance.Show(entityPlacementUI);
}
private void GenerateBuildingCallback(BuildingDef def)
{
entityPlacementUI.currentAction = () =>
{
Managers.EntityManage.Instance.GenerateBuildingEntity(Program.Instance.focuseDimensionId,def, Utils.MousePosition.GetSnappedWorldPosition());
Managers.EntityManage.Instance.GenerateBuildingEntity(Program.Instance.FocusedDimensionId,def, Utils.MousePosition.GetSnappedWorldPosition());
};
entityPlacementUI.Prompt = $"当前生成器:\n名称{def.label}\n描述{def.description}";
entityPlacementUI.snapEnabled = true;
Base.UIInputControl.Instance.Show(entityPlacementUI);
UIInputControl.Instance.Show(entityPlacementUI);
}
private void GeneratePickupCallback(ItemDef itemDef)
{
entityPlacementUI.currentAction = () =>
{
Managers.EntityManage.Instance.GeneratePickupEntity(Program.Instance.FocusedDimensionId,itemDef, Utils.MousePosition.GetWorldPosition());
};
entityPlacementUI.Prompt = $"当前生成器:\n名称{itemDef.label}\n描述{itemDef.description}";
entityPlacementUI.snapEnabled = false;
UIInputControl.Instance.Show(entityPlacementUI);
}
private void HotReload()
{
UIInputControl.Instance.HideAll();
@ -179,5 +198,4 @@ namespace UI
SceneManager.LoadScene(0);
}
}
}

View File

@ -1,10 +1,171 @@
using System;
using System.Collections.Generic;
using Base;
using Entity;
using UnityEngine;
namespace UI
{
public class EquipmentUI:MonoBehaviour
/// <summary>
/// 负责管理和显示角色的装备用户界面。
/// 该组件会监听当前关注实体的变化,并根据所关注角色的库存数据动态更新装备槽位的显示,
/// 同时采用对象池技术高效管理 ItemUI 实例的创建和复用。
/// </summary>
public class EquipmentUI : MonoBehaviour,ITick
{
[SerializeField] private GameObject uiParent;
[SerializeField]
[Tooltip("所有 ItemUI 实例的父级 GameObject用于布局。")]
private GameObject uiParent;
[SerializeField]
[Tooltip("用于实例化装备槽位的 ItemUI 预制件。")]
private ItemUI itemUIPrefab;
/// <summary>
/// 当前界面所关联和关注的角色实体。
/// </summary>
private Character focusedEntity = null;
/// <summary>
/// ItemUI 实例的对象池,用于高效管理和复用 ItemUI。
/// </summary>
private List<ItemUI> itemUIPool = new List<ItemUI>();
/// <summary>
/// MonoBehaviour 的 Start 生命周期方法。
/// 在此方法中,注册当游戏主要程序中关注的实体发生变化时,调用 <see cref="UpdateFocusedEntity"/> 方法进行更新。
/// </summary>
private void Start()
{
Program.Instance.OnFocusedEntityChanged += UpdateFocusedEntity;
}
/// <summary>
/// MonoBehaviour 的 OnDestroy 生命周期方法。
/// 在此方法中,取消注册所有已订阅的事件监听器,并清理对象池中创建的所有 ItemUI 实例,
/// 以防止内存泄漏和不必要的引用。
/// </summary>
private void OnDestroy()
{
Program.Instance.OnFocusedEntityChanged -= UpdateFocusedEntity;
// 如果当前有关注的角色,取消注册其库存改变事件。
// 注意:此处需要确保 focusedEntity 不为 null否则可能抛出 NullReferenceException。
if (focusedEntity != null)
{
focusedEntity.Inventory.OnInventoryChanged -= UpdateUI;
}
// 销毁对象池中所有 ItemUI 的 GameObject。
foreach (var itemUI in itemUIPool)
{
if (itemUI != null && itemUI.gameObject != null)
{
Destroy(itemUI.gameObject);
}
}
itemUIPool.Clear();
}
/// <summary>
/// 当游戏程序中关注的实体发生变化时调用此方法。
/// 该方法会更新当前 EquipmentUI 所关联的角色,并相应地注册或取消注册库存改变事件。
/// </summary>
/// <param name="entity">新的关注实体,可能为 null 或非 Character 类型。</param>
private void UpdateFocusedEntity(Entity.Entity entity)
{
// 如果之前有关注的角色,先取消注册其库存改变事件。
// 注意:此处需要确保 focusedEntity 不为 null。
if (focusedEntity != null)
{
focusedEntity.Inventory.OnInventoryChanged -= UpdateUI;
}
// 尝试将新的实体转换为角色类型。
Character newCharacter = entity as Character;
if (newCharacter != null)
{
focusedEntity = newCharacter;
}
// 如果传入的 entity 不是 Character 类型focusedEntity 将保持其当前值。
// 如果希望在非 Character 实体被关注时清除 focusedEntity则需要在此处添加 `else { focusedEntity = null; }`。
// 如果现在有关注的角色,注册其库存改变事件。
if (focusedEntity != null)
{
focusedEntity.Inventory.OnInventoryChanged += UpdateUI;
}
// 立即更新UI以反映新的关注实体或没有关注实体的状态。
UpdateUI();
}
/// <summary>
/// 根据当前关注角色的库存数据更新装备UI的显示。
/// 该方法通过对象池机制高效地管理 ItemUI 实例的创建、复用和禁用。
/// </summary>
private void UpdateUI()
{
// 如果没有关注的角色或其库存,则禁用所有 ItemUI。
// 注意:此处需要先检查 focusedEntity 是否为 null以避免 NullReferenceException。
if (focusedEntity == null || focusedEntity.Inventory == null)
{
foreach (var itemUI in itemUIPool)
{
if (itemUI != null && itemUI.gameObject != null)
{
itemUI.gameObject.SetActive(false);
}
}
return;
}
// 检查用于创建物品UI的预制件是否已在 Inspector 中赋值。
if (itemUIPrefab == null)
{
Debug.LogError("ItemUIPrefab 未在 EquipmentUI 中指定。无法创建物品用户界面。", this);
foreach (var itemUI in itemUIPool) itemUI.gameObject.SetActive(false);
return;
}
// 获取当前关注角色库存中的所有物品槽位。
var slots = focusedEntity.Inventory.GetSlots();
int requiredUIs = slots.Count; // 需要显示和激活的 ItemUI 数量。
int currentUIPoolSize = itemUIPool.Count; // 当前对象池中 ItemUI 实例的总数。
// 遍历所有必要的物品槽位,复用对象池中的 ItemUI或在不足时创建新的 ItemUI。
for (int i = 0; i < requiredUIs; i++)
{
ItemUI itemUI;
if (i < currentUIPoolSize)
{
itemUI = itemUIPool[i];
}
else
{
itemUI = Instantiate(itemUIPrefab, uiParent.transform);
itemUIPool.Add(itemUI);
currentUIPoolSize++; // 更新池的大小计数。
}
// 确保 ItemUI GameObject 处于激活状态,并使用当前物品槽位的数据进行初始化。
itemUI.gameObject.SetActive(true);
itemUI.Init(slots[i], i);
}
// 如果库存槽位数量减少,禁用对象池中多余的 ItemUI 实例。
for (int i = requiredUIs; i < currentUIPoolSize; i++)
{
if (itemUIPool[i] != null && itemUIPool[i].gameObject != null)
{
itemUIPool[i].gameObject.SetActive(false);
}
}
}
public void Tick()
{
}
}
}
}

View File

@ -1,9 +1,91 @@
using System;
using Base;
using TMPro;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;
namespace UI
{
public class ItemUI:MonoBehaviour
public class ItemUI:MonoBehaviour,IPointerEnterHandler,IPointerExitHandler,IPointerClickHandler,ITick
{
[SerializeField] private Image textureUI;
[SerializeField] private TMP_Text countUI;
[SerializeField] private TMP_Text nameUI;
[SerializeField] private GameObject selectedOutline;
private Entity.InventorySlot _item;
private float timer = 0;
private float switchTime = 0;
private int texturePtr = 0;
public event Action OnPlayerSelect;
public bool Select
{
get => selectedOutline.activeSelf;
set => selectedOutline.SetActive(value);
}
public int SlotIndex { get; private set; } = -1;
public void Init(Entity.InventorySlot item,int index)
{
if (item == null)
{
switchTime = -1;
textureUI.gameObject.SetActive(false);
countUI.text = "";
nameUI.text = "";
return;
}
textureUI.gameObject.SetActive(true);
_item = item;
textureUI.sprite = item.Item.Icon[0];
countUI.text = item.Quantity.ToString();
nameUI.text = item.Item.Name;
nameUI.gameObject.SetActive(false);
Select = false;
SlotIndex = index;
if (item.Item.FPS > 0)
{
switchTime = 1f / item.Item.FPS;
}
else
{
switchTime = 0;
}
}
public void OnPointerEnter(PointerEventData eventData)
{
nameUI.gameObject.SetActive(true);
}
public void OnPointerExit(PointerEventData eventData)
{
nameUI.gameObject.SetActive(false);
}
public void OnPointerClick(PointerEventData eventData)
{
OnPlayerSelect?.Invoke();
}
public void Tick()
{
if (switchTime > 0)
{
timer+=Time.deltaTime;
if (timer >= switchTime)
{
timer-=switchTime;
texturePtr++;
texturePtr%=_item.Item.Icon.Count;
textureUI.sprite=_item.Item.Icon[texturePtr];
}
}
}
}
}

View File

@ -1,3 +1,4 @@
using System;
using TMPro;
using UnityEngine;
@ -7,15 +8,17 @@ namespace UI
{
[SerializeField] private BarUI focusedEntityHP;
[SerializeField] private BarUI lastEntityHP;
public void Tick()
{
var focusedEntity = Program.Instance.focusedEntity;
if (focusedEntity)
var focusedEntity = Program.Instance.FocusedEntity;
if (focusedEntity && focusedEntity.entityDef != null)
{
focusedEntityHP.Progress = (float)focusedEntity.attributes.health/focusedEntity.entityDef.attributes.health;
focusedEntityHP.Progress =
(float)focusedEntity.attributes.health / focusedEntity.entityDef.attributes.health;
}
}
}
}

View File

@ -11,6 +11,7 @@ namespace UI
[SerializeField] private Scrollbar globalVolume;
[SerializeField] private Toggle developerMode;
[SerializeField] private Toggle friendlyFire;
[SerializeField] private Toggle showMiniMap;
[SerializeField] private TMP_Dropdown windowMode;
[SerializeField] private TMP_Dropdown windowResolution;
[SerializeField] private TMP_InputField progressStepDuration;
@ -25,6 +26,7 @@ namespace UI
globalVolume.value = currentSettings.globalVolume;
developerMode.isOn = currentSettings.developerMode;
friendlyFire.isOn = currentSettings.friendlyFire;
showMiniMap.isOn = currentSettings.showMiniMap;
progressStepDuration.text = currentSettings.progressStepDuration.ToString(CultureInfo.InvariantCulture);
exitAnimationDuration.text = currentSettings.exitAnimationDuration.ToString(CultureInfo.InvariantCulture);
@ -59,6 +61,7 @@ namespace UI
currentSettings.windowResolution = Base.Setting.CommonResolutions[windowResolution.value];
currentSettings.progressStepDuration = float.Parse(progressStepDuration.text, CultureInfo.InvariantCulture);
currentSettings.exitAnimationDuration = float.Parse(exitAnimationDuration.text, CultureInfo.InvariantCulture);
currentSettings.showMiniMap = showMiniMap.isOn;
Base.Setting.Instance.CurrentSettings = currentSettings;
Base.Setting.Instance.Apply();
}

View File

@ -342,6 +342,9 @@ MonoBehaviour:
skyOcclusionIntensityMultiplier:
m_OverrideState: 1
m_Value: 1
worldOffset:
m_OverrideState: 1
m_Value: {x: 0, y: 0, z: 0}
--- !u!114 &-1216621516061285780
MonoBehaviour:
m_ObjectHideFlags: 3
@ -462,8 +465,6 @@ MonoBehaviour:
- {fileID: -6288072647309666549}
- {fileID: 7518938298396184218}
- {fileID: -1410297666881709256}
- {fileID: -7750755424749557576}
- {fileID: -5139089513906902183}
--- !u!114 &853819529557874667
MonoBehaviour:
m_ObjectHideFlags: 3

File diff suppressed because one or more lines are too long

View File

@ -236,7 +236,457 @@ MonoBehaviour:
m_FontFeatureTable:
m_MultipleSubstitutionRecords: []
m_LigatureSubstitutionRecords: []
m_GlyphPairAdjustmentRecords: []
m_GlyphPairAdjustmentRecords:
- m_FirstAdjustmentRecord:
m_GlyphIndex: 3
m_GlyphValueRecord:
m_XPlacement: 0
m_YPlacement: 0
m_XAdvance: -4.745117
m_YAdvance: 0
m_SecondAdjustmentRecord:
m_GlyphIndex: 36
m_GlyphValueRecord:
m_XPlacement: 0
m_YPlacement: 0
m_XAdvance: 0
m_YAdvance: 0
m_FeatureLookupFlags: 0
- m_FirstAdjustmentRecord:
m_GlyphIndex: 3
m_GlyphValueRecord:
m_XPlacement: 0
m_YPlacement: 0
m_XAdvance: -1.5537109
m_YAdvance: 0
m_SecondAdjustmentRecord:
m_GlyphIndex: 55
m_GlyphValueRecord:
m_XPlacement: 0
m_YPlacement: 0
m_XAdvance: 0
m_YAdvance: 0
m_FeatureLookupFlags: 0
- m_FirstAdjustmentRecord:
m_GlyphIndex: 3
m_GlyphValueRecord:
m_XPlacement: 0
m_YPlacement: 0
m_XAdvance: -1.5537109
m_YAdvance: 0
m_SecondAdjustmentRecord:
m_GlyphIndex: 60
m_GlyphValueRecord:
m_XPlacement: 0
m_YPlacement: 0
m_XAdvance: 0
m_YAdvance: 0
m_FeatureLookupFlags: 0
- m_FirstAdjustmentRecord:
m_GlyphIndex: 3
m_GlyphValueRecord:
m_XPlacement: 0
m_YPlacement: 0
m_XAdvance: -4.745117
m_YAdvance: 0
m_SecondAdjustmentRecord:
m_GlyphIndex: 827
m_GlyphValueRecord:
m_XPlacement: 0
m_YPlacement: 0
m_XAdvance: 0
m_YAdvance: 0
m_FeatureLookupFlags: 0
- m_FirstAdjustmentRecord:
m_GlyphIndex: 3
m_GlyphValueRecord:
m_XPlacement: 0
m_YPlacement: 0
m_XAdvance: -4.745117
m_YAdvance: 0
m_SecondAdjustmentRecord:
m_GlyphIndex: 836
m_GlyphValueRecord:
m_XPlacement: 0
m_YPlacement: 0
m_XAdvance: 0
m_YAdvance: 0
m_FeatureLookupFlags: 0
- m_FirstAdjustmentRecord:
m_GlyphIndex: 3
m_GlyphValueRecord:
m_XPlacement: 0
m_YPlacement: 0
m_XAdvance: -4.745117
m_YAdvance: 0
m_SecondAdjustmentRecord:
m_GlyphIndex: 839
m_GlyphValueRecord:
m_XPlacement: 0
m_YPlacement: 0
m_XAdvance: 0
m_YAdvance: 0
m_FeatureLookupFlags: 0
- m_FirstAdjustmentRecord:
m_GlyphIndex: 3
m_GlyphValueRecord:
m_XPlacement: 0
m_YPlacement: 0
m_XAdvance: -4.745117
m_YAdvance: 0
m_SecondAdjustmentRecord:
m_GlyphIndex: 846
m_GlyphValueRecord:
m_XPlacement: 0
m_YPlacement: 0
m_XAdvance: 0
m_YAdvance: 0
m_FeatureLookupFlags: 0
- m_FirstAdjustmentRecord:
m_GlyphIndex: 3
m_GlyphValueRecord:
m_XPlacement: 0
m_YPlacement: 0
m_XAdvance: -1.5537109
m_YAdvance: 0
m_SecondAdjustmentRecord:
m_GlyphIndex: 854
m_GlyphValueRecord:
m_XPlacement: 0
m_YPlacement: 0
m_XAdvance: 0
m_YAdvance: 0
m_FeatureLookupFlags: 0
- m_FirstAdjustmentRecord:
m_GlyphIndex: 3
m_GlyphValueRecord:
m_XPlacement: 0
m_YPlacement: 0
m_XAdvance: -1.5537109
m_YAdvance: 0
m_SecondAdjustmentRecord:
m_GlyphIndex: 855
m_GlyphValueRecord:
m_XPlacement: 0
m_YPlacement: 0
m_XAdvance: 0
m_YAdvance: 0
m_FeatureLookupFlags: 0
- m_FirstAdjustmentRecord:
m_GlyphIndex: 3
m_GlyphValueRecord:
m_XPlacement: 0
m_YPlacement: 0
m_XAdvance: -1.5537109
m_YAdvance: 0
m_SecondAdjustmentRecord:
m_GlyphIndex: 861
m_GlyphValueRecord:
m_XPlacement: 0
m_YPlacement: 0
m_XAdvance: 0
m_YAdvance: 0
m_FeatureLookupFlags: 0
- m_FirstAdjustmentRecord:
m_GlyphIndex: 55
m_GlyphValueRecord:
m_XPlacement: 0
m_YPlacement: 0
m_XAdvance: -1.5537109
m_YAdvance: 0
m_SecondAdjustmentRecord:
m_GlyphIndex: 3
m_GlyphValueRecord:
m_XPlacement: 0
m_YPlacement: 0
m_XAdvance: 0
m_YAdvance: 0
m_FeatureLookupFlags: 0
- m_FirstAdjustmentRecord:
m_GlyphIndex: 55
m_GlyphValueRecord:
m_XPlacement: 0
m_YPlacement: 0
m_XAdvance: -9.532227
m_YAdvance: 0
m_SecondAdjustmentRecord:
m_GlyphIndex: 15
m_GlyphValueRecord:
m_XPlacement: 0
m_YPlacement: 0
m_XAdvance: 0
m_YAdvance: 0
m_FeatureLookupFlags: 0
- m_FirstAdjustmentRecord:
m_GlyphIndex: 55
m_GlyphValueRecord:
m_XPlacement: 0
m_YPlacement: 0
m_XAdvance: -4.745117
m_YAdvance: 0
m_SecondAdjustmentRecord:
m_GlyphIndex: 16
m_GlyphValueRecord:
m_XPlacement: 0
m_YPlacement: 0
m_XAdvance: 0
m_YAdvance: 0
m_FeatureLookupFlags: 0
- m_FirstAdjustmentRecord:
m_GlyphIndex: 55
m_GlyphValueRecord:
m_XPlacement: 0
m_YPlacement: 0
m_XAdvance: -9.532227
m_YAdvance: 0
m_SecondAdjustmentRecord:
m_GlyphIndex: 17
m_GlyphValueRecord:
m_XPlacement: 0
m_YPlacement: 0
m_XAdvance: 0
m_YAdvance: 0
m_FeatureLookupFlags: 0
- m_FirstAdjustmentRecord:
m_GlyphIndex: 55
m_GlyphValueRecord:
m_XPlacement: 0
m_YPlacement: 0
m_XAdvance: -9.532227
m_YAdvance: 0
m_SecondAdjustmentRecord:
m_GlyphIndex: 29
m_GlyphValueRecord:
m_XPlacement: 0
m_YPlacement: 0
m_XAdvance: 0
m_YAdvance: 0
m_FeatureLookupFlags: 0
- m_FirstAdjustmentRecord:
m_GlyphIndex: 55
m_GlyphValueRecord:
m_XPlacement: 0
m_YPlacement: 0
m_XAdvance: -9.532227
m_YAdvance: 0
m_SecondAdjustmentRecord:
m_GlyphIndex: 30
m_GlyphValueRecord:
m_XPlacement: 0
m_YPlacement: 0
m_XAdvance: 0
m_YAdvance: 0
m_FeatureLookupFlags: 0
- m_FirstAdjustmentRecord:
m_GlyphIndex: 55
m_GlyphValueRecord:
m_XPlacement: 0
m_YPlacement: 0
m_XAdvance: -6.3828125
m_YAdvance: 0
m_SecondAdjustmentRecord:
m_GlyphIndex: 36
m_GlyphValueRecord:
m_XPlacement: 0
m_YPlacement: 0
m_XAdvance: 0
m_YAdvance: 0
m_FeatureLookupFlags: 0
- m_FirstAdjustmentRecord:
m_GlyphIndex: 55
m_GlyphValueRecord:
m_XPlacement: 0
m_YPlacement: 0
m_XAdvance: -1.5537109
m_YAdvance: 0
m_SecondAdjustmentRecord:
m_GlyphIndex: 50
m_GlyphValueRecord:
m_XPlacement: 0
m_YPlacement: 0
m_XAdvance: 0
m_YAdvance: 0
m_FeatureLookupFlags: 0
- m_FirstAdjustmentRecord:
m_GlyphIndex: 55
m_GlyphValueRecord:
m_XPlacement: 0
m_YPlacement: 0
m_XAdvance: -9.532227
m_YAdvance: 0
m_SecondAdjustmentRecord:
m_GlyphIndex: 68
m_GlyphValueRecord:
m_XPlacement: 0
m_YPlacement: 0
m_XAdvance: 0
m_YAdvance: 0
m_FeatureLookupFlags: 0
- m_FirstAdjustmentRecord:
m_GlyphIndex: 55
m_GlyphValueRecord:
m_XPlacement: 0
m_YPlacement: 0
m_XAdvance: -9.532227
m_YAdvance: 0
m_SecondAdjustmentRecord:
m_GlyphIndex: 70
m_GlyphValueRecord:
m_XPlacement: 0
m_YPlacement: 0
m_XAdvance: 0
m_YAdvance: 0
m_FeatureLookupFlags: 0
- m_FirstAdjustmentRecord:
m_GlyphIndex: 55
m_GlyphValueRecord:
m_XPlacement: 0
m_YPlacement: 0
m_XAdvance: -9.532227
m_YAdvance: 0
m_SecondAdjustmentRecord:
m_GlyphIndex: 72
m_GlyphValueRecord:
m_XPlacement: 0
m_YPlacement: 0
m_XAdvance: 0
m_YAdvance: 0
m_FeatureLookupFlags: 0
- m_FirstAdjustmentRecord:
m_GlyphIndex: 55
m_GlyphValueRecord:
m_XPlacement: 0
m_YPlacement: 0
m_XAdvance: -3.1914062
m_YAdvance: 0
m_SecondAdjustmentRecord:
m_GlyphIndex: 76
m_GlyphValueRecord:
m_XPlacement: 0
m_YPlacement: 0
m_XAdvance: 0
m_YAdvance: 0
m_FeatureLookupFlags: 0
- m_FirstAdjustmentRecord:
m_GlyphIndex: 55
m_GlyphValueRecord:
m_XPlacement: 0
m_YPlacement: 0
m_XAdvance: -9.532227
m_YAdvance: 0
m_SecondAdjustmentRecord:
m_GlyphIndex: 82
m_GlyphValueRecord:
m_XPlacement: 0
m_YPlacement: 0
m_XAdvance: 0
m_YAdvance: 0
m_FeatureLookupFlags: 0
- m_FirstAdjustmentRecord:
m_GlyphIndex: 55
m_GlyphValueRecord:
m_XPlacement: 0
m_YPlacement: 0
m_XAdvance: -3.1914062
m_YAdvance: 0
m_SecondAdjustmentRecord:
m_GlyphIndex: 85
m_GlyphValueRecord:
m_XPlacement: 0
m_YPlacement: 0
m_XAdvance: 0
m_YAdvance: 0
m_FeatureLookupFlags: 0
- m_FirstAdjustmentRecord:
m_GlyphIndex: 55
m_GlyphValueRecord:
m_XPlacement: 0
m_YPlacement: 0
m_XAdvance: -9.532227
m_YAdvance: 0
m_SecondAdjustmentRecord:
m_GlyphIndex: 86
m_GlyphValueRecord:
m_XPlacement: 0
m_YPlacement: 0
m_XAdvance: 0
m_YAdvance: 0
m_FeatureLookupFlags: 0
- m_FirstAdjustmentRecord:
m_GlyphIndex: 55
m_GlyphValueRecord:
m_XPlacement: 0
m_YPlacement: 0
m_XAdvance: -3.1914062
m_YAdvance: 0
m_SecondAdjustmentRecord:
m_GlyphIndex: 88
m_GlyphValueRecord:
m_XPlacement: 0
m_YPlacement: 0
m_XAdvance: 0
m_YAdvance: 0
m_FeatureLookupFlags: 0
- m_FirstAdjustmentRecord:
m_GlyphIndex: 55
m_GlyphValueRecord:
m_XPlacement: 0
m_YPlacement: 0
m_XAdvance: -4.745117
m_YAdvance: 0
m_SecondAdjustmentRecord:
m_GlyphIndex: 90
m_GlyphValueRecord:
m_XPlacement: 0
m_YPlacement: 0
m_XAdvance: 0
m_YAdvance: 0
m_FeatureLookupFlags: 0
- m_FirstAdjustmentRecord:
m_GlyphIndex: 55
m_GlyphValueRecord:
m_XPlacement: 0
m_YPlacement: 0
m_XAdvance: -4.745117
m_YAdvance: 0
m_SecondAdjustmentRecord:
m_GlyphIndex: 92
m_GlyphValueRecord:
m_XPlacement: 0
m_YPlacement: 0
m_XAdvance: 0
m_YAdvance: 0
m_FeatureLookupFlags: 0
- m_FirstAdjustmentRecord:
m_GlyphIndex: 90
m_GlyphValueRecord:
m_XPlacement: 0
m_YPlacement: 0
m_XAdvance: -4.745117
m_YAdvance: 0
m_SecondAdjustmentRecord:
m_GlyphIndex: 15
m_GlyphValueRecord:
m_XPlacement: 0
m_YPlacement: 0
m_XAdvance: 0
m_YAdvance: 0
m_FeatureLookupFlags: 0
- m_FirstAdjustmentRecord:
m_GlyphIndex: 90
m_GlyphValueRecord:
m_XPlacement: 0
m_YPlacement: 0
m_XAdvance: -4.745117
m_YAdvance: 0
m_SecondAdjustmentRecord:
m_GlyphIndex: 17
m_GlyphValueRecord:
m_XPlacement: 0
m_YPlacement: 0
m_XAdvance: 0
m_YAdvance: 0
m_FeatureLookupFlags: 0
m_MarkToBaseAdjustmentRecords: []
m_MarkToMarkAdjustmentRecords: []
m_ShouldReimportFontFeatures: 0

View File

@ -4,7 +4,8 @@
<defName>smallHealthPotion</defName>
<label>小生命瓶</label>
<description>可以回复一点点血量</description>
<!-- <texture>TestGun</texture>
<itemTexture>TestGunItem</itemTexture> -->
<textures>
<li>TestGun</li>
</textures>
</ItemDef>
</Define>

View File

@ -4,8 +4,24 @@
<MonsterDef>
<defName>chicken</defName>
<label>测试鸡</label>
<aiController>embrace</aiController>
<!-- <weapon>Claw</weapon> -->
<behaviorTree>
<Node className="JobGiver_RandomWander"/>
</behaviorTree>
<affiliation>monster</affiliation>
<drawingOrder>
<idle_down name="Body" FPS="10">
<textures>
<li>testPawnAnimation_0</li>
<li>testPawnAnimation_1</li>
<li>testPawnAnimation_2</li>
<li>testPawnAnimation_3</li>
<li>testPawnAnimation_4</li>
<li>testPawnAnimation_3</li>
<li>testPawnAnimation_2</li>
<li>testPawnAnimation_1</li>
</textures>
</idle_down>
</drawingOrder>
</MonsterDef>