unity3d- 循环调用构造,生成重复gUI控件

tag: 常见问题

预制件的实例化,有两种方法:
1. 直接拖动到 “Hierarchy”视图中。
2. 代码生成。

出于项目需要,我需要代码中主动实例化一个预制件。犯了一个很简单的错误,记录一下。

出错描述:

我的控件叫“UIMessageCanvas”,里面有个UI.Button控件而已。

代码定义的实例化的类,如下:

class SendMessageManager : MonoBehaviour {

    private static readonly object _locker = new object();

    #region Singleton

    private static SendMessageManager _instance = null;

    public static SendMessageManager Inst
    {
        get
        {
            if (_instance == null) { 
                lock (_locker)
                {
                    if (_instance == null) {
                        GameObject obj = new GameObject(typeof(SendMessageManager).Name);
                        _instance = obj.AddComponent();
                        //_instance = new GameObject(typeof(SendMessageManager).Name, typeof(SendMessageManager)).GetComponent();
                        DontDestroyOnLoad(_instance);
                    }
                }
            }
            return _instance;
        }
    }

    #endregion

    void Start() {

        if (_initFinish == false) {


            _messageGameObject = Instantiate(Resources.Load("Prefabs/UI/UIMessageCanvas"));

            if (_messageGameObject != null) {
                _trans = _messageGameObject.transform;
            }

            Debug.Log("Call End:" + _messageGameObject == null);
            _initFinish = true;
        }
    }

    public void Click() {
        Debug.debug("按钮被点击了");
    }

    public void Show() {
    Start(); 
    }
}

我又要给按钮“Button”设置一个点击事件,所以,就在里面写了个方法”Click”, 于是,我把 SendMessageManager设置成 UIMessageCanvas 的组件,运行时,
这样使用这个类:

SendMessageManager.Inst.Show(); 实例化”UIMessageCanvas”。

测试中,发现”UIMessageCanvas”不停的在视图中生成。

图1 不停生成的UIMessageCanvas

单例方法明明写了,构造方法应该只调用了一次呀?

于是就开始想是什么原因?

后来经过公司高手帮助,原来是把 SendMessageManager设置成 UIMessageCanvas 的组件, 好给Button设置点击事件 Click()。这会主动调用SendMessageManager的构造方法,我在代码里,有主动生成这个控件,
Start 方法里,又主动实例化此控件,这就造成循环实例化 UIMessageCanvas 组件。

解决方法,就是去掉 UIMessageCanvas 的 SendMessageManager 组件,在代码中,给Button按钮,设置匿名点击事件。

buttonText.onClick.AddListener(delegate() {
            DebugLog("click button!!");
            sendMessage();
});

那么总结一下,GUI实例化有2种方式:
1. 拖动控件实例化。
2. 代码中调用:“ Instantiate()”方法实例化。

不论如何实例化,“他绑定的脚本控件,都会主动调用构造方法实例化。”

预制件里获取Button:

在代码中如何获取一个GUI控件的子控件呢?

之前,一直调用 Transform.GetComponent

你可能感兴趣的:(unity3d)