private IEnumerator <IYieldInstruction> WalkingTask(Pair <Vector3> target, Hangout.Shared.Action onTargetReachedCallback) { Vector3 headingSmooth = this.UnityGameObject.transform.forward; do { this.DisplayObject.animation[mActiveWalkCycle.name].speed = mWalkSpeed * mActiveWalkCycleSpeed; yield return(new YieldUntilNextFrame()); Vector3 position = this.UnityGameObject.transform.position; Vector3 positionDifference = target.First - position; float distanceToTarget = positionDifference.magnitude; if (distanceToTarget < 0.00001f) { // Avoid divide by zero and floating point rounding weirdness break; } Vector3 directionToTarget = positionDifference / distanceToTarget; Vector3 heading = directionToTarget; ConfigManagerClient configManager = GameFacade.Instance.RetrieveProxy <ConfigManagerClient>(); bool enableCollisionAvoidance = configManager.GetBool("enableCollisionAvoidance", true); if (enableCollisionAvoidance) { Vector3 avoidCollisionsVect = Vector3.zero; int collisionLayer = mStateMachine.CurrentFashionState.CollisionCheckLayer; foreach (Collider collider in Physics.OverlapSphere(position, COLLISION_CHECK_RADIUS, collisionLayer)) { if (collider.gameObject == UnityGameObject) { continue; } Vector3 colliderToModel = collider.gameObject.transform.position - position; float weight = -1.0f / Mathf.Max(colliderToModel.sqrMagnitude, 0.01f); // inverse square weight Vector3 avoidCollisionInfluence = colliderToModel.normalized * weight; if (Vector3.Dot(avoidCollisionInfluence, positionDifference) > 0.3f) // make sure we only influence towards the end goal { avoidCollisionsVect += avoidCollisionInfluence; } } DebugUtility.DrawCicrleXZ(position, COLLISION_CHECK_RADIUS, Color.yellow); if (avoidCollisionsVect.magnitude > 0.0f) { Debug.DrawLine(position, position + avoidCollisionsVect, Color.yellow); heading += avoidCollisionsVect * Mathf.Clamp01(distanceToTarget * DISTANCE_TO_TARGET_CHECK); heading.Normalize(); headingSmooth += heading * Time.deltaTime; headingSmooth.Normalize(); Debug.DrawLine(position, position + headingSmooth, Color.green); heading = headingSmooth; } else { headingSmooth = heading; } } else { headingSmooth = heading; } this.UnityGameObject.transform.position += headingSmooth * mWalkSpeed * Time.deltaTime; // Walk towards the target this.UnityGameObject.transform.forward = headingSmooth; }while (DistanceTo(target.First) > (mWalkSpeed * Time.deltaTime * 1.1f)); this.UnityGameObject.transform.position = target.First; this.UnityGameObject.transform.forward = target.Second; if (onTargetReachedCallback != null) { onTargetReachedCallback(); } }