[英]UNity3D, return value from one class/method to another class/method in Unity3D
[英]Inspector value cannot access from another class in Unity3d
我有两节课。 一个叫GameManager ,另一个叫敌人 。 我在GameManager中有两个变量,它们已从检查器currentLevel=1
和totalEnemy=10.
更改totalEnemy=10.
// GameManager.cs
private static GameManager instance = new GameManager();
public static GameManager get(){ return instance; }
public int currentLevel;
public int curLevel { get; set; }
public int totalEnemy;
public int totLevel { get; set; }
void Start () {
curLevel = currentLevel;
totLevel = totalEnemy;
}
我试图像这样从Eneimes类访问这两个变量; 但是每次它都会给我curLevel = 0
,但是我希望得到curLevel = 1
。 我做错了什么?
// Enemies.cs
void Start () {
Debug.Log (GameManager.get().curLevel); // always output = 0
}
该行的private static GameManager instance = new GameManager();
是问题。
当脚本被附接到GameObject
,该脚本的类型的实例被引用作为this
脚本内部。 换句话说,如果将相同的脚本附加到多个GameObject
,则可以存在多个相同类型的实例。
因此,您在Inspector中设置的具有curLevel = 1
的特定实例是附加到特定 GameObject
的类型的实例 。 这意味着在脚本中应将其称为this
。
如果您在代码中声明了GameManager
的新实例,则基本上将忽略Inspector中的所有值,因为static GameManager instance
所指向的实例与您在Inspector中为其设置值的实例不同。
为了使用您使用检查器声明的特定实例,您应该执行以下操作。
using System.Collections.Generic;
using System.Collections;
using UnityEngine;
public class GameManager : MonoBehaviour
{
private static GameManager instance;
public static GameManager get() { return instance; }
public int currentLevel;
public int curLevel { get; set; }
public int totalEnemy;
public int totLevel { get; set; }
void Awake()
{
if (instance == null)
{
instance = this;
}
else
{
Debug.LogError(string.Format("GameManager.Awake(): More than one instances of this type {0} is being initialised but it's meant to be Singleton and should not be initialised twice. It is currently being initialised under the GameObject {1}.", this.GetType(), this.gameObject.name));
Destroy(gameObject);
}
curLevel = currentLevel;
totLevel = totalEnemy;
}
}
请注意,我将Start()
更改为Awake()
。 这是因为您是从其他脚本中引用此方法中初始化的值,并且不能保证在运行时中的不同MonoBehaviours
之间首先调用哪个Start()
。 但是,Unity保证总是在Start()
之前调用Awake()
Start()
。 此外,Unity的最佳实践是在Awake()
初始化可自我初始化的变量,并由于该执行顺序而在Start()
初始化依赖于其他脚本的变量。
最后,就会出现问题,当有多个GameObject
是具有GameManager
作为其在场景中的组成部分。 考虑一下您有两个这样的对象的情况。 加载场景时,每个脚本都将调用Awake()
,并且两个脚本都将设置private static GameManager instance;
每两个this
。 结果将是一个被另一个覆盖。
您可能会说,使用该脚本时要小心,并确保只有一个GameObject
将此脚本作为其组件。 但是,您应该始终编写代码,就像不了解您的代码的人可以不经考虑就使用它,并且可以很容易地发现其他人对项目的愚蠢错误。
编辑:
为了回应OP的评论,我添加了代码以在项目中多次初始化此类型时进行处理。 除了@Kardux的建议之外,我还添加了Debug.LogError()
因为我不希望该项目静默地解决问题。 如果发生问题,我想得到通知。
如果您在项目中经常使用Singleton
,则可能需要一个父abstract class Singleton
来处理所有子Singleton
的实例检查过程,并使GameManager
继承自Singleton
。
但是,请谨慎使用Singleton
,因为如果滥用它,这将被视为不良的设计模式。 (而且我不知道如何正确使用它,所以我避免使用它。)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.