/// <summary>Update is called once per frame</summary> protected override void OnUpdate(float dt) { deltaTime = dt; if (richPath != null) { //System.Diagnostics.Stopwatch w = new System.Diagnostics.Stopwatch(); //w.Start(); RichPathPart pt = richPath.GetCurrentPart(); var fn = pt as RichFunnel; if (fn != null) { //Clear buffers for reuse Vector3 position = UpdateTarget(fn); //tr.position = ps; //Only get walls every 5th frame to save on performance if (Time.frameCount % 5 == 0 && wallForce > 0 && wallDist > 0) { wallBuffer.Clear(); fn.FindWalls(wallBuffer, wallDist); } /*for (int i=0;i<wallBuffer.Count;i+=2) { * Debug.DrawLine (wallBuffer[i],wallBuffer[i+1],Color.magenta); * }*/ //Pick next waypoint if current is reached int tgIndex = 0; /*if (buffer.Count > 1) { * if ((buffer[tgIndex]-tr.position).sqrMagnitude < pickNextWaypointDist*pickNextWaypointDist) { * tgIndex++; * } * }*/ //Target point Vector3 tg = nextCorners[tgIndex]; Vector3 dir = tg - position; dir.y = 0; bool passedTarget = Vector3.Dot(dir, currentTargetDirection) < 0; //Check if passed target in another way if (passedTarget && nextCorners.Count - tgIndex > 1) { tgIndex++; tg = nextCorners[tgIndex]; } if (tg != lastTargetPoint) { currentTargetDirection = (tg - position); currentTargetDirection.y = 0; currentTargetDirection.Normalize(); lastTargetPoint = tg; //Debug.DrawRay (tr.position, Vector3.down*2,Color.blue,0.2f); } //Direction to target dir = (tg - position); dir.y = 0; float magn = dir.magnitude; //Write out for other scripts to read distanceToSteeringTarget = magn; //Normalize dir = magn == 0 ? Vector3.zero : dir / magn; Vector3 normdir = dir; Vector3 force = Vector3.zero; if (wallForce > 0 && wallDist > 0) { float wLeft = 0; float wRight = 0; for (int i = 0; i < wallBuffer.Count; i += 2) { Vector3 closest = VectorMath.ClosestPointOnSegment(wallBuffer[i], wallBuffer[i + 1], tr.position); float dist = (closest - position).sqrMagnitude; if (dist > wallDist * wallDist) { continue; } Vector3 tang = (wallBuffer[i + 1] - wallBuffer[i]).normalized; //Using the fact that all walls are laid out clockwise (seeing from inside) //Then left and right (ish) can be figured out like this float dot = Vector3.Dot(dir, tang) * (1 - System.Math.Max(0, (2 * (dist / (wallDist * wallDist)) - 1))); if (dot > 0) { wRight = System.Math.Max(wRight, dot); } else { wLeft = System.Math.Max(wLeft, -dot); } } Vector3 norm = Vector3.Cross(Vector3.up, dir); force = norm * (wRight - wLeft); //Debug.DrawRay (tr.position, force, Color.cyan); } //Is the endpoint of the path (part) the current target point bool endPointIsTarget = lastCorner && nextCorners.Count - tgIndex == 1; if (endPointIsTarget) { //Use 2nd or 3rd degree motion equation to figure out acceleration to reach target in "exact" [slowdownTime] seconds //Clamp to avoid divide by zero if (slowdownTime < 0.001f) { slowdownTime = 0.001f; } Vector3 diff = tg - position; diff.y = 0; if (preciseSlowdown) { //{ t = slowdownTime //{ diff = vt + at^2/2 + qt^3/6 //{ 0 = at + qt^2/2 //{ solve for a dir = (6 * diff - 4 * slowdownTime * velocity) / (slowdownTime * slowdownTime); } else { dir = 2 * (diff - slowdownTime * velocity) / (slowdownTime * slowdownTime); } dir = Vector3.ClampMagnitude(dir, acceleration); force *= System.Math.Min(magn / 0.5f, 1); if (magn < endReachedDistance) { //END REACHED NextPart(); } } else { dir *= acceleration; } //Debug.DrawRay (tr.position+Vector3.up, dir*3, Color.blue); velocity += (dir + force * wallForce) * deltaTime; if (slowWhenNotFacingTarget) { float dot = (Vector3.Dot(normdir, tr.forward) + 0.5f) * (1.0f / 1.5f); //velocity = Vector3.ClampMagnitude (velocity, maxSpeed * Mathf.Max (dot, 0.2f) ); float xzmagn = Mathf.Sqrt(velocity.x * velocity.x + velocity.z * velocity.z); float prevy = velocity.y; velocity.y = 0; float mg = Mathf.Min(xzmagn, maxSpeed * Mathf.Max(dot, 0.2f)); velocity = Vector3.Lerp(tr.forward * mg, velocity.normalized * mg, Mathf.Clamp(endPointIsTarget ? (magn * 2) : 0, 0.5f, 1.0f)); velocity.y = prevy; } else { // Clamp magnitude on the XZ axes float xzmagn = Mathf.Sqrt(velocity.x * velocity.x + velocity.z * velocity.z); xzmagn = maxSpeed / xzmagn; if (xzmagn < 1) { velocity.x *= xzmagn; velocity.z *= xzmagn; //Vector3.ClampMagnitude (velocity, maxSpeed); } } //Debug.DrawLine (tr.position, tg, lastCorner ? Color.red : Color.green); if (endPointIsTarget) { Vector3 trotdir = Vector3.Lerp(velocity, currentTargetDirection, System.Math.Max(1 - magn * 2, 0)); RotateTowards(trotdir); } else { RotateTowards(velocity); } //Applied after rotation to enable proper checks on if velocity is zero velocity += deltaTime * gravity; if (rvoController != null && rvoController.enabled) { //Use RVOController tr.position = position; rvoController.Move(velocity); } else if (controller != null && controller.enabled) { //Use CharacterController tr.position = position; controller.Move(velocity * deltaTime); } else { //Use Transform float lasty = position.y; position += velocity * deltaTime; position = RaycastPosition(position, lasty); tr.position = position; } } else { if (rvoController != null && rvoController.enabled) { //Use RVOController rvoController.Move(Vector3.zero); } } if (pt is RichSpecial) { if (!traversingOffMeshLink) { StartCoroutine(TraverseSpecial(pt as RichSpecial)); } } //w.Stop(); //Debug.Log ((w.Elapsed.TotalMilliseconds*1000)); } else { if (rvoController != null && rvoController.enabled) { //Use RVOController rvoController.Move(Vector3.zero); } else if (controller != null && controller.enabled) { } else { tr.position = RaycastPosition(tr.position, tr.position.y); } } UpdateVelocity(); lastDeltaTime = dt; }
// Token: 0x0600276A RID: 10090 RVA: 0x001AE518 File Offset: 0x001AC718 protected override void Update() { LegacyRichAI.deltaTime = Mathf.Min(Time.smoothDeltaTime * 2f, Time.deltaTime); if (this.richPath != null) { RichPathPart currentPart = this.richPath.GetCurrentPart(); RichFunnel richFunnel = currentPart as RichFunnel; if (richFunnel != null) { Vector3 vector = this.UpdateTarget(richFunnel); if (Time.frameCount % 5 == 0 && this.wallForce > 0f && this.wallDist > 0f) { this.wallBuffer.Clear(); richFunnel.FindWalls(this.wallBuffer, this.wallDist); } int num = 0; Vector3 vector2 = this.nextCorners[num]; Vector3 vector3 = vector2 - vector; vector3.y = 0f; if (Vector3.Dot(vector3, this.currentTargetDirection) < 0f && this.nextCorners.Count - num > 1) { num++; vector2 = this.nextCorners[num]; } if (vector2 != this.lastTargetPoint) { this.currentTargetDirection = vector2 - vector; this.currentTargetDirection.y = 0f; this.currentTargetDirection.Normalize(); this.lastTargetPoint = vector2; } vector3 = vector2 - vector; vector3.y = 0f; float magnitude = vector3.magnitude; this.distanceToSteeringTarget = magnitude; vector3 = ((magnitude == 0f) ? Vector3.zero : (vector3 / magnitude)); Vector3 lhs = vector3; Vector3 a = Vector3.zero; if (this.wallForce > 0f && this.wallDist > 0f) { float num2 = 0f; float num3 = 0f; for (int i = 0; i < this.wallBuffer.Count; i += 2) { float sqrMagnitude = (VectorMath.ClosestPointOnSegment(this.wallBuffer[i], this.wallBuffer[i + 1], this.tr.position) - vector).sqrMagnitude; if (sqrMagnitude <= this.wallDist * this.wallDist) { Vector3 normalized = (this.wallBuffer[i + 1] - this.wallBuffer[i]).normalized; float num4 = Vector3.Dot(vector3, normalized) * (1f - Math.Max(0f, 2f * (sqrMagnitude / (this.wallDist * this.wallDist)) - 1f)); if (num4 > 0f) { num3 = Math.Max(num3, num4); } else { num2 = Math.Max(num2, -num4); } } } a = Vector3.Cross(Vector3.up, vector3) * (num3 - num2); } bool flag = this.lastCorner && this.nextCorners.Count - num == 1; if (flag) { if (this.slowdownTime < 0.001f) { this.slowdownTime = 0.001f; } Vector3 a2 = vector2 - vector; a2.y = 0f; if (this.preciseSlowdown) { vector3 = (6f * a2 - 4f * this.slowdownTime * this.velocity) / (this.slowdownTime * this.slowdownTime); } else { vector3 = 2f * (a2 - this.slowdownTime * this.velocity) / (this.slowdownTime * this.slowdownTime); } vector3 = Vector3.ClampMagnitude(vector3, this.acceleration); a *= Math.Min(magnitude / 0.5f, 1f); if (magnitude < this.endReachedDistance) { base.NextPart(); } } else { vector3 *= this.acceleration; } this.velocity += (vector3 + a * this.wallForce) * LegacyRichAI.deltaTime; if (this.slowWhenNotFacingTarget) { float a3 = (Vector3.Dot(lhs, this.tr.forward) + 0.5f) * 0.6666667f; float a4 = Mathf.Sqrt(this.velocity.x * this.velocity.x + this.velocity.z * this.velocity.z); float y = this.velocity.y; this.velocity.y = 0f; float d = Mathf.Min(a4, this.maxSpeed * Mathf.Max(a3, 0.2f)); this.velocity = Vector3.Lerp(this.tr.forward * d, this.velocity.normalized * d, Mathf.Clamp(flag ? (magnitude * 2f) : 0f, 0.5f, 1f)); this.velocity.y = y; } else { float num5 = Mathf.Sqrt(this.velocity.x * this.velocity.x + this.velocity.z * this.velocity.z); num5 = this.maxSpeed / num5; if (num5 < 1f) { this.velocity.x = this.velocity.x * num5; this.velocity.z = this.velocity.z * num5; } } if (flag) { Vector3 trotdir = Vector3.Lerp(this.velocity, this.currentTargetDirection, Math.Max(1f - magnitude * 2f, 0f)); this.RotateTowards(trotdir); } else { this.RotateTowards(this.velocity); } this.velocity += LegacyRichAI.deltaTime * this.gravity; if (this.rvoController != null && this.rvoController.enabled) { this.tr.position = vector; this.rvoController.Move(this.velocity); } else if (this.controller != null && this.controller.enabled) { this.tr.position = vector; this.controller.Move(this.velocity * LegacyRichAI.deltaTime); } else { float y2 = vector.y; vector += this.velocity * LegacyRichAI.deltaTime; vector = this.RaycastPosition(vector, y2); this.tr.position = vector; } } else if (this.rvoController != null && this.rvoController.enabled) { this.rvoController.Move(Vector3.zero); } if (currentPart is RichSpecial && !base.traversingOffMeshLink) { base.StartCoroutine(this.TraverseSpecial(currentPart as RichSpecial)); } } else if (this.rvoController != null && this.rvoController.enabled) { this.rvoController.Move(Vector3.zero); } else if (!(this.controller != null) || !this.controller.enabled) { this.tr.position = this.RaycastPosition(this.tr.position, this.tr.position.y); } base.UpdateVelocity(); this.lastDeltaTime = Time.deltaTime; }