From d9badf5c6a64b2aab282e80ddc7661c5061179ad Mon Sep 17 00:00:00 2001 From: Hazim Bin Ijaz Date: Wed, 13 Aug 2025 19:17:14 +0500 Subject: [PATCH] Working on AI movement completed UI system etc --- .../Scenes/DemoExterior.unity | 32 +++- Assets/Prefabs/UI/AbilityUIItem.prefab | 173 ++++++++++++++++-- .../Abilities/Channel Heal Ability.asset | 21 +++ .../Abilities/Channel Heal Ability.asset.meta | 8 + ...l Ability.asset => Fireball Ability.asset} | 2 +- ...asset.meta => Fireball Ability.asset.meta} | 0 .../AbilityClasses/ChannelHealAbility.cs | 50 +++++ .../AbilityClasses/ChannelHealAbility.cs.meta | 11 ++ .../AbilityClasses/FreezeShardAbility.cs | 39 ++++ .../AbilityClasses/FreezeShardAbility.cs.meta | 11 ++ Assets/Scripts/Abilities/AbilityInput.cs | 12 ++ Assets/Scripts/Abilities/AbilitySlot.cs | 1 + .../Scripts/Behvaiours/FreezableNavAgent.cs | 121 ++++++++++++ .../Behvaiours/FreezableNavAgent.cs.meta | 11 ++ .../Behvaiours/FreezeShardProjectile.cs | 31 ++++ .../Behvaiours/FreezeShardProjectile.cs.meta | 11 ++ Assets/Scripts/Interfaces/IFreezable.cs | 4 + Assets/Scripts/Interfaces/IFreezable.cs.meta | 11 ++ Assets/Scripts/UI.meta | 8 + Assets/Scripts/UI/AbilityUIItem.cs | 19 ++ Assets/Scripts/UI/AbilityUIItem.cs.meta | 11 ++ 21 files changed, 573 insertions(+), 14 deletions(-) create mode 100644 Assets/ScriptableObjects/Abilities/Channel Heal Ability.asset create mode 100644 Assets/ScriptableObjects/Abilities/Channel Heal Ability.asset.meta rename Assets/ScriptableObjects/Abilities/{New Fireball Ability.asset => Fireball Ability.asset} (95%) rename Assets/ScriptableObjects/Abilities/{New Fireball Ability.asset.meta => Fireball Ability.asset.meta} (100%) create mode 100644 Assets/Scripts/Abilities/AbilityClasses/ChannelHealAbility.cs create mode 100644 Assets/Scripts/Abilities/AbilityClasses/ChannelHealAbility.cs.meta create mode 100644 Assets/Scripts/Abilities/AbilityClasses/FreezeShardAbility.cs create mode 100644 Assets/Scripts/Abilities/AbilityClasses/FreezeShardAbility.cs.meta create mode 100644 Assets/Scripts/Behvaiours/FreezableNavAgent.cs create mode 100644 Assets/Scripts/Behvaiours/FreezableNavAgent.cs.meta create mode 100644 Assets/Scripts/Behvaiours/FreezeShardProjectile.cs create mode 100644 Assets/Scripts/Behvaiours/FreezeShardProjectile.cs.meta create mode 100644 Assets/Scripts/Interfaces/IFreezable.cs create mode 100644 Assets/Scripts/Interfaces/IFreezable.cs.meta create mode 100644 Assets/Scripts/UI.meta create mode 100644 Assets/Scripts/UI/AbilityUIItem.cs create mode 100644 Assets/Scripts/UI/AbilityUIItem.cs.meta diff --git a/Assets/Polyart/PolyartStudio/DreamscapeCastle/Scenes/DemoExterior.unity b/Assets/Polyart/PolyartStudio/DreamscapeCastle/Scenes/DemoExterior.unity index 3340d236..76036581 100644 --- a/Assets/Polyart/PolyartStudio/DreamscapeCastle/Scenes/DemoExterior.unity +++ b/Assets/Polyart/PolyartStudio/DreamscapeCastle/Scenes/DemoExterior.unity @@ -160535,6 +160535,18 @@ RectTransform: type: 3} m_PrefabInstance: {fileID: 1019458777} m_PrefabAsset: {fileID: 0} +--- !u!114 &1019458779 stripped +MonoBehaviour: + m_CorrespondingSourceObject: {fileID: 372725716160773496, guid: d208e0f3e2f10a440a15e9b095c4a0e8, + type: 3} + m_PrefabInstance: {fileID: 1019458777} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 30dcebf945ea1bc439c74273d4bf48f5, type: 3} + m_Name: + m_EditorClassIdentifier: --- !u!1001 &1021336978 PrefabInstance: m_ObjectHideFlags: 0 @@ -354747,12 +354759,16 @@ MonoBehaviour: user: {fileID: 2042403783257441066} slots: - ability: {fileID: 11400000, guid: 238ff629516647b448b2d6517f15b364, type: 2} + abilityUiItem: {fileID: 3533359467842034143} + cdTimer: 0 + - ability: {fileID: 11400000, guid: 2cdcec8b6c2310d46847af6f490ad3e8, type: 2} + abilityUiItem: {fileID: 1019458779} cdTimer: 0 - ability: {fileID: 0} + abilityUiItem: {fileID: 0} cdTimer: 0 - ability: {fileID: 0} - cdTimer: 0 - - ability: {fileID: 0} + abilityUiItem: {fileID: 0} cdTimer: 0 --- !u!1001 &2612565535725099600 PrefabInstance: @@ -355112,6 +355128,18 @@ RectTransform: type: 3} m_PrefabInstance: {fileID: 3533359467842034141} m_PrefabAsset: {fileID: 0} +--- !u!114 &3533359467842034143 stripped +MonoBehaviour: + m_CorrespondingSourceObject: {fileID: 372725716160773496, guid: d208e0f3e2f10a440a15e9b095c4a0e8, + type: 3} + m_PrefabInstance: {fileID: 3533359467842034141} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 30dcebf945ea1bc439c74273d4bf48f5, type: 3} + m_Name: + m_EditorClassIdentifier: --- !u!1001 &3685549447243067346 PrefabInstance: m_ObjectHideFlags: 0 diff --git a/Assets/Prefabs/UI/AbilityUIItem.prefab b/Assets/Prefabs/UI/AbilityUIItem.prefab index a72f834c..cb64a187 100644 --- a/Assets/Prefabs/UI/AbilityUIItem.prefab +++ b/Assets/Prefabs/UI/AbilityUIItem.prefab @@ -12,7 +12,7 @@ GameObject: - component: {fileID: 2242664937601471350} - component: {fileID: 1137290063122843096} m_Layer: 5 - m_Name: Text (TMP) + m_Name: AbiliyNameText (TMP) m_TagString: Untagged m_Icon: {fileID: 0} m_NavMeshLayer: 0 @@ -32,10 +32,10 @@ RectTransform: m_Children: [] m_Father: {fileID: 4918938079055515515} m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} - m_AnchorMin: {x: 0, y: 0} - m_AnchorMax: {x: 1, y: 0} - m_AnchoredPosition: {x: 0, y: 17.2471} - m_SizeDelta: {x: 0, y: 34.4941} + m_AnchorMin: {x: 0, y: 1} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: -17.24704} + m_SizeDelta: {x: 0, y: 34.494095} m_Pivot: {x: 0.5, y: 0.5} --- !u!222 &2242664937601471350 CanvasRenderer: @@ -65,7 +65,7 @@ MonoBehaviour: m_OnCullStateChanged: m_PersistentCalls: m_Calls: [] - m_text: Ability 1 + m_text: -- m_isRightToLeft: 0 m_fontAsset: {fileID: 11400000, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2} m_sharedMaterial: {fileID: 2180264, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2} @@ -166,9 +166,9 @@ RectTransform: m_Children: [] m_Father: {fileID: 4918938079055515515} 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: -60.000023} + 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: 120, y: 120} m_Pivot: {x: 0.5, y: 0.5} --- !u!222 &5111066452280026694 @@ -209,6 +209,140 @@ MonoBehaviour: m_FillOrigin: 0 m_UseSpriteMesh: 0 m_PixelsPerUnitMultiplier: 1 +--- !u!1 &5864139777741960210 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 703745729791789310} + - component: {fileID: 7002079901696980481} + - component: {fileID: 5028474175908707617} + m_Layer: 5 + m_Name: KeyText + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &703745729791789310 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 5864139777741960210} + 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: 4918938079055515515} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 1, y: 0} + m_AnchoredPosition: {x: 0, y: 17.24704} + m_SizeDelta: {x: 0, y: 34.494095} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!222 &7002079901696980481 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 5864139777741960210} + m_CullTransparentMesh: 1 +--- !u!114 &5028474175908707617 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 5864139777741960210} + 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: -- + m_isRightToLeft: 0 + m_fontAsset: {fileID: 11400000, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2} + m_sharedMaterial: {fileID: 2180264, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2} + m_fontSharedMaterials: [] + m_fontMaterial: {fileID: 0} + m_fontMaterials: [] + m_fontColor32: + serializedVersion: 2 + rgba: 4294967295 + m_fontColor: {r: 1, g: 1, b: 1, 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: 30.85 + m_fontSizeBase: 36 + m_fontWeight: 400 + m_enableAutoSizing: 1 + m_fontSizeMin: 18 + m_fontSizeMax: 43 + 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_enableWordWrapping: 1 + m_wordWrappingRatios: 0.4 + m_overflowMode: 0 + m_linkedTextComponent: {fileID: 0} + parentLinkedComponent: {fileID: 0} + m_enableKerning: 1 + m_enableExtraPadding: 0 + checkPaddingRequired: 0 + m_isRichText: 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 &8450869184831564982 GameObject: m_ObjectHideFlags: 0 @@ -218,6 +352,7 @@ GameObject: serializedVersion: 6 m_Component: - component: {fileID: 4918938079055515515} + - component: {fileID: 372725716160773496} m_Layer: 5 m_Name: AbilityUIItem m_TagString: Untagged @@ -239,10 +374,26 @@ RectTransform: m_Children: - {fileID: 6280358973369407615} - {fileID: 1233609033755628515} + - {fileID: 703745729791789310} m_Father: {fileID: 0} 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: -32.887497, y: 11.3029} - m_SizeDelta: {x: 120, y: 157.6877} + m_AnchoredPosition: {x: -32.887497, y: -3.9686} + m_SizeDelta: {x: 120, y: 188.2307} m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &372725716160773496 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 8450869184831564982} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 30dcebf945ea1bc439c74273d4bf48f5, type: 3} + m_Name: + m_EditorClassIdentifier: + abilityIcon: {fileID: 4802381344739625320} + abilityName: {fileID: 1137290063122843096} + abilityKeyText: {fileID: 5028474175908707617} diff --git a/Assets/ScriptableObjects/Abilities/Channel Heal Ability.asset b/Assets/ScriptableObjects/Abilities/Channel Heal Ability.asset new file mode 100644 index 00000000..aaa5f2b3 --- /dev/null +++ b/Assets/ScriptableObjects/Abilities/Channel Heal Ability.asset @@ -0,0 +1,21 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!114 &11400000 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: a39eb7f0fc0fd394abd3f393fb93ef34, type: 3} + m_Name: Channel Heal Ability + m_EditorClassIdentifier: + displayName: Channel Heal + icon: {fileID: 10913, guid: 0000000000000000f000000000000000, type: 0} + manaCost: 10 + cooldown: 2 + description: + channelTime: 5 + healAmount: 50 diff --git a/Assets/ScriptableObjects/Abilities/Channel Heal Ability.asset.meta b/Assets/ScriptableObjects/Abilities/Channel Heal Ability.asset.meta new file mode 100644 index 00000000..a0b3d34c --- /dev/null +++ b/Assets/ScriptableObjects/Abilities/Channel Heal Ability.asset.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 2cdcec8b6c2310d46847af6f490ad3e8 +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 11400000 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/ScriptableObjects/Abilities/New Fireball Ability.asset b/Assets/ScriptableObjects/Abilities/Fireball Ability.asset similarity index 95% rename from Assets/ScriptableObjects/Abilities/New Fireball Ability.asset rename to Assets/ScriptableObjects/Abilities/Fireball Ability.asset index c111d70a..d0e37db8 100644 --- a/Assets/ScriptableObjects/Abilities/New Fireball Ability.asset +++ b/Assets/ScriptableObjects/Abilities/Fireball Ability.asset @@ -10,7 +10,7 @@ MonoBehaviour: m_Enabled: 1 m_EditorHideFlags: 0 m_Script: {fileID: 11500000, guid: 9285d1b57504d78469204d8011a14dff, type: 3} - m_Name: New Fireball Ability + m_Name: Fireball Ability m_EditorClassIdentifier: displayName: Fireball icon: {fileID: 10913, guid: 0000000000000000f000000000000000, type: 0} diff --git a/Assets/ScriptableObjects/Abilities/New Fireball Ability.asset.meta b/Assets/ScriptableObjects/Abilities/Fireball Ability.asset.meta similarity index 100% rename from Assets/ScriptableObjects/Abilities/New Fireball Ability.asset.meta rename to Assets/ScriptableObjects/Abilities/Fireball Ability.asset.meta diff --git a/Assets/Scripts/Abilities/AbilityClasses/ChannelHealAbility.cs b/Assets/Scripts/Abilities/AbilityClasses/ChannelHealAbility.cs new file mode 100644 index 00000000..494fa52b --- /dev/null +++ b/Assets/Scripts/Abilities/AbilityClasses/ChannelHealAbility.cs @@ -0,0 +1,50 @@ +using System.Collections; +using UnityEngine; + +[CreateAssetMenu(menuName = "Abilities/Channel Heal")] +public class ChannelHealAbility : Ability +{ + public float channelTime = 5f; // seconds to wait + public float healAmount = 50f; // how much to heal + + public override void Activate(AbilityUser user) + { + if (!user) return; + user.StartCoroutine(ChannelRoutine(user)); + } + + private IEnumerator ChannelRoutine(AbilityUser user) + { + float elapsed = 0f; + + while (elapsed < channelTime) + { + // Cancel if player moves + if (IsPlayerMoving()) + { + Debug.Log("Heal cancelled: player moved."); + yield break; + } + + elapsed += Time.deltaTime; + yield return null; + } + + // Heal and spend mana on completion + if (user.mana && !user.mana.Spend(manaCost)) + { + Debug.Log("Not enough mana to complete heal."); + yield break; + } + + if (user.health) user.health.Heal(healAmount); + Debug.Log($"Healed {healAmount} HP after channel."); + } + + private bool IsPlayerMoving() + { + float h = Input.GetAxisRaw("Horizontal"); + float v = Input.GetAxisRaw("Vertical"); + return (Mathf.Abs(h) > 0.01f || Mathf.Abs(v) > 0.01f); + } +} \ No newline at end of file diff --git a/Assets/Scripts/Abilities/AbilityClasses/ChannelHealAbility.cs.meta b/Assets/Scripts/Abilities/AbilityClasses/ChannelHealAbility.cs.meta new file mode 100644 index 00000000..14c62fd8 --- /dev/null +++ b/Assets/Scripts/Abilities/AbilityClasses/ChannelHealAbility.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: a39eb7f0fc0fd394abd3f393fb93ef34 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Abilities/AbilityClasses/FreezeShardAbility.cs b/Assets/Scripts/Abilities/AbilityClasses/FreezeShardAbility.cs new file mode 100644 index 00000000..02ca5563 --- /dev/null +++ b/Assets/Scripts/Abilities/AbilityClasses/FreezeShardAbility.cs @@ -0,0 +1,39 @@ +using UnityEngine; + +[CreateAssetMenu(menuName = "Abilities/Freeze Shard")] +public class FreezeShardAbility : Ability +{ + public GameObject projectilePrefab; + public float speed = 20f; + public float damage = 0f; // optional direct damage + public float freezeDuration = 3f; + public float lifeTime = 4f; + public float spawnOffset = 0.5f; + + public override void Activate(AbilityUser user) + { + if (!user || !projectilePrefab) return; + + var pos = user.CastPos() + user.Forward() * spawnOffset; + var rot = Quaternion.LookRotation(user.Forward()); + var go = Instantiate(projectilePrefab, pos, rot); + + var rb = go.GetComponent(); + if (rb) rb.velocity = user.Forward() * speed; + + var shard = go.GetComponent(); + if (!shard) shard = go.AddComponent(); + shard.damage = damage; + shard.freezeDuration = freezeDuration; + shard.ownerRoot = user.transform; + + var projCol = go.GetComponent(); + if (projCol) + { + foreach (var oc in user.GetComponentsInChildren()) + Physics.IgnoreCollision(projCol, oc, true); + } + + Destroy(go, lifeTime); + } +} \ No newline at end of file diff --git a/Assets/Scripts/Abilities/AbilityClasses/FreezeShardAbility.cs.meta b/Assets/Scripts/Abilities/AbilityClasses/FreezeShardAbility.cs.meta new file mode 100644 index 00000000..740ccdc7 --- /dev/null +++ b/Assets/Scripts/Abilities/AbilityClasses/FreezeShardAbility.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 49bbd40b4b6c27046ad28ab6eb3de43e +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Abilities/AbilityInput.cs b/Assets/Scripts/Abilities/AbilityInput.cs index 9f9ec784..b179d875 100644 --- a/Assets/Scripts/Abilities/AbilityInput.cs +++ b/Assets/Scripts/Abilities/AbilityInput.cs @@ -1,3 +1,4 @@ +using System; using UnityEngine; public class AbilityInput : MonoBehaviour @@ -6,6 +7,17 @@ public class AbilityInput : MonoBehaviour public AbilityUser user; public AbilitySlot[] slots = new AbilitySlot[4]; + private void Start() + { + foreach (var slot in slots) + { + if (slot.abilityUiItem) + { + slot.abilityUiItem.Init(slot.ability); + } + } + } + void Update() { foreach (var s in slots) s?.Tick(Time.deltaTime); diff --git a/Assets/Scripts/Abilities/AbilitySlot.cs b/Assets/Scripts/Abilities/AbilitySlot.cs index 58954874..c493be54 100644 --- a/Assets/Scripts/Abilities/AbilitySlot.cs +++ b/Assets/Scripts/Abilities/AbilitySlot.cs @@ -4,6 +4,7 @@ using UnityEngine; public class AbilitySlot { public Ability ability; + public AbilityUIItem abilityUiItem; [HideInInspector] public float cdTimer; // counts down at runtime public bool IsOnCooldown => cdTimer > 0f; diff --git a/Assets/Scripts/Behvaiours/FreezableNavAgent.cs b/Assets/Scripts/Behvaiours/FreezableNavAgent.cs new file mode 100644 index 00000000..c04d0524 --- /dev/null +++ b/Assets/Scripts/Behvaiours/FreezableNavAgent.cs @@ -0,0 +1,121 @@ +using UnityEngine; +using UnityEngine.AI; +using System.Collections; + +[RequireComponent(typeof(NavMeshAgent))] +public class FreezableNavAgent : MonoBehaviour, IFreezable +{ + [Header("Optional")] + [SerializeField] Animator animator; // optional: pause/resume anim + [SerializeField] string speedParam = "Speed"; // optional: set 0 while frozen + + // Saved agent settings + float _origSpeed, _origAccel, _origAngSpeed; + bool _frozen; + Coroutine _freezeCo; + + NavMeshAgent _agent; + + void Awake() + { + _agent = GetComponent(); + if (!animator) animator = GetComponentInChildren(); + CacheOriginals(); + } + + void OnEnable() { CacheOriginals(); } + + void CacheOriginals() + { + if (_agent == null) return; + _origSpeed = _agent.speed; + _origAccel = _agent.acceleration; + _origAngSpeed = _agent.angularSpeed; + } + + public void Freeze(float duration) + { + // If already frozen, refresh duration + if (_freezeCo != null) StopCoroutine(_freezeCo); + _freezeCo = StartCoroutine(FreezeRoutine(duration)); + } + + IEnumerator FreezeRoutine(float duration) + { + // Enter freeze + if (!_frozen) EnterFreeze(); + + // Wait for duration + float t = duration; + while (t > 0f) + { + t -= Time.deltaTime; + yield return null; + } + + // Exit + ExitFreeze(); + _freezeCo = null; + } + + void EnterFreeze() + { + _frozen = true; + + // Stop movement immediately + if (_agent) + { + _agent.isStopped = true; // halts pathfinding updates + _agent.ResetPath(); // clear current path + _agent.velocity = Vector3.zero; + + // Optional: zero out movement-related params to avoid jitter + _agent.speed = 0f; + _agent.acceleration = 0f; + _agent.angularSpeed = 0f; + } + + // Pause animations + if (animator) + { + animator.speed = 0f; + if (!string.IsNullOrEmpty(speedParam) && animator.HasParameterOfType(speedParam, AnimatorControllerParameterType.Float)) + animator.SetFloat(speedParam, 0f); + } + } + + void ExitFreeze() + { + _frozen = false; + + if (_agent) + { + // Restore movement settings + _agent.speed = _origSpeed; + _agent.acceleration = _origAccel; + _agent.angularSpeed = _origAngSpeed; + _agent.isStopped = false; + } + + if (animator) + { + animator.speed = 1f; + // (Your AI animation controller will resume updating speedParam from its movement script) + } + } + + // Handy debug + [ContextMenu("Debug/Freeze 2s")] + void DebugFreeze2() => Freeze(2f); +} + +// Small helper so we can safely check an Animator param +static class AnimatorExt +{ + public static bool HasParameterOfType(this Animator self, string name, AnimatorControllerParameterType type) + { + foreach (var p in self.parameters) + if (p.type == type && p.name == name) return true; + return false; + } +} diff --git a/Assets/Scripts/Behvaiours/FreezableNavAgent.cs.meta b/Assets/Scripts/Behvaiours/FreezableNavAgent.cs.meta new file mode 100644 index 00000000..1568ae75 --- /dev/null +++ b/Assets/Scripts/Behvaiours/FreezableNavAgent.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 0fa5d25552156d040b84773c3488e856 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Behvaiours/FreezeShardProjectile.cs b/Assets/Scripts/Behvaiours/FreezeShardProjectile.cs new file mode 100644 index 00000000..d2ca5503 --- /dev/null +++ b/Assets/Scripts/Behvaiours/FreezeShardProjectile.cs @@ -0,0 +1,31 @@ +using UnityEngine; +using System.Collections; + +public class FreezeShardProjectile : MonoBehaviour +{ + public float damage; + public float freezeDuration; + public Transform ownerRoot; + public float armTime = 0.05f; + float spawnTime; + + void Awake() => spawnTime = Time.time; + + void OnTriggerEnter(Collider other) + { + if (Time.time - spawnTime < armTime) return; + if (ownerRoot && other.transform.root == ownerRoot) return; + + if (other.TryGetComponent(out var dmg)) + { + if (damage > 0) dmg.ApplyDamage(damage); + } + + if (other.TryGetComponent(out var freezable)) + { + freezable.Freeze(freezeDuration); + } + + Destroy(gameObject); + } +} diff --git a/Assets/Scripts/Behvaiours/FreezeShardProjectile.cs.meta b/Assets/Scripts/Behvaiours/FreezeShardProjectile.cs.meta new file mode 100644 index 00000000..901b0200 --- /dev/null +++ b/Assets/Scripts/Behvaiours/FreezeShardProjectile.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 3f8a87ffd94add94f81964c4de32beb2 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Interfaces/IFreezable.cs b/Assets/Scripts/Interfaces/IFreezable.cs new file mode 100644 index 00000000..bf6fe2ae --- /dev/null +++ b/Assets/Scripts/Interfaces/IFreezable.cs @@ -0,0 +1,4 @@ +public interface IFreezable +{ + void Freeze(float duration); +} \ No newline at end of file diff --git a/Assets/Scripts/Interfaces/IFreezable.cs.meta b/Assets/Scripts/Interfaces/IFreezable.cs.meta new file mode 100644 index 00000000..01f5aff4 --- /dev/null +++ b/Assets/Scripts/Interfaces/IFreezable.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 2bc48da20a9b35745816045624cbdfd3 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/UI.meta b/Assets/Scripts/UI.meta new file mode 100644 index 00000000..be649b3f --- /dev/null +++ b/Assets/Scripts/UI.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: abdf3871aa2f985469f4153ebdff67f9 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/UI/AbilityUIItem.cs b/Assets/Scripts/UI/AbilityUIItem.cs new file mode 100644 index 00000000..3679e117 --- /dev/null +++ b/Assets/Scripts/UI/AbilityUIItem.cs @@ -0,0 +1,19 @@ +using System.Collections; +using System.Collections.Generic; +using TMPro; +using UnityEngine; +using UnityEngine.UI; + +public class AbilityUIItem : MonoBehaviour +{ + [SerializeField] private Image abilityIcon; + [SerializeField] private TMP_Text abilityName; + [SerializeField] private TMP_Text abilityKeyText; + + public void Init(Ability ability) + { + this.abilityIcon.sprite = ability.icon; + this.abilityName.text = ability.displayName; + this.abilityKeyText = abilityKeyText; + } +} diff --git a/Assets/Scripts/UI/AbilityUIItem.cs.meta b/Assets/Scripts/UI/AbilityUIItem.cs.meta new file mode 100644 index 00000000..19520460 --- /dev/null +++ b/Assets/Scripts/UI/AbilityUIItem.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 30dcebf945ea1bc439c74273d4bf48f5 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: