chenxin
2020-11-16 895e6764872749a2a26415d17697b19ee2587ea9
水精灵技能 冷冻气息

# Conflicts:
# Assets/Scripts/Event/EventType.cs
4 files added
15 files modified
808 ■■■■ changed files
Assets/00000/package/Prefab/ChongNengEffect.prefab 12 ●●●● patch | view | raw | blame | history
Assets/00000/package/Prefab/Effect_PenBing.prefab 45 ●●●● patch | view | raw | blame | history
Assets/Prefabs/Towers/Water/CopyCatTower.prefab 4 ●●● patch | view | raw | blame | history
Assets/Prefabs/UI/FreezeEnergy.prefab 169 ●●●●● patch | view | raw | blame | history
Assets/Prefabs/UI/FreezeEnergy.prefab.meta 7 ●●●●● patch | view | raw | blame | history
Assets/Scenes/Levels/Battle/Endless2D.unity 6 ●●●● patch | view | raw | blame | history
Assets/Scripts/ActionGameFramework/Health/Targetable.cs 4 ●●●● patch | view | raw | blame | history
Assets/Scripts/Event/EventType.cs 2 ●●●●● patch | view | raw | blame | history
Assets/Scripts/TowerDefense/Affectors/AttackAffector.cs 118 ●●●●● patch | view | raw | blame | history
Assets/Scripts/TowerDefense/Agents/Agent.cs 20 ●●●●● patch | view | raw | blame | history
Assets/Scripts/TowerDefense/Towers/Placement/IPlacementArea.cs 9 ●●●●● patch | view | raw | blame | history
Assets/Scripts/TowerDefense/Towers/Placement/SingleTowerPlacementArea.cs 8 ●●●● patch | view | raw | blame | history
Assets/Scripts/TowerDefense/Towers/Placement/TowerPlacementGrid.cs 19 ●●●●● patch | view | raw | blame | history
Assets/Scripts/TowerDefense/Towers/Placement/TowerPlacementGridEndless.cs 87 ●●●●● patch | view | raw | blame | history
Assets/Scripts/TowerDefense/Towers/Projectiles/BallisticAttack.cs 9 ●●●● patch | view | raw | blame | history
Assets/Scripts/TowerDefense/Towers/Tower.cs 157 ●●●● patch | view | raw | blame | history
Assets/Scripts/TowerDefense/UI/FreezeBreath.cs 117 ●●●●● patch | view | raw | blame | history
Assets/Scripts/TowerDefense/UI/FreezeBreath.cs.meta 11 ●●●●● patch | view | raw | blame | history
Assets/UI/energy.png.meta 4 ●●●● patch | view | raw | blame | history
Assets/00000/package/Prefab/ChongNengEffect.prefab
@@ -48,7 +48,7 @@
  ringBufferLoopRange: {x: 0, y: 1}
  looping: 1
  prewarm: 0
  playOnAwake: 1
  playOnAwake: 0
  useUnscaledTime: 0
  autoRandomSeed: 1
  useRigidbodyForVelocity: 1
@@ -4918,7 +4918,7 @@
  ringBufferLoopRange: {x: 0, y: 1}
  looping: 1
  prewarm: 1
  playOnAwake: 1
  playOnAwake: 0
  useUnscaledTime: 0
  autoRandomSeed: 1
  useRigidbodyForVelocity: 1
@@ -9788,7 +9788,7 @@
  ringBufferLoopRange: {x: 0, y: 1}
  looping: 1
  prewarm: 0
  playOnAwake: 1
  playOnAwake: 0
  useUnscaledTime: 0
  autoRandomSeed: 1
  useRigidbodyForVelocity: 1
@@ -14658,7 +14658,7 @@
  ringBufferLoopRange: {x: 0, y: 1}
  looping: 1
  prewarm: 1
  playOnAwake: 1
  playOnAwake: 0
  useUnscaledTime: 0
  autoRandomSeed: 1
  useRigidbodyForVelocity: 1
@@ -19532,7 +19532,7 @@
  ringBufferLoopRange: {x: 0, y: 1}
  looping: 1
  prewarm: 1
  playOnAwake: 1
  playOnAwake: 0
  useUnscaledTime: 0
  autoRandomSeed: 1
  useRigidbodyForVelocity: 1
@@ -24403,7 +24403,7 @@
  ringBufferLoopRange: {x: 0, y: 1}
  looping: 1
  prewarm: 0
  playOnAwake: 1
  playOnAwake: 0
  useUnscaledTime: 0
  autoRandomSeed: 0
  useRigidbodyForVelocity: 1
Assets/00000/package/Prefab/Effect_PenBing.prefab
@@ -48,7 +48,7 @@
  ringBufferLoopRange: {x: 0, y: 1}
  looping: 0
  prewarm: 0
  playOnAwake: 1
  playOnAwake: 0
  useUnscaledTime: 0
  autoRandomSeed: 0
  useRigidbodyForVelocity: 1
@@ -4918,7 +4918,7 @@
  ringBufferLoopRange: {x: 0, y: 1}
  looping: 0
  prewarm: 0
  playOnAwake: 1
  playOnAwake: 0
  useUnscaledTime: 0
  autoRandomSeed: 1
  useRigidbodyForVelocity: 1
@@ -9788,7 +9788,7 @@
  ringBufferLoopRange: {x: 0, y: 1}
  looping: 0
  prewarm: 0
  playOnAwake: 1
  playOnAwake: 0
  useUnscaledTime: 0
  autoRandomSeed: 0
  useRigidbodyForVelocity: 1
@@ -14619,6 +14619,8 @@
  serializedVersion: 6
  m_Component:
  - component: {fileID: 7583847468063483658}
  - component: {fileID: 4516808969569714994}
  - component: {fileID: 1262205863516427559}
  m_Layer: 0
  m_Name: Effect_PenBing
  m_TagString: Untagged
@@ -14641,6 +14643,35 @@
  m_Father: {fileID: 0}
  m_RootOrder: 0
  m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!114 &4516808969569714994
MonoBehaviour:
  m_ObjectHideFlags: 0
  m_CorrespondingSourceObject: {fileID: 0}
  m_PrefabInstance: {fileID: 0}
  m_PrefabAsset: {fileID: 0}
  m_GameObject: {fileID: 3459016936373460007}
  m_Enabled: 1
  m_EditorHideFlags: 0
  m_Script: {fileID: 11500000, guid: 59d007c1fe5e41c1888e4af3392f8676, type: 3}
  m_Name:
  m_EditorClassIdentifier:
  initialPoolCapacity: 5
