diff options
Diffstat (limited to 'SurvivalTest/Assets/Scripts/TopDown')
11 files changed, 472 insertions, 0 deletions
diff --git a/SurvivalTest/Assets/Scripts/TopDown/Editor.meta b/SurvivalTest/Assets/Scripts/TopDown/Editor.meta new file mode 100644 index 0000000..fa70114 --- /dev/null +++ b/SurvivalTest/Assets/Scripts/TopDown/Editor.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 80c8d9ba082ca27419e9d6e6bbb39f6d +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/SurvivalTest/Assets/Scripts/TopDown/Editor/TopDownTransformInspector.cs b/SurvivalTest/Assets/Scripts/TopDown/Editor/TopDownTransformInspector.cs new file mode 100644 index 0000000..1e4f6e0 --- /dev/null +++ b/SurvivalTest/Assets/Scripts/TopDown/Editor/TopDownTransformInspector.cs @@ -0,0 +1,50 @@ +using System.Collections; +using System.Collections.Generic; +using UnityEngine; +using UnityEditor; + + +[CustomEditor(typeof(TopDownTransform))] +public class TopDownTransformInspector : Editor +{ + + TopDownTransform m_TopDownTransform; + + private void OnEnable() + { + m_TopDownTransform = target as TopDownTransform; + } + + private void OnDisable() + { + } + + public override void OnInspectorGUI() + { + base.OnInspectorGUI(); + } + + protected override void OnHeaderGUI() + { + base.OnHeaderGUI(); + } + + //https://answers.unity.com/questions/463207/how-do-you-make-a-custom-handle-respond-to-the-mou.html + private void OnSceneGUI() + { + Vector3 pos3d = m_TopDownTransform.GetProjectedPosition(); + + float arrowSize = 2f; + + Handles.color = Handles.xAxisColor; + m_TopDownTransform.x += EditorHandlesHelper.PositionArrow(pos3d + new Vector3(0, -m_TopDownTransform.z, 0), Vector3.right, 1f, arrowSize).x; + + Handles.color = Handles.yAxisColor; + m_TopDownTransform.y -= EditorHandlesHelper.PositionArrow(pos3d + new Vector3(0, -m_TopDownTransform.z, 0), Vector3.up, 1f, arrowSize).y; + + Handles.color = Handles.zAxisColor; + m_TopDownTransform.z -= EditorHandlesHelper.PositionArrow(pos3d /*+ new Vector3(-0.3f, 0, 0)*/, Vector3.up, 1.4f, arrowSize).y; + + } + +}
\ No newline at end of file diff --git a/SurvivalTest/Assets/Scripts/TopDown/Editor/TopDownTransformInspector.cs.meta b/SurvivalTest/Assets/Scripts/TopDown/Editor/TopDownTransformInspector.cs.meta new file mode 100644 index 0000000..09d9899 --- /dev/null +++ b/SurvivalTest/Assets/Scripts/TopDown/Editor/TopDownTransformInspector.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: a1871ab3b887e6b41ba4a43777b53192 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/SurvivalTest/Assets/Scripts/TopDown/TopDownShadowCaster.cs b/SurvivalTest/Assets/Scripts/TopDown/TopDownShadowCaster.cs new file mode 100644 index 0000000..ed17323 --- /dev/null +++ b/SurvivalTest/Assets/Scripts/TopDown/TopDownShadowCaster.cs @@ -0,0 +1,70 @@ +using System.Collections; +using System.Collections.Generic; +using UnityEngine; + +//[ExecuteInEditMode] +[DisallowMultipleComponent] +[RequireComponent(typeof(TopDownTransform))] +[RequireComponent(typeof(SpriteRenderer))] +public class TopDownShadowCaster : MonoBehaviour +{ + [SerializeField] private Color m_Color = new Color32(0,0,0, 58); + [SerializeField] private Vector2 m_Scale = new Vector2(1, 0.5f); + + private GameObject m_Shadow; + private SpriteRenderer m_ShadowRenderer; + + private TopDownTransform m_Coord; + private SpriteRenderer m_SpriteRenderer; + + public void Flip(bool flip) + { + m_ShadowRenderer.flipX = flip; + } + + private void Awake() + { + m_Coord = GetComponent<TopDownTransform>(); + m_SpriteRenderer = GetComponent<SpriteRenderer>(); + + // + for(int i = this.transform.childCount - 1; i >= 0 ; --i) + { + GameObject child = this.transform.GetChild(i).gameObject; + if (child.name == "shadow") + { + Destroy(child); + } + } + + if (m_Shadow == null) + { + m_Shadow = new GameObject("shadow"); +// m_Shadow.hideFlags = HideFlags.HideAndDontSave; + + m_Shadow.transform.SetParent(transform); + m_Shadow.transform.localScale = m_Scale; + + m_ShadowRenderer = m_Shadow.AddComponent<SpriteRenderer>(); + m_ShadowRenderer.color = m_Color; + m_ShadowRenderer.sprite = m_SpriteRenderer.sprite; + m_ShadowRenderer.sortingLayerName = "Shadow"; + } + } + + //private void Update() + private void LateUpdate() + { + m_ShadowRenderer.color = m_Color; + m_ShadowRenderer.sprite = m_SpriteRenderer.sprite; + + SetPosition(); + } + + public void SetPosition() + { + Vector3 pos = m_Coord.GetProjectedGroundPosition(); + m_Shadow.transform.position = pos; + } + +} diff --git a/SurvivalTest/Assets/Scripts/TopDown/TopDownShadowCaster.cs.meta b/SurvivalTest/Assets/Scripts/TopDown/TopDownShadowCaster.cs.meta new file mode 100644 index 0000000..24ecda5 --- /dev/null +++ b/SurvivalTest/Assets/Scripts/TopDown/TopDownShadowCaster.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: f1ce201566412034c99687a8c5b94075 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 9 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/SurvivalTest/Assets/Scripts/TopDown/TopDownSorting.cs b/SurvivalTest/Assets/Scripts/TopDown/TopDownSorting.cs new file mode 100644 index 0000000..3ee2f0a --- /dev/null +++ b/SurvivalTest/Assets/Scripts/TopDown/TopDownSorting.cs @@ -0,0 +1,40 @@ +using System.Collections; +using System.Collections.Generic; +using UnityEngine; + +[DisallowMultipleComponent] +[RequireComponent(typeof(SpriteRenderer))] +[RequireComponent(typeof(TopDownTransform))] +public class TopDownSorting : MonoBehaviour +{ + private SpriteRenderer m_SpriteRenderer; + private TopDownTransform m_Coord; + + private void Awake() + { + m_SpriteRenderer = GetComponent<SpriteRenderer>(); + m_Coord = GetComponent<TopDownTransform>(); + } + + private void Update() + { + Sorting(); + } + + public void Sorting() + { + if(m_SpriteRenderer == null) + { + m_SpriteRenderer = GetComponent<SpriteRenderer>(); + } + + if(m_Coord == null) + { + m_Coord = GetComponent<TopDownTransform>(); + } + + // 根据y设置sortOrder + m_SpriteRenderer.sortingOrder = (int)(-m_Coord.position.y * 100); + } + +} diff --git a/SurvivalTest/Assets/Scripts/TopDown/TopDownSorting.cs.meta b/SurvivalTest/Assets/Scripts/TopDown/TopDownSorting.cs.meta new file mode 100644 index 0000000..33f3c75 --- /dev/null +++ b/SurvivalTest/Assets/Scripts/TopDown/TopDownSorting.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 7a9f0293bd6e86e43bbbefc99b5e2722 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 8 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: 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 diff --git a/SurvivalTest/Assets/Scripts/TopDown/TopDownTransform.cs.meta b/SurvivalTest/Assets/Scripts/TopDown/TopDownTransform.cs.meta new file mode 100644 index 0000000..2853e32 --- /dev/null +++ b/SurvivalTest/Assets/Scripts/TopDown/TopDownTransform.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 2b1fbd797bf03674e9d1b81edc11e3f1 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 5 + icon: {fileID: 2800000, guid: b7cb09ba3d43de2418ea93e3aa9cd4e4, type: 3} + userData: + assetBundleName: + assetBundleVariant: diff --git a/SurvivalTest/Assets/Scripts/TopDown/TopDownUtils.cs b/SurvivalTest/Assets/Scripts/TopDown/TopDownUtils.cs new file mode 100644 index 0000000..f42e123 --- /dev/null +++ b/SurvivalTest/Assets/Scripts/TopDown/TopDownUtils.cs @@ -0,0 +1,25 @@ +using System.Collections; +using System.Collections.Generic; +using UnityEngine; + +public class TopDownUtils +{ + + /// <summary> + /// 从TopDown空间转到3D空间下(TopDownTransform -> Transform) + /// </summary> + /// <param name="topDownCoord"></param> + /// <param name="z"></param> + /// <returns></returns> + public static Vector3 Project(Vector3 topDownCoord, float z = 0) + { + Vector3 pos = new Vector3(); + + pos.x = topDownCoord.x; + pos.y = topDownCoord.y + topDownCoord.z; + pos.z = z; + + return pos; + } + +}
\ No newline at end of file diff --git a/SurvivalTest/Assets/Scripts/TopDown/TopDownUtils.cs.meta b/SurvivalTest/Assets/Scripts/TopDown/TopDownUtils.cs.meta new file mode 100644 index 0000000..f60e1ef --- /dev/null +++ b/SurvivalTest/Assets/Scripts/TopDown/TopDownUtils.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: c60891307755afb4fb72033ed1cd557d +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: |