예제 #1
0
    private bool FindEnemy(IAiStateMachine stateMachine)
    {
        //visibility Check
        var objectsInView = stateMachine.FieldOfViewComponent.GameObjectsInView;

        //check surroundings for enemy target or friendlies
        if (stateMachine.EnemyTags.Length > 0 && objectsInView.Count > 0)
        {
            string[]     tags    = stateMachine.EnemyTags;
            GameObject[] enemies = objectsInView.Where(enemy => tags.Contains(enemy.tag)).ToArray();

            if (enemies.Length <= 0)
            {
                return(false);
            }

            var priorityEnemy = FindPriorityEnemy(enemies);

            if (priorityEnemy != stateMachine.GameObject && priorityEnemy != stateMachine.CharacterStateMachine.TargetObject)
            {
                stateMachine.CharacterStateMachine.SetTargetObject(priorityEnemy);
                return(true);
            }
        }

        return(false);
    }
예제 #2
0
    public IAiState Execute(IAiStateMachine stateMachine, float deltaTime)
    {
        _attackTimer += deltaTime;

        if (TargetObject == null)
        {
            var enemies = CheckForEnemies(stateMachine);

            //go to position and arrive first if there are no enemies before returning to wander state.
            //check distance from target Position is close before checking other things;

            if (enemies == null)
            {
                return(stateMachine.WanderState);
            }

            if (enemies.Length == 0)
            {
                return(stateMachine.WanderState);
            }

            TargetObject = enemies[0];
            Reposition(TargetObject, stateMachine, deltaTime);
        }
        else
        {
            Reposition(TargetObject, stateMachine, deltaTime);
        }

        stateMachine.MoverComponent.MoveDirection(_direction);


        return(this);
    }
예제 #3
0
    private void StayNearSpawnPoint(IAiStateMachine stateMachine)
    {
        _distanceFromSpawnPoint = Vector3.Distance(spawnPoint, stateMachine.MoverComponent.CurrentPosition);

        if (_distanceFromSpawnPoint > maxDistanceFromSpawnPoint)
        {
            _wanderPoint = GetPointWithinACircle(spawnPoint, UnityEngine.Random.Range(0, radius), 360);
            stateMachine.CharacterStateMachine.SetTargetLocation(_wanderPoint);
        }
    }
예제 #4
0
    private void Wander(IAiStateMachine stateMachine, float interval)
    {
        if (_time > interval)
        {
            _time = 0;

            _wanderIntervalTime = UnityEngine.Random.Range(minWanderTimeInterval, maxWanderTimeInterval);
            _distanceAhead      = UnityEngine.Random.Range(minDistanceAhead, maxDistanceAhead);
            _wanderPoint        = PickAPointInFront(stateMachine.MoverComponent, _distanceAhead, radius, maxDirectionAngleRange);

            stateMachine.CharacterStateMachine.SetTargetLocation(_wanderPoint);
        }
    }
예제 #5
0
    public IAiState Execute(IAiStateMachine stateMachine, float deltaTime)
    {
        _time += deltaTime;

        if (FindEnemy(stateMachine))
        {
            Debug.Log("Enemy Found.");
        }
        //return stateMachine.EngagedState;
        Wander(stateMachine, _wanderIntervalTime);
        StayNearSpawnPoint(stateMachine);

        return(this);
    }
예제 #6
0
    private void Reposition(GameObject targetObject, IAiStateMachine stateMachine, float deltaTime)
    {
        var   targetPosition = targetObject.transform.position;
        float distance       = Vector3.Distance(targetPosition, stateMachine.MoverComponent.CurrentPosition);

        bool isInAttackRange = distance <= attackDistance;
        bool canAttack       = _attackTimer > attackInterval;
        bool isClose         = distance < minDistanceToMaintain;
        bool isFar           = distance > maxDistanceToMaintain;
        bool isTooFar        = distance > stateMachine.FieldOfViewComponent.Radius;
        bool canSeeTarget    = stateMachine.FieldOfViewComponent.GameObjectsInView.Contains(TargetObject);

        if (isTooFar || !canSeeTarget)
        {
            TargetObject = null;
        }

        //if low on life go to flee state

        if (canAttack && isInAttackRange)
        {
            //go to attack state
            Attack(TargetObject);
        }

        if (isClose)
        {
            _direction += SteeringBehaviour.Flee(targetPosition, _direction, stateMachine.MoverComponent) * deltaTime;
        }
        else if (isFar)
        {
            _direction += SteeringBehaviour.Seek(targetPosition, _direction, stateMachine.MoverComponent) * deltaTime;
        }
        else
        {
            var direction = SteeringBehaviour.Seek(targetPosition, _direction, stateMachine.MoverComponent).normalized;
            stateMachine.MoverComponent.MoveDirection(direction);
            _direction = SteeringBehaviour.Arriving(stateMachine.MoverComponent, _direction, targetPosition, maxDistanceToMaintain, .05f);
        }
        //arrival behaviour
        //attack
        //roam around
    }
예제 #7
0
    private GameObject[] CheckForEnemies(IAiStateMachine stateMachine)
    {
        //visibility Check
        var objectsInView = stateMachine.FieldOfViewComponent.GameObjectsInView;

        //check surroundings for enemy target or friendlies
        if (stateMachine.EnemyTags.Length > 0 && objectsInView.Count > 0)
        {
            string[]     tags    = stateMachine.EnemyTags;
            GameObject[] enemies = objectsInView.Where(item => tags.Contains(item.tag)).ToArray();

            //first enemy
            //closest enemy
            //lowest health enemy
            return(enemies);
        }
        //if enemy - change to engaged behaviour
        //if friendly - implement cohesion behaviour?
        //if neutral - do nothing

        //implement obstacle avoidance
        return(null);
    }
 public IAiState Execute(IAiStateMachine stateMachine, float deltaTime)
 {
     return(this);
 }