Pathfinding.RichAI.Update C# (CSharp) Method

Update() protected method

protected Update ( ) : void
return void
		protected virtual void Update () {
			deltaTime = Mathf.Min (Time.smoothDeltaTime*2, Time.deltaTime);
			
			if (rp != null) {
				//System.Diagnostics.Stopwatch w = new System.Diagnostics.Stopwatch();
				//w.Start();
				RichPathPart pt = rp.GetCurrentPart();
				RichFunnel 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) {
						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 = buffer[tgIndex];
					Vector3 dir = tg-position;
					dir.y = 0;
					
					bool passedTarget = Vector3.Dot (dir,currentTargetDirection) < 0;
					//Check if passed target in another way
					if (passedTarget && buffer.Count-tgIndex > 1) {
						tgIndex++;
						tg = buffer[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
					distanceToWaypoint = 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 = AstarMath.NearestPointStrict (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 && buffer.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) {
					RichSpecial rs = pt as RichSpecial;
					
					if (!traversingSpecialPath) {
						StartCoroutine(TraverseSpecial(rs));
					}
				}
				//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);
				}
			}
		}