当前位置: 首页 > news >正文

【Unity笔记】视频播放控制器全攻略:支持延迟播放、事件回调与多视频管理的完整实现

关键词:Unity 视频播放、延迟播放、事件回调、多视频管理、VideoPlayer 教程


摘要:本教程详细讲解了如何在 Unity 中使用 VideoPlayer 实现一个功能完善的视频播放控制器,支持按视频名称播放、播放开始/结束事件回调、以及延迟播放等高级功能。
通过使用 NamedClip 数据结构和 Dictionary 映射,你可以轻松管理多个视频并在 Inspector 中绑定自定义逻辑,无需修改代码即可适应不同场景。


在这里插入图片描述


视频播放控制器全攻略:支持延迟播放、事件回调与多视频管理的完整实现


一、引言

在 Unity 项目中,视频播放已经成为许多项目的刚需。无论是游戏过场动画教学演示、还是互动展览,视频内容都能极大提升用户的沉浸感。

Unity 提供了功能强大的 VideoPlayer 组件,但直接使用它进行多视频管理时,经常会遇到以下痛点:

  • 需要手动指定 视频索引,一旦顺序改动,调用方就需要全局修改,极易出错。

  • 难以在播放开始播放结束时执行自定义逻辑,比如:

    • 播放背景音乐
    • 切换 UI 面板
    • 自动播放下一个视频
  • 缺乏延迟播放的机制,不便于在流程中穿插过渡动画或加载时间。

举个例子:

  • 在一款解谜游戏中,解锁机关后会播放一段剧情动画来推进故事;
  • 在博物馆互动大屏中,用户点击某个展品,会播放它的历史介绍视频;
  • 在教学软件中,教师点击按钮即可播放不同章节的教学视频。

虽然 Unity 自带了功能强大的 VideoPlayer 组件,但如果直接使用它来管理多段视频,很快就会暴露出以下问题:


为了解决这些问题,可参考下面实现一个可扩展的 VideoSubtitleController 脚本,它支持:

  • 按视频名称调用播放,不依赖索引顺序
  • 视频开始与结束的 UnityEvent 回调
  • 延迟播放(可在其它 UnityEvent 中直接触发)
  • 清除 RenderTexture 画面,避免残影

接下来,我们将从需求分析开始,一步步实现这个脚本。


二、需求分析

1. 多视频管理问题

假设一个场景有 10 段视频,如果用数组索引来播放:

videoClips[3] // 播放第 4 个视频

一旦数组顺序发生变化(比如插入新视频),所有调用索引的地方都得改,维护成本极高。

改进方式

  • 视频名称(string)作为唯一标识
  • 通过字典 (Dictionary<string, NamedClip>) 查找视频资源

2. 播放回调的必要性

在视频播放开始或结束时,我们可能需要执行:

  • 开始播放时:隐藏 Loading UI、启动计时器、播放音乐
  • 结束播放时:切换场景、显示问卷、加载下一个视频

通过 UnityEvent,我们可以在 Inspector 中绑定事件,无需改代码即可定制逻辑。


3. 延迟播放的使用场景

延迟播放可用于:

  • 播放前等待过渡动画结束
  • 给用户留出操作时间
  • 等待网络数据加载完成

三、脚本设计思路

我们将脚本分成几个核心模块:

模块功能说明
NamedClip存储视频的名字、视频文件、事件回调
clipDict用视频名字快速查找视频资源
PlayVideo播放指定名字的视频
PlayVideoWithDelay延迟播放指定视频
StopVideo停止播放并触发结束事件
ClearToTransparent清除 RenderTexture 画面

四、完整代码实现

1. 数据结构定义

[Serializable]
public class NamedClip
{[Tooltip("视频的唯一标识名称")]public string name;[Tooltip("视频文件")]public VideoClip clip;[Tooltip("视频播放开始时的事件回调")]public UnityEvent onVideoStarted;[Tooltip("视频播放结束时的事件回调")]public UnityEvent onVideoEnded;
}

