当前位置: 首页 > 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.xdnf.cn/news/1284787.html

相关文章:

  • 数据结构:图
  • 【力扣494】目标和
  • 【代码随想录day 17】 力扣 98.验证二叉搜索树
  • 网站测评-利用缓存机制实现XSS的分步测试方法
  • 正向传播与反向传播(神经网络思维的逻辑回归)
  • 动态规划----1.爬楼梯
  • VUE的8个生命周期
  • 将黑客拒之物联网网络之外的竞赛
  • Openlayers基础教程|从前端框架到GIS开发系列课程(24)openlayers结合canva绘制矩形绘制线
  • Etcd客户端工具Etcd Workbench更新了1.2.0版本!多语言支持了中文,新增了许多快捷功能使用体验再次提升
  • Linux中Apache与Web之虚拟主机配置指南
  • 【门诊进销存出入库管理系统】佳易王医疗器械零售进销存软件:门诊进销存怎么操作?系统实操教程 #医药系统进销存
  • sqli-labs通关笔记-第44关 POST字符型堆叠注入(单引号闭合 手工注入+脚本注入3种方法)
  • 「数据获取」中国高技术产业统计年鉴(1995-2024年)(获取方式看绑定的资源)
  • 文字转语音 edge_tts
  • Docker概述与安装Dockerfile文件
  • 大数据技术入门精讲(Hadoop+Spark)
  • 【密码学】9. 可证明安全
  • 链动 3+1 模式:重构商业增长逻辑的新引擎
  • Mac M1探索AnythingLLM+Ollama+知识库问答
  • 支持任意 MCP 协议的客户端
  • 数据可视化交互深入理解
  • 最终章【1】Epson机器人篇
  • 如何提升需求分析能力
  • maven项目打包成sdk后在别的项目使用
  • 企业级高性能WEB服务器Nginx
  • 编程技能:递归
  • B 树与 B + 树解析与实现
  • SSE流式输出分层与解耦、用户自动结束语错误处理
  • 【13-向量化-高效计算】