diff options
Diffstat (limited to 'SurvivalTest/Assets/Scripts/TopDown/TopDownTransform.cs')
-rw-r--r-- | SurvivalTest/Assets/Scripts/TopDown/TopDownTransform.cs | 224 |
1 files changed, 224 insertions, 0 deletions
diff --git a/SurvivalTest/Assets/Scripts/TopDown/TopDownTransform.cs b/SurvivalTest/Assets/Scripts/TopDown/TopDownTransform.cs new file mode 100644 index 0000000..103e214 --- /dev/null +++ b/SurvivalTest/Assets/Scripts/TopDown/TopDownTransform.cs @@ -0,0 +1,224 @@ +using System.Collections; +using System.Collections.Generic; +using UnityEngine; +#if UNITY_EDITOR +using UnityEditor; +#endif + +/// <summary> +/// 用于TopDown的Transform,支持模拟垂直高度,不允许旋转和缩放 +/// TopDownTransform的父节点必须也是TopDownTransform,Transform的父节点可以是TopDownTransform +/// </summary> +[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; + } + } + + /// <summary> + /// 全局坐标 + /// </summary> + public Vector3 position + { + get + { + Vector3 pos = m_LocalPosition; + Transform self = this.transform; + while(self.parent != null) + { + TopDownTransform parentTransform = self.parent.GetComponent<TopDownTransform>(); + 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<TopDownTransform>(); + if (parentTransform == null) + { + Debug.LogError("Parent is not TopDownTransform"); + continue; + } + pos -= parentTransform.m_LocalPosition; + self = self.parent; + } + m_LocalPosition = pos; + Project(); + } + } + + /// <summary> + /// 地表坐标(Topdown空间) + /// </summary> + 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(); + } + } + + /// <summary> + /// “投影”,把坐标转换到Transform上 + /// </summary> + 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<SpriteRenderer>(); + if (sr) + { + gameObject.AddOrGetComponent<TopDownSorting>(); + //gameObject.AddOrGetComponent<TopDownShadowCaster>(); + } + } + + 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; + } + + /// <summary> + /// 注意是在3D空间下 + /// </summary> + /// <returns></returns> + 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 + +}
\ No newline at end of file |