using UnityEngine; using UnityEngine.Video; public class Game360VideoBackground : MonoBehaviour { [SerializeField] private VideoClip videoClip; [SerializeField] private int renderTextureSize = 2048; [SerializeField] private bool muteVideoAudio = true; [SerializeField, Range(0f, 360f)] private float skyboxRotationDegrees = 0f; [SerializeField, Range(0f, 8f)] private float skyboxExposure = 1f; private GameObject videoPlayerObject; private Material skyboxMaterial; private Material previousSkybox; private RenderTexture renderTexture; private VideoPlayer videoPlayer; private void Awake() { if (videoClip == null) { Debug.LogWarning("[Game360VideoBackground] videoClip is not assigned."); return; } CreateSkyboxMaterial(); CreateVideoPlayer(); } private void OnDestroy() { if (videoPlayer != null) { videoPlayer.prepareCompleted -= OnVideoPrepared; videoPlayer.errorReceived -= OnVideoError; } if (renderTexture != null) { renderTexture.Release(); Destroy(renderTexture); } RenderSettings.skybox = previousSkybox; DynamicGI.UpdateEnvironment(); if (skyboxMaterial != null) Destroy(skyboxMaterial); if (videoPlayerObject != null) Destroy(videoPlayerObject); } private void CreateSkyboxMaterial() { renderTexture = new RenderTexture(renderTextureSize, renderTextureSize / 2, 0, RenderTextureFormat.ARGB32) { name = "Game360VideoRenderTexture", wrapMode = TextureWrapMode.Clamp, filterMode = FilterMode.Bilinear, }; renderTexture.Create(); previousSkybox = RenderSettings.skybox; skyboxMaterial = new Material(ResolveSkyboxShader()) { name = "Game360VideoMaterial", }; skyboxMaterial.SetTexture("_MainTex", renderTexture); skyboxMaterial.SetFloat("_ImageType", 0f); skyboxMaterial.SetFloat("_Mapping", 0f); skyboxMaterial.SetFloat("_Layout", 0f); ApplySkyboxSettings(); RenderSettings.skybox = skyboxMaterial; DynamicGI.UpdateEnvironment(); } private void CreateVideoPlayer() { videoPlayerObject = new GameObject("[360 Video Skybox Player]"); videoPlayerObject.transform.SetParent(transform, false); videoPlayer = videoPlayerObject.AddComponent(); videoPlayer.playOnAwake = false; videoPlayer.isLooping = true; videoPlayer.waitForFirstFrame = true; videoPlayer.renderMode = VideoRenderMode.RenderTexture; videoPlayer.targetTexture = renderTexture; videoPlayer.clip = videoClip; videoPlayer.audioOutputMode = muteVideoAudio ? VideoAudioOutputMode.None : VideoAudioOutputMode.Direct; videoPlayer.prepareCompleted += OnVideoPrepared; videoPlayer.errorReceived += OnVideoError; videoPlayer.Prepare(); } private static Shader ResolveSkyboxShader() { return Shader.Find("Skybox/Panoramic") ?? Shader.Find("Skybox/6 Sided") ?? Shader.Find("Standard"); } private void OnVideoPrepared(VideoPlayer source) { source.Play(); } private void OnValidate() { ApplySkyboxSettings(); } private void ApplySkyboxSettings() { if (skyboxMaterial == null) return; skyboxMaterial.SetFloat("_Exposure", skyboxExposure); skyboxMaterial.SetFloat("_Rotation", skyboxRotationDegrees); DynamicGI.UpdateEnvironment(); } private static void OnVideoError(VideoPlayer source, string message) { Debug.LogWarning($"[Game360VideoBackground] VideoPlayer error: {message}"); } }