初始化
This commit is contained in:
426
UnityGame/Assets/Scripts/ThirdParty/YIUIFramework/Plugins/YIUI3DDisplay/Runtime/UI3DDisplay.cs
vendored
Normal file
426
UnityGame/Assets/Scripts/ThirdParty/YIUIFramework/Plugins/YIUI3DDisplay/Runtime/UI3DDisplay.cs
vendored
Normal file
@@ -0,0 +1,426 @@
|
||||
//------------------------------------------------------------
|
||||
// Author: 亦亦
|
||||
// Mail: 379338943@qq.com
|
||||
// Data: 2023年2月12日
|
||||
//------------------------------------------------------------
|
||||
|
||||
using UnityEngine;
|
||||
using UnityEngine.Assertions;
|
||||
using UnityEngine.EventSystems;
|
||||
using UnityEngine.UI;
|
||||
using System.Collections.Generic;
|
||||
using Sirenix.OdinInspector;
|
||||
using System;
|
||||
using Sirenix.Serialization;
|
||||
using YIUIBind;
|
||||
|
||||
namespace YIUIFramework
|
||||
{
|
||||
/// <summary>
|
||||
/// 这个类用于在UI中显示3D对象。
|
||||
/// </summary>
|
||||
public sealed partial class UI3DDisplay : SerializedMonoBehaviour,
|
||||
IDragHandler, IPointerDownHandler, IPointerUpHandler
|
||||
{
|
||||
[OdinSerialize]
|
||||
[ShowInInspector]
|
||||
[LabelText("[动态] 展示的对象")]
|
||||
private GameObject m_ShowObject;
|
||||
|
||||
[OdinSerialize]
|
||||
[ShowInInspector]
|
||||
[LabelText("[动态] 观察的摄像机")]
|
||||
private Camera m_LookCamera = null;
|
||||
|
||||
[Required]
|
||||
[OdinSerialize]
|
||||
[ShowInInspector]
|
||||
[LabelText("面板")]
|
||||
private RawImage m_ShowImage;
|
||||
|
||||
[Required]
|
||||
[OdinSerialize]
|
||||
[ShowInInspector]
|
||||
[LabelText("摄像机")]
|
||||
private Camera m_ShowCamera;
|
||||
|
||||
//摄像机的初始化位置
|
||||
private Vector3 m_ShowCameraDefPos;
|
||||
|
||||
[Required]
|
||||
[OdinSerialize]
|
||||
[ShowInInspector]
|
||||
[LabelText("摄像机控制器")]
|
||||
private UI3DDisplayCamera m_ShowCameraCtrl;
|
||||
|
||||
[Required]
|
||||
[OdinSerialize]
|
||||
[ShowInInspector]
|
||||
[LabelText("灯光")]
|
||||
private Light m_ShowLight;
|
||||
|
||||
[Required]
|
||||
[OdinSerialize]
|
||||
[ShowInInspector]
|
||||
[LabelText("这个变换将自动适应比例")]
|
||||
private Transform m_FitScaleRoot;
|
||||
|
||||
[OdinSerialize]
|
||||
[ShowInInspector]
|
||||
[LabelText("自动设置图像大小")]
|
||||
private bool m_AutoChangeSize = true;
|
||||
|
||||
[OdinSerialize]
|
||||
[ShowInInspector]
|
||||
[LabelText("图像宽")]
|
||||
[MinValue(0)]
|
||||
private int m_ResolutionX = 512;
|
||||
|
||||
[OdinSerialize]
|
||||
[ShowInInspector]
|
||||
[LabelText("图像高")]
|
||||
[MinValue(0)]
|
||||
private int m_ResolutionY = 512;
|
||||
|
||||
[LabelText("深度值")] //默认16
|
||||
private readonly int m_RenderTextureDepthBuffer = 16;
|
||||
|
||||
[OdinSerialize]
|
||||
[ShowInInspector]
|
||||
[ReadOnly]
|
||||
[LabelText("当前显示层级")]
|
||||
private int m_ShowLayer = 0;
|
||||
|
||||
private const string YIUI3DLayer = "YIUI3DLayer";
|
||||
|
||||
[ShowInInspector]
|
||||
[LabelText("当前显示层级")]
|
||||
[ReadOnly]
|
||||
private string m_ShowLayerName = YIUI3DLayer;
|
||||
|
||||
[OdinSerialize]
|
||||
[ShowInInspector]
|
||||
[LabelText("允许拖拽")]
|
||||
private bool m_CanDrag = true;
|
||||
|
||||
[OdinSerialize]
|
||||
[ShowInInspector]
|
||||
[LabelText("拖拽速度")]
|
||||
[ShowIf("m_CanDrag")]
|
||||
private float m_DragSpeed = 10.0f;
|
||||
|
||||
[OdinSerialize]
|
||||
[ShowInInspector]
|
||||
[LabelText("显示对象的位置偏移值")]
|
||||
private Vector3 m_ShowOffset = Vector3.zero;
|
||||
|
||||
[OdinSerialize]
|
||||
[ShowInInspector]
|
||||
[LabelText("显示对象的旋转偏移值")]
|
||||
private Vector3 m_ShowRotation = Vector3.zero;
|
||||
|
||||
[OdinSerialize]
|
||||
[ShowInInspector]
|
||||
[LabelText("显示对象的比例")]
|
||||
private Vector3 m_ShowScale = Vector3.one;
|
||||
|
||||
[OdinSerialize]
|
||||
[ShowInInspector]
|
||||
[LabelText("镜面反射面")]
|
||||
private Transform m_ReflectionPlane = null;
|
||||
|
||||
[OdinSerialize]
|
||||
[ShowInInspector]
|
||||
[LabelText("阴影面")]
|
||||
private Transform m_ShadowPlane = null;
|
||||
|
||||
[OdinSerialize]
|
||||
[ShowInInspector]
|
||||
[LabelText("使用观察摄像机的颜色")]
|
||||
private bool m_UseLookCameraColor = false;
|
||||
|
||||
[OdinSerialize]
|
||||
[ShowInInspector]
|
||||
[LabelText("自动同步")]
|
||||
private bool m_AutoSync = false;
|
||||
|
||||
//显示的拖动旋转
|
||||
private float m_DragRotation;
|
||||
|
||||
//显示渲染纹理
|
||||
private RenderTexture m_ShowTexture;
|
||||
|
||||
//记录显示位置
|
||||
private Vector3 m_ShowPosition;
|
||||
|
||||
//正交大小
|
||||
private float m_OrthographicSize;
|
||||
|
||||
//每显示一次就会+1 用于位置偏移
|
||||
private static int g_DisPlayUIIndex = 0;
|
||||
|
||||
//当前模型偏移位置
|
||||
private Vector3 m_ModelGlobalOffset = Vector3.zero;
|
||||
|
||||
//所有已采集的阴影
|
||||
private List<Renderer> m_RenderList = new List<Renderer>();
|
||||
|
||||
private Camera m_UICamera = null;
|
||||
|
||||
private Camera UICamera
|
||||
{
|
||||
get
|
||||
{
|
||||
if (m_UICamera != null) return m_UICamera;
|
||||
m_UICamera = PanelMgr.Inst.UICamera;
|
||||
return m_UICamera;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 设置动画选择目标
|
||||
/// </summary>
|
||||
private void SetAnimatorCullingMode(Transform target)
|
||||
{
|
||||
var animator = target.GetComponent<Animator>();
|
||||
if (animator)
|
||||
animator.cullingMode = AnimatorCullingMode.AlwaysAnimate;
|
||||
}
|
||||
|
||||
//设置所有动画
|
||||
//总是让整个角色动画化。对象即使在屏幕外也是动画的。
|
||||
//因为我们会吧对象丢到屏幕外否则动画可能会不动
|
||||
private void SetAllAnimatorCullingMode(Transform target)
|
||||
{
|
||||
SetAnimatorCullingMode(target);
|
||||
for (var i = 0; i < target.childCount; ++i)
|
||||
{
|
||||
SetAnimatorCullingMode(target.GetChild(i));
|
||||
}
|
||||
}
|
||||
|
||||
//吧指定对象的层级改为设定的层级
|
||||
private void SetupShowLayer()
|
||||
{
|
||||
if (m_ShowCameraCtrl != null && m_ShowCameraCtrl.ShowObject != null)
|
||||
{
|
||||
m_ShowCameraCtrl.SetupRenderer(m_ShowCameraCtrl.ShowObject.transform);
|
||||
}
|
||||
}
|
||||
|
||||
//修改层级 //目前使用默认层级最好不要修改
|
||||
private void ChangeLayerName(string layerName)
|
||||
{
|
||||
m_ShowLayerName = layerName;
|
||||
m_ShowLayer = LayerMask.NameToLayer(layerName);
|
||||
if (m_ShowLayer != -1) return;
|
||||
if (layerName == YIUI3DLayer)
|
||||
{
|
||||
Debug.LogError($"第一次使用请手动创建 YIUI3DLayer 层级");
|
||||
return;
|
||||
}
|
||||
|
||||
Debug.LogError($"当前设定的UI层级不存在请检查 {layerName} 强制修改层级为 {YIUI3DLayer}");
|
||||
m_ShowLayerName = YIUI3DLayer;
|
||||
m_ShowLayer = LayerMask.NameToLayer(YIUI3DLayer);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 设置对象的显示层级
|
||||
/// </summary>
|
||||
private void SetupShowLayerTarget(Transform target)
|
||||
{
|
||||
if (m_ShowCameraCtrl != null && m_ShowCameraCtrl.ShowObject != null)
|
||||
{
|
||||
m_ShowCameraCtrl.SetupRenderer(target);
|
||||
}
|
||||
}
|
||||
|
||||
//回收回调
|
||||
private Action<GameObject> m_RecycleLastAction;
|
||||
|
||||
//回收之前的对象 如果有回调就回调自行处理 否则会被无视
|
||||
private void RecycleLastShow(GameObject lastShowObject)
|
||||
{
|
||||
if (lastShowObject == null) return;
|
||||
lastShowObject.SetActive(false);
|
||||
m_RecycleLastAction?.Invoke(lastShowObject);
|
||||
}
|
||||
|
||||
//更新显示的对象
|
||||
//父级 位置 旋转
|
||||
private void UpdateShowObject(GameObject showObject)
|
||||
{
|
||||
if (showObject != m_ShowObject)
|
||||
RecycleLastShow(m_ShowObject);
|
||||
|
||||
showObject.SetActive(true);
|
||||
|
||||
m_ShowObject = showObject;
|
||||
|
||||
m_DragRotation = 0f;
|
||||
|
||||
m_DragTarge = m_MultipleTargetMode ? null : m_ShowObject;
|
||||
|
||||
var showTransform = m_ShowObject.transform;
|
||||
if (m_FitScaleRoot != null)
|
||||
{
|
||||
m_FitScaleRoot.localScale = Vector3.one;
|
||||
showTransform.SetParent(
|
||||
m_FitScaleRoot, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
showTransform.SetParent(
|
||||
transform, true);
|
||||
}
|
||||
|
||||
m_ShowCameraCtrl ??= m_ShowCamera.GetOrAddComponent<UI3DDisplayCamera>();
|
||||
if (m_ShowCameraCtrl == null)
|
||||
{
|
||||
Debug.LogError($"必须有 UI3DDisplayCamera 组件 请检查");
|
||||
return;
|
||||
}
|
||||
|
||||
//对象层级
|
||||
m_ShowCameraCtrl.ShowLayer = m_ShowLayer;
|
||||
m_ShowCameraCtrl.ShowObject = m_ShowObject;
|
||||
|
||||
//动画屏幕外也可动
|
||||
SetAllAnimatorCullingMode(m_ShowObject.transform);
|
||||
|
||||
//位置大小旋转
|
||||
var showRotation = Quaternion.Euler(m_ShowRotation);
|
||||
var showUp = showRotation * Vector3.up;
|
||||
showRotation *= Quaternion.AngleAxis(
|
||||
m_DragRotation, showUp);
|
||||
showTransform.localRotation = showRotation;
|
||||
showTransform.localScale = m_ShowScale;
|
||||
showTransform.localPosition = m_ModelGlobalOffset + m_ShowOffset;
|
||||
m_ShowPosition = showTransform.localPosition;
|
||||
|
||||
//镜面反射
|
||||
if (m_ReflectionPlane != null)
|
||||
{
|
||||
m_ReflectionPlane.position = showTransform.position;
|
||||
m_ReflectionPlane.rotation = showTransform.rotation;
|
||||
}
|
||||
|
||||
//阴影
|
||||
DisableMeshRectShadow();
|
||||
if (m_ShadowPlane != null)
|
||||
{
|
||||
EnableMeshRectShadow(m_ShowObject.transform);
|
||||
m_ShadowPlane.position = showTransform.position;
|
||||
m_ShadowPlane.rotation = showTransform.rotation;
|
||||
}
|
||||
|
||||
if (m_FitScaleRoot != null)
|
||||
{
|
||||
var lossyScale = m_FitScaleRoot.lossyScale;
|
||||
var localScale = transform.localScale;
|
||||
m_FitScaleRoot.localScale = new Vector3(
|
||||
1f / lossyScale.x * localScale.x,
|
||||
1f / lossyScale.y * localScale.y,
|
||||
1f / lossyScale.z * localScale.z);
|
||||
}
|
||||
}
|
||||
|
||||
//更新摄像机配置根据传入的摄像机
|
||||
private void UpdateLookCamera(Camera lookCamera)
|
||||
{
|
||||
Assert.IsNotNull(m_ShowCamera);
|
||||
|
||||
lookCamera.gameObject.SetActive(false);
|
||||
m_ShowCamera.orthographic = lookCamera.orthographic;
|
||||
m_ShowCamera.orthographicSize = lookCamera.orthographicSize;
|
||||
m_ShowCamera.fieldOfView = lookCamera.fieldOfView;
|
||||
m_ShowCamera.nearClipPlane = lookCamera.nearClipPlane;
|
||||
m_ShowCamera.farClipPlane = lookCamera.farClipPlane;
|
||||
m_ShowCamera.orthographic = lookCamera.orthographic;
|
||||
m_ShowCamera.orthographicSize = lookCamera.orthographicSize;
|
||||
m_ShowCamera.clearFlags = CameraClearFlags.SolidColor;
|
||||
m_ShowCamera.backgroundColor = m_UseLookCameraColor ? lookCamera.backgroundColor : Color.clear;
|
||||
m_OrthographicSize = lookCamera.orthographicSize;
|
||||
m_LookCamera = lookCamera;
|
||||
|
||||
m_ShowCamera.cullingMask = 1 << m_ShowLayer;
|
||||
|
||||
if (m_ShowLight)
|
||||
m_ShowLight.cullingMask = m_ShowCamera.cullingMask;
|
||||
|
||||
var lookCameraTsf = lookCamera.transform;
|
||||
if (lookCamera == m_ShowCamera)
|
||||
{
|
||||
//当使用默认相机作为显示相机时 需要处理每个显示物体的额外偏移
|
||||
lookCamera.transform.localPosition = m_ShowCameraDefPos + m_ModelGlobalOffset;
|
||||
}
|
||||
m_ShowCamera.transform.SetPositionAndRotation(
|
||||
lookCameraTsf.position,
|
||||
lookCameraTsf.rotation);
|
||||
|
||||
m_ShowCamera.enabled = true;
|
||||
m_ShowCamera.gameObject.SetActive(true);
|
||||
}
|
||||
|
||||
//RawImage 用的RenderTexture就是这样动态创建的
|
||||
private void SetTemporaryRenderTexture()
|
||||
{
|
||||
Assert.IsNotNull(m_ShowImage);
|
||||
|
||||
if (m_ShowTexture != null)
|
||||
RenderTexture.ReleaseTemporary(m_ShowTexture);
|
||||
|
||||
m_ShowTexture = RenderTexture.GetTemporary(m_ResolutionX, m_ResolutionY, m_RenderTextureDepthBuffer);
|
||||
m_ShowImage.texture = m_ShowTexture;
|
||||
m_ShowCamera.targetTexture = m_ShowTexture;
|
||||
m_ShowImage.enabled = true;
|
||||
}
|
||||
|
||||
//阴影采集
|
||||
private void EnableMeshRectShadow(Transform goNode)
|
||||
{
|
||||
var render = goNode.GetComponent<SkinnedMeshRenderer>();
|
||||
if (render != null)
|
||||
{
|
||||
if (render.shadowCastingMode == UnityEngine.Rendering.ShadowCastingMode.Off)
|
||||
{
|
||||
render.shadowCastingMode = UnityEngine.Rendering.ShadowCastingMode.On;
|
||||
m_RenderList.Add(render);
|
||||
}
|
||||
}
|
||||
|
||||
for (var i = 0; i < goNode.childCount; ++i)
|
||||
{
|
||||
EnableMeshRectShadow(goNode.GetChild(i));
|
||||
}
|
||||
}
|
||||
|
||||
//关闭所有已采集的阴影
|
||||
private void DisableMeshRectShadow()
|
||||
{
|
||||
foreach (var render in m_RenderList)
|
||||
{
|
||||
render.shadowCastingMode = UnityEngine.Rendering.ShadowCastingMode.Off;
|
||||
}
|
||||
|
||||
m_RenderList.Clear();
|
||||
}
|
||||
|
||||
//交换显示的rawImage 一般不需要
|
||||
private void ExchangeShowImage(RawImage img)
|
||||
{
|
||||
m_ShowImage = img;
|
||||
if (null != m_ShowTexture)
|
||||
{
|
||||
m_ShowImage.texture = m_ShowTexture;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_ShowTexture = RenderTexture.GetTemporary(m_ResolutionX, m_ResolutionY, m_RenderTextureDepthBuffer);
|
||||
m_ShowImage.texture = m_ShowTexture;
|
||||
m_ShowCamera.targetTexture = m_ShowTexture;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6beceb02921d4f718798027eb1260be0
|
||||
timeCreated: 1684737421
|
||||
@@ -0,0 +1,79 @@
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace YIUIFramework
|
||||
{
|
||||
public sealed class UI3DDisplayCamera : MonoBehaviour
|
||||
{
|
||||
private GameObject m_ShowObject;
|
||||
|
||||
internal GameObject ShowObject
|
||||
{
|
||||
get => m_ShowObject;
|
||||
set
|
||||
{
|
||||
if (m_ShowObject != null &&
|
||||
m_ShowObject != value)
|
||||
{
|
||||
ResetRenderer(m_ShowObject.transform);
|
||||
}
|
||||
|
||||
m_ShowObject = value;
|
||||
if (value != null)
|
||||
SetupRenderer(value.transform);
|
||||
}
|
||||
}
|
||||
|
||||
private int m_ShowLayer = 0;
|
||||
|
||||
internal int ShowLayer
|
||||
{
|
||||
get => m_ShowLayer;
|
||||
set
|
||||
{
|
||||
if (m_ShowLayer != value)
|
||||
{
|
||||
m_ShowLayer = value;
|
||||
if (ShowObject != null)
|
||||
SetupRenderer(ShowObject.transform);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void ResetRenderer(Transform transform)
|
||||
{
|
||||
var renderers = ListPool<Renderer>.Get();
|
||||
transform.GetComponentsInChildren(true, renderers);
|
||||
foreach (var renderer in renderers)
|
||||
renderer.gameObject.layer = 0;
|
||||
ListPool<Renderer>.Put(renderers);
|
||||
}
|
||||
|
||||
public void SetupRenderer(Transform transform)
|
||||
{
|
||||
if (ShowObject == null) return;
|
||||
|
||||
var renderers = ListPool<Renderer>.Get();
|
||||
transform.GetComponentsInChildren(true, renderers);
|
||||
foreach (var renderer in renderers)
|
||||
renderer.gameObject.layer = ShowLayer;
|
||||
ListPool<Renderer>.Put(renderers);
|
||||
}
|
||||
|
||||
private void OnEnable()
|
||||
{
|
||||
if (ShowObject != null)
|
||||
{
|
||||
SetupRenderer(ShowObject.transform);
|
||||
}
|
||||
}
|
||||
|
||||
private void OnDisable()
|
||||
{
|
||||
if (ShowObject != null)
|
||||
{
|
||||
ResetRenderer(ShowObject.transform);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1b68c6c15482408c8c2e344c1c889597
|
||||
timeCreated: 1684737442
|
||||
@@ -0,0 +1,57 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace YIUIFramework
|
||||
{
|
||||
/// <summary>
|
||||
/// 用于记录原始层,并在渲染器中可见。
|
||||
/// </summary>
|
||||
public sealed class UI3DDisplayRecord : MonoBehaviour
|
||||
{
|
||||
private int m_Layer;
|
||||
private bool m_Visible;
|
||||
private Renderer m_AttachRenderer;
|
||||
private UI3DDisplayCamera m_ShowCamera;
|
||||
|
||||
internal void Initialize(Renderer renderer, UI3DDisplayCamera camera)
|
||||
{
|
||||
m_AttachRenderer = renderer;
|
||||
m_ShowCamera = camera;
|
||||
m_Layer = renderer.gameObject.layer;
|
||||
m_Visible = renderer.enabled;
|
||||
}
|
||||
|
||||
private static bool IsParentOf(Transform obj, Transform parent)
|
||||
{
|
||||
if (obj == parent)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (obj.parent == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return IsParentOf(obj.parent, parent);
|
||||
}
|
||||
|
||||
private void OnTransformParentChanged()
|
||||
{
|
||||
if (m_ShowCamera == null ||
|
||||
!IsParentOf(transform, m_ShowCamera.transform))
|
||||
{
|
||||
this.SafeDestroySelf();
|
||||
}
|
||||
}
|
||||
|
||||
private void OnDestroy()
|
||||
{
|
||||
if (m_AttachRenderer != null)
|
||||
{
|
||||
m_AttachRenderer.enabled = m_Visible;
|
||||
}
|
||||
|
||||
gameObject.layer = m_Layer;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 099b60e5d5e04715a605425de4c2c7f7
|
||||
timeCreated: 1684737467
|
||||
124
UnityGame/Assets/Scripts/ThirdParty/YIUIFramework/Plugins/YIUI3DDisplay/Runtime/UI3DDisplay_API.cs
vendored
Normal file
124
UnityGame/Assets/Scripts/ThirdParty/YIUIFramework/Plugins/YIUI3DDisplay/Runtime/UI3DDisplay_API.cs
vendored
Normal file
@@ -0,0 +1,124 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
namespace YIUIFramework
|
||||
{
|
||||
public sealed partial class UI3DDisplay
|
||||
{
|
||||
//当前显示的层级 默认>>YIUI3DLayer 最好不要改
|
||||
public string ShowLayerName => m_ShowLayerName;
|
||||
|
||||
//当前显示的摄像机
|
||||
public Camera ShowCamera => m_ShowCamera;
|
||||
|
||||
//添加回收 回调 如果自己有所有对象的引用管理 可以自行管理 也可以使用回调管理
|
||||
//如果没有回调 上一个物体不做处理 不会被看到因为他层级会被修改到默认
|
||||
public void AddRecycleLastAction(Action<GameObject> action)
|
||||
{
|
||||
m_RecycleLastAction += action;
|
||||
}
|
||||
|
||||
//移除回收 回调
|
||||
public void RemoveRecycleLastAction(Action<GameObject> action)
|
||||
{
|
||||
m_RecycleLastAction -= action;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 显示3D
|
||||
/// </summary>
|
||||
/// <param name="showObject">需要被显示的对象</param>
|
||||
/// <param name="lookCamera">摄像机参数</param>
|
||||
internal void Show(GameObject showObject, Camera lookCamera)
|
||||
{
|
||||
if (showObject == null)
|
||||
{
|
||||
Debug.LogError($"必须设置显示对象");
|
||||
return;
|
||||
}
|
||||
|
||||
if (lookCamera == null)
|
||||
{
|
||||
Debug.LogError($"必须设置参考摄像机");
|
||||
return;
|
||||
}
|
||||
|
||||
SetTemporaryRenderTexture();
|
||||
|
||||
UpdateShowObject(showObject);
|
||||
|
||||
UpdateLookCamera(lookCamera);
|
||||
}
|
||||
|
||||
//清除显示的对象
|
||||
public void ClearShow()
|
||||
{
|
||||
if (m_ShowCameraCtrl != null)
|
||||
{
|
||||
m_ShowCameraCtrl.ShowObject = null;
|
||||
}
|
||||
|
||||
DisableMeshRectShadow();
|
||||
RecycleLastShow(m_ShowObject);
|
||||
m_ShowObject = null;
|
||||
}
|
||||
|
||||
//重置旋转
|
||||
public void ResetRotation()
|
||||
{
|
||||
m_DragRotation = 0.0f;
|
||||
if (m_ShowObject == null) return;
|
||||
|
||||
var showTsf = m_ShowObject.transform;
|
||||
var showRotation = Quaternion.Euler(m_ShowRotation);
|
||||
var showUp = showRotation * Vector3.up;
|
||||
showRotation *= Quaternion.AngleAxis(m_DragRotation, showUp);
|
||||
showTsf.rotation = showRotation;
|
||||
}
|
||||
|
||||
//设置旋转
|
||||
public void SetRotation(Vector3 rotation)
|
||||
{
|
||||
m_ShowRotation = rotation;
|
||||
if (m_ShowObject == null) return;
|
||||
|
||||
var showTsf = m_ShowObject.transform;
|
||||
var showRotation = Quaternion.Euler(m_ShowRotation);
|
||||
var showUp = showRotation * Vector3.up;
|
||||
showRotation *= Quaternion.AngleAxis(m_DragRotation, showUp);
|
||||
showTsf.rotation = showRotation;
|
||||
}
|
||||
|
||||
//设置位置偏移
|
||||
public void SetOffset(Vector3 offset)
|
||||
{
|
||||
m_ShowOffset = offset;
|
||||
if (m_ShowObject == null) return;
|
||||
|
||||
var showTsf = m_ShowObject.transform;
|
||||
showTsf.localPosition = m_ModelGlobalOffset + m_ShowOffset;
|
||||
m_ShowPosition = showTsf.localPosition;
|
||||
}
|
||||
|
||||
//设置大小
|
||||
public void SetScale(Vector3 scale)
|
||||
{
|
||||
m_ShowScale = scale;
|
||||
if (m_ShowObject == null) return;
|
||||
|
||||
var showTsf = m_ShowObject.transform;
|
||||
showTsf.localScale = m_ShowScale;
|
||||
}
|
||||
|
||||
//改变 当前的分辨率 一般情况下 都不会改变
|
||||
public void ChangeResolution(Vector2 newResolution)
|
||||
{
|
||||
if (!(Math.Abs(newResolution.x - m_ResolutionX) > 0.01f) &&
|
||||
!(Math.Abs(newResolution.y - m_ResolutionY) > 0.01f)) return;
|
||||
|
||||
m_ResolutionX = (int)Math.Round(newResolution.x);
|
||||
m_ResolutionY = (int)Math.Round(newResolution.y);
|
||||
SetTemporaryRenderTexture();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d9f31432528440fa834b6b606ae785a6
|
||||
timeCreated: 1684742385
|
||||
138
UnityGame/Assets/Scripts/ThirdParty/YIUIFramework/Plugins/YIUI3DDisplay/Runtime/UI3DDisplay_Event.cs
vendored
Normal file
138
UnityGame/Assets/Scripts/ThirdParty/YIUIFramework/Plugins/YIUI3DDisplay/Runtime/UI3DDisplay_Event.cs
vendored
Normal file
@@ -0,0 +1,138 @@
|
||||
using UnityEngine;
|
||||
using UnityEngine.Assertions;
|
||||
using UnityEngine.EventSystems;
|
||||
using UnityEngine.UI;
|
||||
using System.Collections.Generic;
|
||||
using Sirenix.OdinInspector;
|
||||
using System;
|
||||
using Sirenix.Serialization;
|
||||
using UnityEngine.Serialization;
|
||||
using YIUIBind;
|
||||
|
||||
namespace YIUIFramework
|
||||
{
|
||||
public sealed partial class UI3DDisplay
|
||||
{
|
||||
public bool CanDrag
|
||||
{
|
||||
get => m_CanDrag;
|
||||
set => m_CanDrag = value;
|
||||
}
|
||||
|
||||
[MinValue(0)]
|
||||
[LabelText("点击时允许偏移值")]
|
||||
[OdinSerialize]
|
||||
[ShowInInspector]
|
||||
private Vector2 m_OnClickOffset = new Vector2(50, 50);
|
||||
|
||||
private Vector2 m_OnClickDownPos = Vector2.zero;
|
||||
private RaycastHit m_ClickRaycastHit;
|
||||
private RaycastHit m_DragRaycastHit;
|
||||
private Action<GameObject, GameObject> m_OnClickEvent; //参数1 被点击的对象 参数2 他的最终父级是谁(显示对象)
|
||||
|
||||
//添加一个回调
|
||||
public void AddClickEvent(Action<GameObject, GameObject> action)
|
||||
{
|
||||
m_OnClickEvent += action;
|
||||
}
|
||||
|
||||
//移除一个回调
|
||||
public void RemoveClickEvent(Action<GameObject, GameObject> action)
|
||||
{
|
||||
m_OnClickEvent -= action;
|
||||
}
|
||||
|
||||
//从屏幕坐标发送射线检测
|
||||
public bool Raycast(Vector2 screenPoint, out RaycastHit hitInfo)
|
||||
{
|
||||
var rect = transform as RectTransform;
|
||||
if (RectTransformUtility.ScreenPointToLocalPointInRectangle(rect, screenPoint, UICamera,
|
||||
out var localScreenPoint) == false)
|
||||
{
|
||||
hitInfo = default;
|
||||
return false;
|
||||
}
|
||||
|
||||
localScreenPoint -= rect.rect.min;
|
||||
var ray = m_ShowCamera.ScreenPointToRay(localScreenPoint);
|
||||
return Physics.Raycast(ray, out hitInfo, float.PositiveInfinity, 1 << m_ShowLayer);
|
||||
}
|
||||
|
||||
//可拖拽目标
|
||||
private GameObject m_DragTarge;
|
||||
|
||||
//拖拽
|
||||
public void OnDrag(PointerEventData eventData)
|
||||
{
|
||||
if (!m_CanDrag) return;
|
||||
|
||||
if (!m_DragTarge || !(m_DragSpeed > 0.0f)) return;
|
||||
|
||||
var delta = eventData.delta.x;
|
||||
var deltaRot = -m_DragSpeed * delta * Time.deltaTime;
|
||||
var dragTsf = m_DragTarge.transform;
|
||||
|
||||
if (m_MultipleTargetMode)
|
||||
{
|
||||
dragTsf.Rotate(Vector3.up * deltaRot, Space.World);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_DragRotation += deltaRot;
|
||||
var showRotation = Quaternion.Euler(m_ShowRotation);
|
||||
var showUp = showRotation * Vector3.up;
|
||||
showRotation *= Quaternion.AngleAxis(
|
||||
m_DragRotation, showUp);
|
||||
dragTsf.rotation = showRotation;
|
||||
}
|
||||
}
|
||||
|
||||
//按下
|
||||
public void OnPointerDown(PointerEventData eventData)
|
||||
{
|
||||
if (m_MultipleTargetMode)
|
||||
{
|
||||
if (!Raycast(eventData.position, out m_DragRaycastHit))
|
||||
return;
|
||||
|
||||
m_DragTarge = GetMultipleTargetByClick(m_DragRaycastHit.collider.gameObject);
|
||||
}
|
||||
|
||||
|
||||
if (m_OnClickEvent != null)
|
||||
m_OnClickDownPos = eventData.position;
|
||||
}
|
||||
|
||||
//抬起
|
||||
public void OnPointerUp(PointerEventData eventData)
|
||||
{
|
||||
if (m_OnClickEvent == null)
|
||||
return;
|
||||
|
||||
if (!ClickSucceed(eventData.position))
|
||||
return;
|
||||
|
||||
if (!Raycast(eventData.position, out m_ClickRaycastHit))
|
||||
return;
|
||||
|
||||
var clickObj = m_ClickRaycastHit.collider.gameObject;
|
||||
var clickObjParent = m_MultipleTargetMode ? GetMultipleTargetByClick(clickObj) : m_ShowObject;
|
||||
|
||||
try
|
||||
{
|
||||
m_OnClickEvent?.Invoke(clickObj, clickObjParent);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.LogError(e);
|
||||
}
|
||||
}
|
||||
|
||||
//范围检测 因为手机上会有偏移
|
||||
private bool ClickSucceed(Vector2 upPos)
|
||||
{
|
||||
var offset = upPos - m_OnClickDownPos;
|
||||
return Math.Abs(offset.x) <= m_OnClickOffset.x && Math.Abs(offset.y) <= m_OnClickOffset.y;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 696afc55470e44f9a0fec170053a2cab
|
||||
timeCreated: 1684742706
|
||||
127
UnityGame/Assets/Scripts/ThirdParty/YIUIFramework/Plugins/YIUI3DDisplay/Runtime/UI3DDisplay_Mono.cs
vendored
Normal file
127
UnityGame/Assets/Scripts/ThirdParty/YIUIFramework/Plugins/YIUI3DDisplay/Runtime/UI3DDisplay_Mono.cs
vendored
Normal file
@@ -0,0 +1,127 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
using YIUIBind;
|
||||
|
||||
namespace YIUIFramework
|
||||
{
|
||||
/// <summary>
|
||||
/// 生命周期相关
|
||||
/// </summary>
|
||||
public sealed partial class UI3DDisplay
|
||||
{
|
||||
private void Awake()
|
||||
{
|
||||
m_ShowImage ??= GetComponent<RawImage>();
|
||||
|
||||
if (m_ShowImage != null)
|
||||
{
|
||||
if (m_ShowObject == null)
|
||||
m_ShowImage.enabled = false;
|
||||
}
|
||||
|
||||
if (m_ShowCamera != null)
|
||||
{
|
||||
if (m_ShowObject == null)
|
||||
m_ShowCamera.enabled = false;
|
||||
m_ShowCameraCtrl = m_ShowCamera.GetOrAddComponent<UI3DDisplayCamera>();
|
||||
m_ShowCameraDefPos = m_ShowCamera.transform.localPosition;
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogError($"{this.gameObject.name} ShowCamera == null 这是不允许的 请检查 建议直接使用默认预制 不要自己修改");
|
||||
}
|
||||
|
||||
g_DisPlayUIIndex += 1;
|
||||
var offsetY = g_DisPlayUIIndex * 100.0f;
|
||||
if (offsetY >= 2147)
|
||||
g_DisPlayUIIndex = 0;
|
||||
|
||||
m_ModelGlobalOffset = new Vector3(0, offsetY, 0);
|
||||
|
||||
if (m_MultipleTargetMode)
|
||||
InitRotationData();
|
||||
}
|
||||
|
||||
private void Start()
|
||||
{
|
||||
//如果提前设置显示对象 在非多模式下 自动设置
|
||||
if (!m_MultipleTargetMode && m_ShowObject != null && m_LookCamera != null)
|
||||
{
|
||||
Show(m_ShowObject, m_LookCamera);
|
||||
}
|
||||
}
|
||||
|
||||
private void OnEnable()
|
||||
{
|
||||
if (m_ShowObject == null || m_ShowTexture != null) return;
|
||||
|
||||
m_ShowTexture = RenderTexture.GetTemporary(
|
||||
m_ResolutionX, m_ResolutionY, m_RenderTextureDepthBuffer);
|
||||
|
||||
if (m_ShowImage != null)
|
||||
{
|
||||
m_ShowImage.texture = m_ShowTexture;
|
||||
m_ShowImage.enabled = true;
|
||||
}
|
||||
|
||||
if (m_ShowCamera != null)
|
||||
{
|
||||
m_ShowCamera.targetTexture = m_ShowTexture;
|
||||
m_ShowCamera.enabled = true;
|
||||
}
|
||||
}
|
||||
|
||||
private void OnDisable()
|
||||
{
|
||||
if (m_ShowTexture == null) return;
|
||||
|
||||
RenderTexture.ReleaseTemporary(m_ShowTexture);
|
||||
m_ShowTexture = null;
|
||||
|
||||
if (m_ShowImage != null)
|
||||
{
|
||||
m_ShowImage.texture = null;
|
||||
m_ShowImage.enabled = false;
|
||||
}
|
||||
|
||||
if (m_ShowCamera != null)
|
||||
{
|
||||
m_ShowCamera.targetTexture = null;
|
||||
m_ShowCamera.enabled = false;
|
||||
}
|
||||
}
|
||||
|
||||
private void OnDestroy()
|
||||
{
|
||||
if (m_ShowTexture != null)
|
||||
{
|
||||
RenderTexture.ReleaseTemporary(m_ShowTexture);
|
||||
m_ShowTexture = null;
|
||||
m_ShowImage.texture = null;
|
||||
m_ShowCamera.targetTexture = null;
|
||||
m_ShowCamera.enabled = false;
|
||||
}
|
||||
|
||||
DisableMeshRectShadow();
|
||||
|
||||
if (m_ShowCameraCtrl != null)
|
||||
{
|
||||
m_ShowCameraCtrl.ShowObject = null;
|
||||
}
|
||||
}
|
||||
|
||||
private void Update()
|
||||
{
|
||||
if (!m_ShowCamera)
|
||||
return;
|
||||
|
||||
//自动同步摄像机位置旋转
|
||||
if (m_AutoSync && m_LookCamera)
|
||||
{
|
||||
var tsf = m_LookCamera.transform;
|
||||
m_ShowCamera.transform.SetPositionAndRotation(tsf.position, tsf.rotation);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 27c02a4b778f43fdad4cb5fc7dacd930
|
||||
timeCreated: 1684835681
|
||||
@@ -0,0 +1,147 @@
|
||||
using System.Collections.Generic;
|
||||
using Sirenix.OdinInspector;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Serialization;
|
||||
|
||||
namespace YIUIFramework
|
||||
{
|
||||
/// <summary>
|
||||
/// 多个
|
||||
/// </summary>
|
||||
public sealed partial class UI3DDisplay
|
||||
{
|
||||
[SerializeField]
|
||||
[LabelText("多目标模式")]
|
||||
private bool m_MultipleTargetMode = false;
|
||||
|
||||
//可动态设置改变多目标 但是尽量不要所以关闭了
|
||||
public bool MultipleTargetMode
|
||||
{
|
||||
get => m_MultipleTargetMode;
|
||||
private set
|
||||
{
|
||||
m_MultipleTargetMode = value;
|
||||
if (value)
|
||||
{
|
||||
InitRotationData();
|
||||
}
|
||||
else
|
||||
{
|
||||
ClearMultipleData();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private List<GameObject> m_AllMultipleTarget;
|
||||
|
||||
private Dictionary<GameObject, GameObject> m_MultipleCache;
|
||||
|
||||
private bool m_InitMultipleData = false;
|
||||
|
||||
//初始化
|
||||
private void InitRotationData()
|
||||
{
|
||||
if (m_InitMultipleData) return;
|
||||
|
||||
m_AllMultipleTarget = new List<GameObject>();
|
||||
m_MultipleCache = new Dictionary<GameObject, GameObject>();
|
||||
m_InitMultipleData = true;
|
||||
}
|
||||
|
||||
//清除
|
||||
private void ClearMultipleData()
|
||||
{
|
||||
m_AllMultipleTarget = null;
|
||||
m_MultipleCache = null;
|
||||
m_InitMultipleData = false;
|
||||
m_DragTarge = m_ShowObject;
|
||||
}
|
||||
|
||||
//添加目标
|
||||
public void AddMultipleTarget(GameObject obj, Camera lookCamera = null, Transform parent = null)
|
||||
{
|
||||
if (m_ShowObject == null)
|
||||
{
|
||||
Debug.LogError($"多目标 使用前 需要一个父级对象");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!m_InitMultipleData)
|
||||
{
|
||||
Debug.LogError("多目标模式 未初始化");
|
||||
return;
|
||||
}
|
||||
|
||||
SetPosAndRotAndParent(obj.transform, lookCamera, parent);
|
||||
|
||||
SetAllAnimatorCullingMode(obj.transform);
|
||||
|
||||
SetupShowLayerTarget(obj.transform);
|
||||
|
||||
m_AllMultipleTarget.Add(obj);
|
||||
}
|
||||
|
||||
//移除目标
|
||||
public void RemoveMultipleTarget(GameObject obj)
|
||||
{
|
||||
if (!m_InitMultipleData)
|
||||
{
|
||||
Debug.LogError("多目标模式 未初始化");
|
||||
return;
|
||||
}
|
||||
|
||||
m_AllMultipleTarget.Remove(obj);
|
||||
}
|
||||
|
||||
//获取点击目标的父级对象
|
||||
private GameObject GetMultipleTargetByClick(GameObject child)
|
||||
{
|
||||
var obj = GetMultipleCache(child);
|
||||
if (obj != null)
|
||||
return obj;
|
||||
|
||||
if (IsMultipleTarget(child))
|
||||
return child;
|
||||
|
||||
var parent = child.transform.parent;
|
||||
if (parent)
|
||||
return GetMultipleTargetByClick(parent.gameObject);
|
||||
|
||||
Debug.LogError($"没有找到这个对象 {child.name}");
|
||||
return null;
|
||||
}
|
||||
|
||||
private GameObject GetMultipleCache(GameObject obj)
|
||||
{
|
||||
m_MultipleCache.TryGetValue(obj, out var rotationObj);
|
||||
return rotationObj;
|
||||
}
|
||||
|
||||
private bool IsMultipleTarget(GameObject obj)
|
||||
{
|
||||
foreach (var item in m_AllMultipleTarget)
|
||||
{
|
||||
if (item == obj)
|
||||
{
|
||||
m_MultipleCache.Add(obj, item);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
//多目标下 设置位置旋转父级
|
||||
private static void SetPosAndRotAndParent(Transform target, Camera lookCamera = null, Transform parent = null)
|
||||
{
|
||||
if (parent)
|
||||
target.SetParent(parent, false);
|
||||
|
||||
target.localPosition = Vector3.zero;
|
||||
|
||||
target.localScale = Vector3.one;
|
||||
|
||||
target.localRotation = lookCamera ? lookCamera.transform.localRotation : Quaternion.identity;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0c02f6b1bdc2422496ec6a1882a92e6f
|
||||
timeCreated: 1684832776
|
||||
@@ -0,0 +1,23 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
namespace YIUIFramework
|
||||
{
|
||||
public sealed partial class UI3DDisplay
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
private void OnValidate()
|
||||
{
|
||||
if (m_AutoChangeSize)
|
||||
{
|
||||
var rect = transform.GetComponent<RectTransform>();
|
||||
if (Math.Abs(rect.sizeDelta.x - m_ResolutionX) > 0.01f ||
|
||||
Math.Abs(rect.sizeDelta.y - m_ResolutionY) > 0.01f)
|
||||
rect.sizeDelta = new Vector2(m_ResolutionX, m_ResolutionY);
|
||||
}
|
||||
|
||||
ChangeLayerName(m_ShowLayerName);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6adb597d668c40e4a1c4fae82f60682a
|
||||
timeCreated: 1684741864
|
||||
Reference in New Issue
Block a user