// Add force only till max force // Return true if there is still capacity to add // Return false if max force has been reached bool AccumulateForceForWeightedPriority(BaseBehavior b) { Vector3 force = b.steeringForce; // Apply scaling weight factor with individual weight b.ApplySteeringScaleFactor(_weightScaleFactor * b.weight); float combinedForceMagnitude = _steeringForce.magnitude; float remainingForceMagnitude = maxForce - combinedForceMagnitude; if (remainingForceMagnitude <= 0) { return(false); } float currentForceMagnitude = force.magnitude; if (currentForceMagnitude <= remainingForceMagnitude) { _steeringForce += force; } else { force.Normalize(); Vector3 newForce = force * remainingForceMagnitude; _steeringForce += newForce; return(false); } return(true); }
public void InitForTick() { if (isPaused) { return; } _position = _aiCharacter.Position; _rotation = _aiCharacter.Rotation; _heading = _aiCharacter.Forward; _side = _aiCharacter.Right; _up = _aiCharacter.Up; BaseBehavior b = null; for (int i = 0; i < _currentBehaviors.Count; ++i) { b = _currentBehaviors[i]; if (!b.isPaused) { b.InitForFrame(); } } }
public void UpdateForTick() { if (isPaused) { return; } if (_currentBehaviors.Count > 0) { _totalActiveBehaviors = 0; BaseBehavior b = null; // Get total active behaviors for (int i = 0; i < _currentBehaviors.Count; ++i) { b = _currentBehaviors[i]; if (b.CanUpdateThisFrame()) { _totalActiveBehaviors++; } } if (_totalActiveBehaviors > 0) { // Calculate the weight scale factor based on total active _weightScaleFactor = _totalActiveBehaviors > 0?_currentBehaviors.Count / _totalActiveBehaviors:1; _steeringForce = Vector3.zero; for (int i = 0; i < _currentBehaviors.Count; ++i) { b = _currentBehaviors[i]; if (b.CanUpdateThisFrame()) { // Calculate the steering force by each behavior b.UpdateForFrame(); bool hasSteeringForce = b.steeringForce.sqrMagnitude > 0; if (hasSteeringForce) { if (UsePrioritizedWeightSum()) { AccumulateForceForWeightedPriority(b); } else if (UsePriortizedSkip()) { _steeringForce += b.steeringForce; break; } else if (UsePriortizedDither()) { float randomChance = Random.Range(0.0f, 1.0f); if (randomChance < b.probability) { _steeringForce += b.steeringForce; break; } } else if (UseWeightedSum()) { _steeringForce += b.steeringForce * b.weight; } } } } // Steering Force ClampSteeringForce(); // Acceleration _acceleration = _steeringForce / mass; // Velocity _velocity += _acceleration; // Position if (_velocity.sqrMagnitude > ZERO_VELOCITY_APPROX) { ClampVelocity(); _position += _velocity * Time.deltaTime; if (SteeringManager.Instance.useXYPlane) { _rotation = Quaternion.LookRotation(_velocity, -Vector3.forward); } else { _rotation = Quaternion.LookRotation(_velocity); } } } } }
int SortBehavior(BaseBehavior b1, BaseBehavior b2) { return(b2.priority - b1.priority); }
public void RemoveBehavior(BaseBehavior b) { _currentBehaviors.Remove(b); }
public void AddBehavior(BaseBehavior b) { _currentBehaviors.Add(b); _currentBehaviors.Sort(SortBehavior); }