示例#1
0
    private void SetSize(CritterConstants.CreatureSize newSize, bool animate)
    {
        _size            = newSize;
        _critterDNA.Size = newSize;
        _vigorUI.gameObject.SetActive(((int)_size >= (int)kMinVigorSize));

        if (animate)
        {
            StartCoroutine(UpdateSizeAsync());
        }
        else
        {
            _visualRoot.localScale = Vector3.one * CritterConstants.GetCreatureSizeScale(_size);
        }
    }
示例#2
0
    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);
    }