From dfeed782989012c01885bb2a706765f5762814d8 Mon Sep 17 00:00:00 2001
From: ksh999000 <740612340@qq.com>
Date: Wed, 1 Jul 2026 00:30:19 +0800
Subject: [PATCH] =?UTF-8?q?=E6=9B=B4=E6=96=B0=E6=95=8C=E4=BA=BA=E8=A1=80?=
=?UTF-8?q?=E9=87=8F=E5=8A=9F=E8=83=BD?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
unity/Assets/2.5D Engine/Enemy.prefab | 249 ++++++++++++++++++
.../shaders/IndianOcean_DarknessOverlay.mat | 2 +-
unity/Assets/Scenes/Gameplay.unity | 6 +-
unity/Assets/eco/Prefabs/white_pixel.png | Bin 0 -> 68 bytes
unity/Assets/eco/Prefabs/white_pixel.png.meta | 175 ++++++++++++
unity/Assets/enemy/EnemyHealthBar.cs | 97 +++++++
unity/Assets/enemy/EnemyHealthBar.cs.meta | 11 +
7 files changed, 538 insertions(+), 2 deletions(-)
create mode 100644 unity/Assets/eco/Prefabs/white_pixel.png
create mode 100644 unity/Assets/eco/Prefabs/white_pixel.png.meta
create mode 100644 unity/Assets/enemy/EnemyHealthBar.cs
create mode 100644 unity/Assets/enemy/EnemyHealthBar.cs.meta
diff --git a/unity/Assets/2.5D Engine/Enemy.prefab b/unity/Assets/2.5D Engine/Enemy.prefab
index 4948ea1..d50e02d 100644
--- a/unity/Assets/2.5D Engine/Enemy.prefab
+++ b/unity/Assets/2.5D Engine/Enemy.prefab
@@ -1,5 +1,39 @@
%YAML 1.1
%TAG !u! tag:yousandi.cn,2023:
+--- !u!1 &1748704152308654635
+GameObject:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ serializedVersion: 7
+ m_Component:
+ - component: {fileID: 3470028423354261367}
+ m_Layer: 0
+ m_HasEditorInfo: 1
+ m_Name: HealthBar_Root
+ m_TagString: Untagged
+ m_Icon: {fileID: 0}
+ m_NavMeshLayer: 0
+ m_StaticEditorFlags: 0
+ m_IsActive: 1
+--- !u!4 &3470028423354261367
+Transform:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 1748704152308654635}
+ serializedVersion: 2
+ m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
+ m_LocalPosition: {x: 0, y: 1.2, z: 0}
+ m_LocalScale: {x: 1, y: 1, z: 1}
+ m_ConstrainProportionsScale: 0
+ m_Children:
+ - {fileID: 657877630226175948}
+ - {fileID: 5577642396534762232}
+ m_Father: {fileID: 8894851355281676783}
+ m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!1 &1886377545685493984
GameObject:
m_ObjectHideFlags: 0
@@ -89,6 +123,94 @@ SpriteRenderer:
m_WasSpriteAssigned: 1
m_MaskInteraction: 0
m_SpriteSortPoint: 0
+--- !u!1 &2094714580264746838
+GameObject:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ serializedVersion: 7
+ m_Component:
+ - component: {fileID: 5577642396534762232}
+ - component: {fileID: 6035173797039965174}
+ m_Layer: 0
+ m_HasEditorInfo: 1
+ m_Name: Fill
+ m_TagString: Untagged
+ m_Icon: {fileID: 0}
+ m_NavMeshLayer: 0
+ m_StaticEditorFlags: 0
+ m_IsActive: 1
+--- !u!4 &5577642396534762232
+Transform:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 2094714580264746838}
+ serializedVersion: 2
+ m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
+ m_LocalPosition: {x: 0, y: 0, z: 0}
+ m_LocalScale: {x: 1, y: 0.1, z: 1}
+ m_ConstrainProportionsScale: 0
+ m_Children: []
+ m_Father: {fileID: 3470028423354261367}
+ m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+--- !u!212 &6035173797039965174
+SpriteRenderer:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 2094714580264746838}
+ m_Enabled: 1
+ m_CastShadows: 0
+ m_ReceiveShadows: 0
+ m_DynamicOccludee: 1
+ m_StaticShadowCaster: 0
+ m_MotionVectors: 1
+ m_LightProbeUsage: 1
+ m_ReflectionProbeUsage: 1
+ m_RayTracingMode: 0
+ m_RayTraceProcedural: 0
+ m_virtualGeometry: 0
+ m_virtualGeometryShadow: 0
+ m_ShadingRate: 0
+ m_RenderingLayerMask: 1
+ m_RendererPriority: 0
+ m_Materials:
+ - {fileID: 10754, guid: 0000000000000000f000000000000000, type: 0}
+ m_StaticBatchInfo:
+ firstSubMesh: 0
+ subMeshCount: 0
+ m_StaticBatchRoot: {fileID: 0}
+ m_ProbeAnchor: {fileID: 0}
+ m_LightProbeVolumeOverride: {fileID: 0}
+ m_ScaleInLightmap: 1
+ m_ReceiveGI: 1
+ m_PreserveUVs: 0
+ m_IgnoreNormalsForChartDetection: 0
+ m_ImportantGI: 0
+ m_StitchLightmapSeams: 1
+ m_SelectedEditorRenderState: 0
+ m_MinimumChartSize: 4
+ m_AutoUVMaxDistance: 0.5
+ m_AutoUVMaxAngle: 89
+ m_LightmapParameters: {fileID: 0}
+ m_SortingLayerID: 0
+ m_SortingLayer: 0
+ m_SortingOrder: 10001
+ m_Sprite: {fileID: 21300000, guid: af0b4d1e932af904b993bb0c1dcdd8ad, type: 3}
+ m_Color: {r: 0.8, g: 0.1, b: 0.1, a: 0.9}
+ m_FlipX: 0
+ m_FlipY: 0
+ m_DrawMode: 0
+ m_Size: {x: 0.01, y: 0.01}
+ m_AdaptiveModeThreshold: 0.5
+ m_SpriteTileMode: 0
+ m_WasSpriteAssigned: 1
+ m_MaskInteraction: 0
+ m_SpriteSortPoint: 0
--- !u!1 &2150025513644625521
GameObject:
m_ObjectHideFlags: 0
@@ -103,6 +225,8 @@ GameObject:
- component: {fileID: 8968468909950613264}
- component: {fileID: 6802842831935334424}
- component: {fileID: 2877034408413616420}
+ - component: {fileID: 350980459442417952}
+ - component: {fileID: 1893771889199554109}
m_Layer: 6
m_HasEditorInfo: 1
m_Name: Enemy
@@ -125,6 +249,7 @@ Transform:
m_ConstrainProportionsScale: 0
m_Children:
- {fileID: 2387478274195477212}
+ - {fileID: 3470028423354261367}
m_Father: {fileID: 0}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!95 &8063991991785530743
@@ -243,6 +368,130 @@ MonoBehaviour:
rotationSpeed: 8
snapAngle: 0.5
deadZone: 0.2
+--- !u!114 &350980459442417952
+MonoBehaviour:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 2150025513644625521}
+ m_Enabled: 1
+ m_EditorHideFlags: 0
+ m_Script: {fileID: 11500000, guid: f9e36f6d2e0ea0541bad29e784e0841b, type: 3}
+ m_Name:
+ m_EditorClassIdentifier:
+ maxHealth: 3
+ deathEffect: {fileID: 0}
+ isPlayer: 0
+--- !u!114 &1893771889199554109
+MonoBehaviour:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 2150025513644625521}
+ m_Enabled: 1
+ m_EditorHideFlags: 0
+ m_Script: {fileID: 11500000, guid: 4e48ef6f15c1fe4489685589431cf726, type: 3}
+ m_Name:
+ m_EditorClassIdentifier:
+ barRoot: {fileID: 3470028423354261367}
+ bgRenderer: {fileID: 3494928282840881329}
+ fillRenderer: {fileID: 6035173797039965174}
+ barWidth: 1
+ barHeight: 0.1
+ fillColor: {r: 0.8, g: 0.1, b: 0.1, a: 0.9}
+ lowHealthColor: {r: 1, g: 0.3, b: 0, a: 0.9}
+ lowHealthThreshold: 0.3
+ hideWhenFull: 1
+--- !u!1 &8348150211127470280
+GameObject:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ serializedVersion: 7
+ m_Component:
+ - component: {fileID: 657877630226175948}
+ - component: {fileID: 3494928282840881329}
+ m_Layer: 0
+ m_HasEditorInfo: 1
+ m_Name: BG
+ m_TagString: Untagged
+ m_Icon: {fileID: 0}
+ m_NavMeshLayer: 0
+ m_StaticEditorFlags: 0
+ m_IsActive: 1
+--- !u!4 &657877630226175948
+Transform:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 8348150211127470280}
+ serializedVersion: 2
+ m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
+ m_LocalPosition: {x: 0, y: 0, z: 0}
+ m_LocalScale: {x: 1, y: 0.1, z: 1}
+ m_ConstrainProportionsScale: 0
+ m_Children: []
+ m_Father: {fileID: 3470028423354261367}
+ m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+--- !u!212 &3494928282840881329
+SpriteRenderer:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 8348150211127470280}
+ m_Enabled: 1
+ m_CastShadows: 0
+ m_ReceiveShadows: 0
+ m_DynamicOccludee: 1
+ m_StaticShadowCaster: 0
+ m_MotionVectors: 1
+ m_LightProbeUsage: 1
+ m_ReflectionProbeUsage: 1
+ m_RayTracingMode: 0
+ m_RayTraceProcedural: 0
+ m_virtualGeometry: 0
+ m_virtualGeometryShadow: 0
+ m_ShadingRate: 0
+ m_RenderingLayerMask: 1
+ m_RendererPriority: 0
+ m_Materials:
+ - {fileID: 10754, guid: 0000000000000000f000000000000000, type: 0}
+ m_StaticBatchInfo:
+ firstSubMesh: 0
+ subMeshCount: 0
+ m_StaticBatchRoot: {fileID: 0}
+ m_ProbeAnchor: {fileID: 0}
+ m_LightProbeVolumeOverride: {fileID: 0}
+ m_ScaleInLightmap: 1
+ m_ReceiveGI: 1
+ m_PreserveUVs: 0
+ m_IgnoreNormalsForChartDetection: 0
+ m_ImportantGI: 0
+ m_StitchLightmapSeams: 1
+ m_SelectedEditorRenderState: 0
+ m_MinimumChartSize: 4
+ m_AutoUVMaxDistance: 0.5
+ m_AutoUVMaxAngle: 89
+ m_LightmapParameters: {fileID: 0}
+ m_SortingLayerID: 0
+ m_SortingLayer: 0
+ m_SortingOrder: 10000
+ m_Sprite: {fileID: 21300000, guid: af0b4d1e932af904b993bb0c1dcdd8ad, type: 3}
+ m_Color: {r: 0.2, g: 0.2, b: 0.2, a: 0.8}
+ m_FlipX: 0
+ m_FlipY: 0
+ m_DrawMode: 0
+ m_Size: {x: 0.01, y: 0.01}
+ m_AdaptiveModeThreshold: 0.5
+ m_SpriteTileMode: 0
+ m_WasSpriteAssigned: 1
+ m_MaskInteraction: 0
+ m_SpriteSortPoint: 0
--- !u!1 &8532340994753211982
GameObject:
m_ObjectHideFlags: 0
diff --git a/unity/Assets/Light/shaders/IndianOcean_DarknessOverlay.mat b/unity/Assets/Light/shaders/IndianOcean_DarknessOverlay.mat
index 93efba6..2abee3a 100644
--- a/unity/Assets/Light/shaders/IndianOcean_DarknessOverlay.mat
+++ b/unity/Assets/Light/shaders/IndianOcean_DarknessOverlay.mat
@@ -31,7 +31,7 @@ Material:
- _EchoRadius: 39.41617
- _EchoWidth: 2.5
- _LightSoftness: 1
- - _MinBrightness: 1
+ - _MinBrightness: 0
m_Colors:
- _DarknessColor: {r: 0.01, g: 0.01, b: 0.02, a: 1}
- _EchoCenter: {r: -2.4399998, g: -1.5000057, b: 0, a: 0}
diff --git a/unity/Assets/Scenes/Gameplay.unity b/unity/Assets/Scenes/Gameplay.unity
index 099affa..e053130 100644
--- a/unity/Assets/Scenes/Gameplay.unity
+++ b/unity/Assets/Scenes/Gameplay.unity
@@ -155,7 +155,7 @@ MonoBehaviour:
m_Name:
m_EditorClassIdentifier:
darknessMaterial: {fileID: 2100000, guid: 6dd18d2379aff3040813ab8005b1898a, type: 2}
- debugShowAll: 1
+ debugShowAll: 0
minBrightness: 0
darknessColor: {r: 0.01, g: 0.01, b: 0.02, a: 1}
lightSoftness: 1
@@ -2514,6 +2514,10 @@ PrefabInstance:
propertyPath: m_Sprite
value:
objectReference: {fileID: 21300000, guid: 65c67fef26e92dc468f154fb308d155a, type: 3}
+ - target: {fileID: 6139836475852784366, guid: caf051d43a1fd9344a29f0c7376bbf5f, type: 3}
+ propertyPath: lanternPrefab
+ value:
+ objectReference: {fileID: 6632183076166779216, guid: 0f3bb1de506ca954eb6fa1ddfc32d9bb, type: 3}
- target: {fileID: 7107154609808163723, guid: caf051d43a1fd9344a29f0c7376bbf5f, type: 3}
propertyPath: m_Name
value: Player
diff --git a/unity/Assets/eco/Prefabs/white_pixel.png b/unity/Assets/eco/Prefabs/white_pixel.png
new file mode 100644
index 0000000000000000000000000000000000000000..5aae8d9404b4e4655023c203f60a0af223370bc7
GIT binary patch
literal 68
zcmeAS@N?(olHy`uVBq!ia0vp^j3CUx1|;Q0k8}blZci7-5DwYoAN(u~oWGg>^6ZX&
Q4iskaboFyt=akR{0Dt=qE&u=k
literal 0
HcmV?d00001
diff --git a/unity/Assets/eco/Prefabs/white_pixel.png.meta b/unity/Assets/eco/Prefabs/white_pixel.png.meta
new file mode 100644
index 0000000..3f71011
--- /dev/null
+++ b/unity/Assets/eco/Prefabs/white_pixel.png.meta
@@ -0,0 +1,175 @@
+fileFormatVersion: 2
+guid: Xiwf5y75Ui7b+pZE3ACZZLCVq7I9YvrjuIcdh3DN9vuK0lWxN39X+XA=
+TextureImporter:
+ internalIDToNameTable: []
+ externalObjects: {}
+ serializedVersion: 13
+ mipmaps:
+ mipMapMode: 0
+ enableMipMap: 0
+ sRGBTexture: 1
+ linearTexture: 0
+ fadeOut: 0
+ borderMipMap: 0
+ mipMapsPreserveCoverage: 0
+ alphaTestReferenceValue: 0.5
+ mipMapFadeDistanceStart: 1
+ mipMapFadeDistanceEnd: 3
+ bumpmap:
+ convertToNormalMap: 0
+ externalNormalMap: 0
+ heightScale: 0.25
+ normalMapFilter: 0
+ flipGreenChannel: 0
+ isReadable: 0
+ webStreaming: 0
+ priorityLevel: 0
+ uploadedMode: 2
+ streamingMipmaps: 0
+ streamingMipmapsPriority: 0
+ vTOnly: 0
+ ignoreMipmapLimit: 0
+ grayScaleToAlpha: 0
+ generateCubemap: 6
+ cubemapConvolution: 0
+ seamlessCubemap: 0
+ textureFormat: 1
+ maxTextureSize: 2048
+ textureSettings:
+ serializedVersion: 2
+ filterMode: 1
+ aniso: 1
+ mipBias: 0
+ wrapU: 1
+ wrapV: 1
+ wrapW: 1
+ nPOTScale: 0
+ lightmap: 0
+ compressionQuality: 50
+ spriteMode: 1
+ spriteExtrude: 1
+ spriteMeshType: 1
+ alignment: 0
+ spritePivot: {x: 0.5, y: 0.5}
+ spritePixelsToUnits: 100
+ spriteBorder: {x: 0, y: 0, z: 0, w: 0}
+ spriteGenerateFallbackPhysicsShape: 1
+ alphaUsage: 1
+ alphaIsTransparency: 1
+ spriteTessellationDetail: -1
+ textureType: 8
+ textureShape: 1
+ singleChannelComponent: 0
+ flipbookRows: 1
+ flipbookColumns: 1
+ maxTextureSizeSet: 0
+ compressionQualitySet: 0
+ textureFormatSet: 0
+ ignorePngGamma: 0
+ applyGammaDecoding: 0
+ swizzle: 50462976
+ cookieLightType: 0
+ platformSettings:
+ - serializedVersion: 3
+ buildTarget: DefaultTexturePlatform
+ maxTextureSize: 2048
+ maxPlaceholderSize: 32
+ resizeAlgorithm: 0
+ textureFormat: -1
+ textureCompression: 0
+ compressionQuality: 50
+ crunchedCompression: 0
+ allowsAlphaSplitting: 0
+ overridden: 0
+ ignorePlatformSupport: 0
+ androidETC2FallbackOverride: 0
+ forceMaximumCompressionQuality_BC6H_BC7: 0
+ - serializedVersion: 3
+ buildTarget: Standalone
+ maxTextureSize: 2048
+ maxPlaceholderSize: 32
+ resizeAlgorithm: 0
+ textureFormat: -1
+ textureCompression: 1
+ compressionQuality: 50
+ crunchedCompression: 0
+ allowsAlphaSplitting: 0
+ overridden: 0
+ ignorePlatformSupport: 0
+ androidETC2FallbackOverride: 0
+ forceMaximumCompressionQuality_BC6H_BC7: 0
+ - serializedVersion: 3
+ buildTarget: Server
+ maxTextureSize: 2048
+ maxPlaceholderSize: 32
+ resizeAlgorithm: 0
+ textureFormat: -1
+ textureCompression: 1
+ compressionQuality: 50
+ crunchedCompression: 0
+ allowsAlphaSplitting: 0
+ overridden: 0
+ ignorePlatformSupport: 0
+ androidETC2FallbackOverride: 0
+ forceMaximumCompressionQuality_BC6H_BC7: 0
+ - serializedVersion: 3
+ buildTarget: Android
+ maxTextureSize: 2048
+ maxPlaceholderSize: 32
+ resizeAlgorithm: 0
+ textureFormat: -1
+ textureCompression: 1
+ compressionQuality: 50
+ crunchedCompression: 0
+ allowsAlphaSplitting: 0
+ overridden: 0
+ ignorePlatformSupport: 0
+ androidETC2FallbackOverride: 0
+ forceMaximumCompressionQuality_BC6H_BC7: 0
+ - serializedVersion: 3
+ buildTarget: HMIAndroid
+ maxTextureSize: 2048
+ maxPlaceholderSize: 32
+ resizeAlgorithm: 0
+ textureFormat: -1
+ textureCompression: 1
+ compressionQuality: 50
+ crunchedCompression: 0
+ allowsAlphaSplitting: 0
+ overridden: 0
+ ignorePlatformSupport: 0
+ androidETC2FallbackOverride: 0
+ forceMaximumCompressionQuality_BC6H_BC7: 0
+ - serializedVersion: 3
+ buildTarget: OpenHarmony
+ maxTextureSize: 2048
+ maxPlaceholderSize: 32
+ resizeAlgorithm: 0
+ textureFormat: -1
+ textureCompression: 1
+ compressionQuality: 50
+ crunchedCompression: 0
+ allowsAlphaSplitting: 0
+ overridden: 0
+ ignorePlatformSupport: 0
+ androidETC2FallbackOverride: 0
+ forceMaximumCompressionQuality_BC6H_BC7: 0
+ spriteSheet:
+ serializedVersion: 2
+ sprites: []
+ outline: []
+ physicsShape: []
+ bones: []
+ spriteID: 5e97eb03825dee720800000000000000
+ internalID: 0
+ vertices: []
+ indices:
+ edges: []
+ weights: []
+ secondaryTextures: []
+ nameFileIdTable: {}
+ mipmapLimitGroupName:
+ pSDRemoveMatte: 0
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/unity/Assets/enemy/EnemyHealthBar.cs b/unity/Assets/enemy/EnemyHealthBar.cs
new file mode 100644
index 0000000..99c3ac8
--- /dev/null
+++ b/unity/Assets/enemy/EnemyHealthBar.cs
@@ -0,0 +1,97 @@
+using UnityEngine;
+
+namespace IndianOceanAssets.Engine2_5D
+{
+ ///
+ /// 敌人头顶血条 —— 挂在敌人 Prefab 上。
+ /// 血条可视化物体(BG、Fill)已在 Prefab 中预建,
+ /// 运行时直接引用,无需动态创建。
+ ///
+ [RequireComponent(typeof(HealthSystem))]
+ public class EnemyHealthBar : MonoBehaviour
+ {
+ [Header("血条引用(Prefab 中预建)")]
+ [SerializeField] private Transform barRoot;
+ [SerializeField] private SpriteRenderer bgRenderer;
+ [SerializeField] private SpriteRenderer fillRenderer;
+
+ [Header("血条参数")]
+ [Tooltip("血条宽度(世界单位)")]
+ [SerializeField] private float barWidth = 1f;
+
+ [Tooltip("血条高度(世界单位)")]
+ [SerializeField] private float barHeight = 0.1f;
+
+ [Header("颜色")]
+ [SerializeField] private Color fillColor = new Color(0.8f, 0.1f, 0.1f, 0.9f);
+ [SerializeField] private Color lowHealthColor = new Color(1f, 0.3f, 0f, 0.9f);
+
+ [Tooltip("低于此比例时切换为低血量颜色")]
+ [SerializeField] private float lowHealthThreshold = 0.3f;
+
+ [Header("显示控制")]
+ [Tooltip("满血时是否隐藏血条")]
+ [SerializeField] private bool hideWhenFull = false;
+
+ private HealthSystem _healthSystem;
+ private int _lastHealth = -1;
+ private int _maxHealth;
+
+ private void Start()
+ {
+ _healthSystem = GetComponent();
+ if (_healthSystem == null)
+ {
+ enabled = false;
+ return;
+ }
+
+ // 获取 maxHealth(通过反射读取私有字段)
+ var field = typeof(HealthSystem).GetField("maxHealth",
+ System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
+ if (field != null)
+ _maxHealth = (int)field.GetValue(_healthSystem);
+ else
+ _maxHealth = 3;
+
+ UpdateBar();
+ }
+
+ private void LateUpdate()
+ {
+ UpdateBar();
+ }
+
+ ///
+ /// 根据当前血量更新血条显示。
+ ///
+ private void UpdateBar()
+ {
+ if (_healthSystem == null || fillRenderer == null || bgRenderer == null) return;
+
+ // 获取当前血量(反射)
+ var healthField = typeof(HealthSystem).GetField("health",
+ System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
+ int currentHealth = healthField != null ? (int)healthField.GetValue(_healthSystem) : _maxHealth;
+
+ // 血量没变化则跳过(性能优化)
+ if (currentHealth == _lastHealth) return;
+ _lastHealth = currentHealth;
+
+ float ratio = Mathf.Clamp01((float)currentHealth / _maxHealth);
+
+ // 更新填充条缩放(居中对齐)
+ fillRenderer.transform.localScale = new Vector3(barWidth * ratio, barHeight, 1f);
+ fillRenderer.transform.localPosition = new Vector3(
+ -(barWidth * (1f - ratio)) * 0.5f, 0f, 0f);
+
+ // 低血量变色
+ fillRenderer.color = ratio <= lowHealthThreshold ? lowHealthColor : fillColor;
+
+ // 满血隐藏
+ bool visible = !(hideWhenFull && ratio >= 1f);
+ bgRenderer.enabled = visible;
+ fillRenderer.enabled = visible;
+ }
+ }
+}
diff --git a/unity/Assets/enemy/EnemyHealthBar.cs.meta b/unity/Assets/enemy/EnemyHealthBar.cs.meta
new file mode 100644
index 0000000..6519f6b
--- /dev/null
+++ b/unity/Assets/enemy/EnemyHealthBar.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: Cy8bvX/7VS2Xw8UPm+xVO10St2ZLYIfNQjI1F32eDgJoKoBuc0L5+W0=
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant: