⭐ Unity Pico PXR_SDK转场淡入淡出

发布于:2024-10-17 ⋅ 阅读:(7) ⋅ 点赞:(0)
  1. PXR_ScreenFade 脚本:官方SDK 脚本实现了屏幕的淡入淡出功能,封装了 CloseEyesOpenEyes 方法,可以通过传入 Action 执行淡入淡出完成后的逻辑。

  2. FadeController 脚本

    • 通过 GetComponent 获取 PXR_ScreenFade 组件,并调用 CloseEyes() 和 OpenEyes() 来控制屏幕的淡入淡出。
    • 在淡入淡出结束后,通过传递的回调函数执行相关的操作  
  3. /*******************************************************************************
    Copyright © 2015-2022 Pico Technology Co., Ltd.All rights reserved.  
    
    NOTICE:All information contained herein is, and remains the property of 
    Pico Technology Co., Ltd. The intellectual and technical concepts 
    contained hererin are proprietary to Pico Technology Co., Ltd. and may be 
    covered by patents, patents in process, and are protected by trade secret or 
    copyright law. Dissemination of this information or reproduction of this 
    material is strictly forbidden unless prior written permission is obtained from
    Pico Technology Co., Ltd. 
    *******************************************************************************/
    
    using System;
    using System.Collections;
    using UnityEngine;
    
    namespace Unity.XR.PXR
    {
        public class PXR_ScreenFade : MonoBehaviour
        {
            [Tooltip("Define the duration of screen fade.")]
            public float fadeTime = 5.0f;
            [Tooltip("Define the color of screen fade.")]
            public Color fadeColor = new Color(0.0f, 0.0f, 0.0f, 1.0f);
            public int renderQueue = 5000;
            private MeshRenderer fadeMeshRenderer;
            private MeshFilter fadeMeshFilter;
            private Material fadeMaterial = null;
            private bool isFading = false;
            private float currentAlpha;
            private float nowFadeAlpha;
    
            void Awake()
            {
                CreateFadeMesh();
                SetCurrentAlpha(0);
            }
            void OnEnable()
            {
                StartCoroutine(ScreenFade(1, 0));
            }
            void OnDestroy()
            {
                DestoryFadeMesh();
            }
    
            private void CreateFadeMesh()
            {
                fadeMaterial = new Material(Shader.Find("PXR_SDK/PXR_Fade"));
                fadeMeshFilter = gameObject.AddComponent<MeshFilter>();
                fadeMeshRenderer = gameObject.AddComponent<MeshRenderer>();
    
                var mesh = new Mesh();
                fadeMeshFilter.mesh = mesh;
    
                Vector3[] vertices = new Vector3[4];
    
                float width = 2f;
                float height = 2f;
                float depth = 1f;
    
                vertices[0] = new Vector3(-width, -height, depth);
                vertices[1] = new Vector3(width, -height, depth);
                vertices[2] = new Vector3(-width, height, depth);
                vertices[3] = new Vector3(width, height, depth);
    
                mesh.vertices = vertices;
    
                int[] tri = new int[6];
    
                tri[0] = 0;
                tri[1] = 2;
                tri[2] = 1;
    
                tri[3] = 2;
                tri[4] = 3;
                tri[5] = 1;
    
                mesh.triangles = tri;
    
                Vector3[] normals = new Vector3[4];
    
                normals[0] = -Vector3.forward;
                normals[1] = -Vector3.forward;
                normals[2] = -Vector3.forward;
                normals[3] = -Vector3.forward;
    
                mesh.normals = normals;
    
                Vector2[] uv = new Vector2[4];
    
                uv[0] = new Vector2(0, 0);
                uv[1] = new Vector2(1, 0);
                uv[2] = new Vector2(0, 1);
                uv[3] = new Vector2(1, 1);
    
                mesh.uv = uv;
            }
    
            private void DestoryFadeMesh()
            {
                if (fadeMeshRenderer != null)
                    Destroy(fadeMeshRenderer);
    
                if (fadeMaterial != null)
                    Destroy(fadeMaterial);
    
                if (fadeMeshFilter != null)
                    Destroy(fadeMeshFilter);
            }
    
            public void SetCurrentAlpha(float alpha)
            {
                currentAlpha = alpha;
                SetMaterialAlpha();
            }
    
            IEnumerator ScreenFade(float startAlpha, float endAlpha)
            {
                float elapsedTime = 0.0f;
                while (elapsedTime < fadeTime)
                {
                    elapsedTime += Time.deltaTime;
                    nowFadeAlpha = Mathf.Lerp(startAlpha, endAlpha, Mathf.Clamp01(elapsedTime / fadeTime));
                    SetMaterialAlpha();
                    yield return new WaitForEndOfFrame();
                }
            }
    
            private void SetMaterialAlpha()
            {
                Color color = fadeColor;
                color.a = Mathf.Max(currentAlpha, nowFadeAlpha);
                isFading = color.a > 0;
                if (fadeMaterial != null)
                {
                    fadeMaterial.color = color;
                    fadeMaterial.renderQueue = renderQueue;
                    fadeMeshRenderer.material = fadeMaterial;
                    fadeMeshRenderer.enabled = isFading;
                }
            }
    
            public void CloseEyes(Action _action)
            {
                StartCoroutine(ScreenFade(0, 1, _action));
            }
    
            IEnumerator ScreenFade(float startAlpha, float endAlpha, Action action)
            {
                float elapsedTime = 0.0f;
                while (elapsedTime < fadeTime)
                {
                    elapsedTime += Time.deltaTime;
                    nowFadeAlpha = Mathf.Lerp(startAlpha, endAlpha, Mathf.Clamp01(elapsedTime / fadeTime));
                    SetMaterialAlpha();
                    yield return new WaitForEndOfFrame();
                }
                action.Invoke();
            }
    
            public void OpenEyes(Action _action)
            {
                StartCoroutine(ScreenFadeOpen(1, 0, _action));
            }
    
            IEnumerator ScreenFadeOpen(float startAlpha, float endAlpha, Action action)
            {
                float elapsedTime = 0.0f;
                while (elapsedTime < fadeTime)
                {
                    elapsedTime += Time.deltaTime;
                    nowFadeAlpha = Mathf.Lerp(startAlpha, endAlpha, Mathf.Clamp01(elapsedTime / fadeTime));
                    SetMaterialAlpha();
                    yield return new WaitForEndOfFrame();
                }
    
                action.Invoke();
            }
    
            IEnumerator ScreenFade(float closeTime, float openTime, Action action, Action complete)
            {
                float elapsedTime = 0.0f;
                while (elapsedTime < closeTime)
                {
                    elapsedTime += Time.deltaTime;
                    nowFadeAlpha = Mathf.Lerp(0, 1, Mathf.Clamp01(elapsedTime / closeTime));
                    SetMaterialAlpha();
                    yield return new WaitForEndOfFrame();
                }
                action.Invoke();
    
                float elapsedTime2 = 0.0f;
                while (elapsedTime2 < openTime)
                {
                    elapsedTime2 += Time.deltaTime;
                    nowFadeAlpha = Mathf.Lerp(1, 0, Mathf.Clamp01(elapsedTime2 / openTime));
                    SetMaterialAlpha();
                    yield return new WaitForEndOfFrame();
                }
                complete?.Invoke();
            }
    
            public void Blink(float closeTime, float openTime, Action action, Action complete = null)
            {
                StartCoroutine(ScreenFade(closeTime, openTime, action, complete));
            }
        }
    }
    
    using UnityEngine;
    using Unity.XR.PXR;  // 引入PXR_ScreenFade的命名空间
    
    public class FadeController : MonoBehaviour
    {
        private PXR_ScreenFade screenFade;
    
        void Start()
        {
            // 获取附加在同一对象上的PXR_ScreenFade组件,或者通过其他方式获取
            screenFade = GetComponent<PXR_ScreenFade>();
    
            // 触发淡出效果
            if (screenFade != null)
            {
                // 画面淡入:从当前状态到完全黑屏(1为全黑)
                screenFade.CloseEyes(() => 
                {
                    Debug.Log("淡入结束,画面已完全黑屏");
                    // 在淡入结束时执行一些操作
                });
    
                // 可以在一定时间后触发淡出效果,比如在5秒后淡出
                Invoke("OpenScreen", 5f);
            }
        }
    
        void OpenScreen()
        {
            // 画面淡出:从完全黑屏(1)回到正常视图(0)
            screenFade.OpenEyes(() => 
            {
                Debug.Log("淡出结束,画面已恢复正常");
                // 在淡出结束时执行一些操作
            });
        }
    }
    

    官方文档链接:PICO Unity Integration SDK 画面淡入淡出