Gameplay FAQ
How do I dynamically create a wall via a player technique?
The typical way something like this is done, is by gathering a list of points on the client that is "casting" the spell, and providing them to the server. Hero's Journey does a very similar thing for its Wall of Fire ability, where the user draws a line on the ground to specify the area of effect.
The client has several external functions that allow you to get the intercept with the ground:
external function DropToSurface(position references Vector3, distance as Float) as Boolean external function GetGrounding(paramPos as Vector3,checkAbove as Float,walkSlope as Float,groundY references Float) as Boolean external function RaycastPhysX(v1 as Vector3, v2 as Vector3, intercept references Vector3, normal references Vector3, walkable references Boolean) as Boolean
Hero's Journey does this work in the Input_LineCircle and their $LINECIRCLE system node. Of course much of this code relies on how Hero's Journey implements abilities, but it serves as an example. As far as instantiating the wall itself, you have a couple of options, using either the FX System, or creating your own system for this type of object using replication (Replication Tutorial) and prop buckets (Prop bucket).
The next issue here is ensuring that pathfinding avoids the area. One way would be to use a pathfinding node (marking it inactive to notify the pathfinding server to not path through nodes included in its volume) and utilize HeroEngine's capability to apply micro-updates to the navmesh. Using this solution does presume that you intend to use sufficient hardware to handle the additional load that this capability requires of the servers. The way our team would probably do it is simply create a scripted system that your AI could query for information about any dynamic walls that may have been placed.
Additionally, if you want characters to be nudged out of the way when the wall appears, you can use the sweep tests to determine if a character needs to be nudged. You then simply implement the behavior in the character controller to deal with nudging them one way or another.
How come when I add a prop bucket physics do not apply to it?
The PhysicsType of a prop bucket instance is set at activation time (i.e. ActivateInstance()) and is by default NO_PHYSICS. If you want it to be collideable, you must set it to STATIC prior to activation. After-activation changes do not alter the behavior. STATIC should only be used for objects that are not going to move. If your object is going to move, it should be set to DYNAMIC.
How do I implement a ski lift?
The default controller does not have built in support for this concept (though at some point it will get added) so this would require a custom character controller. This is complicated, but ultimately most licensees will choose to create one to have characters "behave" in precisely the way the designers want them to behave. The character controller also works hand-in-hand with the animation agent to ultimately play the "right" animation. See:
Ultimately you will probably not want to inherit from the HeroEngine_ACCController (and instead just inherit from the base _ACCController) to remove any fields you do not need, and allow for very game-specific control over the replication/bandwidth shaping strategies used for the various fields of your controller.
Note: While you are inheriting from the HeroEngine_ACCController on the server, it is necessary to add the inherited fields directly to your class, so you can mark them to replicated (and be part of the initial set data).
The next issue is the SkiLift itself. Using pathfollower to handle the actual movement of your lift will work if this is only something the local client will view. However, assuming the design requirement is that other players see the same thing, it's not going to work. Pathfollowers move independently on each client (i.e. their movement is not synchronized). Consequently, we need to handle the skilift differently so that all connected clients see "relatively" the same movement. There are a couple ways this could be accomplished:
- Make the skilift an actual character and treat it like an NPC
- Create a custom controller to behave like a skilift
- An advantage to going this route is that your artists could animate the skilift in a variety of interesting ways (bounces, doors shuddering closed, etc)
- Create a static object using a prop bucket. See the Replication tutorial for a good example of how you might implement the skilift
- Why a prop bucket instance, instead of making it part of the area (like a tree). The reasons you would want to use a prop bucket instance are:
- Area edits are not optimized for gameplay but rather for ease of debugging/use
- Area edits must be communicated to clients connecting to the area
- Your server object would perform a simulation of movement that sends movement packets to interested clients (i.e. at time Y expect the skilift to be at point 4 along its route)
- Why a prop bucket instance, instead of making it part of the area (like a tree). The reasons you would want to use a prop bucket instance are:
Assuming the prop bucket route is chosen, the fundamentals of providing for character movement relative to a moving object are the same.
Next, as to the actual player character controller. You are going to need to create a number of additional fields (server and client) and set up replication (the fields will need to allow reverse replication much like position does in the default controller). The fields that will be needed will exist on the server and client, and need to be replicated, initial set, reverse replicated and probably should be part of an atomic set. The fields (this is not a complete list) include:
- MY_ControllerIsRelativeTo (noderef) - stores a reference to the server/client object that is the skilift (not to be confused with the prop bucket instance which will have a different ID on every client)
- MY_RelativePosition (vector3) - I think you'll probably want separate fields for relative position/rotation, but it'll depend on what you do in your controller.
- MY_RelativeRotation (vector3)
And one of the client-only fields is:
- MY_ControllerRelativeToHBNode (client noderef) - stores a reference to the prop bucket instance (this would cache a reference to the prop bucket instance representing the visualization of a skilift)
When the player boards the skilift (whether you detect this via a trigger, or you take over control of the player to move them on the skilift, etc), you will need to set the character controller MY_ControllerIsRelativeTo field to the ID of the server/client lift object. Additionally, you will have to change their position to be relative to the skilift now. During the pre/post anim update calls, you will adjust the character position to maintain their relative positioning to the skilift. Additional complexity will be added to your controller if you decide it is valid for the player to "dismount" at any arbitrary point along the way as opposed to defined locations.
There are of course alternatives to doing things this way. For example, many games do not actually allow you to control your character in these kinds of situations, and may even choose not to animate the character "boarding". In this type of scheme, you might have the skilift be a dynamic character that has dynamic parts that look like characters to act as proxies.