⭐ Unity AVProVideo插件自带播放器 脚本重构 实现视频激活重置功能 - 实践
2025-10-05 21:56 tlnshuju 阅读(0) 评论(0) 收藏 举报一、功能概述
本笔记记录直接修改插件自带的场景播放其中 原始的 MediaPlayerUI 脚本,实现激活时自动重置播放器的功能。 我用的插件版本是 AVPro Video - Ultra Edition 2.7.3
修改后的脚本将具备以下特性:
激活 GameObject 时自动重置播放位置到开头
可配置是否在重置后自动开始播放
可配置重置前的延迟时间
视频播放结束后自动回到开头
保留原始脚本所有功能
二、修改步骤
1. 添加新变量
在类变量声明区域添加以下变量:
[Header("Activation Behavior")]
[Tooltip("Reset playback to beginning when enabled")]
[SerializeField] bool _resetOnEnable = true;[Tooltip("Automatically start playback after reset")]
[SerializeField] bool _playOnReset = true;[Tooltip("Delay before resetting after enable (seconds)")]
[SerializeField] float _resetDelay = 0.1f;private Coroutine _resetCoroutine;
2. 添加 ResetPlayer 方法
在 Start()
方法后添加:
///
/// Resets the player to beginning and optionally starts playback
///
public void ResetPlayer()
{
if (_mediaPlayer == null || _mediaPlayer.Control == null)
{
Debug.LogWarning("MediaPlayer or Control is not available",
this);
return;
}// Reset playback position
_mediaPlayer.Control.Seek(0);// Reset audio state
_audioVolume = 1f;
_audioFade = 1f;
_isAudioFadingUpToPlay = true;
_audioFadeTime = 0f;
ApplyAudioVolume();// Update UI
UpdateVolumeSlider();// Start playback if configured to do so
if (_playOnReset)
{
_mediaPlayer.Play();// Trigger play feedback if overlay manager exists
if (_overlayManager)
{
_overlayManager.TriggerFeedback(OverlayManager.Feedback.Play);
}
}
else
{
_mediaPlayer.Pause();
}// Ensure controls are visible
_controlsFade = 1f;
if (_controlsGroup != null)
{
_controlsGroup.alpha = 1f;
_controlsGroup.gameObject.SetActive(true);
}// Update timeline slider
if (_sliderTime != null)
{
_sliderTime.value = 0f;
}
}
3. 修改/添加 OnEnable 方法
private void OnEnable()
{
if (_resetOnEnable)
{
// Start reset coroutine with small delay to ensure everything is initialized
if (_resetCoroutine != null)
{
StopCoroutine(_resetCoroutine);
}
_resetCoroutine = StartCoroutine(DelayedReset());
}
}
4. 添加 OnDisable 方法
private void OnDisable()
{
if (_resetCoroutine != null)
{
StopCoroutine(_resetCoroutine);
_resetCoroutine = null;
}
}
5. 添加 DelayedReset 协程
private IEnumerator DelayedReset()
{
yield return new WaitForSeconds(_resetDelay);
ResetPlayer();
}
6. 修改 Update 方法
// Check if video has finished playing
if (_mediaPlayer != null && _mediaPlayer.Control != null &&
_mediaPlayer.Control.IsFinished())
{
// Reset to beginning but don't auto-play
_mediaPlayer.Control.Seek(0);
_mediaPlayer.Pause();// Update timeline slider
if (_sliderTime != null)
{
_sliderTime.value = 0f;
}
}
7. 修改 Awake 方法(可选)
void Awake()
{
#if UNITY_IOS
Application.targetFrameRate = 60;
#endif// 确保在第一次启用时也会重置
if (_resetOnEnable && enabled && gameObject.activeInHierarchy)
{
StartCoroutine(DelayedReset());
}
}
三、使用说明
1. Inspector 配置
修改后,脚本的 Inspector 面板将显示新的配置选项:
Reset On Enable:是否在激活时重置
Play On Reset:重置后是否自动播放
Reset Delay:重置前的延迟时间(秒)
2. 代码调用
可以通过代码调用 ResetPlayer()
方法手动重置播放器:
GetComponent().ResetPlayer();
3. 注意事项
修改后的脚本保留了所有原始功能
重置操作包括:播放位置、音频状态、UI 控件状态
视频播放结束后会自动回到开头并暂停
四、实现原理
激活重置:通过
OnEnable
触发重置协程延迟处理:使用
DelayedReset
协程确保组件完全初始化完整重置:
ResetPlayer
方法处理所有重置逻辑播放结束检测:在
Update
中检测播放结束状态
五、适用场景
需要重复播放视频的场景
视频播放器需要频繁激活/禁用的场景
需要精确控制播放初始状态的场景
六、完整代码
// UnityEngine.UI was moved to a package in 2019.2.0
// Unfortunately no way to test for this across all Unity versions yet
// You can set up the asmdef to reference the new package, but the package doesn't
// existing in Unity 2017 etc, and it throws an error due to missing reference
#define AVPRO_PACKAGE_UNITYUI
#if (UNITY_2019_2_OR_NEWER && AVPRO_PACKAGE_UNITYUI) || (!UNITY_2019_2_OR_NEWER)using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.EventSystems;
using RenderHeads.Media.AVProVideo;
using RenderHeads.Media.AVProVideo.Demos.UI;//-----------------------------------------------------------------------------
// Copyright 2018-2021 RenderHeads Ltd. All rights reserved.
//-----------------------------------------------------------------------------namespace RenderHeads.Media.AVProVideo.Demos
{
public class MediaPlayerUI : MonoBehaviour
{
[SerializeField] MediaPlayer _mediaPlayer = null;[Header("Options")][SerializeField] float _keyVolumeDelta = 0.05f;
[SerializeField] float _jumpDeltaTime = 5f;
[SerializeField] bool _showOptions = true;
[SerializeField] bool _autoHide = true;
[SerializeField] float _userInactiveDuration = 1.5f;
[SerializeField] bool _useAudioFading = true;[Header("Keyboard Controls")]
[SerializeField] bool _enableKeyboardControls = true;
[SerializeField] KeyCode KeyVolumeUp = KeyCode.UpArrow;
[SerializeField] KeyCode KeyVolumeDown = KeyCode.DownArrow;
[SerializeField] KeyCode KeyTogglePlayPause = KeyCode.Space;
[SerializeField] KeyCode KeyToggleMute = KeyCode.M;
[SerializeField] KeyCode KeyJumpForward = KeyCode.RightArrow;
[SerializeField] KeyCode KeyJumpBack = KeyCode.LeftArrow;[Header("Optional Components")]
[SerializeField] OverlayManager _overlayManager = null;
[SerializeField] MediaPlayer _thumbnailMediaPlayer = null;
[SerializeField] RectTransform _timelineTip = null;[Header("UI Components")]
[SerializeField] RectTransform _canvasTransform = null;
//[SerializeField] Image image = null;
[SerializeField] Slider _sliderTime = null;
[SerializeField] EventTrigger _videoTouch = null;
[SerializeField] CanvasGroup _controlsGroup = null;[Header("UI Components (Optional)")]
[SerializeField] GameObject _liveItem = null;
[SerializeField] Text _textMediaName = null;
[SerializeField] Text _textTimeDuration = null;
[SerializeField] Slider _sliderVolume = null;
[SerializeField] Button _buttonPlayPause = null;
[SerializeField] Button _buttonVolume = null;
[SerializeField] Button _buttonSubtitles = null;
[SerializeField] Button _buttonOptions = null;
[SerializeField] Button _buttonTimeBack = null;
[SerializeField] Button _buttonTimeForward = null;
[SerializeField] RawImage _imageAudioSpectrum = null;
[SerializeField] GameObject _optionsMenuRoot = null;
[SerializeField] HorizontalSegmentsPrimitive _segmentsSeek = null;
[SerializeField] HorizontalSegmentsPrimitive _segmentsBuffered = null;
[SerializeField] HorizontalSegmentsPrimitive _segmentsProgress = null;private bool _wasPlayingBeforeTimelineDrag;
private float _controlsFade = 1f;
private Material _playPauseMaterial;
private Material _volumeMaterial;
private Material _subtitlesMaterial;
private Material _optionsMaterial;
private Material _audioSpectrumMaterial;
private float[] _spectrumSamples = new float[128];
private float[] _spectrumSamplesSmooth = new float[128];
private float _maxValue = 1f;
private float _audioVolume = 1f;private float _audioFade = 0f;
private bool _isAudioFadingUpToPlay = true;
private const float AudioFadeDuration = 0.25f;
private float _audioFadeTime = 0f;private readonly LazyShaderProperty _propMorph = new LazyShaderProperty("_Morph");
private readonly LazyShaderProperty _propMute = new LazyShaderProperty("_Mute");
private readonly LazyShaderProperty _propVolume = new LazyShaderProperty("_Volume");
private readonly LazyShaderProperty _propSpectrum = new LazyShaderProperty("_Spectrum");
private readonly LazyShaderProperty _propSpectrumRange = new LazyShaderProperty("_SpectrumRange");//cyqq
[Header("Activation Behavior")]
[Tooltip("Reset playback to beginning when enabled")]
[SerializeField] bool _resetOnEnable = true;[Tooltip("Automatically start playback after reset")]
[SerializeField] bool _playOnReset = true;[Tooltip("Delay before resetting after enable (seconds)")]
[SerializeField] float _resetDelay = 0.1f;private Coroutine _resetCoroutine;void Awake()
{
#if UNITY_IOS
Application.targetFrameRate = 60;
#endif// 确保在第一次启用时也会重置
if (_resetOnEnable && enabled &
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/928779.shtml
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!相关文章
dede网站打开慢做采集网站赚钱
旧项目用的 vue3-seamless-scroll 怎么写都不生效,一看源码两年没更新了,不想调试,还是自己写吧,再不济问问GPT都会更快一点
scroll.vue
<template><div class"scroll-container" ref"scrollContainerR…
网站做视频的软件营销型网站哪家好
课程背景
2023年,以ChatGPT为代表的接近人类水平的对话机器人,AIGC不断刷爆网络,其强大的内容生成能力给人们带来了巨大的震撼。学术界和产业界也都形成共识:AIGC绝非昙花一现,其底层技术和产业生态已经形成了新的格局…
做损坏文档的网站seo搜索引擎推广
更新Milvus各个组件的配置参数。
调试
您可以在OpenAPI Explorer中直接运行该接口,免去您计算签名的困扰。运行成功后,OpenAPI Explorer可以自动生成SDK代码示例。
编辑调试
授权信息
下表是API对应的授权信息,可以在RAM权限策略语句的…
linux做网站服务器吗中企动力官网网站
侯建业 本文由是石科技CIO侯建业撰写并投递参与“数据猿年度金猿策划活动——2023大数据产业年度优秀CIO榜单及奖项”评选。 大数据产业创新服务媒体 ——聚焦数据 改变商业 是石科技(江苏)有限公司成立于2021年,由国家超级计算无锡中心与…
nodejs做网站的弊端网站备案中是什么意思
Title: 非线性最小二乘问题的数值方法 —— 从高斯-牛顿法到列文伯格-马夸尔特法 (I) 文章目录 前言I. 从高斯-牛顿法II. 到阻尼高斯-牛顿法III. 再到列文伯格-马夸尔特法1. 列文伯格-马夸尔特法的由来2. 列文伯格-马夸尔特法的说明说明一. 迭代方向说明二. 近似于带权重的梯度…
保险业网站建设想卖产品怎么推广宣传
要使用Python批量根据Excel数据绘制饼状图,可以使用pandas和matplotlib库来实现。以下是一个基本的代码示例: import pandas as pd import matplotlib.pyplot as plt
# 读取Excel文件 data pd.read_excel(data.xlsx)
# 提取需要用于绘制饼状图的数据列…
网站建设与服务技能实训心得体会采集网站如何收录
一、可继承的属性
1. 文本相关属性 color:文本的颜色。 font-family:字体系列。 font-size:文本的大小。 font-style:文本的样式。 line-height:行与行之间的垂直间距。 2. 列表相关属性 list-style-type:…
uboot 2020版本下gpio命令的使用
1.在uboot命令行中想要支持gpio的命令,需要打开如下宏CONFIG_CMD_GPIO=y2.选用gpio引脚,作为测试引脚
2.1 查看电路原理图,选用那种soc不和mcu连接的pin,这样可以避免mcu的干扰。
2.2 查看pinmux的配置文件pinmux.…
邢台建网站找谁广安做网站
需求: 创建A项目,有函数和类,将A项目生成DLL动态链接库 创建B项目,使用A项目生成的dll和lib相关文件
正常项目开发.h用于函数声明,.cpp用于函数实现,但是项目开发往往不喜欢将.cpp函数实现的代码发给别人&…
网站推广怎么写牡丹江市西安区建设局网站
读 TCP 协议 RFC-793_rfc 793-CSDN博客TCP灌包中RTT时延与RTO超时关系 - konglingbin - 博客园 TCP的RTT算法
从前面的TCP重传机制我们知道Timeout的设置对于重传非常重要。
设长了,重发就慢,丢了老半天才重发,没有效率,性能差&…
C#定时器深度对比:System.Timers.Timer vs System.Threading.Timer性能实测与选型指南 - 教程
pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …
盛世华诞 举国同庆|热烈庆祝 LEWISAK 英勇重创消火栓 1 周年!
前情提要:我们在星光灿烂下倾听时代的钟声,我们在漫漫长夜中等待黎明的曙光,多少次,我们心潮难平,多少次,我们辗转难眠,多少次,我们都是为了这不同寻常的一天 —— LEWISAK 重创消火栓 1 周年! !
望长空,历…
完整教程:<el-table>构建树形结构
完整教程:<el-table>构建树形结构pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monac…
集团企业网站建设文案wordpress图片不清晰
C、Java、JavaScript和python几个语句的对比介绍 C、Java、JavaScript和python语言的for语句 C、Java和JavaScript的for语句的语法类似如下:
for (初始条件; 循环条件; 循环后操作) { // 循环体代码
}
初始条件是在进入循环之前执行的语句,初始化循环…
如何在markdown中插入折叠框
rt,我使用的方法比较朴素简单。
直接在markdown中写入html的标签即可,如下:
<details>
<summary>标题</summary>
内容
</details>就会呈现以下效果:标题
内容
ESP32-C3 Vscode+ESP-IDF开发环境搭建 保姆级教程 - 教程
ESP32-C3 Vscode+ESP-IDF开发环境搭建 保姆级教程 - 教程pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas…
网站数据模版收费网站推广
为什么80%的码农都做不了架构师?>>> 反正每次来做一个不熟悉的东西,就是各种的search ,前一次去做过一个apache的东西,各种蛋疼,各种不能用。好多的东西也是比较旧了的咯。 这次结合前辈的各种东借西拿,总…
CF2115 VP 记录
CF2115 Div1
B
比较人类智慧.
后面操作会覆盖前面的,考虑对序列 \(b\) 构造一种具有必要性的操作使得满足题目限制,因为一个重要事实是序列 \(a\) 并不唯一,只要对于任意位置,在被覆盖前没有覆盖其他位置的操作,或…