Hello everyone,
First topic here, I hope I’m not mistaken on where I’m posting this.
I’ve started Unity a few months ago, and decided to make a simple top-down game to learn. At first it was a bit confusing, but now I’ve made my way through the basics of Unity and my small project is nearly finished.
I have a small character I can control, 2 levels, an inventory system, items I can pick up, objects I can interact with, even a NPC that is moving and who I can talk to. OK fine.
But as I was testing my game, I came accross a bug that is inherent to the architecture I chose, which lead me to read discussions here about the different patterns, and now I’m confused about things should really be.
So I’m gonna make it a unique question, through the following example.
EXAMPLE :
When the player’s character enters a collider somewhere in the level, I want the following things to happen :
- the player is unable to control the character anymore
- the npc (who is usually constantly moving) stops moving
- a dialogue box appears with a text in it
When the player press the key “Z” :
- the dialogue box closes
- the player character is teleported to a “spawner” object position
- the player regains control of character
- the NPC restarts moving
Thing to take into account :
Player Character and Dialog Box are in Scene1
The “world”, NPC, collider and spawner are in Scene2
END OF EXAMPLE
I’m taking a real example so we all understand what we’re talking about and I think it might help the answers be more specific.
So the question is : how would you technically do that ?
To be a bit more specific, I’m interested in how you make the action happening in a collider object in scene2 have impact on objects that are in scene1, and same for the key input after the dialog appeared.
I’m going to answer my own question with the solution I chose and that I’m now doubting
MY SOLUTION
I used custom ScriptableObject events as suggested in this (outdated I guess) talk :
In my collider, I raise an event “OpenDialogBox” with a string parameter. I also set a “actionStarted” bool to true.
Player subscribed to that event and I disable the controls when it is raised. Same for the NPC, disabling its movement.
DialogManager also subscribed to that event (of course!) and shows itself with the string that was passed as a parameter to the event.
In DialogManager Update function, I check if the DialogBox is active and if the Z key is pressed, then I close the DialogBox and raise an event “CloseDialogBox”.
Player subscribed to it and enables the controls back when raised. NPC same.
Collider subscribed to it and if “actionStarted” is true, sets it to false and raises a “SpawnPlayerEvent”.
Player subscribed to this “SpawnPlayerEvent” and proceeds to a GameObject.FindWithTag(“Spawner”) to find the spawner and modifies its position with that of the spawner.
END OF MY SOLUTION
I started implementing this pattern after I found so many warnings about the Singleton pattern. But since, I’ve read about different patterns and quite some critics about the ScriptableObjects Events pattern. After reading a lot of topics, I’m lost as how to implement other patterns (Service Locator, DI, UnityEvents, others ?) and if one can be considered better.
I’m not seeking the answer “if your project is small you shouldn’t care as long as it works”, I want to learn how I can do something that would be optimized for a big project.
Sorry for the long post, and thanks in advance to anyone who will share their insights with me or point the flaws and stupidities of my solution. I’m here to learn.