You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Unity场景中敌人脚本自动查找Player Transform对象问题——新手开发者求助

Fixing the Automatic Player Transform Lookup Error in Your Enemy Script

Hey there! Let's break down why your current code is throwing an error and fix it properly.

The Root Cause

You can't use GameObject.Find("Player") directly when initializing a class field like public Transform player = GameObject.Find("Player"); in Unity. Here's why:

  • When your script's fields are initialized (before Awake() or Start() runs), Unity hasn't fully loaded the scene or spawned all GameObjects yet. The Player object might not exist in the scene at this point, so Find() returns null—which causes errors when you try to access player.position in Update().

The Fix: Move the Lookup to Awake() or Start()

We'll move the Player lookup into the Awake() method (which runs before Start(), ensuring we have the Player reference ready for the first frame of Update()). We'll also add a safety check to catch cases where the Player isn't found, so you get a clear warning instead of a cryptic error.

Here's the revised script:

public class Enemies : MonoBehaviour { 
    // Declare the field without initializing it here
    private Transform player; 
    private Rigidbody2D rb; 
    private Vector2 movement; 
    public float speed = 5f; 
    public int health; 

    // Awake runs before Start, perfect for initializing references
    void Awake() { 
        // Find the Player GameObject and get its Transform component
        GameObject playerObj = GameObject.Find("Player");
        if (playerObj != null)
        {
            player = playerObj.GetComponent<Transform>();
        }
        else
        {
            Debug.LogWarning("Player GameObject not found in the scene! Make sure it's named exactly 'Player'.");
        }
    }

    // Start is called before the first frame update 
    void Start() { 
        rb = this.GetComponent<Rigidbody2D>(); 
    } 

    // Update is called once per frame 
    void Update() { 
        // Add a check to avoid null reference errors if Player isn't found
        if (player == null) return;

        Vector2 direction = player.position - transform.position; 
        float angle = Mathf.Atan2(direction.y, direction.x) * Mathf.Rad2Deg; 
        rb.rotation = angle; 
        direction.Normalize(); 
        movement = direction; 
    } 

    private void FixedUpdate() { 
        // Only move if we have a valid Player reference
        if (player == null) return;
        Move(movement); 
    } 

    void Move(Vector2 direction) { 
        rb.MovePosition((Vector2)transform.position + (direction * speed * Time.deltaTime)); 
    } 

    private void OnMouseDown() { 
        health = health - 1; 
        if(health <= 0) { 
            Destroy(gameObject); 
        } 
    } 
}

Bonus: A More Reliable Alternative (Using Tags)

If you ever rename your Player GameObject, GameObject.Find("Player") will break. A better approach is to use Tags:

  1. Select your Player GameObject in the Hierarchy.
  2. In the Inspector, set its Tag to "Player" (create the tag if it doesn't exist).
  3. Replace the lookup line in Awake() with:
GameObject playerObj = GameObject.FindGameObjectWithTag("Player");

This way, even if you rename the Player, as long as the Tag stays "Player", the lookup will work.

Why This Works

  • By moving the lookup to Awake(), we wait until Unity has loaded all scene objects before trying to find the Player.
  • The null checks prevent your script from trying to access a non-existent Player reference, which avoids runtime errors.

内容的提问来源于stack exchange,提问作者Vadim

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.29 07:23:13