Posted February 14, 2022 by Bald Men
Intro
So this is just a basic "tutorial" on how I made this game, and how you can make a FNAF-like game in Godot.
I first just wanna mention that the sole reason I started working on this was Tech Rules' great video on the FNAF AI, which I assume you've seen already if you're reading this. If you haven't I would highly recommend watching it here.
I won't be discussing the title screen and other things here, just the main game itself.
Something else that I have to mention is that for this project, I made the whole game in one big scene. In my opinion this is actually really bad! You end up with a giant scene that has way too much stuff in it, and in my case, a script with 750 lines (that sucks!!). I was pretty inexperienced when I made this though, so my #1 tip for beginner Godot developers is please, split stuff up into separate scenes if you can.
For FNAF-likes, I would definitely recommend at least making separate scenes for the room and the camera view, and an extra scene for when the power goes out. You can use a global scene to control all the game variables, this can be done in "AutoLoad" in the project settings. But anyways, let's just get into what I did.
Walker AI
So each enemy has an AI level, which is assigned like this:
The "level" array gets assigned the correct value depending on the night. It's taken from the "lvls" array if it's night 1 to 5, or it gets forced to a specific value if it's a custom night.
First let's talk about "walking" enemies, that walk through rooms until they get to your doors. I have another array to control their locations:
These enemies all use timers that activate a "movement opportunity". You can use the timeout signal on a timer to achieve this.
So that's the function for a basic walker. Let's dissect it.
So what's going on here? Well, "if l!=0" means if they aren't at your door. So, a normal movement.
This one in specific is somewhat random. If the location isn't 11 or 13, then they pick a random location from 8, 9, 11, or 12.
If it is 11, then they always move to 13. And if it's 13, then they try to go to your door. atdoors[1] represents who's at the right door currently, so if it's empty, then they're free to go there.
The line at the bottom is pretty important. changecam is the function that updates the camera and enemy sprites, and this is the relevant part of it:
Basically if the camera is at an enemy's location, then show their sprite and update the texture to the correct one. All walking enemies have different sprites depending on what room they're in. And if they aren't at the camera's room, then hide them.
If the camera is up, and the camera location is equal to this enemy's location, and the enemy moved (either to or from this room), then update the camera view.
Now here's the second part of the movement.
This when the enemy IS at your door. door[1] represents if the right door is closed. So if it is closed, then reset the location to either 8 or 9. If the camera is currently at that same location, then update the camera view. Finally, play a footstep sound effect.
But if the door is open, then go in the room. The game checks for this, so the moment the inroom variable isn't empty, a timer starts. At this point you get jumpscared if you either put down the camera or the timer runs out. And that's it for this enemy!
There are other walking enemies that pick an adjacent room instead of choosing randomly, but the rest is exactly the same.
We subtract 8 from the location to get the index for the p array. So for example, when this enemy is in room 8, that checks index 0 of the array, which is [9,10]. So they go to either room 9 or 10.
Other AI
This guy is my equivalent of Foxy. It has the same level check, but the cam also has to be invisible and he can't be locked. (The lock is just a timer that starts whenever you put the camera down, and has "One Shot" set to true so that it doesn't loop forever. It's very short)
"zain" is the variable that determines his stage. Each time it goes up, it also updates his sprite, and when it hits 3 that means he's going to attack soon. At this point the run animation is queued up, and a timer starts with a specific time that gets faster with a higher level.
What happens now is either the timer runs out, or you check cam 4 which will play the run animation and shorten the timer significantly.
When the timer runs out:
"down" is the variable that represents if the power is out, since he's not supposed to kill you in that case.
If the left door is open, then play his jumpscare. Otherwise remove a bit of power, play a footstep sound, and reset him.
All done
Thanks for reading. If there's anything more specific that you'd like to know, tell me and I'll try to help.