From 841b66ef416a727a0c798ad2263b098247cb4aa7 Mon Sep 17 00:00:00 2001
From: chenxin <chenxin6991@163.com>
Date: Fri, 27 Nov 2020 12:00:16 +0800
Subject: [PATCH] buff预览暂停

---
 Assets/Scripts/TowerDefense/Towers/TowerLevel.cs |  715 +++++++++++++++++++++++++++++++++++++++++------------------
 1 files changed, 498 insertions(+), 217 deletions(-)

diff --git a/Assets/Scripts/TowerDefense/Towers/TowerLevel.cs b/Assets/Scripts/TowerDefense/Towers/TowerLevel.cs
index 49eab2e..35b5bcc 100644
--- a/Assets/Scripts/TowerDefense/Towers/TowerLevel.cs
+++ b/Assets/Scripts/TowerDefense/Towers/TowerLevel.cs
@@ -1,6 +1,7 @@
 using System.Collections.Generic;
 using ActionGameFramework.Health;
 using Core.Health;
+using KTGMGemClient;
 using TowerDefense.Affectors;
 using TowerDefense.Towers.Data;
 using TowerDefense.UI.HUD;
@@ -8,243 +9,523 @@
 
 namespace TowerDefense.Towers
 {
-	/// <summary>
-	/// An individual level of a tower
-	/// </summary>
-	[DisallowMultipleComponent]
-	public class TowerLevel : MonoBehaviour, ISerializationCallbackReceiver
-	{
-		/// <summary>
-		/// The prefab for communicating placement in the scene
-		/// </summary>
-		public TowerPlacementGhost towerGhostPrefab;
+    /// <summary>
+    /// An individual level of a tower
+    /// </summary>
+    [DisallowMultipleComponent]
+    public class TowerLevel : MonoBehaviour, ISerializationCallbackReceiver
+    {
+        /// <summary>
+        /// The prefab for communicating placement in the scene
+        /// </summary>
+        public TowerPlacementGhost towerGhostPrefab;
 
-		/// <summary>
-		/// Build effect gameObject to instantiate on start
-		/// </summary>
-		public GameObject buildEffectPrefab;
+        /// <summary>
+        /// Build effect gameObject to instantiate on start
+        /// </summary>
+        //public GameObject buildEffectPrefab;
 
+        /// <summary>
+        /// 升级特效
+        /// </summary>
+        public GameObject UpgradeEffectPrefab;
 
-		/// <summary>
-		/// 当前的Level对应的DamagerData.
-		/// </summary>
-		public Damager levelDamager;
+        /// <summary>
+        /// 当前的Level对应的DamagerData.
+        /// </summary>
+        public Damager levelDamager;
 
-		/// <summary>
-		/// Reference to scriptable object with level data on it
-		/// </summary>
-		public  TowerLevelData levelData;
+        /// <summary>
+        /// Reference to scriptable object with level data on it
+        /// </summary>
+        public TowerLevelData levelData;
 
-		/// <summary>
-		/// The parent tower controller of this tower
-		/// </summary>
-		protected Tower m_ParentTower;
+        /// <summary>
+        /// The parent tower controller of this tower
+        /// </summary>
+        protected Tower m_ParentTower;
 
-		/// <summary>
-		/// The list of effects attached to the tower
-		/// </summary>
-		Affector[] m_Affectors;
+        /// <summary>
+        /// The list of effects attached to the tower
+        /// </summary>
+        Affector[] m_Affectors;
 
-		/// <summary>
-		/// Gets the list of effects attached to the tower
-		/// </summary>
-		protected Affector[] Affectors
-		{
-			get
-			{
-				if (m_Affectors == null)
-				{
-					m_Affectors = GetComponentsInChildren<Affector>();
-				}
-				return m_Affectors;
-			}
-		}
+        /// <summary>
+        /// TEST CODE: 是否已经缩放.
+        /// </summary>
+        protected bool bScaleForCombat = false;
 
-		/// <summary>
-		/// The physics layer mask that the tower searches on
-		/// </summary>
-		public LayerMask mask { get; protected set; }
+        /// <summary>
+        /// 未上阵的形象
+        /// </summary>
+        public GameObject Body;
 
-		/// <summary>
-		/// Gets the cost value
-		/// </summary>
-		public int cost
-		{
-			get { return levelData.cost; }
-		}
+        /// <summary>
+        /// 上阵形象
+        /// </summary>
+        public GameObject AttackBody;
 
-		/// <summary>
-		/// Gets the sell value
-		/// </summary>
-		public int sell
-		{
-			get { return levelData.sell; }
-		}
+        /// <summary>
+        /// 可以放置的材质
+        /// </summary>
+        public MeshRenderer canPlaceMesh;
 
-		/// <summary>
-		/// Gets the max health
-		/// </summary>
-		public int maxHealth
-		{
-			get { return levelData.maxHealth; }
-		}
+        /// <summary>
+        /// 精灵塔动作状态
+        /// </summary>
+        public TowerActionState ActionState { get; protected set; }
 
-		/// <summary>
-		/// Gets the starting health
-		/// </summary>
-		public int startingHealth
-		{
-			get { return levelData.startingHealth; }
-		}
+        private string paramName = "ActionState";
 
-		/// <summary>
-		/// Gets the tower description
-		/// </summary>
-		public string description
-		{
-			get { return levelData.description; }
-		}
+        /// <summary>
+        /// 动作动画器
+        /// </summary>
+        public Animator ActionAnimator;
 
-		/// <summary>
-		/// Gets the tower description
-		/// </summary>
-		public string upgradeDescription
-		{
-			get { return levelData.upgradeDescription; }
-		}
+        /// <summary>
+        /// 发射子弹速率
+        /// </summary>
+        protected float fireRate;
 
-		/// <summary>
-		/// Initialises the Effects attached to this object
-		/// </summary>
-		public virtual void Initialize(Tower tower, LayerMask enemyMask, IAlignmentProvider alignment)
-		{
-			mask = enemyMask;
-			
-			foreach (Affector effect in Affectors)
-			{
-				effect.Initialize(alignment, mask);
-			    
-			}
-			m_ParentTower = tower;
-		}
+        /// <summary>
+        /// 初始攻击速率
+        /// </summary>
+        private float attackSpeed = 1f;
 
-		/// <summary>
-		/// 当前的TowerLevel设置为对应怪物的材质显示
-		/// </summary>
-		/// <param name="mat"></param>
-		public void SetTowerMonsterMat( Material mat)
+        /// <summary>
+        /// 多倍速攻击速度,基准速度的 N 倍速
+        /// </summary>
+        private float fireSpeed = 1f;
+
+        /// <summary>
+        /// 发射倍速,如果设置多倍速攻击,直接修改此属性,恢复之前的攻速直接设置为 1
+        /// </summary>
+        /// <value></value>
+        public float FireSpeed
         {
-			if (mat == null) return;
-			// 查找子结点:
-			foreach (Transform t in transform.GetComponentsInChildren<Transform>())
-			{
-				if (t.name == "Cube")
-				{
-					t.GetComponent<MeshRenderer>().material = mat;
-					Vector3 scale = t.localScale;
-					scale.z *= 1.267f;
-					t.localScale = scale;
-					Vector3 pos = t.localPosition;
-					pos.z -= 0.2f;
-					t.localPosition = pos;
-				}
-			}
-		}
+            get { return fireSpeed; }
+            set
+            {
+                if (value < 0) value = 0;
 
-		/// <summary>
-		/// A method for activating or deactivating the attached <see cref="Affectors"/>
-		/// </summary>
-		public void SetAffectorState(bool state,int waveline )
-		{
-			foreach (Affector affector in Affectors)
-			{
-				if (affector != null)
-				{
-					affector.enabled = state;
-					affector.waveLineID = waveline;
-				}
-			}
-		}
+                fireSpeed = value;
 
+                if (ActionState == TowerActionState.Attack)
+                    ActionAnimator.speed = attackSpeed * fireSpeed;
+            }
+        }
 
-		/// <summary>
-		/// Returns a list of affectors that implement ITowerRadiusVisualizer
-		/// </summary>
-		/// <returns>ITowerRadiusVisualizers of tower</returns>
-		public List<ITowerRadiusProvider> GetRadiusVisualizers()
-		{
-			List<ITowerRadiusProvider> visualizers = new List<ITowerRadiusProvider>();
-			foreach (Affector affector in Affectors)
-			{
-				var visualizer = affector as ITowerRadiusProvider;
-				if (visualizer != null)
-				{
-					visualizers.Add(visualizer);
-				}
-			}
-			return visualizers;
-		}
+        /// <summary>
+        /// 各个动作的基准播放时长(播放一遍用的时间)
+        /// </summary>
+        protected float[] actionTimeArr;
 
-		/// <summary>
-		/// Returns the dps of the tower
-		/// </summary>
-		/// <returns>The dps of the tower</returns>
-		public float GetTowerDps()
-		{
-			float dps = 0;
-			foreach (Affector affector in Affectors)
-			{
-				var attack = affector as AttackAffector;
-				if (attack != null && attack.damagerProjectile != null)
-				{
-					dps += attack.GetProjectileDamage() * attack.fireRate;
-				}
-			}
-			return dps;
-		}
-
-		public void Kill()
-		{
-			m_ParentTower.KillTower();
-		}
-
-		public void OnBeforeSerialize()
-		{
-		}
-
-
-		/// <summary>
-		/// 获取当前TowerLevel对应的AttackRise.
-		/// </summary>
-		public float attackRise { get { return m_ParentTower.attackRise; } }
-
-		public void OnAfterDeserialize()
-		{
-			// Setting this member to null is required because we are setting this value on a prefab which will 
-			// persists post run in editor, so we null this member to ensure it is repopulated every run
-			m_Affectors = null;
-		}
-
-		/// <summary>
-		/// Insntiate the build particle effect object
-		/// </summary>
-		void Start()
-		{
-			if (buildEffectPrefab != null)
-			{
-				Instantiate(buildEffectPrefab, transform);
-			}
-		}
-
-		/// <summary>
-		/// 播放升级特效
-		/// </summary>
-		public void PlayUpGradeEffect()
+        /// <summary>
+        /// Gets the list of effects attached to the tower
+        /// </summary>
+        protected Affector[] Affectors
         {
-			if (buildEffectPrefab != null)
-			{
-				Instantiate(buildEffectPrefab, transform);
-			}
-		}
-	}
+            get
+            {
+                if (m_Affectors == null)
+                {
+                    m_Affectors = GetComponentsInChildren<Affector>();
+                }
+                return m_Affectors;
+            }
+        }
+
+        /// <summary>
+        /// The physics layer mask that the tower searches on
+        /// </summary>
+        public LayerMask mask { get; protected set; }
+
+        /// <summary>
+        /// Gets the cost value
+        /// </summary>
+        public int cost
+        {
+            get { return levelData.cost; }
+        }
+
+        /// <summary>
+        /// Gets the sell value
+        /// </summary>
+        public int sell
+        {
+            get { return levelData.sell; }
+        }
+
+        /// <summary>
+        /// Gets the max health
+        /// </summary>
+        public int maxHealth
+        {
+            get { return levelData.maxHealth; }
+        }
+
+        /// <summary>
+        /// Gets the starting health
+        /// </summary>
+        public int startingHealth
+        {
+            get { return levelData.startingHealth; }
+        }
+
+        /// <summary>
+        /// Gets the tower description
+        /// </summary>
+        public string description
+        {
+            get { return levelData.description; }
+        }
+
+        /// <summary>
+        /// Gets the tower description
+        /// </summary>
+        public string upgradeDescription
+        {
+            get { return levelData.upgradeDescription; }
+        }
+
+
+        /// <summary>
+        /// Initialises the Effects attached to this object
+        /// </summary>
+        public virtual void Initialize(Tower tower, LayerMask enemyMask, IAlignmentProvider alignment)
+        {
+            mask = enemyMask;
+
+            foreach (Affector effect in Affectors)
+            {
+                effect.Initialize(alignment, mask);
+                effect.towerPtr = tower;
+                AttackAffector attackAffector = effect.GetComponent<AttackAffector>();
+
+                // if (attackAffector.projectile != null)
+                // {
+                //     Damager damager = attackAffector.projectile.gameObject.GetComponent<Damager>();
+                //     damager.TowerAttributeId = tower.attributeId;
+                // }
+            }
+            m_ParentTower = tower;
+            Transform starTs = transform.Find("Star");
+            starTs.localPosition = new Vector3(0, 0.2f, 0.6f);
+            starTs.localRotation = Quaternion.Euler(60, 180, 0);
+        }
+
+        private Transform mat;
+        private MeshRenderer myRender;
+
+        Vector3 normalScale;
+
+        private void Awake()
+        {
+            mat = transform.Find("Cube");
+            myRender = mat.GetComponent<MeshRenderer>();
+            normalScale = new Vector3(1.5f, 1.5f, 1.5f);
+            canPlaceMesh.enabled = false;
+        }
+
+        private void Start()
+        {
+            if (ActionAnimator != null)
+            {
+                AnimationClip[] clips = ActionAnimator.runtimeAnimatorController.animationClips;
+                actionTimeArr = new float[clips.Length];
+
+                for (int i = 0; i < clips.Length; ++i)
+                {
+                    if (clips[i].name == "Standing")
+                        actionTimeArr[0] = clips[i].length;
+                    else if (clips[i].name == "Attack")
+                        actionTimeArr[1] = clips[i].length;
+                }
+
+                GameObject affectorObj = transform.Find("Affector").gameObject;
+                AttackAffector attackAffector = affectorObj.GetComponent<AttackAffector>();
+                fireRate = attackAffector.FireRate;
+
+                if (actionTimeArr[1] > 1 / fireRate)
+                {
+                    // 动画时间比攻击长
+                    attackSpeed = actionTimeArr[1] * fireRate;
+                }
+                SetAttackState(false);
+            }
+        }
+
+        public void LateUpdate()
+        {
+            if (ActionAnimator == null || !ActionAnimator.isActiveAndEnabled) return;
+
+            AnimatorStateInfo stateInfo = ActionAnimator.GetCurrentAnimatorStateInfo(0);
+
+            if (ActionState == TowerActionState.Attack && stateInfo.normalizedTime >= 1f)
+                ChangeState(TowerActionState.Standing);
+        }
+
+        /// <summary>
+        /// 设置可以放置
+        /// </summary>
+        /// <param name="isOn"></param>
+        public void SetCanPlace(bool isOn)
+        {
+            if (canPlaceMesh.enabled != isOn)
+                canPlaceMesh.enabled = isOn;
+        }
+        
+        public void ChangeState(TowerActionState state)
+        {
+            if (ActionAnimator == null || !ActionAnimator.isActiveAndEnabled) return;
+
+            ActionState = state;
+
+            if (ActionState == TowerActionState.Attack && state == TowerActionState.Attack)
+            {
+                ActionAnimator.Update(0);
+                ActionAnimator.Play("Attack", 0, 0);
+            }
+            ActionAnimator.SetInteger(paramName, (int)state);
+
+            if (state == TowerActionState.Attack)
+                ActionAnimator.speed = attackSpeed * FireSpeed;
+            else if (state == TowerActionState.Standing)
+                ActionAnimator.speed = 1f;
+        }
+
+        /// <summary>
+        /// 未上阵塔缩放,固定缩放
+        /// </summary>
+        public void NormalScale()
+        {
+            mat.localScale = normalScale;
+            mat.localPosition = Vector3.zero;
+        }
+
+        private bool isAttack;
+        /// <summary>
+        /// 设置火宝石攻速
+        /// </summary>
+        /// <param name="isAttack"></param>
+        public void SetFireMatSpeed(bool isFast)
+        {
+            if (isFast && isAttack)
+            {
+                myRender.material.SetFloat("_Speed", 40);
+            }
+            else
+            {
+                //还原10
+                myRender.material.SetFloat("_Speed", 8);
+            }
+        }
+        /// <summary>
+        /// 上阵塔缩放
+        /// </summary>
+        public void ResetScale()
+        {
+            if (transform.name.StartsWith("GrowUpTower"))
+            {
+                //火元素
+                mat.localScale = GameConfig.fireScale;
+                mat.localPosition = GameConfig.fireOffectp;
+            }
+            else if (transform.name.StartsWith("BlinkTower"))
+            {
+                //木元素
+                mat.localScale = GameConfig.woodScale;
+                mat.localPosition = GameConfig.woodOffectp;
+
+            }
+            else if (transform.name.StartsWith("CopyCatTower"))
+            {
+                //水元素
+                //mat.localScale = woodScale;
+
+                Vector3 scale = mat.localScale;
+
+                if (!this.bScaleForCombat)
+                {
+                    scale.z *= 1.267f;
+                    mat.localScale = scale;
+                    Vector3 pos = mat.localPosition;
+                    pos.z -= 0.2f;
+                    mat.localPosition = pos;
+                    bScaleForCombat = true;
+                }
+            }
+        }
+
+
+        /// <summary>
+        /// 当前的TowerLevel设置为对应怪物的材质显示
+        /// </summary>
+        /// <param name="mat"></param>
+        public void SetTowerMonsterMat(Material material, bool isAttack)
+        {
+            if (material == null) return;
+
+            this.isAttack = isAttack;
+            myRender.material = material;
+            if (isAttack)
+            {
+                if (transform.name.StartsWith("GrowUpTower") || transform.name.StartsWith("BlinkTower"))
+                {
+                    float t = Mathf.Floor(Time.time);
+                    float offect = t % 8;
+                    myRender.material.SetFloat("_ChangeTime", Mathf.Floor(Time.time - offect));
+
+                }
+            }
+            else
+            {
+                myRender.material.SetFloat("_ChangeTime", Mathf.Floor(Time.time));
+            }
+
+            //Debug.Log("当前时间Time.time:"+Time.time);
+            // if (transform.name.StartsWith("GrowUpTower") && mat.localPosition != fireOffectp)
+            // {
+            //     mat.localPosition = fireOffectp;
+            // }
+            // else if (transform.name.StartsWith("BlinkTower") && mat.localPosition != woodOffectp)
+            // {
+            //     //木元素
+            //     mat.localPosition = woodOffectp;
+            // }
+            // // 查找子结点:
+            // foreach (Transform t in transform.GetComponentsInChildren<Transform>())
+            // {
+            //     if (t.name == "Cube")
+            //     {
+            //         t.GetComponent<MeshRenderer>().material = mat;
+            //         //Vector3 scale = t.localScale;
+
+            //         // if (!this.bScaleForCombat)
+            //         // {
+            //         //     scale.z *= 1.267f;
+            //         //     t.localScale = scale;
+            //         //     Vector3 pos = t.localPosition;
+            //         //     pos.z -= 0.2f;
+            //         //     t.localPosition = pos;
+            //         //     bScaleForCombat = true;
+            //         // }
+            //     }
+            // }
+        }
+
+        /// <summary>
+        /// A method for activating or deactivating the attached <see cref="Affectors"/>
+        /// </summary>
+        public void SetAffectorState(bool state, int waveline)
+        {
+            foreach (Affector affector in Affectors)
+            {
+                if (affector != null)
+                {
+                    affector.enabled = state;
+                    affector.waveLineID = waveline;
+                }
+            }
+        }
+
+
+        /// <summary>
+        /// Returns a list of affectors that implement ITowerRadiusVisualizer
+        /// </summary>
+        /// <returns>ITowerRadiusVisualizers of tower</returns>
+        public List<ITowerRadiusProvider> GetRadiusVisualizers()
+        {
+            List<ITowerRadiusProvider> visualizers = new List<ITowerRadiusProvider>();
+            foreach (Affector affector in Affectors)
+            {
+                var visualizer = affector as ITowerRadiusProvider;
+                if (visualizer != null)
+                {
+                    visualizers.Add(visualizer);
+                }
+            }
+            return visualizers;
+        }
+
+        /// <summary>
+        /// Returns the dps of the tower
+        /// </summary>
+        /// <returns>The dps of the tower</returns>
+        public float GetTowerDps()
+        {
+            float dps = 0;
+            foreach (Affector affector in Affectors)
+            {
+                var attack = affector as AttackAffector;
+                if (attack != null && attack.damagerProjectile != null)
+                {
+                    dps += attack.GetProjectileDamage() * attack.FireRate;
+                }
+            }
+            return dps;
+        }
+
+        public void Kill()
+        {
+            m_ParentTower.KillTower();
+        }
+
+        public void OnBeforeSerialize()
+        {
+        }
+
+
+        /// <summary>
+        /// 获取当前TowerLevel对应的AttackRise.
+        /// </summary>
+        public float attackRise { get { return m_ParentTower.attackRise; } }
+
+        public void OnAfterDeserialize()
+        {
+            // Setting this member to null is required because we are setting this value on a prefab which will 
+            // persists post run in editor, so we null this member to ensure it is repopulated every run
+            m_Affectors = null;
+        }
+
+        /// <summary>
+        /// 设置上阵和非上阵状态下,塔的自身形象
+        /// </summary>
+        /// <param name="isAttackMode"></param>
+        public void SetAttackState(bool isAttackMode)
+        {
+            if (isAttackMode)
+            {
+                AttackBody.SetActive(isAttackMode);
+                Body.SetActive(!isAttackMode);
+                ChangeState(TowerActionState.Attack);
+            }
+            else
+            {
+                ChangeState(TowerActionState.Standing);
+            }
+        }
+
+        /// <summary>
+        /// 播放升级特效
+        /// </summary>
+        public void PlayUpGradeEffect()
+        {
+            if (UpgradeEffectPrefab != null)
+            {
+                GameObject obj = Instantiate(UpgradeEffectPrefab);
+                obj.transform.position = gameObject.transform.position;
+                ParticleSystem ps = obj.GetComponent<ParticleSystem>();
+
+                if (ps == null)
+                    ps = obj.transform.GetChild(0).GetComponent<ParticleSystem>();
+
+                Vector3 pos = obj.transform.position;
+                pos.y = 5f;
+                obj.transform.position = pos;
+                ps.Play();
+                Destroy(obj, ps.main.duration);
+            }
+        }
+    }
 }
\ No newline at end of file

--
Gitblit v1.9.1