C# 统一重用列表中的Ui元素
我在我的项目中遇到了一些问题,我正在创建一个滚动列表视图来显示屏幕列表中的所有元素。 我正在使用面板中的按钮显示列表。 现在,当我调用ShowList()时,它会显示列表中的元素 但如果我将一些对象添加到列表中,并再次调用ShowList(),那么它也会克隆上一个对象,因为存在实例化的对象 为了解决这个问题,我使用Destroy()删除克隆,但是当列表中包含太多的项目(300~400)时,删除它们会导致游戏延迟。我如何为ui按钮创建对象池,或者仅仅停用它们C# 统一重用列表中的Ui元素,c#,unity3d,unityscript,unity5,C#,Unity3d,Unityscript,Unity5,我在我的项目中遇到了一些问题,我正在创建一个滚动列表视图来显示屏幕列表中的所有元素。 我正在使用面板中的按钮显示列表。 现在,当我调用ShowList()时,它会显示列表中的元素 但如果我将一些对象添加到列表中,并再次调用ShowList(),那么它也会克隆上一个对象,因为存在实例化的对象 为了解决这个问题,我使用Destroy()删除克隆,但是当列表中包含太多的项目(300~400)时,删除它们会导致游戏延迟。我如何为ui按钮创建对象池,或者仅仅停用它们 public class two
public class two : MonoBehaviour {
public GameObject Button_Template;
private List<GameName> gm = new List<GameName>();
public void Exit()
{
var og = GameObject.FindGameObjectsWithTag("clone");
for (int i = 0; i < og.Length; i++)
{
Destroy(og[i]);
}
}
void Start()
{ gm.Add(new GameName("1"));
gm.Add(new GameName("2"));
gm.Add(new GameName("3"));
gm.Add(new GameName("4"));
}
public void ShowList()
{
for (int i = 0 ; i < gm.Count; i++)
{
GameObject go = Instantiate(Button_Template) as GameObject;
go.SetActive(true);
one TB = go.GetComponent<one>();
TB.SetName(gm[i].GName);
go.transform.SetParent(Button_Template.transform.parent);
go.tag = "clone";
}
}
}
公共类二:单一行为{
公共游戏对象按钮模板;
私有列表gm=新列表();
公共无效出口()
{
var og=GameObject.FindGameObjectsWithTag(“克隆”);
对于(int i=0;i
列表可用于实现对象池。使用完毕后,只需禁用游戏对象即可。如果要再次使用,请重新启用它。下面的简单游戏对象池脚本重新实现了实例化
和销毁
功能
public class BUTTONPOOL : MonoBehaviour
{
GameObject buttonPrefab;
List<GameObject> buttonPool;
bool ready = false;
public void createButtonPool(GameObject buttonPrefab, int amount = 400)
{
if (ready)
{
Debug.LogError("createButtonPool can only be called once");
return;
}
this.buttonPrefab = buttonPrefab;
//Create 400 Buttons
buttonPool = new List<GameObject>();
for (int i = 0; i < amount; i++)
{
buttonPool.Add(Instantiate(this.buttonPrefab) as GameObject);
}
ready = true;
}
//Creates/Enables single Button
public GameObject Instantiate()
{
if (!ready)
{
showError();
return null;
}
//Return any Button that is not active
for (int i = 0; i < buttonPool.Count; i++)
{
if (!buttonPool[i].activeSelf)
{
return buttonPool[i];
}
}
//Create new Button if there is none available in the pool. Add it to the list then return it
GameObject tempButton = Instantiate(this.buttonPrefab) as GameObject;
buttonPool.Add(tempButton);
return tempButton;
}
//Destroys/Disables single Button
public void Destroy(GameObject button)
{
if (!ready)
{
showError();
return;
}
button.SetActive(false);
}
//Destroys/Disables all Buttons
public void DestroyAll()
{
if (!ready)
{
showError();
return;
}
for (int i = 0; i < buttonPool.Count; i++)
{
if (buttonPool[i].activeSelf)
{
buttonPool[i].SetActive(false);
}
}
}
private void showError()
{
Debug.LogError("createButtonPool must be called once before any other function can be called");
}
}
公共类按钮工具:单一行为
{
游戏对象按钮预览;
列表按钮工具;
bool ready=false;
public void createButtonPool(游戏对象buttonPrefab,int amount=400)
{
如果(准备就绪)
{
LogError(“createButtonPool只能调用一次”);
返回;
}
this.buttonPrefab=buttonPrefab;
//创建400个按钮
buttonPool=新列表();
对于(int i=0;i
用法:
public GameObject ButtonPrefab;
BUTTONPOOL bPool;
void test()
{
if ((bPool = GetComponent<BUTTONPOOL>()) == null)
{
gameObject.AddComponent<BUTTONPOOL>();
bPool = GetComponent<BUTTONPOOL>();
}
//Initiate with 300 Buttons
bPool.createButtonPool(ButtonPrefab, 50);
GameObject tempButton = bPool.Instantiate();
//MUST SET BUTTON ACTIVE CALLING Instantiate()
tempButton.SetActive(true);
//You can do other things with the button
one TB = tempButton.GetComponent<one>();
//To destroy that single button
bPool.Destroy(tempButton);
//OR destroy that all button
bPool.DestroyAll();
}
公共游戏对象按钮预览;
BUTTONPOOL bPool;
无效测试()
{
if((bPool=GetComponent())==null)
{
gameObject.AddComponent();
bPool=GetComponent();
}
//用300个按钮启动
bPool.createButtonPool(ButtonPrefab,50);
GameObject tempButton=bPool.Instantiate();
//必须将按钮设置为活动调用实例化()
tempButton.SetActive(真);
//你可以用这个按钮做其他事情
一个TB=tempButton.GetComponent();
//摧毁那个按钮
b工具销毁(临时按钮);
//或者毁掉所有的按钮
bPool.DestroyAll();
}
请注意,在从
buttonpol
脚本调用自定义Instantiate()
函数后,必须将按钮设置为活动状态。是否可能,仅仅是您需要使用预置?我尝试过使用预置,但它仍然滞后,因为我正在实例化500多个项的按钮。当我使用OnGui时,它可以毫无延迟地工作,但我在某个地方读到,总是使用canvas而不是GUI。您应该使用程序员提供的奇妙解决方案。没有理由你应该有“500”的任何东西。如果你这样做,你必须使用池。这是一个很好的学习机会。我不认为对象池对我有帮助,因为我正在实例化按钮,有时会有500多个项目,所以它会滞后,但是,如果我使用OnGui,那么它可以毫无延迟地工作,但是我读到一些地方总是使用canvas而不是gui,我仍然在考虑可能的问题solutions@paulp2天后回复一篇没有意义的帖子。我不认为对象池对我有帮助,因为我有时会实例化500多个项目,所以它会滞后。你知道什么是对象池吗?你知道为什么实例化滞后吗?请随意使用“有效”的OnGUI。我已经尽了我的一份力量为你的冰冻问题提供解决方案,但不能强迫你使用它。