--- !u!114 &1262205863516427559
MonoBehaviour:
  m_ObjectHideFlags: 0
  m_CorrespondingSourceObject: {fileID: 0}
  m_PrefabInstance: {fileID: 0}
  m_PrefabAsset: {fileID: 0}
  m_GameObject: {fileID: 3459016936373460007}
  m_Enabled: 1
  m_EditorHideFlags: 0
  m_Script: {fileID: 11500000, guid: 2952db25fdd244f4a9981e4350b798e2, type: 3}
  m_Name:
  m_EditorClassIdentifier:
  time: 2
  death:
    m_PersistentCalls:
      m_Calls: []
--- !u!1 &3817772498780165666
GameObject:
  m_ObjectHideFlags: 0
@@ -14689,7 +14720,7 @@
  ringBufferLoopRange: {x: 0, y: 1}
  looping: 0
  prewarm: 0
  playOnAwake: 1
  playOnAwake: 0
  useUnscaledTime: 0
  autoRandomSeed: 0
  useRigidbodyForVelocity: 1
@@ -19559,7 +19590,7 @@
  ringBufferLoopRange: {x: 0, y: 1}
  looping: 0
  prewarm: 0
  playOnAwake: 1
  playOnAwake: 0
  useUnscaledTime: 0
  autoRandomSeed: 1
  useRigidbodyForVelocity: 1
@@ -24435,7 +24466,7 @@
  ringBufferLoopRange: {x: 0, y: 1}
  looping: 0
  prewarm: 0
  playOnAwake: 1
  playOnAwake: 0
  useUnscaledTime: 0
  autoRandomSeed: 0
  useRigidbodyForVelocity: 1
@@ -29224,7 +29255,7 @@
  ringBufferLoopRange: {x: 0, y: 1}
  looping: 0
  prewarm: 0
  playOnAwake: 1
  playOnAwake: 0
  useUnscaledTime: 0
  autoRandomSeed: 1
  useRigidbodyForVelocity: 1
Assets/Prefabs/Towers/Water/CopyCatTower.prefab
@@ -114,6 +114,7 @@
  PoisonEndParticle: {fileID: 0}
  SlowDownParticle: {fileID: 0}
  FrostParticle: {fileID: 0}
  FireSkillParticle: {fileID: 0}
  towerName: CopyCatTower
  dimensions:
    x: 1
@@ -127,9 +128,10 @@
  materialTowerAttackOppo: {fileID: 0}
  materialTowerWaitOppo: {fileID: 2100000, guid: 02fc3bcbfec233244b426d2427eebf55,
    type: 2}
  eTowerFuntion: 0
  eTowerFuntion: 3
  bulletCtl: {fileID: 0}
  energyCtl: {fileID: 0}
  FreezeBreathCtrl: {fileID: 0}
  levels:
  - {fileID: 114779466188146336, guid: 46284df075bf4504090e7d47372d118e, type: 3}
  - {fileID: 114056922861069036, guid: e41b539c7443b1c46b3c6a80c7cca78d, type: 3}
Assets/Prefabs/UI/FreezeEnergy.prefab
New file
@@ -0,0 +1,169 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!1 &4636030447447409971
GameObject:
  m_ObjectHideFlags: 0
  m_CorrespondingSourceObject: {fileID: 0}
  m_PrefabInstance: {fileID: 0}
  m_PrefabAsset: {fileID: 0}
  serializedVersion: 6
  m_Component:
  - component: {fileID: 4636030447447409970}
  - component: {fileID: 4636030447447409972}
  - component: {fileID: 4636030447447409973}
  - component: {fileID: 4424395808880429278}
  m_Layer: 5
  m_Name: FreezeEnergy
  m_TagString: Untagged
  m_Icon: {fileID: 0}
  m_NavMeshLayer: 0
  m_StaticEditorFlags: 0
  m_IsActive: 1
--- !u!224 &4636030447447409970
RectTransform:
  m_ObjectHideFlags: 0
  m_CorrespondingSourceObject: {fileID: 0}
  m_PrefabInstance: {fileID: 0}
  m_PrefabAsset: {fileID: 0}
  m_GameObject: {fileID: 4636030447447409971}
  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_Children:
  - {fileID: 4636030447972189692}
  m_Father: {fileID: 0}
  m_RootOrder: 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: 0, y: 0}
  m_SizeDelta: {x: 21, y: 90}
  m_Pivot: {x: 0.5, y: 0.5}
--- !u!222 &4636030447447409972
CanvasRenderer:
  m_ObjectHideFlags: 0
  m_CorrespondingSourceObject: {fileID: 0}
  m_PrefabInstance: {fileID: 0}
  m_PrefabAsset: {fileID: 0}
  m_GameObject: {fileID: 4636030447447409971}
  m_CullTransparentMesh: 0
--- !u!114 &4636030447447409973
MonoBehaviour:
  m_ObjectHideFlags: 0
  m_CorrespondingSourceObject: {fileID: 0}
  m_PrefabInstance: {fileID: 0}
  m_PrefabAsset: {fileID: 0}
  m_GameObject: {fileID: 4636030447447409971}
  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: 257d2719341218740b740683c3aa8355, 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!114 &4424395808880429278
MonoBehaviour:
  m_ObjectHideFlags: 0
  m_CorrespondingSourceObject: {fileID: 0}
  m_PrefabInstance: {fileID: 0}
  m_PrefabAsset: {fileID: 0}
  m_GameObject: {fileID: 4636030447447409971}
  m_Enabled: 1
  m_EditorHideFlags: 0
  m_Script: {fileID: 11500000, guid: 446fbeaa4765a1c4dbcc532fc1cb626c, type: 3}
  m_Name:
  m_EditorClassIdentifier:
  ProgressImg: {fileID: 4636030447972189695}
  FreezeJet: {fileID: 3459016936373460007, guid: ca3ce846fd72b2e4bbb24b3a46cc42d0,
    type: 3}
--- !u!1 &4636030447972189693
GameObject:
  m_ObjectHideFlags: 0
  m_CorrespondingSourceObject: {fileID: 0}
  m_PrefabInstance: {fileID: 0}
  m_PrefabAsset: {fileID: 0}
  serializedVersion: 6
  m_Component:
  - component: {fileID: 4636030447972189692}
  - component: {fileID: 4636030447972189694}
  - component: {fileID: 4636030447972189695}
  m_Layer: 5
  m_Name: EnergyProgress
  m_TagString: Untagged
  m_Icon: {fileID: 0}
  m_NavMeshLayer: 0
  m_StaticEditorFlags: 0
  m_IsActive: 1
