Unity中TowerNode脚本找不到Shop脚本引发空引用异常求助
Let's break down why you're hitting that NullReferenceException and fix it step by step:
Root Cause
The error happens because your shop variable in TowerNode is null when you try to call shop.Enable(). Looking at your Start() method:
shop = GetComponent<Shop>(); GameObject.Find("Shop");
GetComponent<Shop>()tries to find a Shop component on the same GameObject as TowerNode—but your Shop script is attached to a separate GameObject named "Shop" (since you're callingGameObject.Find("Shop")).- You call
GameObject.Find("Shop")but don't assign its Shop component to theshopvariable, so the variable stays null.
Also, you have a bug in OnMouseDown(): you're declaring a local bool IsShopOpen = true; which overrides the class-level IsShopOpen field. This means your check if (IsShopOpen == true) will always be true, regardless of the actual state.
Fixes
1. Correctly Assign the Shop Reference
Update the Start() method in TowerNode to properly get the Shop component from the "Shop" GameObject:
void Start() { rend=GetComponent<Renderer>(); startColor = rend.material.color; buildManager = BuildManager.instance; // Replace the old shop assignment with this GameObject shopObj = GameObject.Find("Shop"); if (shopObj != null) { shop = shopObj.GetComponent<Shop>(); } else { Debug.LogError("Couldn't find GameObject named 'Shop' in the scene!"); } }
2. Fix the IsShopOpen Variable Shadowing
In OnMouseDown(), remove the local variable declaration so you use the class-level IsShopOpen:
void OnMouseDown() { // Remove this line: bool IsShopOpen = true; IsShopOpen = true; // Set the class-level variable instead if (IsShopOpen == true) { if (shop != null) { // Add a safety check to avoid future null errors shop.Enable(); } else { Debug.LogWarning("Shop reference is null, can't enable shop!"); } } // ... rest of your code }
Optional: Use a Singleton for Shop (More Reliable)
Just like your BuildManager uses a singleton, you can add one to Shop for easier, more reliable access:
Update your Shop script:
public class Shop : MonoBehaviour { public static Shop instance; // Add this singleton instance public TurretBlueprint Archery; // ... rest of your fields void Start() { // Set up the singleton if (instance == null) { instance = this; } else { Destroy(gameObject); } buildManager = BuildManager.instance; disableAllButtons(); //Enable(); } // ... rest of your methods }
Then in TowerNode's Start(), you can get the Shop instance like this (no need for GameObject.Find):
shop = Shop.instance;
This is better because it avoids relying on GameObject names, which can break if you rename the Shop object later.
Final Notes
- Always add null checks when accessing components you get from other GameObjects—this helps catch issues early and gives clearer debug messages.
- Make sure the GameObject named "Shop" actually exists in your scene and has the Shop script attached to it.
内容的提问来源于stack exchange,提问作者Lian Levi

