How to connect ScriptableObjects to each other

Hi there.

I’m trying to create some system of resources using, through ScriptableObjects. For example, I have 2 type of resources and some building which needs them to be built.

Resource : ScriptableObject
void add
void reduce

Wood : Resource
int amount = 100

Gold : Resource
int amount = 5

Stock
Resource[] array;

There’s no problem to increase/decrease an amount of any type somewhere in a game. But I can’t understand how to connect my building settings with exact type (class) of the resource.

BuildingSettings : ScriptableObject
10 Wood  //basically I need 10 Wood classes 
1 Gold

Maybe the whole idea is wrong. Could you suggest something?

BuildingSettings : ScriptableObject
Wood[] woods=new Wood[10]
for(int i=0;i<woods.Count;i++){
woods[i]=ScriptableObject.CreateInstance(typeof(Wood));
}

you mean something like this?

Nope.
I have Building object with BuildingSettings, where I store the information how much Woods I need to build it.
When I try to build I compare the real amount of Woods with required amount.

In simple terms it looks like

Stock
{
public int woods = 10;
}

Building
{
public GameObject prefab;
public int requiredWoods = 10; 
}

Builder
{
public void Build(Building building)
{
if(Stock.wood >= building.requiredWoods)
Instantiate(building.prefab, position, rotation);
}
}

And I wanna have the information about the resources types in the one exact place.

hmm not getting it…

Using ScriptableObjects to hold your resource data seems a bit strange. You should probably just use plain classes, then it would be easier to set things up through the inspector. I’m guessing that the reason you chose ScriptableObjects was because Unity can’t serialize polymorphic lists of plain classes?

Would it be possible to avoid using inheritance in your resources classes, and instead just differentiate between the different resource types in some other way?

One possible solution would be to use an enum to define the resource type:

public enum ResourceType { Wood, Gold };

public class Resource
{
    public ResourceType resourceType;
    public int amount;
}

Another solution would be to not have the resource class contain any information about its type, but to determine that in another class that holds the resources. You would then always use this container class instead of an array of Resources when determining the cost of something.

public class Resource
{
    public int amount;
}

public class ResourceCost
{
    public Resource wood = new Resource{ amount = 0 };
    public Resource gold = new Resource { amount = 10 };
}

if performance isn’t an issue he could try to use Reflection (still not sure if I’m getting his problem)

Actually using scriptable objects to hold data like this is perfectly normal, its a very valid and common use case for scriptable objects.

1 Like

I was thinking in such a way. But I don’t have the posibility of creating some logic for each type.

Stock
{
public enum RType
{
Wood,
Gold
}
public Dictionary<RType, int> amount;
void Stock
{
amount[RType.Wood] = 10;
}
}

Building
{
Dictionary<RType, int> RequiredAmount;
}

I also just realized that if you use a container class where you define your resources individually, instead of using an array, you won’t run into the issue of polymorphic collection serialization. In this case you could still use inheritance in your Resource classes if you want to.

public abstract class Resource
{
    public int amount;
}

public class Wood : Resource { }

public class Gold : Resource { }

public class ResourceCost
{
    public Wood wood;
    public Gold gold;
}
1 Like

Ok, thanks, guys.