--- !u!224 &4636030447972189692
RectTransform:
  m_ObjectHideFlags: 0
  m_CorrespondingSourceObject: {fileID: 0}
  m_PrefabInstance: {fileID: 0}
  m_PrefabAsset: {fileID: 0}
  m_GameObject: {fileID: 4636030447972189693}
  m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
  m_LocalPosition: {x: 0, y: 0, z: 0}
  m_LocalScale: {x: 1, y: 0, z: 1}
  m_Children: []
  m_Father: {fileID: 4636030447447409970}
  m_RootOrder: 0
  m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
  m_AnchorMin: {x: 0.5, y: 0}
  m_AnchorMax: {x: 0.5, y: 0}
  m_AnchoredPosition: {x: 0, y: 0}
  m_SizeDelta: {x: 21, y: 90}
  m_Pivot: {x: 0.5, y: 0}
--- !u!222 &4636030447972189694
CanvasRenderer:
  m_ObjectHideFlags: 0
  m_CorrespondingSourceObject: {fileID: 0}
  m_PrefabInstance: {fileID: 0}
  m_PrefabAsset: {fileID: 0}
  m_GameObject: {fileID: 4636030447972189693}
  m_CullTransparentMesh: 0
--- !u!114 &4636030447972189695
MonoBehaviour:
  m_ObjectHideFlags: 0
  m_CorrespondingSourceObject: {fileID: 0}
  m_PrefabInstance: {fileID: 0}
  m_PrefabAsset: {fileID: 0}
  m_GameObject: {fileID: 4636030447972189693}
  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: 747f83368dfba694c89bc6908324bb94, type: 3}
  m_Type: 0
  m_PreserveAspect: 0
  m_FillCenter: 1
  m_FillMethod: 1
  m_FillAmount: 0
  m_FillClockwise: 1
  m_FillOrigin: 0
  m_UseSpriteMesh: 0
  m_PixelsPerUnitMultiplier: 1
Assets/Prefabs/UI/FreezeEnergy.prefab.meta
New file
@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 44b8a531e4b9ccf4a9b7bc203ac6c8c6
PrefabImporter:
  externalObjects: {}
  userData:
  assetBundleName:
  assetBundleVariant:
Assets/Scenes/Levels/Battle/Endless2D.unity
@@ -7683,12 +7683,16 @@
    y: 4
  gridSize: 1.109
  TowerGridOpenObjArr: []
  energyEffectPrefab: {fileID: 6740320714111919447, guid: c9fb6497ab1288942a4dd67d131473c9,
  energyEffectPrefab: {fileID: 2066080619878598796, guid: 7fa18b6afd896be469a09f44c4518b10,
    type: 3}
  towerBulletUIPrefab: {fileID: 649954434242370657, guid: f4c10f1b0e730384cacfe2c12ca92ade,
    type: 3}
  towerEnergyUIPrefab: {fileID: 4636030447447409971, guid: 0d97566feabc1d644862df3fb52071a3,
    type: 3}
  FreezeBreathChargePrefab: {fileID: 4636030447447409971, guid: 44b8a531e4b9ccf4a9b7bc203ac6c8c6,
    type: 3}
  FreezeBreathChargeEffect: {fileID: 2507654675392870471, guid: 53b0993ae8a721c4eadc367c48754bfc,
    type: 3}
--- !u!65 &1632078504
BoxCollider:
  m_ObjectHideFlags: 2
Assets/Scripts/ActionGameFramework/Health/Targetable.cs
@@ -163,8 +163,8 @@
        public void addSpeedSlowRate(float rate)
        {
            speedSlowRate += rate;
            if (speedSlowRate >= 0.6f)
                speedSlowRate = 0.6f;
            if (speedSlowRate >= 0.75f)
                speedSlowRate = 0.75f;
        }
        /// <summary>
Assets/Scripts/Event/EventType.cs
@@ -83,6 +83,8 @@
        EndlessBuffRefresh,
        //某一列出怪完毕
        WaveLineFinish,
        // 播放水精灵充能满特效
        EndlessPlayFreezeBreathEffect,
    }
}
Assets/Scripts/TowerDefense/Affectors/AttackAffector.cs
@@ -9,6 +9,8 @@
using TowerDefense.Towers.Projectiles;
using UnityEngine;
using KTGMGemClient;
using TowerDefense.Towers.TowerLaunchers;
using TowerDefense.Level;
namespace TowerDefense.Affectors
{
@@ -101,6 +103,8 @@
        /// </summary>
        protected float m_FireTimer;
        protected float freezeBreathTimer;
        /// <summary>
        /// Reference to the current tracked enemy
        /// </summary>
@@ -114,11 +118,23 @@
        protected float fillBulletTime = 0.0f;
        /// <summary>
        /// 充能时间
        /// 火精灵充能时间
        /// </summary>
        protected float energyCalTime = 0;
        protected float fInEnergy = 0;
        protected float fBackupTimer = 0.0f;
        /// <summary>
        /// 水精灵的充能时间
        /// </summary>
        protected float freezeBreathCallTime = 0;
        protected float inFreezeBreath = 0;
        protected float freezeBreathBackTimer = 0;
        /// <summary>
        /// Gets the search rate from the targetter
        /// </summary>
@@ -258,7 +274,14 @@
        bool fireState = false;
        protected void updateTowerSkillData()
        {
            //
            HandleBullet();
            HandleEnergy();
            HandleFreezeBreath();
        }
        // 处理木精灵装填子弹
        private void HandleBullet()
        {
            // 预留出来装填子弹的时间.
            if (fillBulletTime > 0)
            {
@@ -274,14 +297,17 @@
                    fillBulletTime = 0;
                }
            }
        }
            //
        // 处理火精灵充能
        private void HandleEnergy()
        {
            // 充能时间的处理
            if (towerPtr && towerPtr.energyCtl)
            {
                if (this.fInEnergy <= 0)
                if (fInEnergy <= 0)
                {
                    this.energyCalTime += Time.deltaTime;
                    energyCalTime += Time.deltaTime;
                    float process = energyCalTime % 11.0f;
                    int proint = (int)Math.Floor(process);
                    proint += towerPtr.uiProOffset;
@@ -309,7 +335,7 @@
                        fireState = false;
                        EventCenter.Ins.BroadCast((int)KTGMGemClient.EventType.FireTowerChargeEnd);
                        fInEnergy = 0.0f;
                        this.energyCalTime = 0.0f;
                        energyCalTime = 0.0f;
                        towerPtr.energyCtl.SetEnergyProgress(0);
                        // 恢复正常攻击速度 
@@ -319,7 +345,70 @@
                    }
                }
            }
        }
        // 处理水精灵的充能
        private void HandleFreezeBreath()
        {
            if (towerPtr && towerPtr.FreezeBreathCtrl)
            {
                Damager damager = projectile.gameObject.GetComponent<Damager>();
                float finalDamage = damager.damage;
                List<EndlessBuffConfig> list = EndlessBuffManager.instance.GetBuffListByEffectType(EndlessBuffEffectType.Attack, towerPtr.attributeId);
                float ratio = 0;
                float add = 0;
                if (list.Count > 0)
                {
                    for (int i = 0; i < list.Count; ++i)
                    {
                        ratio += list[i].Config.buff_effect[1];
                        add += list[i].Config.buff_effect[2];
                    }
                }
                finalDamage += (ratio / 100f) * finalDamage + add;
                if (inFreezeBreath <= 0)
                {
                    freezeBreathCallTime += Time.deltaTime;
                    float process = freezeBreathCallTime % (FreezeBreath.ChargeTime + 1);
                    int processInt = (int)Mathf.Floor(process);
                    processInt += towerPtr.FreezeBreathProgressOffset;
                    towerPtr.FreezeBreathCtrl.SetProgress(process);
                    if (processInt == (int)Mathf.Floor(FreezeBreath.ChargeTime))
                    {
                        inFreezeBreath = FreezeBreath.EffectTime;
                        towerPtr.FreezeBreathProgressOffset = 0;
                        towerPtr.PlayFreezeBreathEffect(true);
                        towerPtr.FreezeBreathCtrl.ReleaseCount = 1;
                        towerPtr.FreezeBreathCtrl.ReleaseFreeze(waveLineID, finalDamage, damager.alignmentProvider);
                    }
                }
                else
                {
                    inFreezeBreath -= Time.deltaTime;
                    if (inFreezeBreath <= FreezeBreath.EffectTime / 2 && towerPtr.FreezeBreathCtrl.ReleaseCount != 2)
                    {
                        towerPtr.FreezeBreathCtrl.ReleaseCount = 2;
                        towerPtr.FreezeBreathCtrl.ReleaseFreeze(waveLineID, finalDamage, damager.alignmentProvider);
                        return;
                    }
                    if (inFreezeBreath <= 0)
                    {
                        inFreezeBreath = 0;
                        freezeBreathCallTime = 0;
                        towerPtr.FreezeBreathCtrl.SetProgress(0);
                        towerPtr.PlayFreezeBreathEffect(false);
                        towerPtr.FreezeBreathCtrl.ReleaseCount = 3;
                        towerPtr.FreezeBreathCtrl.ReleaseFreeze(waveLineID, finalDamage, damager.alignmentProvider);
                    }
                }
            }
        }
