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()”方法实例化。
不论如何实例化,“他绑定的脚本控件,都会主动调用构造方法实例化。”
在代码中如何获取一个GUI控件的子控件呢?
之前,一直调用 Transform.GetComponent
方法,但发现没用,在请教同事后发现,可以调用Transform..GetComponentInChildren
,就可以获取了。