chip-gameV3/Assets/Scripts/Media/VideoUtility.cs

191 lines
6.3 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Serialization;
using UnityEngine.Video;
public class VideoUtility : MonoBehaviour
{
[SerializeField, FormerlySerializedAs("player")] private VideoPlayer _primaryPlayer;
[SerializeField] private VideoPlayer _secondaryPlayer;
[SerializeField, FormerlySerializedAs("audioSource")] private AudioSource _audioSource;
[SerializeField, FormerlySerializedAs("fon")] private VideoClip _menuBackground;
[SerializeField] private List<VideoClip> _characterBackgrounds;
[SerializeField, FormerlySerializedAs("ads")] private VideoClip _ads;
[SerializeField, FormerlySerializedAs("ending")] private VideoClip _ending;
[SerializeField] private float _crossFadeDuration = 1f;
[SerializeField, FormerlySerializedAs("canvas")] private Canvas _canvas;
private static VideoUtility _instance;
private VideoPlayer _activeBackgroundPlayer;
private Coroutine _crossFadeCoroutine;
public static float AdsLength => (float)_instance._ads.length;
public static float VictoryLength => (float)_instance._ending.length;
private void Update()
{
if (Input.GetKeyDown(KeyCode.Alpha5))
PlayFon();
if (Input.GetKeyDown(KeyCode.Alpha6))
PlayAds();
if (Input.GetKeyDown(KeyCode.Alpha7))
PlayEnding();
}
public void Initialize()
{
if (_instance == null)
_instance = this;
ConfigureBackgroundPlayer(_primaryPlayer);
ConfigureBackgroundPlayer(_secondaryPlayer);
_activeBackgroundPlayer = _primaryPlayer;
PlayBackgroundImmediately(_menuBackground);
}
public static void CrossFadeToCharacter(int characterIndex)
{
if (characterIndex < 0 || characterIndex >= _instance._characterBackgrounds.Count)
{
Debug.LogError($"Не найден видеофон для персонажа с индексом {characterIndex}");
return;
}
_instance.StartCrossFade(_instance._characterBackgrounds[characterIndex]);
}
public static void CrossFadeToMenu()
=> _instance.StartCrossFade(_instance._menuBackground);
public static void PlayFon()
=> CrossFadeToMenu();
public static void PlayAds()
=> _instance.PlayForeground(_instance._ads);
public static void PlayEnding()
=> _instance.PlayForeground(_instance._ending);
private void StartCrossFade(VideoClip targetClip)
{
if (targetClip == null)
{
Debug.LogError("Не назначен видеофон для переключения");
return;
}
NormalizeInterruptedCrossFade();
if (_activeBackgroundPlayer.clip == targetClip && _activeBackgroundPlayer.isPlaying)
return;
_crossFadeCoroutine = StartCoroutine(CrossFadeCoroutine(targetClip));
}
private IEnumerator CrossFadeCoroutine(VideoClip targetClip)
{
VideoPlayer outgoingPlayer = _activeBackgroundPlayer;
VideoPlayer incomingPlayer = GetInactivePlayer();
ConfigureBackgroundPlayer(incomingPlayer);
incomingPlayer.Stop();
incomingPlayer.clip = targetClip;
incomingPlayer.targetCameraAlpha = 0f;
incomingPlayer.Prepare();
//while (incomingPlayer.isPrepared == false)
// yield return null;
incomingPlayer.Play();
float elapsedTime = 0f;
float duration = Mathf.Max(_crossFadeDuration, 0.01f);
while (elapsedTime < duration)
{
elapsedTime += Time.unscaledDeltaTime;
float progress = Mathf.Clamp01(elapsedTime / duration);
incomingPlayer.targetCameraAlpha = progress;
outgoingPlayer.targetCameraAlpha = 1f - progress;
yield return null;
}
incomingPlayer.targetCameraAlpha = 1f;
outgoingPlayer.targetCameraAlpha = 0f;
outgoingPlayer.Stop();
_activeBackgroundPlayer = incomingPlayer;
_crossFadeCoroutine = null;
}
private void NormalizeInterruptedCrossFade()
{
if (_crossFadeCoroutine == null)
return;
StopCoroutine(_crossFadeCoroutine);
_crossFadeCoroutine = null;
_activeBackgroundPlayer = _primaryPlayer.targetCameraAlpha >= _secondaryPlayer.targetCameraAlpha
? _primaryPlayer
: _secondaryPlayer;
VideoPlayer inactivePlayer = GetInactivePlayer();
_activeBackgroundPlayer.targetCameraAlpha = 1f;
inactivePlayer.targetCameraAlpha = 0f;
inactivePlayer.Stop();
}
private VideoPlayer GetInactivePlayer()
=> _activeBackgroundPlayer == _primaryPlayer ? _secondaryPlayer : _primaryPlayer;
private void PlayBackgroundImmediately(VideoClip clip)
{
_secondaryPlayer.Stop();
_secondaryPlayer.targetCameraAlpha = 0f;
_activeBackgroundPlayer.Stop();
_activeBackgroundPlayer.clip = clip;
_activeBackgroundPlayer.targetCameraAlpha = 1f;
_activeBackgroundPlayer.Play();
}
private void ConfigureBackgroundPlayer(VideoPlayer videoPlayer)
{
videoPlayer.renderMode = VideoRenderMode.CameraFarPlane;
videoPlayer.targetCamera = _primaryPlayer.targetCamera;
videoPlayer.aspectRatio = _primaryPlayer.aspectRatio;
videoPlayer.isLooping = true;
videoPlayer.playOnAwake = false;
videoPlayer.audioOutputMode = VideoAudioOutputMode.None;
}
private void PlayForeground(VideoClip clip)
{
NormalizeInterruptedCrossFade();
_primaryPlayer.Stop();
_secondaryPlayer.Stop();
_primaryPlayer.renderMode = VideoRenderMode.CameraNearPlane;
_primaryPlayer.targetCameraAlpha = 1f;
_primaryPlayer.isLooping = false;
_primaryPlayer.clip = clip;
_primaryPlayer.audioOutputMode = VideoAudioOutputMode.AudioSource;
_primaryPlayer.EnableAudioTrack(0, true);
_primaryPlayer.SetTargetAudioSource(0, _audioSource);
_audioSource.Stop();
StartCoroutine(PrepareAndPlayForeground());
}
private IEnumerator PrepareAndPlayForeground()
{
_primaryPlayer.Prepare();
while (_primaryPlayer.isPrepared == false)
yield return null;
_audioSource.Play();
_primaryPlayer.Play();
}
}