I am currently considering two possibilities to a centralised interaction system within my game.
Consider that you want to produce different results for different types of objects within the game world - you interact with a signpost and dialogue appears, or interact with an item on the ground and it gets added to your inventory with a notification.
Essentially, I cannot decide whether it would be more efficient to implement such functionality all within one centralised place or to spread each function out over separate events.
Option 1: Centralised
This is what I have started coding. One Interact class which contains several "Types" of possible events in my game.
When the player "interacts" with an object implementing this script, it will implement the functionality that it is set to in the Editor. This means I drag and drop this Event Script onto a prefab and can automatically tweak its functionality within a couple of seconds and have it ready to go in the game world.
I have simplified the general consensus of my code into this block for readability:
public string eventName;
public enum EventType
{
Movement = 0,
Dialogue = 1,
NPC = 2,
ItemCollect = 3,
Teleport = 4,
Cutscene = 5,
Switch = 6,
Custom = 7
}
public EventType eventType;
/*
* #############################
* ##@@## INITIALIZATION ##@@##
* #############################
*
*/
private void Awake()
{
SetupEvent(eventType);
}
public void Activate(bool calledFromTrigger = false)
{
if (autoTrigger && !calledFromTrigger)
return;
Debug.Log("Activated " + name + "!");
StartEvent(eventType);
}
private void StartEvent(EventType type)
{
switch (type)
{
case EventType.Movement:
MovePlatform();
break;
case EventType.Dialogue:
break;
case EventType.NPC:
break;
case EventType.ItemCollect:
break;
case EventType.Cutscene:
break;
case EventType.Switch:
break;
case EventType.Custom:
break;
}
}
Resulting in:
Option 2: Inheritance
It is as if I have a little devil and angel on my shoulder, one tugging me towards the easy and half-finished code of the former example, and another urging me to redesign what I am doing into a much cleaner and abstracted approach.
In the previous example, all "event types" (Movement, Dialogue, Item Collection etc.) were handled by enums that were passed through a Switch statement to check which method should be executed based on the parameters inputted into the Unity Editor for that specific Game Object.
In this system, there would be a base "Interactible" class, which various classes would inherit from to implement functionality. The Activate() method would be overridden in the children for each specific class.
public class NPC : Interactible
{
public override void Activate()
{
//NPC Code...
}
}
The unfortunate downside to this is that I can't just use one prefab for all my events and change them based on the custom editor that I define.
I would have to create a custom editor for each possible child of the Interactible class, and instead of selecting which type of event I want it to be from a simple drop down, I will have to swap out different scripts for different functionality.