Unity跨场景不销毁相机无法跟随玩家位置的问题求助
解决跨场景相机无法跟随玩家的问题
核心问题
跨场景保留的相机持有的target引用是第一个场景的玩家对象,切换到第二个场景后,原玩家对象被销毁,target变为null,导致相机跟随逻辑完全失效。
具体解决方案
方案1:场景加载后自动查找玩家
修改相机代码,监听场景加载完成事件,自动定位新场景中的玩家对象:
private Vector3 offset = new Vector3(0f, 0f, -10f); private float smoothTime = 0.25f; private Vector3 velocity = Vector3.zero; [SerializeField] GameObject target; // 给玩家对象设置专属标签,比如"Player" private const string PlayerTag = "Player"; void Start() { // 初始场景查找玩家 FindPlayer(); } void OnEnable() { // 监听场景加载完成事件 UnityEngine.SceneManagement.SceneManager.sceneLoaded += OnSceneLoaded; } void OnDisable() { // 移除监听,避免内存泄漏 UnityEngine.SceneManagement.SceneManager.sceneLoaded -= OnSceneLoaded; } void OnSceneLoaded(UnityEngine.SceneManagement.Scene scene, UnityEngine.SceneManagement.LoadSceneMode mode) { // 场景切换后重新查找玩家 FindPlayer(); } void FindPlayer() { GameObject player = GameObject.FindGameObjectWithTag(PlayerTag); if (player != null) { target = player; } else { Debug.LogError("当前场景未找到标签为Player的玩家对象"); } } void Update() { if (target == null) return; // 避免空引用报错 Vector3 targetPosition = target.transform.position + offset; transform.position = Vector3.SmoothDamp(transform.position, targetPosition, ref velocity, smoothTime); }
配套操作:给第二个场景中的玩家对象在Inspector面板里设置Tag为Player(没有的话直接创建该标签)。
方案2:用单例模式绑定玩家
如果玩家需要跨场景保留,或者每个场景的玩家都用单例管理,可以让相机直接通过单例获取玩家引用:
首先给玩家脚本添加单例逻辑:
public class Player : MonoBehaviour { public static Player Instance; void Awake() { if (Instance != null && Instance != this) { Destroy(gameObject); return; } Instance = this; // 如果玩家需要跨场景保留,就保留下面这句,否则删除 DontDestroyOnLoad(gameObject); } }
然后修改相机代码,直接通过单例获取玩家:
private Vector3 offset = new Vector3(0f, 0f, -10f); private float smoothTime = 0.25f; private Vector3 velocity = Vector3.zero; private Transform targetTransform; void Start() { BindPlayerTransform(); } void OnEnable() { UnityEngine.SceneManagement.SceneManager.sceneLoaded += OnSceneLoaded; } void OnDisable() { UnityEngine.SceneManagement.SceneManager.sceneLoaded -= OnSceneLoaded; } void OnSceneLoaded(UnityEngine.SceneManagement.Scene scene, UnityEngine.SceneManagement.LoadSceneMode mode) { BindPlayerTransform(); } void BindPlayerTransform() { if (Player.Instance != null) { targetTransform = Player.Instance.transform; } else { Debug.LogError("未找到Player单例对象"); } } void Update() { if (targetTransform == null) return; Vector3 targetPosition = targetTransform.position + offset; transform.position = Vector3.SmoothDamp(transform.position, targetPosition, ref velocity, smoothTime); }
额外优化:修复相机单例逻辑
你现有相机的单例代码存在小问题,会导致重复相机执行DontDestroyOnLoad后才被销毁,调整为:
public static Cameradontdestroy Instance; private void Awake() { if (Instance != null && Instance != this) { Destroy(gameObject); return; // 直接返回,避免执行不必要的DontDestroyOnLoad } Instance = this; DontDestroyOnLoad(gameObject); }
内容的提问来源于stack exchange,提问作者Knackered7
相关产品推荐
相关产品推荐