@@ -348,12 +437,15 @@
            {
                towerPtr.PlayEnergyEffect(false, false);
            }
            if (towerPtr && towerPtr.FreezeBreathCtrl)
                towerPtr.PlayFreezeBreathEffect(false, false);
        }
        /// <summary>
        /// Update the timers
        /// </summary>
        protected virtual void LateUpdate()
        protected virtual void Update()
        {
            if (m_Launcher == null) return;
@@ -372,10 +464,16 @@
                towerLevel.FireSpeed = fInEnergy > 0 ? 5f : 1f;
                if (towerPtr && (towerPtr.bulletCtl != null))
                if (towerPtr && towerPtr.bulletCtl != null)
                {
                    int bnum = towerPtr.bulletCtl.GetCtlProgress();
                    if (bnum == 0) return;
                }
                if (towerPtr && towerPtr.FreezeBreathCtrl != null)
                {
                    // 冷冻气息期间不攻击
                    if (inFreezeBreath > 0.0001f) return;
                }
                towerLevel.ChangeState(TowerActionState.Attack);
@@ -417,7 +515,7 @@
            }
            else
            {
                if (this.towerPtr)
                if (towerPtr)
                    towerPtr.setTowerState(true);
            }
@@ -425,7 +523,7 @@
            {
                List<Targetable> enemies = towerTargetter.GetAllTargets();
                if ((enemies != null) && (Targetter.bSearchTarget))
                    m_Launcher.Launch(enemies, projectile, projectilePoints, this.maxAttackNum);
                    m_Launcher.Launch(enemies, projectile, projectilePoints, maxAttackNum);
            }
            else
            {
Assets/Scripts/TowerDefense/Agents/Agent.cs
@@ -479,6 +479,7 @@
            poisonAttid = 0;
            poisonTimes = 0;
            timeToPoisonHurt = 0;
            isFrost = false;
            bShieldBreak = false;
            bInDeathAct = false;
            ChangeState(AgentActionState.Move);
@@ -500,13 +501,8 @@
        private void StopFrostParticle()
        {
            if (isFrost)
            {
                isFrost = false;
                if (FrostParticle != null)
                    FrostParticle.Stop();
            }
            if (FrostParticle != null)
                FrostParticle.Stop();
        }
        /// <summary>    
@@ -1053,6 +1049,16 @@
        }
        /// <summary>
        /// 播放受击动画,直接从头开始播放
        /// </summary>
        public void PlayOnHitImmediately()
        {
            ChangeState(AgentActionState.GetHit);
            ActionAnimator.Play("GetHit", 0, 0);
            ActionAnimator.Update(0);
        }
        /// <summary>
        /// 播放火技能打击动画
        /// </summary>
        public void PlayFireSkillHit()
Assets/Scripts/TowerDefense/Towers/Placement/IPlacementArea.cs
@@ -1,5 +1,6 @@
using Core.Utilities;
using UnityEngine;
using KTGMGemClient;
namespace TowerDefense.Towers.Placement
{
@@ -41,6 +42,14 @@
        EnergyUICtl GetEnergyUICtl(int x, int y);
        /// <summary>
        /// 获取对应位置的水精灵充能条
        /// </summary>
        /// <param name="x"></param>
        /// <param name="y"></param>
        /// <returns></returns>
        FreezeBreath GetFreezeBreath(int x, int y);
        /// <summary>
        /// 是否空置的攻击位
        /// </summary>
        /// <param name="x"></param>
Assets/Scripts/TowerDefense/Towers/Placement/SingleTowerPlacementArea.cs
@@ -1,4 +1,5 @@
using Core.Utilities;
using KTGMGemClient;
using Core.Utilities;
using TowerDefense.UI.HUD;
using UnityEngine;
@@ -92,6 +93,11 @@
            return null;
        }
        public FreezeBreath GetFreezeBreath(int x, int y)
        {
            return null;
        }
        /// <summary>
        /// 获取一个可以放置塔防的位置.
        /// </summary>
Assets/Scripts/TowerDefense/Towers/Placement/TowerPlacementGrid.cs
@@ -198,6 +198,11 @@
            return this.arrTowerEnergyUi[x];
        }
        public FreezeBreath GetFreezeBreath(int x, int y)
        {
            return null;
        }
        /// <summary>
        /// 获取一个可以放置塔防的位置.
        /// </summary>
