【问题标题】:Unity3D GUI Controls creates two of themselvesUnity3D GUI Controls 创建两个自己
【发布时间】:2013-11-29 00:38:20
【问题描述】:

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

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

提前致谢

【问题讨论】:

    标签: unity3d


    【解决方案1】:

    哇,这完全是矫枉过正。

    1. 一种“单例”实现,实际上并不在场景中保留脚本的一个活动副本
    2. 当脚本完全自我调节时,不必要地尝试“单例”模式。所有方法都作为典型引擎更新的一部分被调用。
    3. 使用“count == 1”来确保脚本中只有一组活动的 GUI 指令应该是单例的。

    快速解决方案

    不管有多少脚本,在每个场景中强制使用一个活动 GUI 的真正最懒惰的解决方案是简单地删除当前的 Instance 变量并改为将 Count 设为私有静态.

    稳健的解决方案

    您根本不需要 Count 属性。

    如果您对更健壮的单例 MonoBehaviour 组件感兴趣,请考虑以下内容:

    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.Instance),这将起作用 - 它假定场景中有一个,否则它将创建一个供您参考。但是,您仍然可能不小心在场景中出现多个 UserPrompts,因此还要考虑:

    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】:

      检查脚本是否未在 2 个对象中使用,您也可以通过添加一个标签来检查这一点,该标签将显示 this.parent.name,它将显示使用脚本的 GO。

      【讨论】:

        猜你喜欢
        • 2014-06-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-08-04
        • 2013-08-04
        • 2021-07-28
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多