赞
踩
博主是做安全教育行业的,在开发2d项目中经常会用到视频特效,如果用序列帧动画来做就会很耗内存,进入程序加载时间也会过长,如果用视频来代替这个消耗和加载就下降了一半还多,但是在开发过程中遇到了一个切换视频的bug,例如我现在有一个完整的动画特效,一个是不可循环的,一个是可以循环的,如果用一个视频播放器来播放,切换视频就会出现卡顿的现象,这个问题 我在网上找了好久没有发现比较好的解决方法,经过我个人研究解决了这个问题,废话不多说下面正式干货时间:
首先我们的美术人员给了我两个小的特效视频,不循环和可循环他们组合在一起就是一个完整的特效
正常来看我肯定要先播放第一个,等待第一个播放完毕在播放第二个,但是问题就出现了,在第一个播放完毕播放第二个的时候就会出现加载卡顿一下,这个时候我想到了用两个播放器同时加载两个视频,但是用同一个Render Texture
第一个播放器用来加载不循环的视频
第二个播放器用来加载循环的视频
但是用同一个Render Texture
在第一个视频结束后添加委托事件,播放第二个视频代码如下
using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.Video; using System; public class sp : MonoBehaviour { public static sp spins; public VideoClip []VideoClips;//视频源 public VideoPlayer []VideoPlayers;//播放器 public static Dictionary<string, VideoClip> VideoClipslist = new Dictionary<string, VideoClip>();//用来方便调用视频源,你很可能有很多视频源 VideoPlayer.EventHandler ve;//这个是给视频添加委托的必要,不然就会报错,可能有其他的解决方法,但是目前我没找到 private void Awake() { spins = this; for (int i = 0; i < VideoClips.Length; i++)//这个就是把视频源添加到字典里面 { VideoClipslist.Add(VideoClips[i].name, VideoClips[i]); } //重点来了 ve = (a) => { VideoPlayers[1].Play(); };//把这个委托赋值,大括号内可以写你想让第一个视频播放完做的事情,我只是播放视频,所以就只写了一个视频播放的方法 VideoPlayers[0].loopPointReached += ve;//这个就是把委托加入这个视频的事件内, }
第一步完成,下面这步就是要进入下级界面如何切换视频的问题代码如下
void Start() {//这个是使用下面的方法 Gy_sp2(VideoClipslist["首页不循环"],VideoClipslist["首页循环"],false,true); VideoPlayers[0].Play(); } //这个方法是把两个播放器清空然后预加载上新的视频 public void Gy_sp2(VideoClip videoClip1, VideoClip videoClip2, bool isloop1,bool isloop2)//加载两个视频 { VideoPlayers[0].Stop(); VideoPlayers[1].Stop(); VideoPlayers[0].clip = videoClip1; VideoPlayers[1].clip = videoClip2; VideoPlayers[0].isLooping = isloop1; VideoPlayers[1].isLooping = isloop2; VideoPlayers[0].Prepare(); VideoPlayers[1].Prepare(); }
切换界面的时候只需要把所有RawImage都加入同一个Render Texture
在视频切换的时候调用这个方法就可以了,调用方法参考start里面的方法,只需要改一下视频源名称,切换一下ui,并加入一个过渡效果就完成了。
下面这个是一个扩展跟上一个差不多
/// <summary> /// 切换加载视频也可以用这个 /// </summary> /// <param name="_videoClip">视频源</param> /// <param name="_videoPlayer">播放器</param> /// <param name="_isloop">是否循环</param> /// <param name="_loopPointReached">在视频播放完后添加事件,这个事件只会执行一次</param> public void Gy_sp(VideoClip _videoClip, VideoPlayer _videoPlayer, bool _isloop = false, Action _loopPointReached = null)//加载一次 { _videoPlayer.Stop(); _videoPlayer.clip = _videoClip; _videoPlayer.isLooping = _isloop; _videoPlayer.Prepare(); if (_loopPointReached != null) { VideoPlayer.EventHandler eventHandler = null; eventHandler = (a) => { _loopPointReached(); _videoPlayer.loopPointReached -= eventHandler; }; _videoPlayer.loopPointReached += eventHandler; } }
好了就到这里,本人第一次写,希望帮助到大家,如果转载请注明出处。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。