summaryrefslogtreecommitdiff
path: root/SurvivalTest/Assets/Scripts/TopDown/TopDownTransform.cs
diff options
context:
space:
mode:
Diffstat (limited to 'SurvivalTest/Assets/Scripts/TopDown/TopDownTransform.cs')
-rw-r--r--SurvivalTest/Assets/Scripts/TopDown/TopDownTransform.cs224
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