Design of Main.tscn - leiget/Godot_FPC_Base GitHub Wiki
This chapter explains the main scene (βMain.tscnβ) and its scripts. Each item has the name first and its node type in parentheses.
- Main (Spatial)
- βInit_Script.gdβ is attached to this node.
- Env_and_Lights (Spatial)
- WorldEnvironment (WorldEnvironment)
- Uses the βMain_Env.tresβ file in the βenvironmentβ folder.
- Sun (DirectionalLight)
- Just the main light.
- WorldEnvironment (WorldEnvironment)
- Base (Spatial)
- A instance of βBase.tscnβ.
- Platform_Low (KinematicBody)
- βelevator.gdβ is attached to this node.
- Has a βAnimationPlayerβ node which has a βLiftβ animation.
- Platform_High (KinematicBody)
- βelevator.gdβ is attached to this node.
- Has a βAnimationPlayerβ node which has a βLiftβ animation.
- Big_Sphere (RigidBody)
- βSphere.gdβ is attached to this node.
- Blue_Sphere (RigidBody)
- βSphere.gdβ is attached to this node.
- ZipBox (KinematicBody)
- βelevator.gdβ is attached to this node.
- Has a βAnimationPlayerβ node which has a βLiftβ animation.
- FloorPlatform (KinematicBody)
- βelevator.gdβ is attached to this node.
- Has a βAnimationPlayerβ node which has a βLiftβ animation.
- SmallStep_01 (StaticBody)
- Smallstep_02 (StaticBody)
- Smallstep_03 (StaticBody)
- BigStairs (StaticBody)
- BigStairsPlatform (StaticBody)
- GIProbe (GIProbe)
- Player (KinematicBody)
- And instance of βPlayer.tscnβ.
Scripts Inside Main.tscn
There is only one not explained elsewhere.
Init_Script.gd
There is only one global variable in this scene: a bool that says if we want to have collision slide visualizations. If you set this to true make sure you also put in βemit_signal("Coll_Sphere_Show", slide, get_slide_collision(slide).position)β somewhere in βPlayer.gdβ. Check the bottom of this script for a little more information.
After that we have a β_ready()β function. It sets the window title, mouse mode, and unhandled input process.
Then we have a "if" statement checking if we want to have collision spheres. If we do then it sets up a variable for pointing to the player node, a collision sphere array to hold the instance pointers to the collision spheres, and an integer that holds whatever βMaxSlidesβ is inside βPlayer.gdβ. After that it resizes the collision sphere array to whatever βMaxSlidesβ is. By default thatβs four, so our array would be four elements long. We also have a variable that holds the collision sphere scene so that we can instance it however many times we need.
After this there is a loop that creates instances of the collision sphere scene (βColl_Sphere.tscnβ) according to the amount of slides there are in the playerβs script.
In this loop it first creates the instance that we need. Whenever we βinstanceβ a scene, what we are doing is basically just copying it and making a new, independent object of whatever is in that scene. As I said itβs completely independent and has itβs own variables, settings, and whatever else.
The reason that is important is because our next step in this loop is to set the βArray_Element_Numberβ variable inside the βColl_Sphere.gdβ script that is linked to the instanced scene. Each when setting these variables, each scene has itβs own βArray_Element_Numberβ variable. It doesnβt copy over from one sphere to the next. We set the number of βArray_Element_Numberβ according to whatever iteration the loop is currently in. By default, the variables would number from 0 to 4.
After this, we add the instanced sphere to be a child of the current scene, which would be βMain.tscnβ in this case, as it is the one that has this script attached to it. Hereβs the code:
get_tree().get_root().get_child(0).call_deferred("add_child", Coll_Sphere_Array[x])
Click here to go to the online Godot manual to see how scene trees work.
If that link doesnβt work, then look in the Godot manual for βScene Treeβ. If that doesnβt work, then look for βget_tree()β or βget_root()β and go from there.
One important aspect of this line of code is the βcalled_deferred()β function. What this does is simply defer the execution of the function named in the first argument to until the current scene is completely loaded, so as to keep the engine from trying to load something that isnβt ready yet.
The first argument of βcall_deferred()β is the function you want to execute when everything is done loading, which in this case is βadd_child()β without the parentheses. It must be a string. The second argument is the what you want the first argument of βadd_child()β to be. If you have another function with multiple arguments just add them in a comma separated list. An example:
call_deferred(βSomeFuncβ, 1.2, SomeVar, 5.0)
After that, we finally connect the βColl_Sphere_Showβ signal of the playerβs node to the βColl_Sphere_Show()β function of the collision sphereβs script. Make sure to emit that signal in βPlayer.gdβ somewhere.
The following code, which is an initialization of a temporary variable and a for loop, just sets the initial y position of these sphere instances in 50cm increments above each other, so that the programmer can see them and make sure that things are initializing correctly. Itβs not necessary.
After the β_ready()β function we have an unhandled input function. All it does it quit the program when the player presses whatever the βui_cancelβ action is (the βEscapeβ key by default), and toggles the window into or out of fullscreen whenever the player presses the βToggle_Fullscreenβ action (F4 by default). Note that βis_action_just_pressed()β only gets input once when the button is initially pressed. This works well here as we only want the window to change whenever the player presses the key, but not when it is held down, as that would cause the window to toggle between fullscreen and windowed mode way too much.
Lastly, at the bottom we have the example code you can put into βPlayer.gdβ to show the collision spheres.
Debug Scripts
Here I explain how the two debug scripts work.
Coll_Sphere.gd
This is to be used with an βImmediateGeometryβ node. At the top it has a single global variable called βArray_Element_Numberβ to be used to say what element index the current instance of this scriptβs collision sphere inside the collision sphere array is. So if you have a βMaxSlidesβ of 4 inside the playerβs script, then the βArray_Element_Numberβ at the top of the file represents the slide number to be visualized. Also check the "Init_Script.gd" section on for more information.
β_ready()β makes a sphere and a line going through it. Check the Godot manual or online for tutorials and information about ImmediateGeometry.
The only other thing in here is a function called βColl_Sphere_Show()β which sets the position of the sphere according to the position of the collision slide referenced in the player script.
What it does is take a slide number and a 3D vector. It checks to see if the current slide number (inside the player script) matches the βArray_Element_Numberβ set while being instanced in βInit_Script.gdβ. If theyβre the same it sets the position of the sphere to the current slide collisionβs position using an signal.
Pos_Visual_Axis.gd
This is also to be attached to an βImmediateGeometryβ node.
In the β_ready()β section it creates a line primitive that has three lines all intersecting each other in the center. After that it connects βSet_Position()β in this script to the βRender_Posβ signal in βPlayer.gdβ.
In the βSet_Position()β function it takes a 3D vector given when emitting the signal from βPlayer.gdβ, and simply sets the location of the geometry according to the vector given. Thatβs it.