BRO_TIGER
@BRO_TIGER
Indie Developer (C#, JS)

Проблема с добавлением префабов в иерархию, что делать [C#]?

Доброго времени суток! Столкнулся со странной проблемой которую пока что не могу решить... Дело в том что не так давно я взял более или менее простой скрипт с Онлайн Обучения по Unity... Само учебное видео подсказало мне идею как лучше создать магазин и может быть инвентарь... Я заметил интересную проблему - Префабы (Или их внешний вид) не проявлялись если родитель иерархии был не активен при старте игры, а если был активен. то всё нормально отображалось...
Заранее спасибо за помощь или поддержку!

Обучающее видео по созданию магазина (Ссылка)
Иерархия

ScrollView -> Viewpoint -> Content - вот родитель!
Скрипт 1 (С Учебного видео)
using UnityEngine;
using System.Collections;
using UnityEngine.UI;
using System.Collections.Generic;

[System.Serializable]
public class Item
{
    public string itemName;
    public Sprite icon;
    public float price = 1;
}

public class ShopScrollList : MonoBehaviour {

    public List<Item> itemList;
    public Transform contentPanel;
    public ShopScrollList otherShop;
    public Text myGoldDisplay;
    public SimpleObjectPool buttonObjectPool;
    
    public float gold = 20f;


    // Use this for initialization
    void Start () 
    {
        RefreshDisplay ();
    }

    void RefreshDisplay()
    {
        myGoldDisplay.text = "Gold: " + gold.ToString ();
        RemoveButtons ();
        AddButtons ();
    }

    private void RemoveButtons()
    {
        while (contentPanel.childCount > 0) 
        {
            GameObject toRemove = transform.GetChild(0).gameObject;
            buttonObjectPool.ReturnObject(toRemove);
        }
    }

    private void AddButtons()
    {
        for (int i = 0; i < itemList.Count; i++) 
        {
            Item item = itemList[i];
            GameObject newButton = buttonObjectPool.GetObject();
            newButton.transform.SetParent(contentPanel);

            SampleButton sampleButton = newButton.GetComponent<SampleButton>();
            sampleButton.Setup(item, this);
        }
    }

    public void TryTransferItemToOtherShop(Item item)
    {
        if (otherShop.gold >= item.price) 
        {
            gold += item.price;
            otherShop.gold -= item.price;

            AddItem(item, otherShop);
            RemoveItem(item, this);

            RefreshDisplay();
            otherShop.RefreshDisplay();
            Debug.Log ("enough gold");

        }
        Debug.Log ("attempted");
    }

    void AddItem(Item itemToAdd, ShopScrollList shopList)
    {
        shopList.itemList.Add (itemToAdd);
    }

    private void RemoveItem(Item itemToRemove, ShopScrollList shopList)
    {
        for (int i = shopList.itemList.Count - 1; i >= 0; i--) 
        {
            if (shopList.itemList[i] == itemToRemove)
            {
                shopList.itemList.RemoveAt(i);
            }
        }
    }
}
Скрипт 2 (С Учебного видео)
using UnityEngine;
using System.Collections.Generic;

// A very simple object pooling class
public class SimpleObjectPool : MonoBehaviour
{
    // the prefab that this object pool returns instances of
    public GameObject prefab;
    // collection of currently inactive instances of the prefab
    private Stack<GameObject> inactiveInstances = new Stack<GameObject>();
    
    // Returns an instance of the prefab
    public GameObject GetObject() 
    {
        GameObject spawnedGameObject;
        
        // if there is an inactive instance of the prefab ready to return, return that
        if (inactiveInstances.Count > 0) 
        {
            // remove the instance from teh collection of inactive instances
            spawnedGameObject = inactiveInstances.Pop();
        }
        // otherwise, create a new instance
        else 
        {
            spawnedGameObject = (GameObject)GameObject.Instantiate(prefab);
            
            // add the PooledObject component to the prefab so we know it came from this pool
            PooledObject pooledObject = spawnedGameObject.AddComponent<PooledObject>();
            pooledObject.pool = this;
        }
        
        // put the instance in the root of the scene and enable it
        spawnedGameObject.transform.SetParent(null);
        spawnedGameObject.SetActive(true);
        
        // return a reference to the instance
        return spawnedGameObject;
    }
    
    // Return an instance of the prefab to the pool
    public void ReturnObject(GameObject toReturn) 
    {
        PooledObject pooledObject = toReturn.GetComponent<PooledObject>();
        
        // if the instance came from this pool, return it to the pool
        if(pooledObject != null && pooledObject.pool == this)
        {
            // make the instance a child of this and disable it
            toReturn.transform.SetParent(transform);
            toReturn.SetActive(false);
            
            // add the instance to the collection of inactive instances
            inactiveInstances.Push(toReturn);
        }
        // otherwise, just destroy it
        else
        {
            Debug.LogWarning(toReturn.name + " was returned to a pool it wasn't spawned from! Destroying.");
            Destroy(toReturn);
        }
    }
}

// a component that simply identifies the pool that a GameObject came from
public class PooledObject : MonoBehaviour
{
    public SimpleObjectPool pool;
}
  • Вопрос задан
  • 720 просмотров
Решения вопроса 1
BRO_TIGER
@BRO_TIGER Автор вопроса
Indie Developer (C#, JS)
Я понял в чем дело! Я в настройках button на трех кнопках отключал и включал canvas магазина, и наверное canvas renderer в префабах не мог показать спрайты, надписи и т.д., глупая ошибка получилась)
Ответ написан
Пригласить эксперта
Ответы на вопрос 1
flexer1992
@flexer1992
Unity Developer
Все верно. В методе Start() вызывается метод RefreshDisplay(), который и заполняет список нужными айтемами. Если монобех не активен на старте игры, то метод Start у него не вызовется.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы