//using BeinLab.Util; using DG.Tweening; using ShadowStudio.Tool; using System; using UnityEngine; using XRTool.Util; namespace XRTool.WorldUI { public struct DlgRect { public Vector3 upLeft; public Vector3 upRight; public Vector3 downLeft; public Vector3 downRight; public Vector3[] points; public void CombinePoints() { if (points == null) { points = new Vector3[4]; } points[0] = upRight; points[1] = upLeft; points[2] = downLeft; points[3] = downRight; } } public enum ContainerState { /// /// 自由状态 /// Free = 0, /// /// 稳定与黑板状态 /// OnBoard = 1, /// /// 自由移动状态 /// FreeMove = 2, /// /// 在黑板中移动状态 /// BoardMove = 3 } /// /// 世界UI对话框 /// public class WorldDlg : MonoBehaviour { private RectTransform dlgTrans; private RectTransform root; private RectTransform dlgRoot; private RectTransform fullUIRoot; private RectTransform container; private XRImage bG; private TransferCell transfer; public Vector2 dragOffset = Vector2.zero; private BoxCollider boxCollider; //[HideInInspector] public ContainerState containerState = ContainerState.Free; public bool isAddBgCollider = true; /// /// 是否可编辑姿态(位置,角度,比例) /// 可编辑状态时,取消面部锁定,编辑完成后,设置为世界锁定 /// private bool isDragEnable; /// /// 是否面部锁定 /// 如果面部锁定,代表自动跟随头部进行位移 /// private bool isFaceLock; [HideInInspector] public bool isShowTitle; private XRImage xRTitle; [HideInInspector] public float titleDis = 10f; private Vector3 scaleDefault; private DlgRect dlgRect = new DlgRect(); /// /// UI的缩放比例 /// public const float UIScale = 3; public const float UIDistance = -0.003f; private Ease activeType = Ease.Linear; //public Effect effectType = Effect.None; public event Action OnChangeContainerState; private bool isFristEnable = true; [HideInInspector] public bool isOnBoard; public bool isShowEffect = true; public bool isDisCollider = true; public bool IsDragEnable { get => isDragEnable; set { isDragEnable = value; if (isDragEnable) { ActiveDragDlg(); } else { DisActiveDragDlg(); } } } public bool IsFaceLock { get => isFaceLock; set { isFaceLock = value; if (isFaceLock) { LockDlg(); } else { UnLockDlg(); } } } public RectTransform DlgTrans { get { if (dlgTrans == null) { return dlgTrans = GetComponent(); } return dlgTrans; } } public void ResetScale() { } public RectTransform Root { get { if (root == null) { return root = GetChild("UIRoot"); } return root; } } public XRImage BG { get { if (bG == null) { return bG = GetChild("BG"); } return bG; } } public XRImage XRTitle { get { if (!xRTitle) { xRTitle = GetBreadthChild("XRTitle"); } return xRTitle; } set => xRTitle = value; } public RectTransform FullUIRoot { get { if (!fullUIRoot) { fullUIRoot = GetChild("FullUIRoot"); } return fullUIRoot; } set => fullUIRoot = value; } /// /// 转换 /// public TransferCell Transfer { get { if (!transfer) { transfer = GetComponent(); } return transfer; } } public ContainerState ContainerState { get => containerState; set { if (containerState != value) { containerState = value; OnChangeContainerState?.Invoke(value); } } } private void Start() { if (isFristEnable && isShowEffect) { TimerMgr.Instance.CreateTimer(() => { //showDlg(); isFristEnable = false; if (Transfer && Transfer.BoundBox && Transfer.BoundBox.BoundBoxCollider) { Transfer.BoundBox.BoundBoxCollider.enabled = !isDisCollider; } }, 0.02f); } //RefreshBounds(); } private void Awake() { scaleDefault = transform.localScale; if (isShowEffect) { transform.localScale = new Vector3(0, 0, 0); // this.gameObject.SetActive(false); } } //private void OnEnable() //{ // if (!isFristEnable) // { // ShowActiveEffect(); // } //} //public void showDlg(Action action = null) //{ // ShowActiveEffect(action); // this.gameObject.SetActive(true); //} //public void hideDlg(Action action = null) //{ // switch (effectType) // { // case Effect.None: // transform.localScale = scaleDefault; // if (action != null) // action.Invoke(); // break; // case Effect.Normal: // hideNormalEffect(action); // break; // case Effect.NormalY: // hideNormalYEffect(action); // break; // case Effect.RotateX: // hideRotateXEffect(action); // break; // } //} //void ShowActiveEffect(Action action = null) //{ // switch (effectType) // { // case Effect.None: // transform.localScale = scaleDefault; // break; // case Effect.Normal: // showNormalEffect(action); // break; // case Effect.NormalY: // showNormalYEffect(action); // break; // case Effect.RotateX: // showRotateXEffect(action); // break; // } //} void showRotateXEffect(Action action = null) { Ease ease = Ease.OutBack; if (scaleDefault != Vector3.zero) { transform.DOKill(); transform.localScale = scaleDefault; Vector3 pos = transform.localPosition; transform.localPosition = new Vector3(GSXRManager.Instance.head.position.x, GSXRManager.Instance.head.position.y - 0.5f, GSXRManager.Instance.head.position.z); float activeTime = 0.6f; Vector3 qa = transform.localEulerAngles; transform.localEulerAngles = new Vector3(90, 0, 0); transform.DOLocalRotate(qa, activeTime).OnComplete(() => { if (action != null) action.Invoke(); }); transform.DOLocalMove(pos, activeTime).SetEase(Ease.OutBack); } } void showNormalYEffect(Action action = null) { Ease ease = Ease.OutBack; if (scaleDefault != Vector3.zero) { transform.DOKill(); transform.localScale = new Vector3(scaleDefault.x, scaleDefault.y / 100, scaleDefault.z); float activeTime = 0.3f; transform.DOScale(scaleDefault, activeTime).SetEase(ease).OnComplete(() => { if (action != null) action.Invoke(); }); } } void showNormalEffect(Action action = null) { Ease ease = Ease.OutBack; if (scaleDefault != Vector3.zero) { transform.DOKill(); transform.localScale = scaleDefault / 100; float activeTime = 0.3f; transform.DOScale(scaleDefault, activeTime).SetEase(ease).OnComplete(() => { if (action != null) action.Invoke(); }); } } void hideNormalYEffect(Action action) { Ease ease = Ease.InBack; transform.DOKill(); float activeTime = 0.3f; transform.DOScale(new Vector3(transform.localScale.x, Vector3.zero.y, transform.localScale.z), activeTime).SetEase(ease).OnComplete(() => { if (action != null) action.Invoke(); this.gameObject.SetActive(false); }); } void hideNormalEffect(Action action) { Ease ease = Ease.InBack; transform.DOKill(); float activeTime = 0.3f; transform.DOScale(Vector3.zero, activeTime).SetEase(ease).OnComplete(() => { if (action != null) action.Invoke(); this.gameObject.SetActive(false); }); } void hideRotateXEffect(Action action) { Ease ease = Ease.InBack; transform.DOKill(); float activeTime = 0.3f; transform.DOLocalRotate(new Vector3(45, 0, 0), activeTime).OnComplete(() => { if (action != null) action.Invoke(); }); transform.DOMove(new Vector3(GSXRManager.Instance.head.position.x, GSXRManager.Instance.head.position.y - 0.5f, GSXRManager.Instance.head.position.z), activeTime).SetEase(Ease.InBack); } /// /// 获取指定名称类型的对象 /// /// /// /// public T GetChild(Transform target, string childName) { return UnityUtil.GetChild(target, childName); } /// /// 获取指定名称类型的对象 /// /// /// /// public T GetChild(string childName) { if (DlgRoot) { return GetChild(DlgRoot, childName); } return GetChild(transform, childName); } /// /// 深度优先搜索查找子物体 /// /// /// /// public T GetDepthChild(string childName) { return UnityUtil.GetDepthChild(transform, childName); } /// /// 广度优先查找子物体 /// /// /// /// public T GetBreadthChild(string childName) { return UnityUtil.GetBreadthChild(transform, childName); } public GameObject GetBreadthChild(string childName) { return UnityUtil.GetBreadthChild(transform, childName); } public T GetParent() { return GetComponentInParent(); } public T GetChild() { return GetComponentInChildren(); } public T GetT(GameObject target) { return target.GetComponent(); } public T GetT() { return GetT(gameObject); } public T Get() { return GetComponent(); } /// /// /// /// public void Close(bool isDes = false) { if (isDes) { Destroy(gameObject); } else { gameObject.SetActive(false); } } /// /// 隐藏 /// public void Show() { if (!gameObject.activeSelf) { gameObject.SetActive(true); } } /// /// 激活拖拽窗口组件 /// 窗口可以拖拽移动旋转缩放,同时不再跟随视角移动变化 /// public void ActiveDragDlg() { ///锁定视角 IsFaceLock = true; if (Transfer) { Transfer.IsDragEnable = true; } } /// /// 失活拖拽窗口组件 /// 窗口不可被移动缩放或者旋转 /// public void DisActiveDragDlg() { if (Transfer) { Transfer.IsDragEnable = false; } } /// /// 锁定窗口, /// public void LockDlg() { } /// /// 解锁窗口,此窗口将跟随用户移动而移动 /// public void UnLockDlg() { } public void SetScale(Vector2 size, float infoSize = 1) { size = DlgTrans.rect.size; AutoSetScale(DlgTrans, size); //print(gameObject); BG.UpdateSize(size * WorldDlg.UIScale); SetBoundSize(BG.Back, dragOffset * infoSize); if (isShowTitle) { AutoSetTitle(size); } //RefreshBounds(); } public void AutoSetScale(Transform body, Vector2 size) { if (DlgRoot) { for (int i = 0; i < DlgRoot.childCount; i++) { var child = DlgRoot.GetChild(i) as RectTransform; if (child) { child.sizeDelta = size * WorldDlg.UIScale; child.localScale = Vector3.one / WorldDlg.UIScale; } } } if (FullUIRoot) { FullUIRoot.localScale = Vector3.one; FullUIRoot.sizeDelta = size; } } public void SetBoundSize(RectTransform back, Vector2 dragOffset) { if (isAddBgCollider) { if (!boxCollider) { if (!(boxCollider = BG.GetComponentInChildren())) { boxCollider = BG.gameObject.AddComponent(); } //UIRayCast } Vector3 boxSize = boxCollider.size; boxSize.x = back.rect.size.x + dragOffset.x; boxSize.y = back.rect.size.y + dragOffset.y; boxCollider.size = boxSize; } } public Vector2 DlgSize { get { Vector2 size = DlgTrans.sizeDelta; size.x *= DlgTrans.localScale.x; size.y *= DlgTrans.localScale.y; if (DlgRoot) { size.x *= DlgRoot.localScale.x; size.y *= DlgRoot.localScale.y; } return size; } } /// /// 获取窗口的绝对坐标点 /// public DlgRect DlgRect { get { Vector2 size = DlgTrans.sizeDelta / 2; Vector2 pos = size; dlgRect.upRight = DlgTrans.TransformPoint(pos); pos.x = -size.x; dlgRect.upLeft = DlgTrans.TransformPoint(pos); pos.y = -size.y; dlgRect.downLeft = DlgTrans.TransformPoint(pos); pos.x = size.x; dlgRect.downRight = DlgTrans.TransformPoint(pos); dlgRect.CombinePoints(); return dlgRect; } } public RectTransform DlgRoot { get { if (!dlgRoot) { dlgRoot = GetBreadthChild("DlgRoot"); } return dlgRoot; } } public RectTransform Container { get { if (!container) { if (FullUIRoot) { container = UnityUtil.GetBreadthChild(FullUIRoot, "Container"); } } return container; } } /// /// 自动调整标题板的位置 /// /// public void AutoSetTitle(Vector2 size) { var tmp = XRTitle.rectTransform.rect.size; tmp.x = size.x * WorldDlg.UIScale; XRTitle.UpdateSize(tmp); XRTitle.rectTransform.sizeDelta = tmp; var pos = XRTitle.rectTransform.anchoredPosition3D; pos.y = size.y * WorldDlg.UIScale / 2 + tmp.y / 2 + titleDis; XRTitle.rectTransform.anchoredPosition3D = pos; } /// /// 判断两个窗口是否相交 /// 将另一个窗口转化为本窗口的坐标系 /// /// /// public bool IsIntersect(WorldDlg otherDlg) { Vector3[] other = otherDlg.DlgRect.points; for (int i = 0; i < other.Length; i++) { other[i] = DlgTrans.InverseTransformPoint(other[i]); } for (int i = 0; i < other.Length / 2; i++) { float z = other[2 * i].z * other[2 * i + 1].z; if (z < 0) { if ((Math.Abs(other[2 * i].x) < DlgTrans.sizeDelta.x / 2 && Math.Abs(other[2 * i].y) < DlgTrans.sizeDelta.y / 2) || (Math.Abs(other[2 * i + 1].x) < DlgTrans.sizeDelta.x / 2 && Math.Abs(other[2 * i + 1].y) < DlgTrans.sizeDelta.y / 2)) { return true; } } } return false; } } }