#if UNITY_EDITOR using Sirenix.OdinInspector; using System; using Unity.Mathematics; 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) { var position = lastMoveMatrix.GetColumn(3); // 提取位置 var rotation = Quaternion.LookRotation(lastMoveMatrix.GetColumn(2), lastMoveMatrix.GetColumn(1)); // 提取旋转 Debug.Log($"[I] ApplyTransformByParent {position}, {rotation.eulerAngles}"); parentTf.position += new Vector3(position.x, position.y, position.z); parentTf.rotation *= rotation; if (tf) { var lastTransformMatrixInverse = lastMoveMatrix.inverse; position = lastTransformMatrixInverse.GetColumn(3); // 提取位置 rotation = Quaternion.LookRotation(lastTransformMatrixInverse.GetColumn(2), lastTransformMatrixInverse.GetColumn(1)); // 提取旋转 tf.position += new Vector3(position.x, position.y, position.z); tf.rotation *= rotation; } } 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) { Debug.Log($"[I] ApplyTransform {tf.name}"); 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 { 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