unity avpro实现互动影游关键问题

创建视频播放器

  • 在Hierarchy面板中右键创建:Video > AVPro Video - MediaPlayer
  • 创建后会生成一个MediaPlayer对象,用于控制视频播放

添加视频资源

  • 将视频文件放入项目的StreamingAssets文件夹下
  • 在MediaPlayer组件的设置中选择要播放的视频文件

在UI上显示视频

  • 创建Canvas对象
  • 在Canvas下添加DisplayUGUI组件用于将视频渲染到UI
  • 将MediaPlayer拖拽到DisplayUGUI组件中

unity avpro切换视频播放

核心思路,需要切换视频时。将当前视频A截一帧图片pic显示。播放器加载第二个视频,等第二个视频B事件MediaPlayerEvent.EventType.FirstFrameReady,延迟一帧将图片pic隐藏即可。

实现简单影游根据选项跳转不同视频播放

主要代码:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using RenderHeads.Media.AVProVideo;
using TMPro;
using System;public class Level : MonoBehaviour
{public MediaPlayer mediaPlayer;public string levelID; // 关卡唯一标识public Button op_btn1; // 操作按钮1public Button op_btn2;public TextMeshProUGUI op_btn1_text;public TextMeshProUGUI op_btn2_text;public LevelNode levelNode;public float targetTime = 0.0f;public bool hasTriggered = false;public UnityEngine.UI.RawImage displayImage;// Start is called before the first frame updatevoid Start(){mediaPlayer.AutoStart = false;mediaPlayer.Events.AddListener(OnVideoEvent);op_btn1.onClick.AddListener(OnButtonClick_op1);op_btn2.onClick.AddListener(OnButtonClick_op2);HideOptionsUI();Invoke("test", 1.0f); // 延迟1秒显示操作按钮displayImage.gameObject.SetActive(false);}// Update is called once per framevoid Update(){}void FixedUpdate(){CheckCurrentTime();}void OnButtonClick_op1(){Debug.Log("Button 1 clicked in level: " + levelID);mediaPlayer.Pause();// 在这里添加按钮1的操作逻辑FinishLevel(levelNode.op1_level);}void OnButtonClick_op2(){Debug.Log("Button 2 clicked in level: " + levelID);// 在这里添加按钮2的操作逻辑FinishLevel(levelNode.op2_level);}void ShowOptionsUI(){op_btn1_text.text = levelNode.op1;op_btn2_text.text = levelNode.op2;op_btn1.GetComponent<RectTransform>().localPosition = new Vector3(levelNode.op1_x, levelNode.op1_y, 0);op_btn2.GetComponent<RectTransform>().localPosition = new Vector3(levelNode.op2_x, levelNode.op2_y, 0);op_btn1.gameObject.SetActive(true);op_btn2.gameObject.SetActive(true);}void HideOptionsUI(){op_btn1.gameObject.SetActive(false);op_btn2.gameObject.SetActive(false);}void OnVideoEvent(MediaPlayer mp, MediaPlayerEvent.EventType et, ErrorCode errorCode){switch (et){case MediaPlayerEvent.EventType.ReadyToPlay:Debug.Log("视频加载完成,准备播放");break;case MediaPlayerEvent.EventType.Started:Debug.Log($"当前时间: {DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff")}视频播放开始");break;case MediaPlayerEvent.EventType.FirstFrameReady:Debug.Log($"当前时间: {DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff")}第一帧渲染完成");StartCoroutine(DelayFunction());break;case MediaPlayerEvent.EventType.FinishedPlaying:Debug.Log("视频播放完毕");break;case MediaPlayerEvent.EventType.FinishedSeeking:Debug.Log("跳转到指定时间完成");break;default://Debug.Log("未知视频事件",et);break;}}void CheckCurrentTime(){float currentTime = (float)mediaPlayer.Control.GetCurrentTime();if (targetTime != 0 && currentTime >= targetTime && !hasTriggered){hasTriggered = true;Debug.Log($"视频已播放到目标时间: {targetTime}秒");// 在这里执行你的回调逻辑ShowOptionsUI();}}void test(){StartLevel("1");}void StartLevel(string levelid){LevelNode n = NodeCfg.Instance.GetNode(levelid);levelNode = n;Debug.Log($"当前时间: {DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff")}加载视频开始");string fullpath = System.IO.Path.Combine(Application.streamingAssetsPath, "videos", levelNode.mp4);if (!mediaPlayer.OpenMedia(MediaPathType.RelativeToStreamingAssetsFolder, fullpath, false)){Debug.LogError("Video not found!");return;}if (n.op_time > 0){targetTime = n.op_time;}mediaPlayer.Play();Debug.Log($"当前时间: {DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff")}加载视频结束");}void FinishLevel(string nextlevelid){HideOptionsUI();hasTriggered = false; // 重置触发状态targetTime = 0;CaptureAndDisplayLastFrame();StartLevel(nextlevelid);}private void CaptureAndDisplayLastFrame(){Debug.Log($"当前时间: {DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff")}截图");// 创建Texture2D来保存截图Texture2D texture = new Texture2D(mediaPlayer.Info.GetVideoWidth(), mediaPlayer.Info.GetVideoHeight(), TextureFormat.ARGB32, false);// 截取当前帧(最后一帧)mediaPlayer.ExtractFrame(texture);// 显示截图if (displayImage != null){displayImage.texture = texture;}displayImage.gameObject.SetActive(true);}IEnumerator DelayFunction(){yield return null; // 暂停一帧Debug.Log($"当前时间: {DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff")}下一帧执行");displayImage.gameObject.SetActive(false);}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/diannao/93897.shtml
繁体地址,请注明出处:http://hk.pswp.cn/diannao/93897.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【C找第一个只出现一次的字符】2022-8-18

缘由样例通过&#xff0c;请问为什么错了呢&#xff1f;(语言-c语言)-编程语言-CSDN问答 char str[100000];fgets(str, 100000, stdin);int a[26]{}, i, count 0;int len strlen(str);for (i 0; i<len; i) a[str[i] - a];for (i 0; i<len; i){if (a[str[i] - a] 1){…

MCP AI应用通信的底层机制

技术小馆专注AI与Java领域的前沿技术知识库 技术小馆官网 在AI应用快速发展的今天&#xff0c;不同AI系统之间的高效通信成为技术架构的关键挑战。MCP&#xff08;Model Context Protocol&#xff09;作为新一代AI应用通信协议&#xff0c;正在重新定义AI工具生态的构建方式。…

UI测试平台TestComplete如何实现从Git到Jenkins的持续测试

还在为手动做UI测试又慢又累发愁&#xff1f;更头痛的是&#xff0c;代码改完还得等半天才能测&#xff0c;测完了结果又散得到处都是&#xff0c;根本看不清质量全貌?TestComplete帮你搞定&#xff1a;直接连上你的Git仓库&#xff0c;代码一有动静就能感知。接着&#xff0c…

【Debian】4-‌2 Gitea搭建

【Debian】4-‌2 Gitea搭建一、准备工作二、创建 Gitea 用户&#xff08;推荐&#xff09;三、下载并安装 Gitea四、配置Gitea4-1 创建目录结构4-2 创建配置目录五、配置 Systemd 服务六、访问 Gitea Web 界面七、小插曲一、准备工作 更新系统软件为最新 sudo apt update &am…

【CDH × Docker】一次测试部署,N 次复用的环境镜像方案

&#x1f680; 一次测试环境的探索&#xff1a;我如何将 CDH 集群打包成 Docker 镜像&#xff0c;留给未来的自己 &#x1f9e9; 背景故事 最近在项目中&#xff0c;我们计划上线一个基于 CDH&#xff08;Cloudera Distribution Hadoop&#xff09; 的大数据平台。正式上生产环…

Java 日期时间格式化模式说明

Java 中日期时间格式化使用特定的模式字符串来定义输出格式。以下是常见的格式化符号及其含义&#xff0c;适用于 SimpleDateFormat 和 DateTimeFormatter一、日期部分格式化符号符号含义示例y年 (Year)yyyy → 2023M月 (Month)MM → 09, MMM → Sep, MMMM → Septemberd月中的…

代码随想录算法训练营三十三天|动态规划part06

LeetCode 322 零钱兑换 题目链接&#xff1a;322. 零钱兑换 - 力扣&#xff08;LeetCode&#xff09; 给你一个整数数组 coins &#xff0c;表示不同面额的硬币&#xff1b;以及一个整数 amount &#xff0c;表示总金额。 计算并返回可以凑成总金额所需的 最少的硬币个数 。…

【大模型LLM】大模型训练加速 - 梯度累积(Gradient Accumulation)原理详解

梯度累积&#xff08;Gradient Accumulation&#xff09;原理详解 梯度累积是一种在深度学习训练中常用的技术&#xff0c;特别适用于显存有限但希望使用较大批量大小&#xff08;batch size&#xff09;的情况。通过梯度累积&#xff0c;可以在不增加单个批次大小的情况下模拟…

【数据分享】各省文旅融合耦合协调度及原始数据(2012-2022)

数据介绍引言 文旅融合是推动区域经济高质量发展、促进共同富裕的重要路径。党的二十大报告明确提出“推进文化和旅游深度融合发展”的战略目标&#xff0c;文旅产业通过资源整合与业态创新&#xff0c;可显著缩小城乡、区域差距&#xff0c;提升物质与精神双重福祉&#xff08…

Linux编程: 10、线程池与初识网络编程

今天我计划通过一个小型项目&#xff0c;系统讲解线程池与网络编程的核心原理及实践。项目将围绕 “利用线程池实现高并发网络通信” 这一核心需求展开&#xff0c;具体设计如下&#xff1a; 为保证线程安全&#xff0c;线程池采用单例模式设计&#xff0c;确保全局唯一实例避…

藏云阁 Logo 库(开源项目SVG/PNG高清Logo)

在日常技术方案设计、架构图绘制或PPT制作中&#xff0c;常常会遇到一些问题&#xff0c;比如&#xff1a; 找不到统一风格的开源项目组件图标&#xff0c;PPT中的logo五花八门下载的图标分辨率不足&#xff0c;放大后模糊失真不同来源的图标颜色风格冲突&#xff0c;破坏整体…

从0开始学习R语言--Day64--决策树回归

对于没有特征或者说需要寻找另类关系的数据集&#xff0c;我们通常会用聚合或KNN近邻的方法来分类&#xff0c;但这样的分类或许在结果上是好的&#xff0c;但是解释性并不好&#xff0c;有时候我们甚至能看到好的结果反直觉&#xff1b;而决策树回归做出的结果&#xff0c;由于…

B+树高效实现与优化技巧

B树的定义 一颗M阶B树T,满足以下条件 每个结点至多拥有M课子树 根结点至少拥有两颗子树 除了根结点以外,其余每个分支结点至少拥有M/2课子树 所有的叶结点都在同一层上 有k棵子树的分支结点则存在k-1个关键字,关键字按照递增顺序进行排序 关键字数量满足 ceil( M/2 ) - 1 &…

Android 基础入门学习目录(持续更新)

四大组件 Activity&#xff1a; Service&#xff1a; BroadcastReceiver&#xff1a; ContentProvider&#xff1a; UI 与交互开发 常见的UI布局和UI控件 样式与主题 Fragment Intent 数据存储 自定义View和自定义Group 自定义View 自定义ViewGroup 事件分发 Key…

Linux移动大量文件命令

背景 使用 mv 命令报“/bin/mv: 参数列表过长”&#xff0c;也是第一遇到&#xff0c;查了一下&#xff0c;最后用rsync命令解决了。还好每台服务器&#xff0c;都必装rsync了&#xff0c;记录如下。 命令 nohup rsync -av --remove-source-files --progress /public/tmp/video…

SQL中的HAVING用法

HAVING 是 SQL 中专门对 “分组之后的聚合结果” 再做筛选的子句。 它一般跟在 GROUP BY 后面&#xff0c;不能单独使用&#xff0c;作用类似于分组版的 WHERE。✅ 1. 语法位置 SELECT 列1, 聚合函数(列2) AS 别名 FROM 表 GROUP BY 列1 HAVING 聚合条件; -- 这里写对聚合…

【Halcon 】Halcon 实战:如何为 XLD 模板添加极性信息以提升匹配精度?

Halcon 实战&#xff1a;如何为 XLD 模板添加极性信息以提升匹配精度&#xff1f; 在使用 Halcon 进行模板匹配时&#xff0c;我们通常有两种方式创建模板&#xff1a; 基于图像灰度&#xff08;CreateScaledShapeModel&#xff09;基于轮廓 XLD&#xff08;CreateScaledShapeM…

grafana/lock-stack 日志 Pipeline 配置

前言 本文使用的是 grafana/loki-stack chart 抓取的 k8s 日志。其他 chart 配置都差不多。 日志问题 docker 容器运行时 pod 内原始日志 [cpu-4] Hello, 第 9788 次报时&#xff0c;时间&#xff1a;2025-08-01T06:35:420000 {"HOSTNAME":"cpu-4",&qu…

appium2.0+之PointerActions详解

以下内容在 夜神模拟器 上进行。 一、应用场景 一些针对手势的操作&#xff0c;比如滑动、长按、拖动等。可以将这些基本手势组合成一个相对复杂的手势。 二、使用步骤创建触摸输入设备&#xff08;模拟手指操作&#xff09; touch_input PointerInput(interaction.POINTER_TO…

Java HTTPS 请求失败排查与证书导入全过程

文章目录Java HTTPS 请求失败排查与证书导入全过程问题背景问题初步分析排查过程查看目标地址证书导入证书验证证书是否导入成功重启应用进一步验证&#xff1a;是否真的是证书问题&#xff1f;1. 浏览器访问2. 抓包工具验证&#xff08;如 Charles、Wireshark&#xff09;补充…