无需场景GameObject:脚本间值传递与动态实例化对象位置访问
Absolutely you can! Dynamic instantiation doesn’t block you from accessing the spawned object’s position—you just need to make sure you have a way to reference that instantiated GameObject from your other script. Let’s go through a few solid approaches, ordered by how reliable they are:
When you call Instantiate(myPrefab), it returns the spawned GameObject (or Transform, if you cast it). The simplest way is to save this reference somewhere that your other script can access it:
Option A: Static Variable in a Spawner Class
If you’re spawning the object from a dedicated spawner script, use a static variable to hold the reference:
// SpawnerScript.cs public class SpawnerScript : MonoBehaviour { public GameObject myPrefab; // Static variable lets other scripts access the instance directly public static GameObject spawnedInstance; void Start() { // Capture the reference when instantiating spawnedInstance = Instantiate(myPrefab); } }
Then in your other script, you can grab the position like this:
// OtherScript.cs void Update() { if (SpawnerScript.spawnedInstance != null) { Vector3 instancePosition = SpawnerScript.spawnedInstance.transform.position; // Use the position for your logic here } }
Option B: Singleton Pattern
For more control (especially if you have multiple spawners), use a singleton to manage the reference:
// SpawnManager.cs public class SpawnManager : MonoBehaviour { public static SpawnManager Instance; public GameObject spawnedObject; public GameObject myPrefab; void Awake() { // Ensure only one instance of the manager exists if (Instance == null) Instance = this; else Destroy(gameObject); } public void SpawnMyPrefab() { spawnedObject = Instantiate(myPrefab); } }
Access it in another script:
// OtherScript.cs void Update() { if (SpawnManager.Instance.spawnedObject != null) { Vector3 pos = SpawnManager.Instance.spawnedObject.transform.position; // Do something with pos } }
If you need to react to the spawn event or track position changes, use Unity’s event system to pass the position directly:
// SpawnerScript.cs using UnityEngine.Events; public class SpawnerScript : MonoBehaviour { public GameObject myPrefab; // Define an event that passes a Vector3 (the position) public UnityEvent<Vector3> OnObjectSpawned; void Start() { GameObject newObj = Instantiate(myPrefab); // Trigger the event with the spawned position OnObjectSpawned?.Invoke(newObj.transform.position); } }
Subscribe to the event in your other script:
// OtherScript.cs public class OtherScript : MonoBehaviour { public SpawnerScript spawner; void Awake() { // Subscribe to the event to get notified when the object spawns spawner.OnObjectSpawned += HandleObjectSpawned; } void HandleObjectSpawned(Vector3 spawnPosition) { Debug.Log($"Spawned object is at: {spawnPosition}"); // Use the position here } void OnDestroy() { // Always unsubscribe to avoid memory leaks spawner.OnObjectSpawned -= HandleObjectSpawned; } }
If you can’t set up a direct reference for some reason, you can use tags to find the spawned object. Note: This is not ideal for performance (especially if called every frame) and can cause issues if multiple objects share the same tag.
First, assign a unique tag (e.g., "MySpawnedPrefab") to your prefab in the Inspector. Then use this code:
// OtherScript.cs void Update() { GameObject spawnedObj = GameObject.FindWithTag("MySpawnedPrefab"); if (spawnedObj != null) { Vector3 pos = spawnedObj.transform.position; // Use the position } }
内容的提问来源于stack exchange,提问作者Minimus