@@ -355,7 +360,7 @@
                    Vector3 tpos = this.transform.position;
                    tpos.y += 5.0f;
                    PlayParticle.transform.position = tpos;
                    //Vector3 lookVec = Vector3.zero;
                    //lookVec.x = 1;
                    //PlayParticle.transform.LookAt(lookVec);
@@ -763,16 +768,16 @@
            for (int x = 0; x < dimensions.x; x++)
            {
                m_arrTowerBulletUIPos[x].x = m_arrGridCentUIPos[x, dy].x + m_fGridUISize/2.0f - 10;
                m_arrTowerBulletUIPos[x].x = m_arrGridCentUIPos[x, dy].x + m_fGridUISize / 2.0f - 10;
                m_arrTowerBulletUIPos[x].y = m_arrGridCentUIPos[x, dy].y;
                GameObject go = GameObject.Find("BattleMainUI");
                if (!go) continue;
                Transform tp = go.GetComponent<Transform>();
                GameObject img;
                img = Instantiate(towerBulletUIPrefab);
                img.GetComponent<Transform>().SetParent(tp, true);
                Vector3 tpos = img.transform.position;
@@ -804,7 +809,7 @@
                vpos.x -= (gridSize / 2.0f);
                vpos.y += 5.0f;
                arrTowerEnergyEffect[x] = Instantiate( energyEffectPrefab );
                arrTowerEnergyEffect[x] = Instantiate(energyEffectPrefab);
                arrTowerEnergyEffect[x].transform.position = vpos;
                arrTowerEnergyEffect[x].Stop();
            }
@@ -817,10 +822,10 @@
        /// </summary>
        /// <param name="x"></param>
        /// <param name="play">是播放还是停止播放</param>
        public void PlayEnergyEffect( int x,bool play = true )
        public void PlayEnergyEffect(int x, bool play = true)
        {
            if (!arrTowerEnergyEffect[x]) return;
            if( play)
            if (play)
            {
                arrTowerEnergyEffect[x].Play();
            }
Assets/Scripts/TowerDefense/Towers/Placement/TowerPlacementGridEndless.cs
@@ -117,12 +117,19 @@
        private EnergyUICtl[,] arrTowerEnergyUi;
        private ParticleSystem[,] arrTowerEnergyEffect;
        private FreezeBreath[,] arrTowerFreezeBreathUi;
        private GameObject[,] arrTowerEnergyEffect;
        /// <summary>
        /// 水精灵充能满特效
        /// </summary>
        private GameObject[,] arrTowerFreezeBreathEffect;
        /// <summary>
        /// 充能特效对应的Prefab.
        /// </summary>
        public ParticleSystem energyEffectPrefab;
        public GameObject energyEffectPrefab;
        /// <summary>
        /// 此位置上塔对应的子弹充能Prefab.塔放置到当前的塔位后,如果是对应的塔防类型,需要把
@@ -134,6 +141,16 @@
        /// 充能条对应的界面
        /// </summary>
        public GameObject towerEnergyUIPrefab;
        /// <summary>
        /// 水精灵塔技能(冷冻气息)充能条
        /// </summary>
        public GameObject FreezeBreathChargePrefab;
        /// <summary>
        /// 水精灵塔充能条特效
        /// </summary>
        public GameObject FreezeBreathChargeEffect;
        /// <summary>
        /// Converts a location in world space into local grid coordinates.
@@ -192,6 +209,16 @@
            return arrTowerEnergyUi[x, 3 - y];
        }
        /// <summary>
        /// 获取水精灵对应位置的充能条
        /// </summary>
        /// <param name="x"></param>
        /// <param name="y"></param>
        /// <returns></returns>
        public FreezeBreath GetFreezeBreath(int x, int y)
        {
            return arrTowerFreezeBreathUi[x, 3 - y];
        }
        /// <summary>
        /// 获取一个可以放置塔防的位置.
@@ -660,7 +687,9 @@
            m_arrTowerBulletUIPos = new Vector2[dimensions.x, AttackRowNumbers];
            arrTowerBulletUi = new BulletUICtl[dimensions.x, AttackRowNumbers];
            arrTowerEnergyUi = new EnergyUICtl[dimensions.x, AttackRowNumbers];
            arrTowerEnergyEffect = new ParticleSystem[dimensions.x, AttackRowNumbers];
            arrTowerFreezeBreathUi = new FreezeBreath[dimensions.x, AttackRowNumbers];
            arrTowerEnergyEffect = new GameObject[dimensions.x, AttackRowNumbers];
            arrTowerFreezeBreathEffect = new GameObject[dimensions.x, AttackRowNumbers];
            float[] gapArr = { 0.4f, 0.6f };
@@ -724,7 +753,24 @@
                    arrTowerEnergyEffect[x, y] = Instantiate(energyEffectPrefab);
                    arrTowerEnergyEffect[x, y].transform.position = vpos;
                    arrTowerEnergyEffect[x, y].Stop();
                    // 创建水精灵充能条
                    img = Instantiate(FreezeBreathChargePrefab);
                    img.transform.SetParent(container.transform);
                    tpos = img.transform.position;
                    tpos.x = m_arrTowerBulletUIPos[x, y].x + 4.4f + (x - 2) * gapArr[y];
                    tpos.z = m_arrTowerBulletUIPos[x, y].y + 5f;
                    tpos.y = 30f;
                    img.transform.position = tpos;
                    img.transform.localScale = Vector3.one;
                    img.transform.localRotation = Quaternion.identity;
                    FreezeBreath freezeBreath = img.GetComponent<FreezeBreath>();
                    arrTowerFreezeBreathUi[x, y] = freezeBreath;
                    freezeBreath.gameObject.SetActive(false);
                    arrTowerFreezeBreathEffect[x, y] = Instantiate(FreezeBreathChargeEffect);
                    arrTowerFreezeBreathEffect[x, y].transform.position = vpos;
                }
            }
        }
