Actor - EasterEggProductions/adventure-mode-godot GitHub Wiki
Actor is a core class in Adventure Mode. It performs the operation of stitching together the animation trees of the Modular Mobility system, updating and applying the Dress Up items, contains an example Character class, acts as an input abstraction layer, performs input buffering, and works to synchronize itself across multiplayer instances.
Actor extends CharacterBody3D, and as such inherits it's functionality, such as move_and_slide, which is used for movement.
These are the movement packages that this Actor will use, generally in order of priority, with 0 being a default one to use if no others are taking control.
The actor prefab should have a Skeleton3D, and takes the garments and accessories in the dress up system, and applies them to the skeleton.
Just like actors in real life, the Actor _plays_ a Character. The Character class included in Adventure Mode is not meant to be a one side fits all solution, but rather an example of how to create your own. The Character is where things like hit points, damage, healing, items, and more should be stored, with the Actor handling things such as moving around the world, being hit (and passing that to the character). This is what you would modify if you wanted to do something like add health regeneration. For an explanation on how the example one works, see Character.
Control of an Actor is done through various exposed parameters and methods that are made to be used by a Control Socket, such as the player input socket. This socket node is what would be calling the Input system for key presses, joystick axes, and convert them appropriately. The primary parameter is the Vector3 desired_move, which is a directional vector representing which direction to go. The value for desired_turn is similarly used. Note that in Adventure Mode, desired_move is a global direction pointing to where the actor needs to go, but desired_turn is local, left and right.
During update, the value of the current desired_move is transformed into the appropriate vectors for animation system, generally local space, then passed into any animation node in the Actor's AnimationTree.
For example negative x will play a strafe left animation, and positive x will play a strafe right animation. The y value of desired_move is used to control ascent and descent, a positive value past a threshold can cause a jump, while a negative value could play a crouching animation. Assuming a walking and jumping animation set used this, a swimming set could then use the same values, and thus the same player inputs, for swimming up and down, keeping the direction relative to the controls somewhat intuitive.
This may seem confusing, why was it done this way? Because the Godot AnimationTree did not have any way for you to have a node reference a global value. If you had a node for 'move_walk' and another for 'move_crouch' each one would generate their own Parameter of 'parameter/move_walk/blend position' and 'parameter/move_crouch/blend position', and no capability to have them reference a shared variable existed, requiring code to be constantly refactored to match changes in the animation tree. This system may be more difficult to set up, but it is more dynamic.
Actions the Actor is meant to undertake, such as attack, dodge, or otherwise, and handled as strings with the action_q. When actions are added with enque_action, they and an expiration time (default now + 50 milliseconds) are added to a list. On update, expired actions are removed from the list.
These are used by animation state machines to control their transitions. Specifically within an AnimationNodeStateMachineTransition, it has a field called 'Expression' and this expression is evaluated to a boolean that determines if it should take that transition.
In this example of a simple AnimationNodeStateMachine, the transition between walk_jog_run_idle and aLib_actions_item_crush is selected, and you can see it's expression value:
``action_q_check("item_crush", true)```
This means that when the animation system is evaluating what to do, and it gets here, the function on the actor of action_q_check, will query for an action named "item_crush", and if it's there it will take this path. With the second optional argument of true telling the system to consume this action with this traversal.
The consuming feature of the action is important, and emulates a 'one shot' in the Unity animation system, and assures that animations or states are only visited once per requested action.
The actions of the action_q system are sent across the network with RPC functions. And Actor global position, desired position, and the like are handled with Godot's built in MultiplayerSyncronizer.