Advanced Customizable Character Controller
|
- See also: $ACCC system node
The Advanced Customizable Character Controller (ACCC) supports HeroEngine's highly customizable character controller.
Overview
A character controller is a construct that interprets high level (AI or player driven) decisions and input (ex. move forward) into discrete inputs/knobs which are used by the animation system to cause a resulting visualization (animation of the character). In a general sense, you can think of the character controller living between the movement packets sent by the server and the client animation system.
The MMO Foundation Framework controller HeroEngine_ACCController attempts to identically mimic the behavior of the original C++ character controller "BehaviorCharacter" and is provided as a sample implementation of how each licensee might choose to implement a controller. Ultimately, how your characters behave is totally under your own control.
What problem(s) does this solve
- Fully customizable character controller
- Does not require a Source Code License to modify controller behavior
- Includes a basic character controller which may serve as a starting point for your own game's controller
What problem(s) does this not solve
- Default implementation is a very basic character controller and probably does not eliminate the need for your developers to write a unique controller for your own game.
Concepts
Character Controller
Instantiated from a DOM class, a character controller is linked to the HBNode representing the visualization of a character on the client, when the client is first notified of the existence of the character. The Character controller may be instantiated from the same or different classes, allowing for great flexibility in how the various creatures of your game move through the environment.
Character Controllers are factoried by $ACCC
The system node $ACCC is in charge of factorying character controllers and is the primary mechanism by which a licensee will extend the MMO Foundation Framework to utilize game-specific controllers.
Client representation of a character
The representation of a client is a complex one composed of C++, HSL, and game-specific classes. At a minimum there are several major parts to consider:
- Animation Agent - Interpreter of the animation agent script (.AAS), based on its inputs and knobs determines which animation is playing
- HBNode - C++ representation of a character, responsible for visualization in 3D environment, exposes Properties
Default Character Controller
The MMO Foundation Framework includes a default character controller that your developers may choose to copy and then customize to suit your specific game's needs. The default controller is instantiated from the class HeroEngine_ACCController and its behavior is implemented in the corresponding class methods script.
The 90 degree off problem
One issue is that 3dsMax's default orientation for a biped, is an orientation of +90 degrees off from what the engine considers normal rotation for a model. In order to maintain some semblance of sanity, HeroEngine's default controller corrects for the offset so that the controller uses rotation the same way the server understands a character's rotation.
Consequently, the code for the default controller HeroEngine_ACCController has +90 and -90 degree corrections, depending on the calculation being made.
Usage
Writing a brand new character controller from scratch is beyond the scope of this documentation -- because such an exercise is extremely dependent on the design requirements for a controller. However, the default controller serves as a very strong example of some of the behaviors you might choose to support in your own controller.
Creating a game-specific controller
Controllers exist on both the server and the client, requiring that you create a class for your new controller in both the Server and Client DOMs. The only other requirement for a character controller is that it must inherit from the parent class _ACCController.
It is possible if you only want to slightly modify the behavior of the default controller that you may choose to inherit from HeroEngine_ACCController instead of directly from the _ACCController class.
- Using the DOM Editor, create server and client classes for the new controller
- We recommend that you incorporate the required parent class's name _ACCController as a suffix to your new class. (ex. HJ_ACCController )
- Using the DOM Editor, add _ACCController (you might choose to inherit HeroEngine_ACCController instead) as a parent class (server and client)
- Modify your game-specific class for the $ACCC system node to cause the system to factory controllers from your new controller class.
Entry points from C++
There are 6 entry points from C++ to the character controller.
- _onConstructACCController(): technically a callback made by script, this is triggered by C++'s call to the $ACCC system node's _factoryCustomizableCharacterController() method.
- _onAgentInitialized(): called when an animation agent is first factoried for a character or when the agent is reloaded as the result of the .aas file being recompiled (i.e., uploaded to the Repository)
- _onBehave() Behavior commands not implicitly handled by C++ are passed on to the ACCC's _onBehave() method
- _onPreAnimUpdate() called prior to the processing of animation for the character in the current frame
- _onPostAnimUpdate() called following animation for the character in the current frame
- _ReceiveNPCMovement() called to handle messages coming in from the SendNPCMovement() external function, issued by the server
_onConstructACCController
Called when $ACCC factories up a new controller, providing the controller the opportunity to initialize field values to a default.
Due to the vagaries of asynchronous processes, the animation agent may not be instantiated, requiring that you wait for the _onAgentInitialized callback to perform any agent-related initialization such as setting inputs or animation knobs.
_onAgentInitialized
The _onAgentInitialized() method is called, when an animation agent (.AAS) is instantiated or updated by virtue of uploading a new .aas file to the repository. This call provides the opportunity to initialize the agent's inputs/knobs and to map controller fields to corresponding knobs as a performance optimization.
_onBehave
Behave commands may be sent via script, the Behave Property, or the CLI for a character controller. Behave commands that are not handled by C++ (typically debugging/performance-related commands) are handled by the script character controller. The controller translates behave commands into the necessary state changes to cause the controller to behave in the desired manner.
It is difficult for us to tell you precisely what any particular behave command does or needs to do because it is up to an agreement between your game's character controller(s) and the inputs ultimately used by an animation agent script (.AAS), to choose a particular animation. The HeroEngine_ACCController has numerous examples of potential behaviors your controller may need to support.
_onPreAnimUpdate
One of the two major workhorses of the character controller, the preanim update loop may be called as frequently as every frame. During its loop, preanimupdate figures out what the controller wants to do. It figures out navigational desires, applies gravity/slipping vectors, and modifies of animation agent inputs/knobs to cause the desired animation to play.
During the preanimation loop, the controller needs to perform some or all of the following functionality:
- Figure out Navigation Desires (heading, nav points, analyze controller fields etc)
- Turn Desires into Animation Inputs to play the proper animation
- Handle if we are in water, which adjusts animation inputs
- Apply gravity to deal with slipping/falling, which may adjust animation inputs
- Save preanimation position so post anim can deal with collision/invalid positions
_onPostAnimUpdate
The second major workhorse of the character controller, the postanim update loops is called every frame, allowing script to adjust the final position, to deal with situations where the animation places the character in a spot that should be unreachable due to collision. Additionally, movement packets are sent to the server as are appropriate.
During the postanimation update loop, the controller needs to perform the following functions:
- Deal with collision (restoring position/rotation if necessary)
- Local characters send a movement packet to the server if appropriate to do so
Advanced usage
Performance
Character controllers are extremely sensitive to poorly optimized code because at any given moment there will be generally be many characters within a scene whose controllers must update every frame. We recommend you profile your controller script code frequently as you make changes and optimize whenever possible to LOD out features that are not important at distance.
Reference
- $ACCC: the system node for the Advanced Customizable Character Controller system, primary means of extension of the MMO Foundation Framework to utilize game-specific character controllers
- Animation Agent Script - Simple script executed by the animation system to mix/choose animations to play during the upcoming frame(s)