123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170 |
- using System;
- using System.Reflection;
- using UnityEngine;
- using UnityEngine.EventSystems;
- using UnityEngine.UI;
- namespace Rokid.MRC
- {
- public class UIPanelBase : MonoBehaviour
- {
- private RectTransform rectTransform;
- public bool FollowCam;
- public float CamDistance = 1.3f;
- #if UMR
- public bool UseForUMR;
- #endif
- public bool is3DPanel;
- void Update()
- {
- OnUpdate();
- }
- public virtual void OnInit()
- {
- rectTransform = GetComponent<RectTransform>();
- //GraphicRaycaster设置
- #if UMR
- //因为Package中没办法获取UXR的类(非Package,并在主工程中),此处暂时用反射的方式添加
- if(UseForUMR)
- {
- BaseRaycaster curRayCaster = GetComponent<GraphicRaycaster>();
- Type tp = curRayCaster.GetType();
- //Type rkType = Type.GetType("Rokid.UXR.RKGraphicRaycaster");
- Assembly assembly = Assembly.GetEntryAssembly();
- assembly = Assembly.GetExecutingAssembly();
- assembly = Assembly.GetCallingAssembly();
- assembly = Assembly.GetAssembly(tp);
- assembly = GetAssembly("Rokid.Unity.XR");
- Type rkType = assembly.GetType("Rokid.UXR.RKGraphicRaycaster");
- if(rkType == null)
- {
- Debug.LogError("No RKGraphicRaycaster In Project");
- }
- else
- {
- if(tp != rkType)
- {
- Destroy(curRayCaster);
- gameObject.AddComponent(rkType);
- }
- }
- }
- #endif
- //界面类型
- Canvas canvas = GetComponent<Canvas>();
- if(is3DPanel)
- {
- canvas.renderMode = RenderMode.WorldSpace;
- }
- else
- {
- canvas.renderMode = RenderMode.ScreenSpaceOverlay;
- }
- }
- private Assembly GetAssembly(string name)
- {
- Assembly[] allAssb = AppDomain.CurrentDomain.GetAssemblies();
- for(int i = 0;i < allAssb.Length;i++)
- {
- if(allAssb[i].FullName.Contains(name))
- {
- return allAssb[i];
- }
- }
- return null;
- }
- public virtual void OnOpen()
- {
- }
- public virtual void OnClose()
- {
- }
- public virtual void OnUpdate()
- {
- if(FollowCam)
- {
- UpdatePanelPose();
- }
- }
- private void UpdatePanelPose()
- {
- if(Camera.main == null)
- {
- return;
- }
- //相机前方多远距离
- Vector3 disPos = Camera.main.transform.forward * CamDistance;
- Vector3 temp = Camera.main.transform.position + disPos;
- //UI界面朝向相机
- transform.rotation = Quaternion.LookRotation(Camera.main.transform.forward);
- //获取整个UI界面4个角的位置
- Vector3[] corners = new Vector3[4];
- rectTransform.GetWorldCorners(corners);
- //判断4个点是否在屏幕内
- if(!IsVisible(corners))
- {
- //不在屏幕内,则缓动到屏幕中
- TweenPosition.Begin(gameObject, transform.position, temp, 0.3f);
- }
- else
- {
- //在屏幕内,则计算UI界面与相机的距离,保持在固定距离
- float dist = Vector3.Distance(transform.position, Camera.main.transform.position);
- if(dist > CamDistance + 0.2f && dist > CamDistance - 0.2f)
- {
- transform.position = new Vector3(transform.position.x, transform.position.y, temp.z);
- }
- }
- }
- private bool IsVisible(Vector3[] worldPositions)
- {
- int index = 0;
- for(int i = 0;i < worldPositions.Length;i++)
- {
- if(IsGameObjectInCameraView(worldPositions[i]))
- index++;
- }
- return index >= 3;
- }
- public static bool IsGameObjectInCameraView(Vector3 pos, Camera camera = null)
- {
- if(camera == null)
- camera = Camera.main;
- if(camera == null)
- return false;
- Vector3 targetObjViewportCoord = camera.WorldToViewportPoint(pos);
- if(targetObjViewportCoord.x > 0 && targetObjViewportCoord.x < 1 && targetObjViewportCoord.y > 0f && targetObjViewportCoord.y < 1 && targetObjViewportCoord.z > camera.nearClipPlane && targetObjViewportCoord.z < camera.farClipPlane)
- return true;
- return false;
- }
- }
- }
|