2. 核心脚本实现

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.Video;[RequireComponent(typeof(VideoPlayer))]
public class VideoController : MonoBehaviour
{[Header("视频资源配置")]public NamedClip[] namedVideoClips;private Dictionary<string, NamedClip> clipDict = new Dictionary<string, NamedClip>();private VideoPlayer videoPlayer;private NamedClip currentClip;private void Awake(){videoPlayer = GetComponent<VideoPlayer>();// 构建字典映射foreach (var entry in namedVideoClips){if (!string.IsNullOrEmpty(entry.name) && entry.clip != null){clipDict[entry.name] = entry;}}videoPlayer.loopPointReached += OnVideoFinished;}/// <summary>/// 播放指定名称的视频/// </summary>public void PlayVideo(string clipName){if (!clipDict.TryGetValue(clipName, out var namedClip)){Debug.LogWarning($"未找到视频片段:{clipName}");return;}if (videoPlayer.isPlaying){videoPlayer.Stop();}currentClip = namedClip;videoPlayer.clip = currentClip.clip;videoPlayer.Play();currentClip.onVideoStarted?.Invoke();}/// <summary>/// 延迟播放/// </summary>public void PlayVideoWithDelay(string clipName, float delaySeconds){StartCoroutine(PlayVideoDelayedCoroutine(clipName, delaySeconds));}private IEnumerator PlayVideoDelayedCoroutine(string clipName, float delay){yield return new WaitForSeconds(delay);PlayVideo(clipName);}/// <summary>/// 停止当前视频/// </summary>public void StopVideo(){if (videoPlayer != null && videoPlayer.isPlaying){videoPlayer.Stop();currentClip?.onVideoEnded?.Invoke();}}/// <summary>/// 视频播放结束回调/// </summary>private void OnVideoFinished(VideoPlayer vp){currentClip?.onVideoEnded?.Invoke();}/// <summary>/// 清除 RenderTexture 内容/// </summary>public void ClearToTransparent(RenderTexture rt){if (rt == null) return;RenderTexture currentRT = RenderTexture.active;RenderTexture.active = rt;GL.Clear(true, true, Color.clear);RenderTexture.active = currentRT;}
}

3. Unity 编辑器配置

Inspector 配置示例

在这里插入图片描述


五、使用步骤

  1. 在场景中创建一个 VideoPlayer GameObject
  2. 挂载 VideoSubtitleController
  3. namedVideoClips 中添加多个视频
  4. 为每个视频绑定开始和结束事件
  5. 在 UI 按钮中调用 PlayVideo("Video1")PlayVideoWithDelay("Video2", 3)

六、总结

通过本脚本,我们解决了:

  • 名称播放视频,避免索引错乱
  • 开始 & 结束事件回调,灵活绑定逻辑
  • 延迟播放,方便流程衔接

📌 建议
你可以将本脚本直接放入 Unity 工程,按上面步骤配置即可使用。如果需要跨场景播放,可以结合 DontDestroyOnLoad 保持控制器实例。


http://www.dtcms.com/a/327308.html

相关文章:

  • Linux 系统下 VS Code 降级至 1.85 版本教程:通过历史版本网站解决兼容性问题
  • 二叉树(七)--完全二叉树的节点个数
  • Day13 Vue工程化
  • mysql 简单操作手册
  • 行业分享丨SimSolid 在汽车零部件开发中应用的可行性调研及实践
  • 鸿蒙har包打包与引用,其它主工程entry引用本地har
  • Wireshark专家模式定位网络故障:14种TCP异常深度解剖
  • 西门子S7-200与S7-1200通过PPI以太网模块通讯,赋能汽车制造行业发展
  • 人机交互:连接人类与数字世界的桥梁
  • 【k8s】pvc 配置的两种方式volumeClaimTemplates 和 PersistentVolumeClaim
  • 计算机网络1-8:第一章 概述 习题课
  • UserController类讲解
  • Git 撤回已推送到远程的最近push
  • Linux 服务器,安装mqtt服务
  • AuthController类讲解
  • 思科、华为、华三如何切换三层端口?
  • 前端面试题汇总--Vue2篇
  • 网络安全:如何保障社交媒体账户的安全?
  • 导入文件到iPhone实现
  • Python打卡Day40 训练和测试的规范写法
  • iOS 编译 cpp 代码生成 .a 库备忘
  • 【测试】Bug+设计测试用例
  • 华为发布AI推理新技术,降低对HBM内存依赖
  • C语言—数组和指针练习题合集(二)
  • 终端安全检测和防御技术总结
  • 2025年Java后端秋招面试宝典:高频题库+场景解析
  • wordpress从wp_nav_menu中获取菜单项
  • 聆思duomotai_ap sdk适配dooiRobot
  • 【PyTorch学习笔记 - 03】 Transforms
  • 算法打卡力扣第88题:合并两个有序数组(easy)