Advanced Player Controller
A downloadable node
This node is a great starting point for a complex character controller. The current setup is designed for a Kinematic2D node, but it can be quickly changed to work with RigidBody2D
This is an advanced implementation of a character controller, It is especially useful for complex behavior patterns.
The advantage of this style of player controller is that it is highly modular, keeps code segmented to prevent spaghetti, and lets each state be totally self contained.
The state pattern can be replicated to control any physics body and the input section can be deleted to create a great controller for an npc or enemy.
NOTE : You must implement your own states to make use of this package a demo is given.
README
Set Up
- Extract files directly into your project folder.
- Connect templates to path : Project -> Project Settings -> Application -> Editor -> Script Template Search Path
- Edit the "Script Template Search Path" to point to "AdvancedKinematic2DPlayerController/script_templates/"
- OR
- Copy contents of script_templates to your own templates folder
- Edit the "Script Template Search Path" to point to "AdvancedKinematic2DPlayerController/script_templates/"
- Add Globals.gd as Autoload
Before you begin
Please read through
- KinematicPlayerController2D.gd
- PlayerState.gd
- PlayerStateTemplate_COMMENTED.gd
Inputs
Inputs are set up entirely via code and values are assigned to a dictionary of raw values, this is then parsed into something usable at the start of every frame.
Make sure to make appropriate changes to the raw_input_struct which holds the raw input values and the parsed_input_struct which holds the values you will use regularly in code.
raw_input_struct :
Updated with every input event. This could be any number of times in a frame.
parsed_input_struct :
Updated at the start of every frame. This means inputs are polled only once in a frame. The intention is that parsed_input_struct is used by states for triggering state changes.
States
States are treated similarly to cartridges for old game consoles. Each cartridge (state) contains everything needed to run itself, or it can ask the console (player_controller) to tell it a few things. When the cartridge is over, it tells the console which cartridge to insert next, but the console must actually eject and replace the cartridge.
This way the decisions on which state should be next, and under what conditions a state change should occur happen entirely within the current state.
In practice the system simply assisgns a new script to the current_state node when the old state determines it is done.
i.e. A Jump state could check if the player is grounded, if so it can ask to move to a landing state/ walking state/idle state depending on the desired behavior.
#JumpState func init(_args): name = "JumpState" .init(_args)
On entering the jump state, play jump animation
func on_state_enter(): .on_state_enter() anim_player.play("Jump")
When the animation is done, move to a fall state, the states are already setup to recieve signals from the attached Animation Player Node.
func on_animation_finished(_anim_name: String): .on_animation_finished(_anim_name) if _anim_name = "Jump": request_state_exit(Globals.player_states.fall, null)
Status | In development |
Category | Assets |
Author | neilvaidya |
Genre | Platformer |
Made with | Godot |
Tags | 2D, Game Design, Godot, Singleplayer, sourcecode |
Download
Click download now to get access to the following files:
Development log
- Large Rework and Demo AddedJul 07, 2022