@@ -829,20 +875,49 @@
            if (!arrTowerEnergyEffect[x, dy]) return;
            ParticleSystem ps = arrTowerEnergyEffect[x, dy].GetComponent<ParticleSystem>();
            if (ps == null)
                ps = arrTowerEnergyEffect[x, dy].transform.GetChild(0).GetComponent<ParticleSystem>();
            if (play)
            {
                if (!arrTowerEnergyEffect[x, dy].gameObject.activeSelf)
                    arrTowerEnergyEffect[x, dy].gameObject.SetActive(true);
                arrTowerEnergyEffect[x, dy].Play();
                ps.Play();
            }
            else
            {
                arrTowerEnergyEffect[x, dy].Stop();
                ps.Stop();
                arrTowerEnergyEffect[x, dy].gameObject.SetActive(false);
            }
        }
        public void PlayFreezeBreathEffect(int x, int y, bool play = true)
        {
            int dy = dimensions.y - 1 - y;
            if (!arrTowerFreezeBreathEffect[x, dy]) return;
            ParticleSystem ps = arrTowerFreezeBreathEffect[x, dy].GetComponent<ParticleSystem>();
            if (ps == null)
                ps = arrTowerFreezeBreathEffect[x, dy].transform.GetChild(0).GetComponent<ParticleSystem>();
            if (play)
            {
                if (!arrTowerFreezeBreathEffect[x, dy].gameObject.activeSelf)
                    arrTowerFreezeBreathEffect[x, dy].gameObject.SetActive(true);
                ps.Play();
            }
            else
            {
                ps.Stop();
                arrTowerFreezeBreathEffect[x, dy].gameObject.SetActive(false);
            }
        }
        /// <summary>
        /// Set collider's size and center
        /// </summary>
Assets/Scripts/TowerDefense/Towers/Projectiles/BallisticAttack.cs
@@ -42,18 +42,13 @@
            switch ((enemy as Agent).AgentType)
            {
                case SpawnAgentType.Normal:
                    //Debug.Log($"受到普通塔伤害 attributeId:{attributeId}");
                    HandleNormal(enemy);
                    (enemy as Agent).PlayGetHitParticle(attributeId);
                    break;
                case SpawnAgentType.BubbleBomb:
                    Debug.Log($"泡泡炸弹 attributeId:{attributeId}");
                    HandleBubbleBomb(enemy);
                    break;
                case SpawnAgentType.WoodPile:
                    Debug.Log($"受到木桩墙壁伤害 attributeId:{attributeId}");
                    HandleWoodPile(enemy, attributeId);
                    break;
            }
@@ -192,8 +187,8 @@
                    enemy.SetTargetableMatColor(Color.blue);
                    break;
                case 3:  // 中毒
                    enemy.poisonAgent(damage, attid);
                    enemy.SetTargetableMatColor(Color.green);
                    // enemy.poisonAgent(damage, attid);
                    // enemy.SetTargetableMatColor(Color.green);
                    break;
                case 5:  // 破甲
                    enemy.bShieldBreak = true;
Assets/Scripts/TowerDefense/Towers/Tower.cs
@@ -27,6 +27,7 @@
        NULL,
        BULLET,   // 子弹塔
        ENERGY,   // 能量充能.
        FREEZE, // 水精灵充能
        END
    }
@@ -79,6 +80,8 @@
        public BulletUICtl bulletCtl = null;
        public EnergyUICtl energyCtl = null;
        public FreezeBreath FreezeBreathCtrl = null;
        /// <summary>
        /// The tower levels associated with this tower
        /// </summary>
@@ -126,6 +129,8 @@
        /// </summary>
        protected int progressOffset = 0;
        public int FreezeBreathProgressOffset { get; set; }
        public bool PlayWaveLineFlash { get; set; } = true;
        /// <summary>
@@ -138,10 +143,9 @@
        public int uiProOffset
        {
            get { return this.progressOffset; }
            set { this.progressOffset = value; }
            get { return progressOffset; }
            set { progressOffset = value; }
        }
        /// <summary>
        /// Gets whether the tower can level up anymore
@@ -157,30 +161,30 @@
            if (opponentSide)
            {
                if (attack && (this.curActionState != 2))
                if (attack && (curActionState != 2))
                {
                    currentTowerLevel.SetTowerMonsterMat(materialTowerAttackOppo, true);
                    this.curActionState = 2;
                    curActionState = 2;
                }
                if ((!attack) && (this.curActionState != 1))
                if ((!attack) && (curActionState != 1))
                {
                    currentTowerLevel.SetTowerMonsterMat(materialTowerWaitOppo, false);
                    this.curActionState = 1;
                    curActionState = 1;
                }
            }
            else
            {
                if (attack && (this.curActionState != 2))
                if (attack && (curActionState != 2))
                {
                    currentTowerLevel.SetTowerMonsterMat(materialTowerAttackSelf, true);
                    this.curActionState = 2;
                    curActionState = 2;
                }
                if ((!attack) && (this.curActionState != 1))
                if ((!attack) && (curActionState != 1))
                {
                    currentTowerLevel.SetTowerMonsterMat(materialTowerWaitSelf, false);
                    this.curActionState = 1;
                    curActionState = 1;
                }
            }
        }
