我正在编写一个脚本,其中有一个视频分为3个部分,分别有3个音频,在前一个完成后运行一个(视频和音频),但视频需要播放只有拿着一把钥匙(在我的情况下是"空间")我在按下空格时成功制作了视频和音频:
if (Input.GetButton ("Jump")) {
vp.Play ();
if (!ASource.isPlaying) {
ASource.Play ();
}
暂停而不是:
else {
vp.Pause ();
ASource.Pause ();
}
但它很难,我正在寻找一种让它顺利暂停/恢复的方法,我尝试制作一个功能:
public void videoPause() {
for (i = 0; i < 10; i++) {
vp.playbackSpeed = vp.playbackSpeed / i;
}
}
同样的简历,但有*而不是和i--但它没有工作,任何想法如何让它工作吗?
答案 0 :(得分:0)
见:
for (i = 0; i < 10; i++) {
vp.playbackSpeed = vp.playbackSpeed / i;
}
你正在一帧中完成所有这些,因此无法看到效果。将其移至协程函数,然后在每个for循环后生成,然后您将看到效果。
这样的事情:
for (i = 0; i < 10; i++) {
vp.playbackSpeed = vp.playbackSpeed / i;
yield return null; //Wait for a frame
//OR
yield return new WaitForSeconds(0.1f); //Wait for 0.1 sec
}
您现在应该看到该代码的效果,但不会顺利进行。
怎么做:
lerp函数通常用于这样的事情。 Mathf.Lerp
适用于此。
VideoPlayer.playbackSpeed
的默认/正常值为1
。 2
的值更快,0
更慢。
VideoPlayer
,请将1
从0
暂停到VideoPlayer
放慢速度然后暂停它。0
时,请慢慢恢复,然后从1
翻译到IEnumerator SmoothlyPauseOverTimeCOR(VideoPlayer targetVp, float duration)
{
float counter = 0;
//Get the current playbackSpeed of the VideoPlayer
float startSpeed = targetVp.playbackSpeed;
//We want to go to 0 but within duration
float endSpeed = 0;
//Normal speed to slow speed
while (counter < duration)
{
counter += Time.deltaTime;
targetVp.playbackSpeed = Mathf.Lerp(startSpeed, endSpeed, counter / duration);
yield return null;
}
//Now, do the actual pause
targetVp.Pause();
executingPause = false;
}
IEnumerator SmoothlyResumeOverTimeCOR(VideoPlayer targetVp, float duration)
{
float counter = 0;
//Get the current playbackSpeed of the VideoPlayer
//float startSpeed = targetVp.playbackSpeed;
float startSpeed = 0f;
//We want to go to 1 but within duration
float endSpeed = 1;
//Do the actual resume
targetVp.Play();
//Slow speed to normal Speed
while (counter < duration)
{
counter += Time.deltaTime;
targetVp.playbackSpeed = Mathf.Lerp(startSpeed, endSpeed, counter / duration);
yield return null;
}
}
。以下是两个协程函数,它们应该缓慢而平稳地处理暂停和恢复功能。
Coroutine pauseCoroutine;
Coroutine resumeCoroutine;
bool executingPause = false;
void SmoothlyPauseOverTime(VideoPlayer targetVp, float duration)
{
//Stop old coroutines before starting a new one
if (pauseCoroutine != null)
StopCoroutine(pauseCoroutine);
if (resumeCoroutine != null)
StopCoroutine(resumeCoroutine);
executingPause = true;
pauseCoroutine = StartCoroutine(SmoothlyPauseOverTimeCOR(targetVp, duration));
}
void SmoothlyResumeOverTime(VideoPlayer targetVp, float duration)
{
if (pauseCoroutine != null)
StopCoroutine(pauseCoroutine);
//Stop old coroutines before starting a new one
if (resumeCoroutine != null)
StopCoroutine(resumeCoroutine);
resumeCoroutine = StartCoroutine(SmoothlyResumeOverTimeCOR(targetVp, duration));
}
在开始新的协程之前,您需要确保先前的协同程序功能未运行。停止旧的,然后在需要时开始新的。下面的两个函数应该处理它并能够安全地调用上面的函数:
Update
您的void Update()
{
if (Input.GetButton("Jump"))
{
if (!vp.isPlaying)
{
Debug.Log("Resumed Playing");
SmoothlyResumeOverTime(vp, 0.8f);
}
}
else
{
if (!executingPause && vp.isPlaying)
{
Debug.Log("Paused Playing");
SmoothlyPauseOverTime(vp, 0.8f);
}
}
}
功能:
Start
您的Update
功能:
基于this。它准备视频,但在上面的//Raw Image to Show Video Images [Assign from the Editor]
public RawImage image;
//Video To Play [Assign from the Editor]
public VideoClip videoToPlay;
private VideoPlayer vp;
private VideoSource videoSource;
//Audio
private AudioSource aS;
// Use this for initialization
void Start()
{
Application.runInBackground = true;
StartCoroutine(playVideo());
}
IEnumerator playVideo()
{
//Add VideoPlayer to the GameObject
vp = gameObject.AddComponent<VideoPlayer>();
//Add AudioSource
aS = gameObject.AddComponent<AudioSource>();
//Disable Play on Awake for both Video and Audio
vp.playOnAwake = false;
aS.playOnAwake = false;
//We want to play from video clip not from url
vp.source = VideoSource.VideoClip;
//Set Audio Output to AudioSource
vp.audioOutputMode = VideoAudioOutputMode.AudioSource;
//Assign the Audio from Video to AudioSource to be played
vp.EnableAudioTrack(0, true);
vp.SetTargetAudioSource(0, aS);
//Set video To Play then prepare Audio to prevent Buffering
vp.clip = videoToPlay;
vp.Prepare();
//Wait until video is prepared
while (!vp.isPrepared)
{
Debug.Log("Preparing Video");
yield return null;
}
Debug.Log("Done Preparing Video");
//Assign the Texture from Video to RawImage to be displayed
image.texture = vp.texture;
}
函数中按下空格键之前不会播放它:
public VideoPlayer vp;
<强>用法强>:
SmoothlyPauseOverTime(vp, 0.8f);
.....
将在0.8秒内缓慢暂停
SmoothlyResumeOverTime(vp, 0.8f);
将在0.8秒内缓慢恢复
sed -i '/y$/ {N; s/y\ny/ya\ny/; P; D}' a6s
答案 1 :(得分:0)
videoPause方法中的 for 循环会立即运行它,而不是按照您希望的方式运行。您可以尝试在一段时间内(例如5秒)更新更新方法中的播放速度。像这样的东西
// set when the pause is triggered
videoPauseTime = Time.realtimeSinceStartup;
// duration in seconds to smoothen the pause
duration = 5
public void Update() {
float t = (Time.realtimeSinceStartup - videoPauseTime) / duration;
if(t>1.0f)
t = 1.0f;
vp.playbackSpeed = Mathf.Lerp (vp.playbackSpeed,0.0f,t)
}
请注意,此代码仅供参考, t 将超出1.0,这是您不想要的;因此条件 t> 1.0F 即可。另外,我假设playbackSpeed为0使视频停止播放。