Udemy-Unity制作类暗黑破坏神游戏记录-P75

2024-09-15
91看过
为了每次传送时都拥有淡入淡出的效果,直接在游戏中通过脚本实例化一个持久对象,在场景切换时会一直存在,重复调用。调用Fader脚本时,先将之前的测试代码给删除。



PeristentObjectSpawner:

  1. using System.Collections;
  2. using System.Collections.Generic;
  3. using UnityEngine;
  4. namespace RPG.Core
  5. {
  6.     //在游戏运行时创建并保留一个持久对象,该对象在场景切换时不会被销毁。
  7.     public class PeristentObjectSpawner : MonoBehaviour
  8.     {
  9.         [SerializeField] GameObject persistentObjectPrefab;// 持久对象的预制件
  10.         static bool hasSpawned = false;// 静态变量,用于标记是否已经生成过持久对象
  11.         private void Awake()
  12.         {
  13.             if (hasSpawned) return; // 如果已经生成过持久对象,则直接返回,不再执行下面的代码
  14.             SpawnPersistentObjects();// 生成持久对象
  15.             hasSpawned = true;// 标记已经生成过持久对象
  16.         }
  17.         private void SpawnPersistentObjects()
  18.         {
  19.             // 实例化持久对象的预制件
  20.             GameObject persistentObject = Instantiate(persistentObjectPrefab);
  21.             DontDestroyOnLoad(persistentObject);// 设置实例化的对象为持久对象,即在场景切换时不会被销毁
  22.         }
  23.     }
  24. }
复制代码
Fader:

  1. using System.Collections;
  2. using System.Collections.Generic;
  3. using Unity.VisualScripting;
  4. using UnityEngine;
  5. namespace RPG.SceneMangement
  6. {
  7.     // Fader 类用于在场景加载时实现淡入淡出效果
  8.     public class Fader : MonoBehaviour
  9.     {
  10.         CanvasGroup canvasGroup; // 用于控制画布的透明度
  11.         private void Start()
  12.         {
  13.             canvasGroup = GetComponent<CanvasGroup>();
  14.            
  15.         }
  16.         
  17.         public IEnumerator FadeOut(float time) // 公共协程方法:实现淡出效果
  18.         {
  19.             while(canvasGroup.alpha <1)
  20.             {
  21.                 canvasGroup.alpha += Time.deltaTime / time;// 逐渐增加透明度
  22.                 yield return null;// 等待一帧
  23.             }
  24.         }
  25.         public IEnumerator FadeIn(float time)// 公共协程方法:实现淡入效果
  26.         {
  27.             while (canvasGroup.alpha > 0) // 当透明度大于 0 时持续减少透明度
  28.             {
  29.                 canvasGroup.alpha -= Time.deltaTime / time;// 逐渐减少透明度
  30.                 yield return null;// 等待一帧
  31.             }
  32.         }
  33.     }
  34. }
复制代码
Portal:

  1. using System.Collections;
  2. using System.Collections.Generic;
  3. using Unity.VisualScripting;
  4. using UnityEngine;
  5. using UnityEngine.AI;
  6. using UnityEngine.SceneManagement;
  7. namespace RPG.SceneMangement
  8. {
  9.     //// Portal触发传送 类用于在玩家进入触发器时异步加载新场景
  10.     public class Portal : MonoBehaviour
  11.     {
  12.         enum DestinationIdentifier
  13.         {
  14.             A, B, C,D,E
  15.         }
  16.         [SerializeField] int sceneToLoad = 1;// 要加载的场景索引,默认为1
  17.         [SerializeField] Transform spawnPoint;// 玩家传送后的出生点位置和旋转
  18.         [SerializeField] DestinationIdentifier destination;//给触发器设置目的地
  19.         [SerializeField] float fadeOutTime = 1f;//淡出时间
  20.         [SerializeField] float fadeInTime = 2f;//淡入时间
  21.         [SerializeField] float fadeWaitTime = 0.5f;//等待时间
  22.         // 当触发器碰撞到其他对象时调用
  23.         private void OnTriggerEnter(Collider other)
  24.         {
  25.             // 如果碰撞的对象标签是 "Player"
  26.             if (other.tag == "Player")
  27.             {
  28.                 // 启动协程来处理场景过渡
  29.                 StartCoroutine(Transition());
  30.             }
  31.         }
  32.         // 协程方法:处理场景的异步加载和玩家的位置更新
  33.         private IEnumerator Transition()
  34.         {
  35.             if(sceneToLoad <0)// 如果场景索引无效(小于0),则退出协程
  36.             {
  37.                 yield break;
  38.             }
  39.             
  40.             
  41.             DontDestroyOnLoad(gameObject);// 确保 Portal 对象在加载新场景时不会被销毁
  42.             Fader fader = FindObjectOfType<Fader>();// 查找场景中的第一个 Fader 实例
  43.             yield return fader.FadeOut(fadeOutTime);// 执行淡出效果,等待淡出完成
  44.             yield return SceneManager.LoadSceneAsync(sceneToLoad); // 异步加载指定的场景
  45.            
  46.             Portal otherPortal = GetOtherPortal(); // 查找另一个 Portal 对象(目标场景中的传送门)
  47.             UpdatePlayer(otherPortal);// 更新玩家位置和旋转
  48.            
  49.             yield return new WaitForSeconds(fadeWaitTime);// 等待指定的时间(用于过渡或延迟)
  50.             yield return fader.FadeIn(fadeInTime);// 执行淡入效果,等待淡入完成
  51.             Destroy(gameObject);// 场景加载完成后,销毁当前的 Portal 对象,防止两个场景的Portal重叠出现问题
  52.         }
  53.         // 更新玩家的位置和旋转,使其在目标场景中出现在正确的位置
  54.         private void UpdatePlayer(Portal otherPortal)
  55.         {
  56.             GameObject player = GameObject.FindWithTag("Player");// 查找场景中的玩家对象
  57.             // 使用 Warp 方法将玩家传送到新的出生点位置
  58.             player.GetComponent<NavMeshAgent>().Warp(otherPortal.spawnPoint.position);
  59.             // 设置玩家的旋转角度
  60.             player.transform.rotation = otherPortal.spawnPoint.rotation;
  61.         }
  62.         // 查找并返回目标场景中的另一个 Portal 对象
  63.         private Portal GetOtherPortal()
  64.         {
  65.             // 遍历所有的 Portal 对象
  66.             foreach (Portal portal in FindObjectsOfType<Portal>())
  67.             {
  68.                
  69.                 if (portal == this) continue;// 跳过当前的 Portal 对象
  70.                 // 如果两个触发传送的目的地设置不一样,则跳过该对象,继续检查下一个 portal
  71.                 if (portal.destination != destination) continue;
  72.                 return portal; // 返回第一个找到的不同的 Portal 对象
  73.             }
  74.             return null;// 如果没有找到其他 Portal,则返回 null
  75.         }
  76.       
  77.     }
  78. }
复制代码


回复

举报

 
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

快速回复 返回顶部 返回列表