Hey, right now I’m creating a city-building type game of small scale. I have a list of GameObject prefabs, each with their own assigned ScriptableObjects to carry info about their type (residential, economic), output, etc.
When the player adds a structure to the world, I add it to a list because I need to access things like how many structures are present and how many of each type there are so on.
What I am trying to do is access this list of GameObjects, which could be a mix of anything, to find a certain type (in this case residential) and grab a Transform component from any one of them, to guide human characters towards that position, only in the case that an object of that type exists.
The solutions I have tried returned nothing, and I have hit a wall with this so any help is appreciated.
A good choice for you would be to store the buildings that are being adding into a list in your code. So, when you need to know which buildings are placed, you would always have those in a list you can check.
This will be more efficient than looking for those type of builds in the scene every time you need to handle them.
Really, to find something in a list, you sort of need to know something about what you’re looking for. So if you want a certain ‘type’ of game object, or I guess, a game object with a certain component, you can just run down the list and TryGetComponent each one until you get a hit.
Objects in the list have a ScriptableObject called Structure with an enum structureType. In this case I’m only trying to access those with the type “residential”, is it possible to filter by checking the script on each object which carries this assigned Structure, and then checking Structure.structureType?
If so, I’m still not sure how to individually access those objects in the list.
Just iterate through the list? Either with a foreach or for loop. Run down the list checking the properties of each object until you find what you need.
Might be worth looking up some tutorials on how to query collections.
What does “returns nothing” means? empty list? compilation error? runtime exception? we need to know exactly what did you try, and what are you (not not) getting back so we can help you.
This should be a job of a “Manager” type of script, that you attach to an empty GameObject in your Scene. This “Manager” script/class (let’s call it BuildingsManager) will hold that list, which other scripts can access to, something like this (from the top of my head, code not checked):
public class BuildingsManager : Singleton<BuildingsManager>
{
private List<Building> _activeBuildings = new List<Building>();
// We declare the property as IReadOnlyList to make sure it can't be modified outside this script (good practise)
public IReadOnlyList<Building> ActiveBuildings => _activeBuildings;
public void AddBuilding(Building building)
{
if (!_activeBuildings.Contains(building))
_activeBuildings.Add(building);
}
public void RemoveBuilding(Building building)
{
_activeBuildings.Remove(building);
}
}
Then in your Building script:
private void OnEnable()
{
// Add this building to the Manager when the GameObject is enabled...
BuildingsManager.Instance.AddBuilding(this);
}
private void OnDisable()
{
// Remove this building from the Manager when the GameObject is disabled...
BuildingsManager.Instance.RemoveBuilding(this);
}
And finally, when you want to access the list of current buildings:
foreach (var building in BuildingManager.Instance.Buildings)
{
// Do anything you want with "building"
}
Basic Generic Singleton implementation:
public abstract class Singleton<T> : MonoBehaviour where T : MonoBehaviour
{
public static Instance { get; private set; }
public virtual void Awake()
{
if (Instance == null)
{
Instance = this as T;
return;
}
Destroy(gameObject);
}
}