静态实例不像我预期的那样工作
Static instance does not work like I expect
我正在对使用 Unity 构建的游戏的状态进行一些测试,使用如下内容:
脚本 1
public class ControladorEstados : MonoBehaviour {
private static ControladorEstados controladorEstados = null;
//public bool pause { get; set;} = false; //¿ usa c# 4?
private bool pause;
public bool Pause {
get { return pause; }
set { pause = value; }
}
private bool gameOver;
public bool GameOver {
get { return gameOver; }
set { gameOver = value; }
}
//protected ControladorEstados () {}
private ControladorEstados () {}
void Start () {
pause = false;
gameOver = false;
}
void Update () {
Debug.Log("Update");
if (gameOver == true) {
Debug.Log("GameOver Game");
}
if (pause) {
Debug.Log("Pause Game");
}
}
public static ControladorEstados getInstancia () {
if (controladorEstados == null) {
controladorEstados = new ControladorEstados ();
}
return controladorEstados;
}
}
脚本 2
..//
private ControladorEstados controladorEstados = null;
void Awake() {
rb = GetComponent<Rigidbody>();
controladorEstados = ControladorEstados.getInstancia ();
}
void Start() {
}
void Update () {
// test
gameOver ();
}
private void gameOver (){
controladorEstados.GameOver = true;
Debug.Log("test gameOver () " + controladorEstados.GameOver);
}
}
在test gameOver ()
日志中我可以看到变量设置为true
,但是脚本ControladorEstados
在执行更新时没有像我预期的那样工作。它没有按预期工作。
我已经把Debug.Log("Update");
看成是运行了Update
,是运行,但是没有分支到if
] 语句时为 true
.
我没有 C# 或 Unity 的经验,尽管问这个问题对我来说似乎很尴尬,但我已经这样做了一段时间,但我没有看到错误。此外,我使用的是 Linux 版本,我不知道这是否是错误的一部分。
更新:
我刚刚添加了这个代码更改:
void Update () {
Debug.Log("Update" + gameOver);
if (gameOver == true) {
Debug.Log("GameOver Game");
}
..//
它的输出是 False
所以我可以看到它没有改变。在 script 2 中为真,但在 script 1 中为假。请给我一些关于我做错了什么的想法。
我解决了
脚本 1
void Awake () {
//controladorEstados = new ControladorEstados ();
if (controladorEstados == null) {
controladorEstados = this;
}
}
..//
public static ControladorEstados getInstancia () {
return controladorEstados;
}
根据 Peter Duniho 的回复,我创建了上面的代码,您可以看到更改,我也知道使用 Script Execution Order 来使用它们之间的顺序。
我不知道这是否是最好的方法,但它似乎有效,我 post 它以防有人帮助解决类似的问题。
如果 a good, Minimal, Complete, and Verifiable code example 无法可靠地重现问题,则无法确定您需要更改哪些内容才能解决问题。
但是,很明显您正在处理 ControladorEstados
的两个不同实例。 运行 的实例(以及 Unity3d 为其调用 ControladorEstados.Update()
方法的实例)是 而不是 [=] 引用的同一实例12=] 变量在任何 class 你描述为 "script 2".
在您的 ControladorEstados.getInstancia()
方法中,您不应创建 ControladorEstados
的新实例。相反,您需要做两件事:
- 创建时在
ControladorEstados
class中设置ControladorEstados.controladorEstados
,例如在 Start()
方法中。
- 确保您描述为 "script 2" 的 class 在第 1 步发生之前不会调用
getInstancia()
。
请注意,以上只是解决问题可以采取的最少步骤。很可能有更好的方法来查询 Unity3d API 以允许 "script 2" 检索 the 实例ControladorEstados
您想要的(例如 return 来自场景的当前正确的控制器实例,或类似的东西)。但是,如果没有更完整的代码示例,就无法确定更好的方法到底是什么样子。
您的方法不完全是 Unity 的方法。您基本上是将单例与 MonoBehaviour 混合在一起。
请记住,Unity 是 component-driven。如果您想要扩展 MonoBehaviour 的对象的单个实例,只需创建一个始终在场景中的对象(如 GameManager)并向其添加 ControladorEstados
。
然后您可以在需要使用它而不是使用单例的脚本中从那里引用它。
我正在对使用 Unity 构建的游戏的状态进行一些测试,使用如下内容:
脚本 1
public class ControladorEstados : MonoBehaviour {
private static ControladorEstados controladorEstados = null;
//public bool pause { get; set;} = false; //¿ usa c# 4?
private bool pause;
public bool Pause {
get { return pause; }
set { pause = value; }
}
private bool gameOver;
public bool GameOver {
get { return gameOver; }
set { gameOver = value; }
}
//protected ControladorEstados () {}
private ControladorEstados () {}
void Start () {
pause = false;
gameOver = false;
}
void Update () {
Debug.Log("Update");
if (gameOver == true) {
Debug.Log("GameOver Game");
}
if (pause) {
Debug.Log("Pause Game");
}
}
public static ControladorEstados getInstancia () {
if (controladorEstados == null) {
controladorEstados = new ControladorEstados ();
}
return controladorEstados;
}
}
脚本 2
..//
private ControladorEstados controladorEstados = null;
void Awake() {
rb = GetComponent<Rigidbody>();
controladorEstados = ControladorEstados.getInstancia ();
}
void Start() {
}
void Update () {
// test
gameOver ();
}
private void gameOver (){
controladorEstados.GameOver = true;
Debug.Log("test gameOver () " + controladorEstados.GameOver);
}
}
在test gameOver ()
日志中我可以看到变量设置为true
,但是脚本ControladorEstados
在执行更新时没有像我预期的那样工作。它没有按预期工作。
我已经把Debug.Log("Update");
看成是运行了Update
,是运行,但是没有分支到if
] 语句时为 true
.
我没有 C# 或 Unity 的经验,尽管问这个问题对我来说似乎很尴尬,但我已经这样做了一段时间,但我没有看到错误。此外,我使用的是 Linux 版本,我不知道这是否是错误的一部分。
更新:
我刚刚添加了这个代码更改:
void Update () {
Debug.Log("Update" + gameOver);
if (gameOver == true) {
Debug.Log("GameOver Game");
}
..//
它的输出是 False
所以我可以看到它没有改变。在 script 2 中为真,但在 script 1 中为假。请给我一些关于我做错了什么的想法。
我解决了
脚本 1
void Awake () {
//controladorEstados = new ControladorEstados ();
if (controladorEstados == null) {
controladorEstados = this;
}
}
..//
public static ControladorEstados getInstancia () {
return controladorEstados;
}
根据 Peter Duniho 的回复,我创建了上面的代码,您可以看到更改,我也知道使用 Script Execution Order 来使用它们之间的顺序。
我不知道这是否是最好的方法,但它似乎有效,我 post 它以防有人帮助解决类似的问题。
如果 a good, Minimal, Complete, and Verifiable code example 无法可靠地重现问题,则无法确定您需要更改哪些内容才能解决问题。
但是,很明显您正在处理 ControladorEstados
的两个不同实例。 运行 的实例(以及 Unity3d 为其调用 ControladorEstados.Update()
方法的实例)是 而不是 [=] 引用的同一实例12=] 变量在任何 class 你描述为 "script 2".
在您的 ControladorEstados.getInstancia()
方法中,您不应创建 ControladorEstados
的新实例。相反,您需要做两件事:
- 创建时在
ControladorEstados
class中设置ControladorEstados.controladorEstados
,例如在Start()
方法中。 - 确保您描述为 "script 2" 的 class 在第 1 步发生之前不会调用
getInstancia()
。
请注意,以上只是解决问题可以采取的最少步骤。很可能有更好的方法来查询 Unity3d API 以允许 "script 2" 检索 the 实例ControladorEstados
您想要的(例如 return 来自场景的当前正确的控制器实例,或类似的东西)。但是,如果没有更完整的代码示例,就无法确定更好的方法到底是什么样子。
您的方法不完全是 Unity 的方法。您基本上是将单例与 MonoBehaviour 混合在一起。
请记住,Unity 是 component-driven。如果您想要扩展 MonoBehaviour 的对象的单个实例,只需创建一个始终在场景中的对象(如 GameManager)并向其添加 ControladorEstados
。
然后您可以在需要使用它而不是使用单例的脚本中从那里引用它。