我有一个代码,向用户显示一个是/否的问题,他们是否真的想退出游戏。这是我的代码:
using UnityEngine;
using System.Collections;
public class UserPrompt : MonoBehaviour {
public int count = 0;
public bool paused = false;
public static UserPrompt Instance;
// Use this for initialization
void Awake ()
{
if (Instance == null)
{
Instance = this;
}
}
// Update is called once per frame
void Update ()
{
if (Input.GetKeyDown(KeyCode.Escape))
{
paused = true;
count = 1;
}
if(paused)
Time.timeScale = 0;
else
Time.timeScale = 1;
}
void OnGUI ()
{
if(count == 1)
{
GUI.Box(new Rect(0,0,Screen.width,Screen.height),"Exit");
GUI.Label(new Rect(Screen.width*1/4,Screen.height*2/6,Screen.width*2/4,Screen.height*1/6), "Do you really want quit to main menu ?");
if(GUI.Button(new Rect(Screen.width/4,Screen.height*3/8,Screen.width/2,Screen.height/8),"Yes"))
Application.LoadLevel("Menu");
if(GUI.Button(new Rect(Screen.width/4,Screen.height*4/8,Screen.width/2,Screen.height/8),"Keep Playing"))
{
paused = false;
count = 0;
}
}
}
}
问题是,我应该点击"继续播放"按钮两次才能消失,似乎这些代码为每个GUI对象创建了两次,但我看不出有什么问题
提前感谢
哇,太夸张了。
- 一个"singleton"实现,它实际上并没有在场景中保留脚本的一个活动副本
- 当脚本完全自我调节时,不必要尝试"singleton"模式。所有方法都作为典型引擎更新的一部分进行调用
- 使用"count==1"确保脚本中只有一个活动的GUI指令集,该指令集应该是singleton
快速解决方案
无论有多少脚本,为每个场景强制执行一个活动GUI的最懒惰的解决方案是简单地删除当前Instance变量,并将Count设置为私有静态。
稳健的解决方案
您根本不需要Count属性。
如果你对一个更健壮的单例MonoBehavior组件感兴趣,可以考虑这样的东西:
private static UserPrompt _instance;
public static UserPrompt Instance
{
get
{
if (_instance != null)
return _instance;
_instance = (UserPrompt )FindObjectOfType(typeof(UserPrompt));
if (_instance != null)
return _instance;
GameObject newObject = new GameObject();
_instance = newObject.AddComponent<UserPrompt>();
newObject.name = "UserPrompt";
if (_instance == null)
throw new NullReferenceException("Cannot instance UserPrompt");
return _instance;
}
}
如果您计划在引用脚本时调用该脚本,如UserPrompt.Istance,则该方法有效-它假设场景中有一个脚本,否则它将创建一个脚本供您引用。然而,你仍然可能意外地在场景中出现多个UserPrompt,所以也要考虑:
private void
OnEnable()
{
if (_instance == null || !_instance.enabled)
{
_instance = this;
}
else
{
enabled = false;
}
}
private void
OnDisable()
{
if (this == _instance) _instance = null;
}
如果场景中出现新的UserPrompt,它将检查是否没有活动实例,否则将禁用自身。禁用优先于DestroyImmediate(this),后者可能会在编辑器中引发NullReferenceException。当然,您可以选择简单地捕获异常。
如果脚本没有在2个对象中使用,您也可以通过添加一个标签来检查这一点,该标签将显示this.part.name,它将显示使用脚本的GO。