Point And Click Game Doubt

Hi!

I’m making a point and click game. I’m implementing the typical feature of using an item in your inventory bar on an item in the environment (i.e key on a door).

My question is, what is the best way to go about tracking which tools work on which obstacles?

Right now, I have a scriptable object that keeps track of ID strings related to each tool-obstacle pair. But i feel like this quickly got out of hand as soon as one of the puzzles in the game was to put a mannequin back together, and also didn’t really fit the situation where “many tools were needed for one obstacle”.

My main worries are scalability and avoiding bugs with string reference mismatching.

Other alternatives I can think of is using some kind of JSON serialization, a compositional approach using interfaces or shallow inheritance (Mannequin : Obstacle and then add extra code and / or override methods). Or maybe I’m not approaching the problem with the scriptable object correctly.

Does anybody have any ideas?

Right now my approach I guess is like a data container from which tools and obstacles get their ID from. In this case the data container is a scriptable object. My main worry is, what should this data container look like for optimum developer efficiency? Especially considering that there could be a one to many relationship between tools and obstacles:

  1. many tools solve the same obstacle

  2. many obstacles can be solved by the same tool

Instead of using the strings I would go with a Scriptable Object, basically you would create a very simple SO like:

[CreateAssetMenu] 
public class Tool : ScriptableObject {} 

Then you would create in the inspector the instances of the Tool. In your code instead of string variables you would have the Tool type variable which would be visible in the inspector. Then you could just drag n drop the Tool asset. If you want one obstacle to be solved by many tools you simply instead of creating [SerializeField] private Tool _tool variable, you would create [SerializeField] private List<Tool> _tools. This way in the inspector you can asign more than one tool and in the code just check if the tool that is being used is in that particular list.

1 Like

This solution is much more simple than any of the options I imagined. It went over my head that instances of scriptable objects are uniquely identifiable and thus can be compared to. It was stuck in my head that each scriptable object instance would have to have a string ID, which made assignment a lot more messy.

I added a list to my obstacle file

    [SerializeField] Tool[] solutionTools;

and also the method

 public bool CanBeSolvedBy(Tool tool)
    {
        foreach (Tool solutionTool in solutionTools)
        {
            if (solutionTool == tool)
            {
                return true;
            }
        }
        return false;
    }

and this worked great, thanks!

1 Like

@Chudroy , I am extremely happy it helped. Just a small advice while we are on the subject. You could rewrite your method to look like this:

public bool CanBeSolvedBy(Tool tool) => solutionTools.Any(solutionTool => solutionTool == tool);
1 Like

Hi! Thanks for the extra info, at first this shortened method didn’t work for me, but it was because i had to include

using System.Linq;

for arrays to have an accessible .Any() method

1 Like

This topic was automatically closed 24 hours after the last reply. New replies are no longer allowed.

Privacy & Terms