using System.Collections; using System.Collections.Generic; using UnityEngine; #if UNITY_EDITOR using UnityEditor; #endif /// /// 用于TopDown的Transform,支持模拟垂直高度,不允许旋转和缩放 /// TopDownTransform的父节点必须也是TopDownTransform,Transform的父节点可以是TopDownTransform /// [ExecuteInEditMode] [RequireComponent(typeof(Transform))] public class TopDownTransform : MonoBehaviour { // 右手系 // z // | // | /y // | / // |/______x // x, y, z ( z = height) [SerializeField] private Vector3 m_LocalPosition; // 只能绕一个虚拟轴旋转 //[SerializeField] private float m_LocalRotation; // x, z //[SerializeField] private Vector2 m_LocalScale; public Vector3 localPosition { get { return m_LocalPosition; } set { m_LocalPosition = value; Project(); } } public float x { get { return m_LocalPosition.x; } set { m_LocalPosition.x = value; Project(); } } public float y { get { return m_LocalPosition.y; } set { m_LocalPosition.y = value; Project(); } } public float z { get { return m_LocalPosition.z; } set { m_LocalPosition.z = value; Project(); } } public float height { get { return z; } set { z = value; } } /// /// 全局坐标 /// public Vector3 position { get { Vector3 pos = m_LocalPosition; Transform self = this.transform; while(self.parent != null) { TopDownTransform parentTransform = self.parent.GetComponent(); if (parentTransform == null) { Debug.LogError("Parent is not TopDownTransform"); continue; } pos += parentTransform.m_LocalPosition; self = self.parent; } return pos; } set { Vector3 pos = value; Transform self = this.transform; while (self.parent != null) { TopDownTransform parentTransform = self.parent.GetComponent(); if (parentTransform == null) { Debug.LogError("Parent is not TopDownTransform"); continue; } pos -= parentTransform.m_LocalPosition; self = self.parent; } m_LocalPosition = pos; Project(); } } /// /// 地表坐标(Topdown空间) /// public Vector3 positionOnGround { get { Vector3 pos = position; pos.z = 0; return pos; } set { Vector3 pos = position; pos.x = value.x; pos.y = value.y; position = pos; Project(); } } /// /// “投影”,把坐标转换到Transform上 /// public void Project() { Vector3 pos = transform.localPosition; pos.x = m_LocalPosition.x; pos.y = m_LocalPosition.y + m_LocalPosition.z; transform.localPosition = pos; } private void Awake() { SpriteRenderer sr = GetComponent(); if (sr) { gameObject.AddOrGetComponent(); //gameObject.AddOrGetComponent(); } } private void Update() { Project(); } #region 转换到Transform坐标 public Vector3 GetProjectedPosition() { Vector3 posTD = position; Vector3 pos = new Vector3(); pos.x = posTD.x; pos.y = posTD.y + posTD.z; pos.z = transform.position.z; return pos; } /// /// 注意是在3D空间下 /// /// public Vector3 GetProjectedGroundPosition() { Vector3 posTD = position; Vector3 pos = new Vector3(); pos.x = posTD.x; pos.y = posTD.y; pos.z = transform.position.z; return pos; } #endregion #if UNITY_EDITOR private void OnDrawGizmos() { Vector3 start = TopDownUtils.Project(position); Vector3 end = TopDownUtils.Project(positionOnGround); Handles.DrawDottedLine(start, end, 1f); Handles.DrawWireCube(end, new Vector3(0.1f, 0.1f, 0f)); } #endif }