- Home /
Best practice for adding specific attributes to an object but not all of them
Hi there,
I already know of one solution to my issue but I was wondering what the "best Unity method" would be.
In this scenario, lets say that we have 3 resources: Food, Wood, Research.
I would like to add a "capacity" attribute to Food and Wood, but not Research, to represent physical storage.
When creating the resources, I do it like this currently:
public List<Resource> resources;
resourceNames = new[] {"Food", "Wood", "Research"};
Unlocked = new[] {true, true, true};
for (int i = 0; i < data.NumResource; i++) {
Resource Resource = Instantiate(resourcePrefab, resourcePanel);
Resource.name = resourceNames[i];
Resource.ID = i;
if (!Unlocked[i]) {
Resource.gameObject.SetActive(false);
}
resources.Add(Resource);
}
The most "Unity-like" method I can think of is to create a new component with a script called Capacity, and then attach it to Food and Wood specifically.
Otherwise, I could simply create a new array for Capacity and set it to be [500, 500, -1] and have capacity ignored for components with -1.
From a design standpoint, could someone provide a better idea or explain how one prevails over the other?
Answer by jmhoubre · Nov 02, 2021 at 09:05 PM
Hello, I would try a class and a derived class. Base class: using UnityEngine;
/// <summary>
/// Base class : research, etc.
/// </summary>
public class Collectable
{
public string name;
public GameObject prefab;
public Vector3 position;
public Quaternion rotation;
public GameObject reference;
// Default constructor.
public Collectable ()
{
name = "Default";
prefab = null;
position = Vector3.zero;
rotation = Quaternion.identity;
}
// Full constructor.
public Collectable (string _name, GameObject _prefab, Vector3 _position, Quaternion _rotation)
{
name = _name;
prefab = _prefab;
position = _position;
rotation = _rotation;
reference = GameObject.Instantiate (_prefab, position, rotation);
}
}
Derived class:
using UnityEngine;
/// <summary>
/// Derived class : wood, iron, gold, etc.
/// </summary>
public class Resource : Collectable
{
public int capacity = 500;
public Resource (string _name, GameObject _prefab, Vector3 _position, Quaternion _rotation, int _capacity)
{
name = _name;
prefab = _prefab;
position = _position;
rotation = _rotation;
capacity = _capacity;
reference = GameObject.Instantiate (_prefab, position, rotation);
}
}
Usage script:
using System.Collections.Generic;
using UnityEngine;
/// <summary>
/// Usage script : attached to an empty.
/// </summary>
public class ResourceManager : MonoBehaviour
{
public List<Collectable> resources;
public GameObject prefabForest;
public GameObject prefabBooks;
private void Start ()
{
resources = new List<Collectable> ();
Resource forest = new Resource ("wood", prefabForest, Vector3.zero, Quaternion.identity, 2000);
resources.Add (forest);
Collectable booksStack = new Collectable ("research", prefabBooks, new Vector3 (5 , 0, 5), Quaternion.identity);
resources.Add (booksStack);
foreach (Collectable item in resources)
{
Debug.Log ($"{item.name}");
}
}
}
Answer by swanne · Nov 02, 2021 at 03:18 PM
Hey,
I had a similar requirement to control how many bullets different types of magazine could take. My game had a crazy amount of weapons. Instead of C# array, I used C# Dictionary. Might be worth looking into:
Your answer
Follow this Question
Related Questions
An OS design issue: File types associated with their appropriate programs 1 Answer
Looking for advice about changing levels. 1 Answer
Question on Unity OOD best practices 0 Answers
Multiple Cars not working 1 Answer
Distribute terrain in zones 3 Answers