Hello everyone, I’ve got some questions on my mind and I couldn’t find proper answers for them. I am struggling the same thing for days now, I know how to do what I want to do, but I am not quite sure about the most optimized way. Let me explain my situation.
Okay, think about a level, indoors, lots of rooms, lots of wardrobes, doors, lights etc. The player will be able to interact with these, and ofcourse different things will happen upon interactions. Some examples :
Interacted with a door, door animations will play, some doors will directly open, some doors will need a key, in this case, those doors will need a “condition to happen” in order to use opening animations.
Interacted with lights, some lights will flicker, some will just be switched on, some will even add force to the objects around them.
Interacted with “surroundings”, some different actions will happen if the player is in a certain area.
So as you understand, in my case, I actually need to write 3 base scripts;
Interaction Script, which will check if the player is in the desired position, via raycasts, distance and angle checks. And if able to interact by pressing a key.
Action Scripts, these are the scripts that decide “what” will happen when interacted. Play Animation, Enable & Disable Objects, Play Sound, Spawn Object, Add Force etc.
Condition Scripts, these scripts will be tasked as a connector between interaction script and action scripts. When interacted, if chosen these will be enabled and check if the desired condition fits, if yes, these will call the action scripts, if no, these will call maybe another script or directly will enable the interaction script for further use.
Now my mind is a little confused. As I know, enabling & disabling scripts is a better way than enabling & disabling empty game objects. Now the problem occurs, how will the interaction script know which condition or action script to enable? Same goes for the condition scripts, how will they know which action script to enable? A simple solution may be just using an enum and switch case on OnEnable function. For example condition script will run a switch check and see which action script is selected, and after that will get the component according to that and enable that script. But the thing is, user will be able to interact a lot, so I believe this can cause some performance issues since there will be a lot of switch checks both on Action scripts & Condition scripts, and there also will be a lot of enabling & disabling.
A solution that I’ve thought about this is, using a single Condition script, using a single Action script. But these scripts will have different classes inside them for different purposes. So determining which script to call will not be a problem since there is only 1 kind of a Condition script and Action script. But the thing is, how will these scripts know which classes to call? I’ve got really confused about these things, and couldn’t figure out an appopriate way, any advices? Thanks :).
You are over-complicating this a bit.
Use colliders as triggers and when one is triggered give the player an option to take some action when one of the triggers is active. You might need to check if the player is facing the GameObject with a trigger (eg. a door) as well.
You will probably want to implement the OnTriggerEnter and OnTriggerExit functions.
I though about it, but Ithe problem is, when player interacts, the interaction script is disabled ( also disables the gui script, I use a canvas text to inform the player like “Press F to interact.” ), action script is activated and the action is played. But sometimes, for example for a door to open, player needs to interact twice ( like first interaction plays an animation which removes an object in front, and the second action plays the animation of the door opening ), when Interaction script is disabled, and after a while when it is re-enabled, OnTriggerEnter & OnTriggerStay functions do not work anymore, it requires player to exit the trigger and enter again. Maybe it had something to do with my boolean checks but I do not think so, still, I need a proper and optimized way to handle the connections between 3 scripts. I actually once worked real hard and managed to write a lot of scripts and they were doing the job, but the profiler was not too happy
Instead of disabling scripts just use a bool to check if it should respond to input or not.
And I’m pretty sure you can do this with 1 script attached to player, to check for input and conditions and one script on the object, just to execute the actions.
I actually don’t think writing the script via player’s perspective. Because interactions can be in really different ways, some may need to be interacted only from a specific angle, some may need a different check for player, so there is only 1 interaction script but it is on the objects, not on the player. Maybe this can explain my struggle better :
As you can see, there are a lot of way for an object to be interacted, so I don’t think I should put a script on player for interactions. Actually most of the work is done, I just need a good way to create communications between action & condition scripts as I mentioned.
Well I don’t really know how your scripts look like, but the way I communicate between scripts is by letting one on them have a reference to the other (your condition script could have a reference to the action script) and then I use this to set global variables and call functions in one script from another.
But what if there are multiple condition scripts and multiple action scripts, should I reference them using a switch case ( I will choose which scripts should communicate by setting the desired script enum over the inspector on the desired script ) or should I write one condition, one action script, and make them hold different classes for different tasks ?
What is the relationship between Condition and Action?
One to one (One condition maps to one action?) i.e pass condition a then do action 1
One to many (One condition maps to many actions?) i.e pass condition a then do action 1, 2, 3…
Many to one (Many conditions map to one action?) i.e. pass condition a, b c, … then do action 1
Many condition can map to many actions. For example:
Item condition, I want to use this whenever I need, this can trigger Animation action, Force action, object spawn action.
Player Status condition, checks the status of the player (running, walking, velocity higher/lower than xx amount), this can also map to different actions.
@zoran404 , mostly only empty gameobjects hold the scripts.