【问题标题】:(C#) Instantiated Under Conditions, Else Reuse(C#) 在条件下实例化,否则重用
【发布时间】:2018-11-28 15:14:54
【问题描述】:

我对编程非常陌生,所以请耐心等待。

public void clickWood()
{
   //Check If The Player Has Gotten Wood Previously
   if(_hasWood == false)
    {

        GameObject newItem = Instantiate(wood_prefab) as GameObject;

        //Initial Displayed Name
        newItem.GetComponent<ButtonSetter>().setName("WOOD: ");

        //Starts with 0 Wood, set to 1
        newItem.GetComponent<ButtonSetter>().item_count += 1;

        newItem.transform.SetParent(GameObject.Find("Content").transform,false);

        //Got their first wood, should run else from now on
        _hasWood = true;
    }
    else
    {
        //SEE CONTINUED POST
    }
}

所以,在 else 语句中,我想说的是,

他们获得了第一块木材,因此我们创建了一个面板来显示有关他们拥有的木材的信息。现在我想说,既然我们已经实例化了 displayPanel,我们只想从中工作并调整控制“Wood: 0”整数部分的对象变量

这应该是

newItem.GetComponent<ButtonSetter>().item_count

但是如果我尝试在 else 语句中访问它,如图所示:

newItem.GetComponent<ButtonSetter>().item_count += 1;

它告诉我 newItem 在当前上下文中不存在。 如何在某些条件下实例化某些东西,然后在满足条件后,获取实例化对象并使用其脚本/变量?

Visual representation of my issue

【问题讨论】:

  • newItem 存储到对象的字段中,就像将_hasWood 作为字段一样。
  • 要详细说明@ChrisSinclair 点,您的GameObject newItem = Instantiate(wood_prefab) as GameObject; 属于if 块的范围。那么为什么不在 if 块之前放置 newItem GameObject 引用并将对象实例化保留在 if 块中。 GameObject newItem = nullnewItem = Instantiate(wood_prefab) as GameObject;

标签: c# unity3d instantiation


【解决方案1】:

我认为你需要稍微重构你的代码。

这就是我的做法

public class Item : MonoBehaviour {
    public string itemName;
    public int count;
}

我将为木头、铁或游戏中的任何东西创建一个基类 Item

接下来,我将创建一个处理程序脚本,用于跟踪所有被点击/未点击的项目

Handler.cs

公共类处理程序:MonoBehaviour {

public Item itemPrefab;

public Dictionary<string, Item> displayItems= new Dictionary<string, Item>();

public void OnWoodClicked()
{
    OnItemClicked("wood");
}

public void OnIronClicked()
{
    OnItemClicked("iron");
}

private void OnItemClicked(string itemKey)
{
    if (displayItems.ContainsKey(itemKey))
    {
        displayItems[itemKey].count++;
    }
    else
    {
        Item item = Instantiate(itemPrefab);
        item.count = 1;
        item.itemName=itemKey;
        displayItems.Add(itemKey, item);

    }
}
}

所以为了跟踪创建的项目,我创建了一个字典 public Dictionary&lt;string, Item&gt; displayItems;

在此脚本中OnItemClicked(string itemKey) 方法将检查是否已创建此类型的项目。 (通过检查该键是否存在)

如果该项目未创建,那么我们将实例化新的Item(您要显示的显示项目的预制件)并根据其键将其添加到字典中。

但如果它已经存在,则只需将该对象作为 displayItems[itemKey] 访问即可

因此,例如,如果您点击 Wood,您将可以通过 displayItems["wood"] 访问木质展示项目。

我希望这会有所帮助。 如果您想让我说得更清楚,请发表评论。

【讨论】:

  • 好了!作为一个新手 - 看到我试图实现的凌乱系统被放入更简单和更清洁的代码中会有很大帮助!会试一试,非常感谢:)
  • 我很高兴能帮上忙 :)
【解决方案2】:

按照目前的写法,newItem 只存在于代码的“IF”子句中,所以“ELSE”子句看不到它。

如果您将其分配给班级级别的字段(就像您在班级级别分配了 _hasWood 一样),那么您将能够在“IF”或“ELSE”块中访问它,并保持计数在对象“clickWood()”的生命周期内,它被调用。

private bool _hasWood;
private GameObject _woodItem;

public void clickWood()
{
    //Check If The Player Has Gotten Wood Previously
    if(_hasWood == false)
    {

        _woodItem= Instantiate(wood_prefab) as GameObject;

        //Initial Displayed Name
        _woodItem.GetComponent<ButtonSetter>().setName("WOOD: ");

        //Starts with 0 Wood, set to 1
        _woodItem.GetComponent<ButtonSetter>().item_count += 1;

        _woodItem.transform.SetParent(GameObject.Find("Content").transform,false);

        //Got their first wood, should run else from now on
        _hasWood = true;
    }
    else
    {
        _woodItem.GetComponent<ButtonSetter>().item_count += 1;
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-06-27
    • 1970-01-01
    • 2014-07-03
    • 1970-01-01
    相关资源
    最近更新 更多