I am currently working on a game project on my own and i just came across a scripting design problem. My game is two player multiplayer game and the characters (Thief and a Cop in my case) have to have the ability to interact with some objects around the map. Let’s say the cop has ability to interact with the cameras, some traps etc… while the thief can interact with some tools around the map and such. My problem is about designing a structure so that i can easily extend the properties of interactable objects and adding new ones if need be. My current implementation looked somehow ugly to me i don’t know why but i believe there is a better way to do this.
What i tried was building a base class first
public abstract class Interactable : MonoBehaviour
{
public float maxDistance;
public int cooldown;
public bool discovered;
public abstract string PromptGUI();
public abstract void Interact(PlayerBehaviour player);
}
and then seperated cop and thief interactables like this,
public abstract class CopInteractable : Interactable
{
}
This scripts gets attached to Gameobject
public class VentInteractable : ThiefInteractable
{
public NavigationNode EndPoint;
public override void Interact(PlayerBehaviour player)
{
player.MoveTo(EndPoint);
}
public override string PromptGUI()
{
return "Travel through vent";
}
}
This implementation needed me to set values for each specific interaction(even though their properties are the same like max distance) so i thought it was kind of a reduntant process. So i improved it like this.
public abstract class Interactable : MonoBehaviour
{
public InteractableData values;
public abstract void Interact(PlayerBehaviour player);
}
[CreateAssetMenu(menuName = "Assets/Interaction/New Interaction Data", fileName = "New Interaction")]
public sealed class InteractableData : ScriptableObject
{
public int maxDistance;
public int coolDown;
public bool discovered;
public string promptGUI;
}
public class VentInteractable : ThiefInteractable
{
public int EndPoint;
public override void Interact(PlayerBehaviour player)
{
player.MoveTo(EndPoint);
}
}
I was rather pointing towards interactions that are pretty similar or even the same, but can be done by either the cop or the thief.
I’m not sure what kind of method you currently use to get the interactable components, but most likely GetComponent<…> with either the ThiefInteractable or the CopInteractable.
So in that case, you’d needed to throw 2 mostly exact interactions onto the interactable objects, which is redundant. Or you’d go for the Interactable base class.
With the interfaces, you’d have the chance to get components which implement specific interfaces, and as you might know, you can implement several interfaces. A shared interaction may just implement both interfaces (in contrast to this, it cannot be derived from these 2 base classes) and you’d perhaps benefit from it.
That’s not a must though. That’s just how I’d go for it spontaneously.