void SubscribeToEvents() { //debug: if (false) { Engine.PostRenderUpdate += e => { Scene.GetComponent <DynamicNavigationMesh>().DrawDebugGeometry(true); crowdManager.DrawDebugGeometry(true); }; } crowdManager.CrowdAgentReposition += args => { Node node = args.Node; Vector3 velocity = args.Velocity * -1; var animCtrl = node.GetComponent <AnimationController>(); if (animCtrl != null) { float speed = velocity.Length; if (animCtrl.IsPlaying(WalkingAnimation)) { float speedRatio = speed / args.CrowdAgent.MaxSpeed; // Face the direction of its velocity but moderate the turning speed based on the speed ratio as we do not have timeStep here node.SetRotationSilent(Quaternion.FromRotationTo(Vector3.UnitZ, velocity)); // Throttle the animation speed based on agent speed ratio (ratio = 1 is full throttle) animCtrl.SetSpeed(WalkingAnimation, speedRatio); } else { animCtrl.Play(WalkingAnimation, 0, true, 0.1f); } // If speed is too low then stopping the animation if (speed < args.CrowdAgent.Radius) { animCtrl.Stop(WalkingAnimation, 0.8f); animCtrl.Play(IdleAnimation, 0, true, 0.2f); } } }; }
void SubscribeToEvents() { SubscribeToEvent <PostRenderUpdateEvent>(e => { if (drawDebug) { // Visualize navigation mesh, obstacles and off-mesh connections scene.GetComponent <DynamicNavigationMesh>().DrawDebugGeometry(true); // Visualize agents' path and position to reach crowdManager.DrawDebugGeometry(true); } }); SubscribeToEvent <CrowdAgentFailureEvent>(e => { Node node = e.Node; CrowdAgentState agentState = (CrowdAgentState)e.CrowdAgentState; // If the agent's state is invalid, likely from spawning on the side of a box, find a point in a larger area if (agentState == CrowdAgentState.CA_STATE_INVALID) { // Get a point on the navmesh using more generous extents Vector3 newPos = scene.GetComponent <DynamicNavigationMesh>().FindNearestPoint(node.Position, new Vector3(5.0f, 5.0f, 5.0f)); // Set the new node position, CrowdAgent component will automatically reset the state of the agent node.Position = newPos; } }); SubscribeToEvent <CrowdAgentRepositionEvent>(e => { string WALKING_ANI = "Models/Jack_Walk.ani"; Node node = e.Node; Vector3 velocity = e.Velocity; // Only Jack agent has animation controller AnimationController animCtrl = node.GetComponent <AnimationController>(); if (animCtrl != null) { float speed = velocity.Length; if (animCtrl.IsPlaying(WALKING_ANI)) { float speedRatio = speed / e.CrowdAgent.MaxSpeed; // Face the direction of its velocity but moderate the turning speed based on the speed ratio as we do not have timeStep here node.Rotation = Quaternion.Slerp(node.Rotation, Quaternion.FromRotationTo(Vector3.UnitZ, velocity), 10f * e.TimeStep * speedRatio); // Throttle the animation speed based on agent speed ratio (ratio = 1 is full throttle) animCtrl.SetSpeed(WALKING_ANI, speedRatio); } else { animCtrl.Play(WALKING_ANI, 0, true, 0.1f); } // If speed is too low then stopping the animation if (speed < e.CrowdAgent.Radius) { animCtrl.Stop(WALKING_ANI, 0.8f); } } }); }