From ad376c4760e5e0c2183c51d21d044fd4d03f9721 Mon Sep 17 00:00:00 2001 From: wangguan <wangguan@kt007.com> Date: Thu, 03 Dec 2020 10:22:30 +0800 Subject: [PATCH] 修改新手引导文字 --- Assets/Scripts/TowerDefense/Towers/TowerLevel.cs | 523 +++++++++++++++++++++++++++++++++------------------------ 1 files changed, 303 insertions(+), 220 deletions(-) diff --git a/Assets/Scripts/TowerDefense/Towers/TowerLevel.cs b/Assets/Scripts/TowerDefense/Towers/TowerLevel.cs index 49eab2e..45bc19d 100644 --- a/Assets/Scripts/TowerDefense/Towers/TowerLevel.cs +++ b/Assets/Scripts/TowerDefense/Towers/TowerLevel.cs @@ -1,250 +1,333 @@ using System.Collections.Generic; -using ActionGameFramework.Health; using Core.Health; +using KTGMGemClient; using TowerDefense.Affectors; -using TowerDefense.Towers.Data; using TowerDefense.UI.HUD; using UnityEngine; +using TMPro; 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> + /// 升级特效 + /// </summary> + public GameObject UpgradeEffectPrefab; + /// <summary> + /// The parent tower controller of this tower + /// </summary> + public Tower ParentTower { get; protected set; } - /// <summary> - /// 当前的Level对应的DamagerData. - /// </summary> - public Damager levelDamager; + /// <summary> + /// The list of effects attached to the tower + /// </summary> + Affector[] m_Affectors; - /// <summary> - /// Reference to scriptable object with level data on it - /// </summary> - public TowerLevelData levelData; + /// <summary> + /// 未上阵的形象 + /// </summary> + public GameObject Body; - /// <summary> - /// The parent tower controller of this tower - /// </summary> - protected Tower m_ParentTower; + /// <summary> + /// 上阵形象 + /// </summary> + public GameObject AttackBody; - /// <summary> - /// The list of effects attached to the tower - /// </summary> - Affector[] m_Affectors; + /// <summary> + /// 可以放置的材质 + /// </summary> + public MeshRenderer canPlaceMesh; - /// <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> + /// 精灵塔动作状态 + /// </summary> + public TowerActionState ActionState { get; protected set; } - /// <summary> - /// The physics layer mask that the tower searches on - /// </summary> - public LayerMask mask { get; protected set; } + private string paramName = "ActionState"; - /// <summary> - /// Gets the cost value - /// </summary> - public int cost - { - get { return levelData.cost; } - } + /// <summary> + /// 动作动画器 + /// </summary> + public Animator ActionAnimator; - /// <summary> - /// Gets the sell value - /// </summary> - public int sell - { - get { return levelData.sell; } - } + public TextMeshPro LevelText; - /// <summary> - /// Gets the max health - /// </summary> - public int maxHealth - { - get { return levelData.maxHealth; } - } + /// <summary> + /// 精灵初始配置数据 + /// </summary> + public elf_info ElfInfo { get; protected set; } - /// <summary> - /// Gets the starting health - /// </summary> - public int startingHealth - { - get { return levelData.startingHealth; } - } + /// <summary> + /// 发射子弹速率 + /// </summary> + protected float fireRate; - /// <summary> - /// Gets the tower description - /// </summary> - public string description - { - get { return levelData.description; } - } + /// <summary> + /// 初始攻击速率 + /// </summary> + private float attackSpeed = 1f; - /// <summary> - /// Gets the tower description - /// </summary> - public string upgradeDescription - { - get { return levelData.upgradeDescription; } - } + /// <summary> + /// 多倍速攻击速度,基准速度的 N 倍速 + /// </summary> + private float fireSpeed = 1f; - /// <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> - /// 当前的TowerLevel设置为对应怪物的材质显示 - /// </summary> - /// <param name="mat"></param> - public void SetTowerMonsterMat( Material mat) + /// <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> + /// 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>(); + } + + ParentTower = tower; + ElfInfo = ElfInfoData.GetDataById(tower.ElfId); + } + + /// <summary> + /// 设置显示等级 + /// </summary> + /// <param name="level">从1开始</param> + public void SetShowLevel(int level) + { + LevelText.text = $"{level}"; + } + + private void Awake() + { + 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; + } + + fireRate = GetFireRate(); + + if (actionTimeArr[1] > 1 / fireRate) + { + // 动画时间比攻击长 + attackSpeed = actionTimeArr[1] * fireRate; + } + SetAttackState(false); + } + } + + /// <summary> + /// 获取发射速率 + /// </summary> + /// <returns></returns> + public float GetFireRate() + { + DecreaseTowerAttackCD endlessBuff = (DecreaseTowerAttackCD)EndlessBuffManager.instance.GetBuffInstanceByType(EndlessBuffEffectType.DecreaseTowerAttackCD); + float fireRate = endlessBuff != null ? endlessBuff.GetDecreaseCD(ParentTower.ElfId, 1 / ElfInfo.b_atkf) : 1 / ElfInfo.b_atkf; + + // 限制最大速度为 每0.1s发射一次 + return Mathf.Max(fireRate, 0.1f); + } + + 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> + /// 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; + } + + public void Kill() + { + ParentTower.KillTower(); + } + + public void OnBeforeSerialize() + { + } + + /// <summary> + /// 获取当前TowerLevel对应的AttackRise. + /// /// </summary> + public float attackRise { get { return 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