@@ -196,7 +200,7 @@
        /// <param name="play"></param>
        public void PlayEnergyEffect(bool play, bool isClose = true)
        {
            if (this.energyCtl && isClose)
            if (energyCtl && isClose)
                energyCtl.gameObject.SetActive(!play);
            else if (!isClose)
            {
@@ -215,11 +219,28 @@
        }
        /// <summary>
        /// 播放水精灵充能满了特效
        /// </summary>
        /// <param name="play"></param>
        /// <param name="isClose"></param>
        public void PlayFreezeBreathEffect(bool play, bool isClose = true)
        {
            if (FreezeBreathCtrl && isClose)
                FreezeBreathCtrl.gameObject.SetActive(!play);
            if (!opponentSide)
            {
                if (EndlessGameUI.instanceExists)
                    ((TowerPlacementGridEndless)EndlessGameUI.instance.selfTowerPlaceArea).PlayFreezeBreathEffect(gridPosition.x, gridPosition.y, play);
            }
        }
        /// <summary>
        /// 当前是否处于攻击模式
        /// </summary>
        public bool bInAttackMode
        {
            get { return this.m_bInAttackMode; }
            get { return m_bInAttackMode; }
            // 设置是否处于攻击状态:
            set
@@ -232,18 +253,18 @@
                {
                    if (opponentSide)
                    {
                        OpponentMgr.instance.SetTowerAttID(gridPosition.x, attributeId, this.currentLevel);
                        OpponentMgr.instance.SetTowerAttID(gridPosition.x, attributeId, currentLevel);
                    }
                    else
                    {
                        if (LevelManager.instanceExists)
                        {
                            LevelManager.instance.SetTowerAttID(gridPosition.x, attributeId, this.currentLevel);
                            LevelManager.instance.SetTowerAttID(gridPosition.x, attributeId, currentLevel);
                            WaveLineSelMgr.instance.attackTowerFixed(gridPosition.x);
                        }
                        else if (EndlessLevelManager.instanceExists)
                        {
                            EndlessLevelManager.instance.SetTowerAttID(gridPosition.x, attributeId, this.currentLevel);
                            EndlessLevelManager.instance.SetTowerAttID(gridPosition.x, attributeId, currentLevel);
                            EndlessWaveLineManager.instance.AttackTowerFixed(gridPosition.x, PlayWaveLineFlash);
                        }
                    }
@@ -260,12 +281,12 @@
        public void DisableTowerUICtrl()
        {
            // 根据是否是子弹塔防来决定是否显示相应的界面
            BulletUICtl buc = this.placementArea.GetBulletUICtl(gridPosition.x, gridPosition.y);
            BulletUICtl buc = placementArea.GetBulletUICtl(gridPosition.x, gridPosition.y);
            if ((this.eTowerFuntion == ETowerFuntion.BULLET) && (buc != null))
            if ((eTowerFuntion == ETowerFuntion.BULLET) && (buc != null))
            {
                buc.gameObject.SetActive(false);
                this.bulletCtl = null;
                bulletCtl = null;
            }
            EnergyUICtl euc = placementArea.GetEnergyUICtl(gridPosition.x, gridPosition.y);
@@ -273,23 +294,33 @@
            {
                // 设置数据
                euc.gameObject.SetActive(false);
                this.energyCtl = null;
                energyCtl = null;
            }
            return;
            FreezeBreath ctrl = placementArea.GetFreezeBreath(gridPosition.x, gridPosition.y);
            if (eTowerFuntion == ETowerFuntion.FREEZE && ctrl != null)
            {
                ctrl.gameObject.SetActive(false);
                ctrl = null;
            }
        }
        public int GetTowerUICtrlProgress()
        {
            // 根据是否是子弹塔防来决定是否显示相应的界面
            BulletUICtl buc = this.placementArea.GetBulletUICtl(gridPosition.x, gridPosition.y);
            BulletUICtl buc = placementArea.GetBulletUICtl(gridPosition.x, gridPosition.y);
            if ((this.eTowerFuntion == ETowerFuntion.BULLET) && (buc != null))
            if ((eTowerFuntion == ETowerFuntion.BULLET) && (buc != null))
                return buc.GetCtlProgress();
            EnergyUICtl euc = placementArea.GetEnergyUICtl(gridPosition.x, gridPosition.y);
            if ((eTowerFuntion == ETowerFuntion.ENERGY) && (euc != null))
                return euc.GetCtlProgress();
            FreezeBreath ctrl = placementArea.GetFreezeBreath(gridPosition.x, gridPosition.y);
            if (eTowerFuntion == ETowerFuntion.FREEZE && ctrl != null)
                return ctrl.CurrentProgress;
            return 0;
        }
@@ -297,12 +328,13 @@
        public void SetTowerUICtlProcess(int pro)
        {
            // 根据是否是子弹塔防来决定是否显示相应的界面
            BulletUICtl buc = this.placementArea.GetBulletUICtl(gridPosition.x, gridPosition.y);
            BulletUICtl buc = placementArea.GetBulletUICtl(gridPosition.x, gridPosition.y);
            if ((this.eTowerFuntion == ETowerFuntion.BULLET) && (buc != null))
            if ((eTowerFuntion == ETowerFuntion.BULLET) && (buc != null))
            {
                buc.SetCtlProcess(pro);
                progressOffset = pro;
                return;
            }
            EnergyUICtl euc = placementArea.GetEnergyUICtl(gridPosition.x, gridPosition.y);
@@ -312,53 +344,85 @@
                progressOffset = pro;
                if (progressOffset == 10)
                    progressOffset = 0;
                return;
            }
            FreezeBreath ctrl = placementArea.GetFreezeBreath(gridPosition.x, gridPosition.y);
            return;
            if (eTowerFuntion == ETowerFuntion.FREEZE && ctrl != null)
            {
                ctrl.SetCtrlProgress(pro);
                FreezeBreathProgressOffset = pro;
                if (FreezeBreathProgressOffset == 10)
                    FreezeBreathProgressOffset = 0;
            }
        }
        /// <summary>
        /// 充能技能相关的代码开关。包括子弹充能和时间充能
        /// </summary>
        protected void OnTowerUICtrl()
        {
            HandleBulletUICtrl();
            HandleEnergyUICtrl();
            HandleFreezeBreathCtrl();
        }
        private void HandleBulletUICtrl()
        {
            // 根据是否是子弹塔防来决定是否显示相应的界面
            BulletUICtl buc = this.placementArea.GetBulletUICtl(gridPosition.x, gridPosition.y);
            BulletUICtl buc = placementArea.GetBulletUICtl(gridPosition.x, gridPosition.y);
            if (buc == null) return;
            if ((this.eTowerFuntion == ETowerFuntion.BULLET) && (buc != null))
            if ((eTowerFuntion == ETowerFuntion.BULLET) && (buc != null))
            {
                // 设置数据
                buc.gameObject.SetActive(true);
                this.bulletCtl = buc;
                bulletCtl = buc;
                buc.resetToMaxBullet();
            }
            else
            {
                // 清空数据
                buc.gameObject.SetActive(false);
                this.bulletCtl = null;
                bulletCtl = null;
            }
        }
        private void HandleEnergyUICtrl()
        {
            // 根据是否是能量充能来决定是否显示相应的界面.
            EnergyUICtl euc = placementArea.GetEnergyUICtl(gridPosition.x, gridPosition.y);
            if ((eTowerFuntion == ETowerFuntion.ENERGY) && (euc != null))
            {
                // 设置数据
                euc.gameObject.SetActive(true);
                this.energyCtl = euc;
                energyCtl = euc;
                euc.SetEnergyProgress(0);
            }
            else
            {
                // 清空数据
                euc.gameObject.SetActive(false);
                this.energyCtl = null;
                energyCtl = null;
            }
        }
        private void HandleFreezeBreathCtrl()
        {
            FreezeBreath ctrl = placementArea.GetFreezeBreath(gridPosition.x, gridPosition.y);
            if (eTowerFuntion == ETowerFuntion.FREEZE && ctrl != null)
            {
                ctrl.gameObject.SetActive(true);
                FreezeBreathCtrl = ctrl;
                ctrl.SetProgress(0);
            }
            else
            {
                ctrl.gameObject.SetActive(false);
                FreezeBreathCtrl = null;
            }
        }
@@ -396,6 +460,9 @@
            {
                energyCtl.gameObject.SetActive(false);
            }
            if (FreezeBreathCtrl != null)
                FreezeBreathCtrl.gameObject.SetActive(false);
        }
        /// <summary>
@@ -412,8 +479,8 @@
            }
            // 设置攻击数据的加强,暂时是测试数据,后面需要读取表格数据处理:
            float damageAdd = 0;
            // float damageAdd = (inSceneTowerLevel - 1) * this.INSCENE_TU_DAMAGE;
            for (int ti = 0; ti < this.levels.Length; ti++)
            // float damageAdd = (inSceneTowerLevel - 1) * INSCENE_TU_DAMAGE;
            for (int ti = 0; ti < levels.Length; ti++)
            {
                if (levels[ti].levelDamager)
                {
@@ -425,7 +492,7 @@
        protected void ResetInSceneTowerLevel()
        {
            for (int ti = 0; ti < this.levels.Length; ti++)
            for (int ti = 0; ti < levels.Length; ti++)
            {
                if (levels[ti].levelDamager)
                {
@@ -444,9 +511,9 @@
            inSceneTowerLevel++;
            // 设置攻击数据的加强,暂时是测试数据,后面需要读取表格数据处理:
            float damageAdd = inSceneTowerLevel * this.INSCENE_TU_DAMAGE;
            float damageAdd = inSceneTowerLevel * INSCENE_TU_DAMAGE;
            for (int ti = 0; ti < this.levels.Length; ti++)
            for (int ti = 0; ti < levels.Length; ti++)
            {
                if (levels[ti].levelDamager)
                {
@@ -534,17 +601,17 @@
                EndlessLevelManager.instance.LevelStateChanged += OnLevelStateChanged;
            // 查找Targetter:
            Targetter target = this.GetComponentInChildren<Targetter>();
            Targetter target = GetComponentInChildren<Targetter>();
            if (target)
            {
                target.bOpponent = this.opponentSide;
                target.bOpponent = opponentSide;
            }
            else
                Debug.Log("在当前的Tower中找不到Targetter.");
            // 
            // 初始化当前的局内Tower等级数据
            this.initInSceneTowerLevel(SceneTowerLvl.getInSceneTowerLvl(this.towerName));
            initInSceneTowerLevel(SceneTowerLvl.getInSceneTowerLvl(towerName));
            StartCoroutine(ResetScale());
        }
@@ -583,11 +650,11 @@
        {
            if (vis)
            {
                this.gameObject.SetActive(true);
                gameObject.SetActive(true);
            }
            else
            {
                this.gameObject.SetActive(false);
                gameObject.SetActive(false);
            }
        }
Assets/Scripts/TowerDefense/UI/FreezeBreath.cs
New file
@@ -0,0 +1,117 @@
using UnityEngine.UI;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using DG.Tweening;
using TowerDefense.Level;
using Core.Utilities;
using TowerDefense.Agents;
using Core.Health;
using TowerDefense.UI.HUD;
/**
 * 水精灵技能-冷冻气息控制脚本
 * @Author: chenxin
 * @Date: 2020-11-12 14:41:23
 */
namespace KTGMGemClient
{
    public class FreezeBreath : MonoBehaviour
    {
        public Image ProgressImg;
        private int currentProgress;
        /// <summary>
        /// 充能时间(s)
        /// </summary>
        public static float ChargeTime { get; private set; } = 10f;
        /// <summary>
        /// 技能持续时间
        /// </summary>
        public static float EffectTime { get; private set; } = 1f;
        /// <summary>
        /// 当前的充能进度
        /// </summary>
        public int CurrentProgress { get; private set; }
        /// <summary>
        /// 喷冰特效
        /// </summary>
        public GameObject FreezeJet;
        public int ReleaseCount { get; set; }
        public void SetCtrlProgress(int progress)
        {
            if (progress == (int)Mathf.Floor(ChargeTime))
                progress = 0;
            ProgressImg.rectTransform.DOKill();
            SetProgress(progress, false);
        }
        public void SetProgress(int progress, bool ani = true)
        {
            if (CurrentProgress == progress) return;
            CurrentProgress = progress;
            ProgressImg.rectTransform.DOScaleY(progress / ChargeTime, ani ? 0.3f : 0);
        }
        public void SetProgress(float progress)
        {
            ProgressImg.rectTransform.DOScaleY(progress / ChargeTime, 0);
            CurrentProgress = (int)Mathf.Floor(progress);
        }
        /// <summary>
        /// 释放冷冻气息
        /// </summary>
        /// <param name="waveLineId">哪条兵线</param>
        /// <param name="damage">伤害值</param>
        public void ReleaseFreeze(int waveLineId, float damage, IAlignmentProvider alignmentProvider)
        {
            WaveLineAgentInsMgr[] agentInsMgrs = AgentInsManager.instance.GetWaveLineList();
            WaveLineAgentInsMgr waveLineAgentInsMgr = agentInsMgrs[waveLineId];
            List<Agent> list = waveLineAgentInsMgr.listAgent;
            if (list.Count == 0) return;
            List<Agent> agentList = new List<Agent>();
            for (int i = 0; i < list.Count; ++i)
            {
                agentList.Add(list[i]);
            }
            PlayFreezeEffect(waveLineId);
            while (agentList.Count > 0)
            {
                Agent agent = agentList[0];
                agentList.Remove(agentList[0]);
                if (agent.isDead) continue;
                agent.addSpeedSlowRate(0.25f);
                agent.PlayOnHitImmediately();
                EndlessGameUI.instance.generateBloodText(agent.position, damage);
                agent.TakeDamage(damage, agent.position, alignmentProvider);
            }
        }
        private void PlayFreezeEffect(int waveLineId)
        {
            GameObject obj = Poolable.TryGetPoolable(FreezeJet);
            ParticleSystem ps = obj.GetComponent<ParticleSystem>();
            if (ps == null) ps = obj.transform.GetChild(0).GetComponent<ParticleSystem>();
            ps.transform.position = EndlessLevelManager.instance.WaveManager.GetWaveEndPos(waveLineId);
            ps.Play();
        }
    }
}
Assets/Scripts/TowerDefense/UI/FreezeBreath.cs.meta
New file
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 446fbeaa4765a1c4dbcc532fc1cb626c
MonoImporter:
  externalObjects: {}
  serializedVersion: 2
  defaultReferences: []
  executionOrder: 0
  icon: {instanceID: 0}
  userData:
  assetBundleName:
  assetBundleVariant:
Assets/UI/energy.png.meta
@@ -89,12 +89,12 @@
    buildTarget: Android
    maxTextureSize: 2048
    resizeAlgorithm: 0
    textureFormat: -1
    textureFormat: 4
    textureCompression: 1
    compressionQuality: 50
    crunchedCompression: 0
    allowsAlphaSplitting: 0
    overridden: 0
    overridden: 1
    androidETC2FallbackOverride: 0
    forceMaximumCompressionQuality_BC6H_BC7: 0
  spriteSheet: