private void Update() { // Age over time _age = Mathf.Clamp01(_age + Time.deltaTime * kAgeRate); CritterConstants.CreatureSize ageNewSize = CritterConstants.GetCreatureSizeAtAge(_age); if (ageNewSize != _size) { SetSize(ageNewSize, animate: true); } // Gain vigor, if we're old enough if ((int)_size >= (int)kMinVigorSize) { _vigorLevel = Mathf.Clamp01(_vigorLevel + Time.deltaTime * kVigorGainRate); _vigorUI.FillPercent = _vigorLevel; } // Change direction sometimes _changeDirectionTimer -= Time.deltaTime; if (_changeDirectionTimer < 0) { _changeDirectionTimer = _changeDirTimeRange.RandomValue; _desiredDirection = Random.onUnitSphere.WithY(0).normalized; _isMoving = Random.value > _moveChance; if (_animator != null) { _animator.SetBool(kAnimParamIsWalking, _isMoving); } } // Slowly change move direction towards current desired direction / rotate to face move direction _moveDirection = Mathfx.Damp(_moveDirection, _desiredDirection, 0.5f, Time.deltaTime * _turnSpeed).WithY(0); if (_moveDirection.magnitude > 0.1f) { Quaternion desiredRot = Quaternion.LookRotation(_moveDirection, Vector3.up); _rigidBody.rotation = Mathfx.Damp(_rigidBody.rotation, desiredRot, 0.5f, Time.deltaTime * _turnSpeed); } // Occaisonally raycast for obstacles _obstacleRaycastTimer -= Time.deltaTime; if (_obstacleRaycastTimer < 0) { _obstacleRaycastTimer = 2; RaycastHit hitInfo; if (Physics.Raycast(transform.position, _desiredDirection, out hitInfo, _obstacleAvoidDistance, _obstacleMask)) { _desiredDirection = Quaternion.Euler(0, 90, 0) * _desiredDirection; _changeDirectionTimer = _changeDirTimeRange.MaxValue; Debug.DrawLine(transform.position, hitInfo.point, Color.red, 1.0f); } else { Debug.DrawRay(transform.position, _desiredDirection * _obstacleAvoidDistance, Color.white, 0.5f); } } // If we have full vigor, look for the closest mate and go get em if (IsReadyForLove) { if (_mateSearchIndex >= _instances.Count) { _mateSearchIndex = 0; } // Find nearest available mate lazily over time if (_mateSearchIndex < _instances.Count) { CritterController potentialMate = _instances[_mateSearchIndex]; if (potentialMate != this && potentialMate.IsReadyForLove) { float distToMate = Vector3.Distance(transform.position, potentialMate.transform.position); float distToNearestMate = _nearestMate != null?Vector3.Distance(transform.position, _nearestMate.transform.position) : Mathf.Infinity; if (distToMate < distToNearestMate) { _nearestMate = potentialMate; } } ++_mateSearchIndex; } // Move towards current desired mate if (_nearestMate != null) { Vector3 toMateVec = _nearestMate.transform.position - transform.position; _changeDirectionTimer = 1; _isMoving = true; _desiredDirection = toMateVec.normalized; // If someone gets to our potential mate first we have to try for someone else if (!_nearestMate.IsReadyForLove) { _nearestMate = null; return; } // If we get close enough, begin the process float distToMate = toMateVec.magnitude; if (distToMate < kMinMateDistance) { MateWith(_nearestMate, isLeader: true); } } } Debug.DrawRay(transform.position, _desiredDirection, Color.blue); }
public void SetAge(float newAge, bool animate) { _age = newAge; SetSize(CritterConstants.GetCreatureSizeAtAge(_age), animate); }