#if UNITY_EDITOR using Sirenix.OdinInspector; using System; using Unity.Mathematics; using UnityEditor; using UnityEngine; using UnityEngine.UIElements; namespace UguiToolkit.Editor { public interface IEntity { void SetOriginalMatrix(Transform tf); void ApplyTransform(Transform tf); void InternalApplyTransform(Transform tf); void ApplyTransformByParent(Transform parentTf, Transform tf); bool IsInside(Transform tf); void ApplyData(T ui) where T: Component; void InitPreview(); void ShowSelectionImg(bool show); GameObject gameObject { get; } } public abstract class BaseEntity : MonoBehaviour, IEntity where T1 : Component where T2 : LayoutInfo.ElementInfo { // ElementInfo private T2 m_elementInfo; private UnityEngine.UI.Image m_selectionImg; private Matrix4x4 lastMoveMatrix; private Matrix4x4 oldTransformMatrix; public T2 ElementInfo => m_elementInfo; public void ShowSelectionImg(bool show) { if (m_selectionImg) { m_selectionImg.gameObject.SetActive(show); } } public abstract void InitPreview(); protected abstract void OnApplyTransform(Transform tf); protected abstract void OnApplyData(T1 ui); public virtual void ApplyTransformByParent(Transform parentTf, Transform tf) { Undo.RecordObject(parentTf, "ApplyTransformByParent"); var resultMatrix = lastMoveMatrix * parentTf.localToWorldMatrix; parentTf.position = resultMatrix.GetColumn(3); parentTf.rotation = Quaternion.LookRotation(resultMatrix.GetColumn(2), resultMatrix.GetColumn(1)); parentTf.localScale = new Vector3( resultMatrix.GetColumn(0).magnitude, resultMatrix.GetColumn(1).magnitude, resultMatrix.GetColumn(2).magnitude ); if (tf) { Undo.RecordObject(tf, "ApplyTransformByParent"); resultMatrix = lastMoveMatrix.inverse * tf.localToWorldMatrix; tf.position = resultMatrix.GetColumn(3); tf.rotation = Quaternion.LookRotation(resultMatrix.GetColumn(2), resultMatrix.GetColumn(1)); tf.localScale = new Vector3( resultMatrix.GetColumn(0).magnitude, resultMatrix.GetColumn(1).magnitude, resultMatrix.GetColumn(2).magnitude ); } } public void SetOriginalMatrix(Transform tf) { oldTransformMatrix = Matrix4x4.TRS(tf.position, tf.rotation, tf.localScale); } public void InternalApplyTransform(Transform tf) { OnApplyTransform(tf); } public void ApplyTransform(Transform tf) { Undo.RecordObject(tf, "ApplyTransform"); OnApplyTransform(tf); Matrix4x4 newTransformMatrix = Matrix4x4.TRS(tf.position, tf.rotation, tf.localScale); lastMoveMatrix = newTransformMatrix * oldTransformMatrix.inverse; } public bool IsInside(Transform tf) { var rect = ElementInfo.Rect; var pos = StageManager.Instance.PrefabContentsRoot.transform.InverseTransformPoint(new Vector3(tf.position.x, tf.position.y, 0)); return rect.Contains(pos); } // 创建时调用 public void SetData(T2 elementInfo) { this.m_elementInfo = elementInfo; CreateSelectionImg(); } public void ApplyData(T ui) where T : Component { Undo.RecordObject(ui, "ApplyData"); OnApplyData(ui as T1); } private void CreateSelectionImg() { var go = new GameObject("_selectionImg_", typeof(RectTransform)); EntityHelper.UpdateHierarchyAndSceneVisibilityOfEntity(false, go); var tf = go.transform; tf.SetParent(transform); tf.localPosition = Vector3.zero; tf.localRotation = Quaternion.identity; tf.localScale = Vector3.one; var rtf = go.GetComponent(); rtf.sizeDelta = new Vector2(m_elementInfo.w, m_elementInfo.h); m_selectionImg = go.AddComponent(); m_selectionImg.color = new Color(0, 1, 0, 0.4f); } } } #endif