Unity开发:调用Teleport()时如何获取敌人当前的enemyTransform.position?
问题:调用Teleport()时如何获取敌人当前位置?
触发OnTriggerEnter碰撞敌人时已保存enemyTransform,后续点击传送按钮执行Teleport(),希望传送到敌人的实时位置,但Teleport()内的enemyTransform始终为null,无法实现需求。
问题代码
using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; using ThrowOrbNamespace; public class orbLogic : MonoBehaviour { public ThrowOrbNamespace.ThrowOrb throwOrb; public Button teleportButton; public CharacterController characterController; private Transform enemyTransform; void Start() { teleportButton.interactable = false; } void OnTriggerEnter(Collider other) { if (other.CompareTag("Enemy")) { enemyTransform = other.transform; throwOrb.StopAll(); Destroy(gameObject); teleportButton.interactable = true; Debug.Log(enemyTransform.position); //enemyTransform != null } } public void Teleport() { Debug.Log(enemyTransform.position); //enemyTransform == null if (enemyTransform != null) { characterController.enabled = false; characterController.transform.position = enemyTransform.position; characterController.enabled = true; teleportButton.interactable = false; } } }
问题原因
核心问题是OnTriggerEnter里的Destroy(gameObject);语句——这条代码会销毁挂载orbLogic脚本的游戏对象,脚本实例也会被销毁,导致之前保存的enemyTransform引用直接丢失,因此Teleport()执行时引用为null。
解决方案
方案1:移除销毁当前对象的代码
如果不需要销毁挂载脚本的对象,直接删除Destroy(gameObject);即可,这样enemyTransform的引用会一直保留,Teleport时就能获取敌人的实时位置:
using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; using ThrowOrbNamespace; public class orbLogic : MonoBehaviour { public ThrowOrbNamespace.ThrowOrb throwOrb; public Button teleportButton; public CharacterController characterController; private Transform enemyTransform; void Start() { teleportButton.interactable = false; } void OnTriggerEnter(Collider other) { if (other.CompareTag("Enemy")) { enemyTransform = other.transform; throwOrb.StopAll(); // 移除销毁语句,保留脚本实例和引用 // Destroy(gameObject); teleportButton.interactable = true; Debug.Log(enemyTransform.position); } } public void Teleport() { if (enemyTransform != null) { Debug.Log(enemyTransform.position); characterController.enabled = false; characterController.transform.position = enemyTransform.position; characterController.enabled = true; teleportButton.interactable = false; } else { Debug.LogWarning("未找到敌人Transform引用"); } } }
方案2:用全局管理器存储敌人引用(必须销毁当前对象时)
如果业务逻辑要求必须销毁当前对象,需将敌人的引用转移到一个持久存在的全局脚本中,比如创建GameManager:
using UnityEngine; public class GameManager : MonoBehaviour { public static GameManager Instance; public Transform CurrentEnemyTransform { get; set; } void Awake() { // 确保管理器全局唯一且不被销毁 if (Instance == null) { Instance = this; DontDestroyOnLoad(gameObject); } else { Destroy(gameObject); } } }
修改orbLogic代码,将敌人引用存入全局管理器:
using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; using ThrowOrbNamespace; public class orbLogic : MonoBehaviour { public ThrowOrbNamespace.ThrowOrb throwOrb; public Button teleportButton; public CharacterController characterController; void Start() { teleportButton.interactable = false; } void OnTriggerEnter(Collider other) { if (other.CompareTag("Enemy")) { // 将敌人引用存入全局管理器 GameManager.Instance.CurrentEnemyTransform = other.transform; throwOrb.StopAll(); Destroy(gameObject); // 现在可以安全销毁当前对象 teleportButton.interactable = true; Debug.Log(other.transform.position); } } public void Teleport() { var enemyTransform = GameManager.Instance.CurrentEnemyTransform; if (enemyTransform != null) { Debug.Log(enemyTransform.position); characterController.enabled = false; characterController.transform.position = enemyTransform.position; characterController.enabled = true; teleportButton.interactable = false; // 传送完成后清空引用 GameManager.Instance.CurrentEnemyTransform = null; } else { Debug.LogWarning("未找到敌人Transform引用"); } } }
内容的提问来源于stack exchange,提问作者Ilya
相关产品推荐
相关产品推荐

