Files
ft/Client/Assets/Scripts/EventBossFight/Panel/MainVideo/EventBossFightRectFollowerGraphic.cs
2026-06-29 21:18:33 +08:00

85 lines
2.9 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using UnityEngine;
namespace EventBossFight
{
/// <summary>
/// UI RectTransform 跟随另一 RectTransform视频 Boss 挂点,替代 Spine BoneFollower
/// 同一 rootCanvas 下直接同步世界坐标;否则经屏幕坐标转换到父 Rect 的局部空间。
/// </summary>
[RequireComponent(typeof(RectTransform))]
[DefaultExecutionOrder(1000)]
public class EventBossFightRectFollowerGraphic : MonoBehaviour
{
[SerializeField]
private RectTransform target;
public RectTransform Target => target;
public void SetTarget(RectTransform t)
{
target = t;
}
private void OnEnable()
{
ApplyFollow();
}
private void LateUpdate()
{
ApplyFollow();
}
private void ApplyFollow()
{
if (!target)
return;
var self = (RectTransform)transform;
var parent = self.parent as RectTransform;
if (!parent)
{
self.SetPositionAndRotation(target.position, target.rotation);
return;
}
var canvasSelf = self.GetComponentInParent<Canvas>();
var canvasTarget = target.GetComponentInParent<Canvas>();
if (canvasSelf && canvasTarget && canvasSelf.rootCanvas == canvasTarget.rootCanvas)
{
self.SetPositionAndRotation(target.position, target.rotation);
return;
}
var camTarget = GetEventCamera(canvasTarget);
var camSelf = GetEventCamera(canvasSelf);
// Overlay 下 WorldToScreenPoint 须传 nullCamera 模式用对应 Canvas 的 worldCamera
Camera camForScreen = null;
if (canvasTarget != null && canvasTarget.renderMode == RenderMode.ScreenSpaceOverlay)
camForScreen = null;
else
camForScreen = camTarget ?? camSelf ?? Camera.main;
var screenPoint = RectTransformUtility.WorldToScreenPoint(camForScreen, target.position);
var camForParent = canvasSelf && canvasSelf.renderMode == RenderMode.ScreenSpaceOverlay
? null
: camSelf ?? camForScreen;
if (RectTransformUtility.ScreenPointToLocalPointInRectangle(parent, screenPoint, camForParent,
out var localPoint))
{
self.anchoredPosition = localPoint;
self.localRotation = Quaternion.Inverse(parent.rotation) * target.rotation;
}
else
self.SetPositionAndRotation(target.position, target.rotation);
}
private static Camera GetEventCamera(Canvas canvas)
{
if (!canvas || canvas.renderMode == RenderMode.ScreenSpaceOverlay)
return null;
return canvas.worldCamera;
}
}
}