using DG.Tweening;
|
using KTGMGemClient;
|
using TowerDefense.Towers;
|
using UnityEngine;
|
using UnityEngine.UIElements;
|
|
namespace TowerDefense.UI.HUD
|
{
|
/// <summary>
|
/// Tower placement "ghost" that indicates the position of the tower to be placed and its validity for placement.
|
/// This is built with mouse in mind for testing, but it should be possible to abstract a lot of this into a child
|
/// class for the purposes of a touch UI.
|
///
|
/// Should exist on its own layer to ensure best placement.
|
/// </summary>
|
[RequireComponent(typeof(Collider))]
|
public class TowerPlacementGhost : MonoBehaviour
|
{
|
/// <summary>
|
/// The tower we represent
|
/// </summary>
|
public Tower controller { get; private set; }
|
|
/// <summary>
|
/// Prefab used to visualize effect radius of tower
|
/// </summary>
|
public GameObject radiusVisualizer;
|
|
/// <summary>
|
/// 当前TowerGhost附属的可视化数据,可以为空。
|
/// </summary>
|
public GameObject radiusObject;
|
protected static readonly float BASERADIUS_SIZE = 60.0f;
|
protected float fadeInTime = 0.0f;
|
protected bool bInDisplay = false;
|
|
/// <summary>
|
/// Offset height for radius visualizer
|
/// </summary>
|
public float radiusVisualizerHeight = 0.02f;
|
|
/// <summary>
|
/// Movement damping factor
|
/// </summary>
|
public float dampSpeed = 0.075f;
|
|
/// <summary>
|
/// The two materials used to represent valid and invalid placement, respectively
|
/// </summary>
|
public Material material;
|
|
public Material invalidPositionMaterial;
|
|
/// <summary>
|
/// The list of attached mesh renderers
|
/// </summary>
|
protected MeshRenderer[] m_MeshRenderers;
|
|
/// <summary>
|
/// Movement velocity for smooth damping
|
/// </summary>
|
protected Vector3 m_MoveVel;
|
|
/// <summary>
|
/// Target world position
|
/// </summary>
|
protected Vector3 m_TargetPosition;
|
|
/// <summary>
|
/// True if we're at a valid world position
|
/// </summary>
|
protected bool m_ValidPos;
|
|
/// <summary>
|
/// The attached the collider
|
/// </summary>
|
public Collider ghostCollider { get; private set; }
|
|
public int gridPositionX;
|
public int gridPositionY;
|
|
public void SetGridPosition(int x, int y)
|
{
|
gridPositionX = x;
|
gridPositionY = y;
|
//Debug.Log($"x:{x} y:{y}");
|
}
|
|
/// <summary>
|
/// Initialize this ghost
|
/// </summary>
|
/// <param name="tower">The tower controller we're a ghost of</param>
|
public virtual void Initialize(Tower tower)
|
{
|
//m_MeshRenderers = GetComponentsInChildren<MeshRenderer>();
|
controller = tower;
|
if (GameUI.instanceExists)
|
{
|
GameUI.instance.SetupRadiusVisualizer(controller, transform);
|
}
|
ghostCollider = GetComponent<Collider>();
|
m_MoveVel = Vector3.zero;
|
m_ValidPos = false;
|
|
gridPositionX = tower.gridPosition.x;
|
gridPositionY = tower.gridPosition.y;
|
|
if (null != this.radiusObject)
|
{
|
Material tmat = radiusObject.GetComponent<MeshRenderer>().material;
|
tmat.color = new Color(1.0f, 1.0f, 1.0f, 0.0f);
|
}
|
|
//特效直接把塔做了进去
|
// // 查找子结点,技能塔拖动的时候半透明:
|
// if (controller.towerFeature != EFeatureTower.NULL)
|
// {
|
// foreach (Transform t in transform.GetComponentsInChildren<Transform>())
|
// {
|
// if (t.name == "Effect")
|
// {
|
// // t.GetComponent<MeshRenderer>().material.color = new Color(1.0f, 1.0f, 1.0f, 1.0f);
|
// // t.GetComponent<MeshRenderer>().material.DOColor(new Color(1.0f, 1.0f, 1.0f, 0.4f), 0.4f);
|
// // 改为拖动的时候播放特效
|
// ParticleSystem ps = t.gameObject.GetComponent<ParticleSystem>();
|
|
// if (ps == null)
|
// ps = t.GetChild(0).GetComponent<ParticleSystem>();
|
|
// ps.Play();
|
// break;
|
// }
|
// }
|
// }
|
}
|
|
public void SetAttackArea(int lvl, int attid)
|
{
|
skilllevelinfo slinfo = JsonDataCenter.GetSkillLevelInfo(attid, lvl + 1);
|
if (slinfo == null) return;
|
if (slinfo.atcmod.Count < 2) return;
|
float radius = slinfo.atcmod[1];
|
|
float scale = radius * 2.0f / BASERADIUS_SIZE;
|
if (null != this.radiusObject)
|
{
|
Vector3 svec = new Vector3(scale, scale, scale);
|
radiusObject.transform.localScale = svec;
|
}
|
}
|
|
/// <summary>
|
/// fadeOut fadeIn 攻击区域的
|
/// </summary>
|
/// <param name="fadeOut"></param>
|
public void fadeOutAttackArea()
|
{
|
if (null == this.radiusObject) return;
|
|
if (this.bInDisplay)
|
{
|
this.fadeInTime = 0.15f;
|
return;
|
}
|
|
Material tmat = radiusObject.GetComponent<MeshRenderer>().material;
|
this.bInDisplay = true;
|
this.fadeInTime = 0.15f;
|
tmat.DOColor(new Color(1.0f, 1.0f, 1.0f, 1.0f), 0.2f);
|
}
|
|
/// <summary>
|
/// Hide this ghost
|
/// </summary>
|
public virtual void Hide()
|
{
|
gameObject.SetActive(false);
|
}
|
|
/// <summary>
|
/// Show this ghost
|
/// </summary>
|
public virtual void Show()
|
{
|
if (!gameObject.activeSelf)
|
{
|
gameObject.SetActive(true);
|
m_MoveVel = Vector3.zero;
|
|
m_ValidPos = false;
|
}
|
}
|
|
Vector3 up = new Vector3(0, 10, 0);
|
/// <summary>
|
/// Moves this ghost to a given world position
|
/// </summary>
|
/// <param name="worldPosition">The new position to move to in world space</param>
|
/// <param name="rotation">The new rotation to adopt, in world space</param>
|
/// <param name="validLocation">Whether or not this position is valid. Ghost may display differently
|
/// over invalid locations</param>
|
public virtual void Move(Vector3 worldPosition, Quaternion rotation, bool validLocation)
|
{
|
//Debug.Log("移动了");
|
|
transform.position = worldPosition + up;
|
// if (!m_ValidPos)
|
// {
|
// // Immediately move to the given position
|
// m_ValidPos = true;
|
// transform.position = m_TargetPosition;
|
// }
|
}
|
|
|
/// <summary>
|
/// Damp the movement of the ghost
|
/// </summary>
|
protected virtual void Update()
|
{
|
//Vector3 currentPos = transform.position;
|
//Debug.Log(transform.position);
|
// if (this.bInDisplay && (radiusObject != null))
|
// {
|
// this.fadeInTime -= Time.deltaTime;
|
// if (this.fadeInTime <= 0.0f)
|
// {
|
// bInDisplay = false;
|
// fadeInTime = 0.0f;
|
// Material tmat = radiusObject.GetComponent<MeshRenderer>().material;
|
// tmat.DOColor(new Color(1.0f, 1.0f, 1.0f, 0.0f), 0.1f);
|
// }
|
// }
|
|
// if (Vector3.SqrMagnitude(currentPos - m_TargetPosition) > 0.01f)
|
// {
|
// //currentPos = Vector3.SmoothDamp(currentPos, m_TargetPosition, ref m_MoveVel, dampSpeed);
|
|
// //transform.position = currentPos;
|
// transform.position = m_TargetPosition;
|
|
// }
|
// else
|
// {
|
// m_MoveVel = Vector3.zero;
|
// }
|
}
|
}
|
}
|