初始化

This commit is contained in:
come
2025-07-26 16:56:42 +08:00
parent 8291dbb91c
commit fa81439a8c
2574 changed files with 328492 additions and 2170 deletions

View 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;
}
}
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 6beceb02921d4f718798027eb1260be0
timeCreated: 1684737421

View File

@@ -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);
}
}
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 1b68c6c15482408c8c2e344c1c889597
timeCreated: 1684737442

View File

@@ -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;
}
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 099b60e5d5e04715a605425de4c2c7f7
timeCreated: 1684737467

View 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();
}
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: d9f31432528440fa834b6b606ae785a6
timeCreated: 1684742385

View 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;
}
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 696afc55470e44f9a0fec170053a2cab
timeCreated: 1684742706

View 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);
}
}
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 27c02a4b778f43fdad4cb5fc7dacd930
timeCreated: 1684835681

View File

@@ -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;
}
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 0c02f6b1bdc2422496ec6a1882a92e6f
timeCreated: 1684832776

View File

@@ -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
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 6adb597d668c40e4a1c4fae82f60682a
timeCreated: 1684741864