Factory Pattern (Am I doing it right?)

I am currently doing a project in university in a group. I’m fairly new to Unity since it’s the first time I’m actually picking it up. My group and I decided that we would have Items in our game and since I got this task I thought I could make a factory pattern out of it. But I’m not really sure if I’m doing this right? I have an abstract Item class which the subclasses derive from. By creating the specific Item, it also gets instantiated (prefab) into the scene.
A friend of mine also showed me how she would do it: She would create a script named ItemBehaviour, where you can drag a prefab (with this script attached to it) to the scene and set the ItemType through the inspector.

Which way in this case is better or are both okay? (aka the factory pattern)
And how can I improve my factory, so that I can use it, or is my approach rather wrong?

I appreciate your answers, thank you!

Here is the ItemBehaviour Class :

public class ItemBehaviour : MonoBehaviour
{
    [SerializeField] private string itemName;
    [SerializeField] private ItemTypee itemType;
}

public enum ItemType
{
    BRANCH,
    FOOD,
    CLOCK
}

My Item Class:

 public abstract class Item
    {
        //protected GameObject itemObj;
        public Item(string name, ItemType type, GameObject prefab, Grid grid)
        {
            Name = name;
            ItemType = type;
            InstantiateItem(prefab, grid);
        }

        public string Name
        {
            get;
            set;
        }

        public ItemType ItemType
        {
            get;
            set;
        }

        public GameObject ItemObj
        {
            get;
            set;
        }

        //public List<GameObject> Items
        //{
        //    get;
        //    set;
        //}

        // instantiating specific item
        private GameObject InstantiateItem(GameObject prefab, Grid grid)
        {
            return ItemObj = GameObject.Instantiate<GameObject>(prefab, grid.transform);
        }

        // setting the position of the items
        public void SetPosition(GameObject prefab, Vector3 position)
        {
            prefab.transform.position = position;
        }

        // destroy item
        public void DestroyItem(GameObject prefab)
        {
            UnityEngine.Object.Destroy(prefab);
        }
    }

My ItemFactory Class:

public class ItemFactory
{
    // creating item
    public Item CreateItem(ItemType type, string name, GameObject obj, Grid grid)
    {
        Item item = null;

        switch (type)
        {
            case ItemType.BRANCH:
                item = new Branch(name, ItemType.BRANCH, obj, grid);
                break;
            case ItemType.CLOCK:
                item = new Clock(name, ItemType.CLOCK, obj, grid);
                break;
        }
        return item;
    }
}

ItemFactoryView Class:

  public class ItemFactoryView : MonoBehaviour
    {
        [SerializeField]
        private GameObject prefab;
        [SerializeField]
        private int quantity;
        [SerializeField]
        private Grid grid;
        [SerializeField]
        private ItemType itemType;
        private Item[] items;
        private GameObject[] itemObjects;
        // Use this for initialization
        void Start()
        {
            ItemFactory itemFactory = new ItemFactory();
            items = new Item[quantity];
            itemObjects = new GameObject[quantity];
            int count = 1;
            // creating branches
            for (int i = 0; i < quantity; i++)
            {
                items = itemFactory.CreateItem(itemType, "Item" + i, prefab, grid);
                //branchObj = branches.InstantiateItem(twigPrefab, grid); // saving gameobject for destroying them later
                itemObjects = items.ItemObj;
                Debug.Log(count + " item/s generated");
                count++;
            }
            // setting test positions
            items[0].SetPosition(itemObjects[0], new Vector3(0, 2));
            items[1].SetPosition(itemObjects[1], new Vector3(0, 3));
        }
}

If your assignment isn’t about the Factory pattern, then you have a couple of things to ask yourself:

  • do you understand what your code does?
  • do your team mates, who also touch your code understand what your code does?
  • does this code do what it supposed to?

If the answers are yes, then you’re good to go.

Regarding your friend and the drag and drop. Unity is a special software, it allows us to trade our manual labor (dragging, dropping, editing in the editor) for less code. It serializes the objects people create and edit in the editor and when your game loads, the player loads those objects in big chunks.
It will perform better than your hand-written factory-initialization. Less code, more performance. Always.
But in exchange for this, you need to edit these visually in the editor and there are rules (which I won’t discuss here, they are in the documentation).

But again: If your code is working and everyone understands what it is doing, then you’re okay. Both paths are correct.

1 Like