Unity3D GUI控件自己创建两个



我有一个代码,向用户显示一个是/否的问题,他们是否真的想退出游戏。这是我的代码:

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对象创建了两次,但我看不出有什么问题

提前感谢

哇,太夸张了。

  1. 一个"singleton"实现,它实际上并没有在场景中保留脚本的一个活动副本
  2. 当脚本完全自我调节时,不必要尝试"singleton"模式。所有方法都作为典型引擎更新的一部分进行调用
  3. 使用"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。

最新更新