123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697 |
- 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
- {
- /// <summary>
- /// 自由状态
- /// </summary>
- Free = 0,
- /// <summary>
- /// 稳定与黑板状态
- /// </summary>
- OnBoard = 1,
- /// <summary>
- /// 自由移动状态
- /// </summary>
- FreeMove = 2,
- /// <summary>
- /// 在黑板中移动状态
- /// </summary>
- BoardMove = 3
- }
- /// <summary>
- /// 世界UI对话框
- /// </summary>
- 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;
- /// <summary>
- /// 是否可编辑姿态(位置,角度,比例)
- /// 可编辑状态时,取消面部锁定,编辑完成后,设置为世界锁定
- /// </summary>
- private bool isDragEnable;
- /// <summary>
- /// 是否面部锁定
- /// 如果面部锁定,代表自动跟随头部进行位移
- /// </summary>
- private bool isFaceLock;
- [HideInInspector]
- public bool isShowTitle;
- private XRImage xRTitle;
- [HideInInspector]
- public float titleDis = 10f;
- private Vector3 scaleDefault;
- private DlgRect dlgRect = new DlgRect();
- /// <summary>
- /// UI的缩放比例
- /// </summary>
- public const float UIScale = 3;
- public const float UIDistance = -0.003f;
- private Ease activeType = Ease.Linear;
- public Effect effectType = Effect.None;
- public event Action<ContainerState> 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<RectTransform>();
- }
- return dlgTrans;
- }
- }
- public void ResetScale()
- {
- }
- public RectTransform Root
- {
- get
- {
- if (root == null)
- {
- return root = GetChild<RectTransform>("UIRoot");
- }
- return root;
- }
- }
- public XRImage BG
- {
- get
- {
- if (bG == null)
- {
- return bG = GetChild<XRImage>("BG");
- }
- return bG;
- }
- }
- public XRImage XRTitle
- {
- get
- {
- if (!xRTitle)
- {
- xRTitle = GetBreadthChild<XRImage>("XRTitle");
- }
- return xRTitle;
- }
- set => xRTitle = value;
- }
- public RectTransform FullUIRoot
- {
- get
- {
- if (!fullUIRoot)
- {
- fullUIRoot = GetChild<RectTransform>("FullUIRoot");
- }
- return fullUIRoot;
- }
- set => fullUIRoot = value;
- }
- /// <summary>
- /// 转换
- /// </summary>
- public TransferCell Transfer
- {
- get
- {
- if (!transfer)
- {
- transfer = GetComponent<TransferCell>();
- }
- 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();
- }
- }
- //private void Update()
- //{
- // Debug.Log(gameObject.name + " " + transform.localScale);
- //}
- 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(OpenXRCamera.Instance.head.position.x, OpenXRCamera.Instance.head.position.y - 0.5f, OpenXRCamera.Instance.head.position.z);
- float activeTime = 0.6f;
- Vector3 qa = transform.localEulerAngles;
- transform.localEulerAngles = new Vector3(90, 0, 0);
- transform.DOLocalRotate(qa, activeTime).OnComplete<Tweener>(() =>
- {
- 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)
- {
- Debug.LogError("showNormalYEffect");
- transform.DOKill();
- transform.localScale = new Vector3(scaleDefault.x, scaleDefault.y / 100, scaleDefault.z);
- float activeTime = 0.3f;
- transform.DOScale(scaleDefault, activeTime).SetEase(ease).OnComplete<Tweener>(() =>
- {
- if (action != null)
- action.Invoke();
- });
- }
- }
- void showNormalEffect(Action action = null)
- {
- Ease ease = Ease.OutBack;
- if (scaleDefault != Vector3.zero)
- {
- Debug.LogError("showNormalEffect");
- transform.DOKill();
- transform.localScale = scaleDefault / 100;
- float activeTime = 0.3f;
- transform.DOScale(scaleDefault, activeTime).SetEase(ease).OnComplete<Tweener>(() =>
- {
- if (action != null)
- action.Invoke();
- });
- }
- }
- void hideNormalYEffect(Action action)
- {
- Debug.LogError("hideNormalYEffect");
- 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<Tweener>(() =>
- {
- if (action != null)
- action.Invoke();
- this.gameObject.SetActive(false);
- });
- }
- void hideNormalEffect(Action action)
- {
- Debug.LogError("hideNormalEffect");
- Ease ease = Ease.InBack;
- transform.DOKill();
- float activeTime = 0.3f;
- transform.DOScale(Vector3.zero, activeTime).SetEase(ease).OnComplete<Tweener>(() =>
- {
- 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<Tweener>(() =>
- {
- if (action != null)
- action.Invoke();
- });
- transform.DOMove(new Vector3(OpenXRCamera.Instance.head.position.x, OpenXRCamera.Instance.head.position.y - 0.5f, OpenXRCamera.Instance.head.position.z), activeTime).SetEase(Ease.InBack);
- }
- /// <summary>
- /// 获取指定名称类型的对象
- /// </summary>
- /// <typeparam name="T"></typeparam>
- /// <param name="childName"></param>
- /// <returns></returns>
- public T GetChild<T>(Transform target, string childName)
- {
- return UnityUtil.GetChild<T>(target, childName);
- }
- /// <summary>
- /// 获取指定名称类型的对象
- /// </summary>
- /// <typeparam name="T"></typeparam>
- /// <param name="childName"></param>
- /// <returns></returns>
- public T GetChild<T>(string childName)
- {
- if (DlgRoot)
- {
- return GetChild<T>(DlgRoot, childName);
- }
- return GetChild<T>(transform, childName);
- }
- /// <summary>
- /// 深度优先搜索查找子物体
- /// </summary>
- /// <typeparam name="T"></typeparam>
- /// <param name="childName"></param>
- /// <returns></returns>
- public T GetDepthChild<T>(string childName)
- {
- return UnityUtil.GetDepthChild<T>(transform, childName);
- }
- /// <summary>
- /// 广度优先查找子物体
- /// </summary>
- /// <typeparam name="T"></typeparam>
- /// <param name="childName"></param>
- /// <returns></returns>
- public T GetBreadthChild<T>(string childName)
- {
- return UnityUtil.GetBreadthChild<T>(transform, childName);
- }
- public GameObject GetBreadthChild(string childName)
- {
- return UnityUtil.GetBreadthChild(transform, childName);
- }
- public T GetParent<T>()
- {
- return GetComponentInParent<T>();
- }
- public T GetChild<T>()
- {
- return GetComponentInChildren<T>();
- }
- public T GetT<T>(GameObject target)
- {
- return target.GetComponent<T>();
- }
- public T GetT<T>()
- {
- return GetT<T>(gameObject);
- }
- public T Get<T>()
- {
- return GetComponent<T>();
- }
- /// <summary>
- ///
- /// </summary>
- /// <param name="isDes"></param>
- public void Close(bool isDes = false)
- {
- if (isDes)
- {
- Destroy(gameObject);
- }
- else
- {
- gameObject.SetActive(false);
- }
- }
- /// <summary>
- /// 隐藏
- /// </summary>
- public void Show()
- {
- if (!gameObject.activeSelf)
- {
- gameObject.SetActive(true);
- }
- }
- /// <summary>
- /// 激活拖拽窗口组件
- /// 窗口可以拖拽移动旋转缩放,同时不再跟随视角移动变化
- /// </summary>
- public void ActiveDragDlg()
- {
- ///锁定视角
- IsFaceLock = true;
- if (Transfer)
- {
- Transfer.IsDragEnable = true;
- }
- }
- /// <summary>
- /// 失活拖拽窗口组件
- /// 窗口不可被移动缩放或者旋转
- /// </summary>
- public void DisActiveDragDlg()
- {
- if (Transfer)
- {
- Transfer.IsDragEnable = false;
- }
- }
- /// <summary>
- /// 锁定窗口,
- /// </summary>
- public void LockDlg()
- {
- }
- /// <summary>
- /// 解锁窗口,此窗口将跟随用户移动而移动
- /// </summary>
- 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>()))
- {
- boxCollider = BG.gameObject.AddComponent<BoxCollider>();
- }
- //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;
- }
- }
- /// <summary>
- /// 获取窗口的绝对坐标点
- /// </summary>
- 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<RectTransform>("DlgRoot");
- }
- return dlgRoot;
- }
- }
- public RectTransform Container
- {
- get
- {
- if (!container)
- {
- if (FullUIRoot)
- {
- container = UnityUtil.GetBreadthChild<RectTransform>(FullUIRoot, "Container");
- }
- }
- return container;
- }
- }
- /// <summary>
- /// 自动调整标题板的位置
- /// </summary>
- /// <param name="size"></param>
- 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;
- }
- /// <summary>
- /// 判断两个窗口是否相交
- /// 将另一个窗口转化为本窗口的坐标系
- /// </summary>
- /// <param name="otherDlg"></param>
- /// <returns></returns>
- 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;
- }
- }
- }
|