From a178792731891bcd477ab0812ced1ab5fb9229fc Mon Sep 17 00:00:00 2001
From: yyl <yyl>
Date: 星期四, 09 十月 2025 15:32:54 +0800
Subject: [PATCH] 125 战斗 闪避增加幻影

---
 Main/Component/UI/Common/SkeletonIllusionShadow.cs      |  128 ++++++++++++++++++++++++++++++++
 Main/Component/UI/Common/SkeletonIllusionShadow.cs.meta |   11 ++
 Main/System/Battle/BattleObject/BattleObject.cs         |   11 ++
 Main/System/Battle/Motion/MotionBase.cs                 |   58 ++++++++------
 4 files changed, 182 insertions(+), 26 deletions(-)

diff --git a/Main/Component/UI/Common/SkeletonIllusionShadow.cs b/Main/Component/UI/Common/SkeletonIllusionShadow.cs
new file mode 100644
index 0000000..6deefb6
--- /dev/null
+++ b/Main/Component/UI/Common/SkeletonIllusionShadow.cs
@@ -0,0 +1,128 @@
+using Cysharp.Threading.Tasks;
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using DG.Tweening;
+using Spine;
+using Spine.Unity;
+using UnityEngine;
+
+public class SkeletonIllusionShadow : MonoBehaviour
+{
+    // 璁板綍鎵�鏈夋畫褰卞璞★紝渚夸簬缁熶竴閿�姣�
+    private readonly List<GameObject> illusionShadows = new List<GameObject>();
+    private SkeletonAnimation skeletonAnimation;
+
+    private bool createSwitch = false;
+
+    private int curFrame = 0;
+    private int frameInteral = 2;
+
+    public void SetSkeletonAnimation(SkeletonAnimation _skeletonAnimation)
+    {
+        skeletonAnimation = _skeletonAnimation;
+    }
+
+    public void Show(bool v)
+    {
+        createSwitch = v;
+        curFrame = 0;
+        
+        if (!v)
+        {
+            // 娓呯悊鎵�鏈夋畫褰卞璞�
+            for (int i = illusionShadows.Count - 1; i >= 0; i--)
+            {
+                var go = illusionShadows[i];
+                if (go != null)
+                {
+                    DOTween.Kill(go, complete: false);
+                    if (Application.isPlaying)
+                        Destroy(go);
+                    else
+                        DestroyImmediate(go);
+                }
+            }
+            illusionShadows.Clear();
+
+        }
+    }
+
+
+    public void Run()
+    {
+        if (createSwitch)
+        {
+            //  0.1绉掑垱寤轰竴涓畫鍍�
+            curFrame++;
+            if (curFrame >= frameInteral)
+            {
+                curFrame -= frameInteral;
+                CreateIllusionShadow();
+            }
+        }
+    }
+
+    private void CreateIllusionShadow()
+    {
+        var src = skeletonAnimation.transform;
+
+        // 淇濆瓨婧愮殑涓栫晫鍙樻崲
+        Vector3 worldPos = src.position;
+        Quaternion worldRot = src.rotation;
+        Vector3 worldScale = src.lossyScale;
+
+        GameObject objTest = new GameObject("IllusionShadow");
+        illusionShadows.Add(objTest);
+
+        objTest.transform.SetParent(null, false);
+
+        objTest.transform.position = worldPos;
+        objTest.transform.rotation = worldRot;
+        objTest.transform.localScale = worldScale; // 褰� parent == null 鏃� localScale == worldScale
+
+
+        objTest.layer = LayerMask.NameToLayer("UI");
+        SkeletonAnimation sa = SkeletonAnimation.AddToGameObject(objTest, skeletonAnimation.skeletonDataAsset, false);
+        TrackEntry trackEntry = skeletonAnimation.AnimationState.GetCurrent(0);
+        TrackEntry playedEntry = sa.AnimationState.SetAnimation(0, trackEntry.Animation.Name, trackEntry.Loop);
+        playedEntry.TrackTime = trackEntry.TrackTime;
+
+        sa.timeScale = 0;
+        sa.AnimationState.TimeScale = 0;
+        playedEntry.TimeScale = 0;
+
+        RendererAdjuster parent = skeletonAnimation.GetComponentInParent<RendererAdjuster>();
+        objTest.AddMissingComponent<RendererAdjuster>().SetSortingOrder(parent.sortingOrder);
+
+        sa.skeleton.A = skeletonAnimation.skeleton.A;
+        // 浣跨敤DoTween鍋歛lpha娣″嚭锛孴ween涓巓bjTest缁戝畾锛屼究浜庣粺涓�Kill
+        DOTween.To(() => sa.skeleton.A, x => { sa.skeleton.A = x; sa.LateUpdate(); }, 0f, 0.5f)
+            .SetTarget(objTest);
+
+        // 瀹夊叏閿�姣侊紝绉婚櫎寮曠敤
+        _ = DestroyIllusionShadowAfterAsync(objTest, 0.5f);
+
+    }
+
+    // 鐢║niTask瀹夊叏寤惰繜閿�姣佹畫褰卞璞★紝澶氶噸瀹夊叏妫�鏌�
+    private async UniTaskVoid DestroyIllusionShadowAfterAsync(GameObject go, float delay)
+    {
+        try
+        {
+            await UniTask.Delay((int)(delay * 1000), cancellationToken: this.GetCancellationTokenOnDestroy());
+        }
+        catch (OperationCanceledException)
+        {
+            // 瀵硅薄宸查攢姣侊紝鏃犻渶澶勭悊
+            return;
+        }
+        if (go == null) return;
+        DOTween.Kill(go, complete: false);
+        illusionShadows.Remove(go);
+        if (Application.isPlaying)
+            Destroy(go);
+        else
+            DestroyImmediate(go);
+    }
+}
diff --git a/Main/Component/UI/Common/SkeletonIllusionShadow.cs.meta b/Main/Component/UI/Common/SkeletonIllusionShadow.cs.meta
new file mode 100644
index 0000000..5e2e556
--- /dev/null
+++ b/Main/Component/UI/Common/SkeletonIllusionShadow.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 97920429032421a4081acb2dee82e387
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Main/System/Battle/BattleObject/BattleObject.cs b/Main/System/Battle/BattleObject/BattleObject.cs
index ba47e96..ec4ec52 100644
--- a/Main/System/Battle/BattleObject/BattleObject.cs
+++ b/Main/System/Battle/BattleObject/BattleObject.cs
@@ -288,13 +288,21 @@
         teamHero.curHp = Math.Max(0, teamHero.curHp - (int)bounceHP);
     }
 
