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 0000000..5aae8d9 Binary files /dev/null and b/unity/Assets/eco/Prefabs/white_pixel.png differ 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: