As a few people have asked, I thought I’d share some notes about how I’m setting up my point-and-click interface with Playmaker. I’m pretty sure the Unity 4.2 update opened up NavMesh to Basic users but I don’t think the IK rig is accessible, I’m using that for its “look at” control so you’ll need Pro to recreate this setup completely. You’ll also need the custom actions for both Pathfinding and Mecanim…
There are several things I wanted the character to do in response to a click from the user:
- look at where the click was made
- turn to face that point
- walk towards that point
- upon arrival, complete an action of some kind
It would also be nice to have a method for stopping a walk before completion and for clicked items to have their own pre-defined destinations eg. clicking on a mountain could result in walking to a balcony to look rather than all the way to the mountain…
The character has Animator and Navmesh components, a simple walk cycle animation and clips for basic turning on the spot. The scene is set up like the above image, with several proxy objects to visualise and keep track of different variables:
- Destination: The Agent Destination variable is set to match this object every frame, if the two don’t match up the agent automatically repaths and moves towards it.
- Target Destination: This object is repositioned when the player clicks, having this separate from the Destination allows us to check and set some stuff before the agent sets off.
- Look: The character’s Look At variable is set to match this every frame
- Look Axis: This provides an off set pivot for the Look object, this helps to limit crazy looking head snapping if Target-Look happens to pass very close to the head. (You can see this issue in my previous video)
- Target-Look and LookOrig: Provide positions for setting Look. LookOrig acts as an idle state to reset to.
- Compass: Is a roundabout way to ascertain the angle between whatever direction the character’s facing and the current target. After a click we rotate the Compass to look at the target, store it’s rotation as a variable and then reset it to zero.
All the Global Variables we need to keep track every frame are updated in Update_FSM on an empty GameObject:
- Click_Type (Int)
It also checks for a Right Mouse Click used to instantly stop the character walking. (The extra Get Rotation in there is for the camera and isn’t relevant to this setup…)
There’s a separate FSM on the Look object, this allows us to call Update_Look from Hero_FSM and carry on without having to wait for it to finish.
There are also simple FSMs on the Floor and the Item, both are pretty straight forward. For the Floor I’m using a mouse pick event to set Target_Destination_Vector3 from a raycast, Item just sets a predetermined value. Both update Click_Type and then send the Click event to the Hero FSM where most of the work gets done.
The Animator component uses three parameters to change between clips, two floats; Velocity and Angle_to_Destination and a Turn boolean.
I’ve split the Hero FSM into 5 sections:
- In Idle we’re making sure the Agent_Destination is the same as the Hero’s current position and the Agent isn’t moving. If a click is detected we update the Target_Destination and send an Event to the Look_FSM, at this stage the character still doesn’t start walking, just looks.
- Compass rotation starts at zero as a child of the main character, Compass is rotated to face Target_Destination and its local rotation stored as Angle_to_Target before being reset to zero.
- The NavAgent automatically repaths if already in motion and small changes in direction don’t really require additional animation so, to avoid firing off the turning sequence, we check the current velocity and skip out a few states if the agent is already walking. An exception to this is if you click behind the character, in such a case the agent will stop and perform the turning sequence as if from standing.
- If required, we rotate towards the target, set the Turn boolean and finally update the Destination to start walking.
- Get remaining distance seems to require a slight pause in order to register, after that an Int Switch set by the clicked object differentiates between clicking on an item or the floor. Finally a state for handling post walk action, in this case I’m just setting off a little sprite animation.
I’m sure there are loads of different ways of setting something like this up but this is where I’m at at the moment, crits and comments welcome…