+
+    const float pingpongTime = 0.2f;
     //  闂伩寮�濮�
     public virtual void OnDodgeBegin()
     {
-        float pingpongTime = 0.2f;
         RectTransform rectTrans = heroRectTrans;
         var tween = rectTrans.DOAnchorPos(new Vector3(-30, 0, 0), pingpongTime)
             .SetEase(Ease.OutCubic);
+
+        motionBase.ShowIllusionShadow(true);
+
+        tween.onComplete += () =>
+        {
+            motionBase.ShowIllusionShadow(false);
+        };
 
         battleField.battleTweenMgr.OnPlayTween(tween);
     }
@@ -302,7 +310,6 @@
     //  闂伩缁撴潫
     public virtual void OnDodgeEnd(Action _complete = null)
     {
-        float pingpongTime = 0.2f;
         RectTransform rectTrans = heroRectTrans;
 
         var tween = rectTrans.DOAnchorPos(Vector3.zero, pingpongTime)
diff --git a/Main/System/Battle/Motion/MotionBase.cs b/Main/System/Battle/Motion/MotionBase.cs
index efaefc5..e4434f2 100644
--- a/Main/System/Battle/Motion/MotionBase.cs
+++ b/Main/System/Battle/Motion/MotionBase.cs
@@ -43,6 +43,9 @@
     #endregion
 
     private Spine.TrackEntry currentTrackEntry;
+
+    //  娈嬪奖鐢熸垚鍣�
+    private SkeletonIllusionShadow illusionShadow;
     
 
     #region 鍒濆鍖栨柟娉�
@@ -79,8 +82,8 @@
         {
             BattleDebug.LogError("缂哄皯SkeletonGraphic缁勪欢!");
         }
-        
 
+        illusionShadow = _skeletonAnimation.gameObject.AddMissingComponent<SkeletonIllusionShadow>();
     }
     
     public virtual void Release()
@@ -377,33 +380,34 @@
 
     public virtual void Run()
     {
-// #if UNITY_EDITOR
-//         List<int> removeIndex = new List<int>();
-// #endif
+        // #if UNITY_EDITOR
+        //         List<int> removeIndex = new List<int>();
+        // #endif
         for (int i = runActionList.Count - 1; i >= 0; i--)
         {
-// #if UNITY_EDITOR
-//             try
-//             {
-// #endif
-                runActionList[i]?.Invoke();
-// #if UNITY_EDITOR
-//             }
-//             catch (System.Exception ex)
-//             {
-//                 removeIndex.Add(i);
-//                 BattleDebug.LogError($"鎵цRunAction鏃跺彂鐢熷紓甯�: {ex.Message}\n{ex.StackTrace}");
-//             }
-// #endif
+            // #if UNITY_EDITOR
+            //             try
+            //             {
+            // #endif
+            runActionList[i]?.Invoke();
+            // #if UNITY_EDITOR
+            //             }
+            //             catch (System.Exception ex)
+            //             {
+            //                 removeIndex.Add(i);
+            //                 BattleDebug.LogError($"鎵цRunAction鏃跺彂鐢熷紓甯�: {ex.Message}\n{ex.StackTrace}");
+            //             }
+            // #endif
         }
 
-// #if UNITY_EDITOR
-//         // 绉婚櫎澶辫触鐨凙ction
-//         for (int i = 0; i < removeIndex.Count; i++)
-//         {
-//             runActionList.RemoveAt(removeIndex[i]);
-//         }
-// #endif
+        // #if UNITY_EDITOR
+        //         // 绉婚櫎澶辫触鐨凙ction
+        //         for (int i = 0; i < removeIndex.Count; i++)
+        //         {
+        //             runActionList.RemoveAt(removeIndex[i]);
+        //         }
+        // #endif
+        illusionShadow.Run();
     }
 
     public virtual void Pause()
@@ -432,6 +436,12 @@
         skeletonAnimation.timeScale = ratio;
     }
 
+    public void ShowIllusionShadow(bool v)
+    {
+        illusionShadow.SetSkeletonAnimation(skeletonAnimation);
+        illusionShadow.Show(v);
+    }
+
     #endregion
 
 }
\ No newline at end of file

--
Gitblit v1.8.0