using UnityEngine; using UnityEngine.UI; using UnityEngine.Video; using System.Collections; namespace GameFramework { /// /// 剧情 PV 播放器 —— 点击 StoryReplayButton 后弹出全屏视频覆盖层播放 PV。 /// 播放完毕自动关闭,也可点击"跳过"按钮立即关闭。 /// /// 搭建: /// 1. 在 MainMenu Canvas 下创建 VideoOverlay(初始 SetActive(false)) /// 2. 子物体:BG (全屏黑色 Image)、VideoDisplay (RawImage)、SkipButton (Button) /// 3. 挂 VideoPlayer 组件,VideoClip 赋值为 pv.mp4 /// 4. 挂本脚本,Inspector 中关联各引用 /// public class StoryPVPlayer : MonoBehaviour { [Header("覆盖层")] [Tooltip("视频覆盖层根节点(初始隐藏)")] [SerializeField] private GameObject videoOverlay; [Header("视频显示")] [Tooltip("全屏 RawImage 用于显示视频画面")] [SerializeField] private RawImage videoDisplay; [Header("跳过按钮")] [Tooltip("右下角跳过按钮")] [SerializeField] private Button skipButton; [Header("视频播放器")] [Tooltip("VideoPlayer 组件(挂在 VideoOverlay 或自身上)")] [SerializeField] private VideoPlayer videoPlayer; private RenderTexture _renderTexture; private bool _isPlaying = false; /// /// 懒加载:确保所有引用都已初始化。 /// 使用 GetComponentsInChildren(true) 递归搜索(包括 inactive 子物体)。 /// private void EnsureReferences() { // videoOverlay:默认就是自身(StoryPVPlayer 挂在 VideoOverlay 上) if (videoOverlay == null) { // 递归搜索子物体中名为 "VideoOverlay" 的 GameObject var transforms = GetComponentsInChildren(true); foreach (var t in transforms) { if (t.name == "VideoOverlay") { videoOverlay = t.gameObject; break; } } // 如果没找到,说明本脚本就挂在 VideoOverlay 上 if (videoOverlay == null) videoOverlay = gameObject; } // 查找 RawImage(递归搜索 videoOverlay 的子物体,包括 inactive) if (videoDisplay == null && videoOverlay != null) { var displays = videoOverlay.GetComponentsInChildren(true); if (displays.Length > 0) videoDisplay = displays[0]; } // 查找 SkipButton(递归搜索,按名称匹配避免找到其他按钮) if (skipButton == null && videoOverlay != null) { var buttons = videoOverlay.GetComponentsInChildren