Пример #1
0
        public void AggressiveFindTarget(float time, Vector3 currentPosition)
        {
            // Aggressive monster or summoned monster will find target to attacker
            if (monsterDatabase.characteristic != MonsterCharacteristic.Aggressive &&
                CacheMonsterCharacterEntity.Summoner == null)
            {
                return;
            }

            BaseCharacterEntity targetCharacter;

            if (!CacheMonsterCharacterEntity.TryGetTargetEntity(out targetCharacter) || targetCharacter.IsDead())
            {
                // If no target enenmy or target enemy is dead, Find nearby character by layer mask
                var foundObjects = new List <Collider2D>(Physics2D.OverlapCircleAll(currentPosition, monsterDatabase.visualRange, gameInstance.characterLayer.Mask));
                foreach (var foundObject in foundObjects)
                {
                    var characterEntity = foundObject.GetComponent <BaseCharacterEntity>();
                    // Attack target settings
                    if (characterEntity != null &&
                        characterEntity.CanReceiveDamageFrom(CacheMonsterCharacterEntity))
                    {
                        SetStartFollowTargetTime(time);
                        CacheMonsterCharacterEntity.SetAttackTarget(characterEntity);
                        return;
                    }
                }
            }
        }
Пример #2
0
        protected void FixedUpdate()
        {
            if (!CacheMonsterCharacterEntity.IsServer)
            {
                return;
            }

            if (isStopped)
            {
                CacheRigidbody2D.velocity = Vector2.zero;
                return;
            }

            if (currentDestination.HasValue)
            {
                var currentPosition = new Vector2(CacheTransform.position.x, CacheTransform.position.y);
                moveDirection = (currentDestination.Value - currentPosition).normalized;
                if (Vector3.Distance(currentDestination.Value, currentPosition) < stoppingDistance)
                {
                    StopMove();
                }
                else
                {
                    CacheMonsterCharacterEntity.UpdateCurrentDirection(moveDirection);
                    CacheRigidbody2D.velocity = moveDirection * speed;
                }
            }
        }
        public void FollowSummoner(float time)
        {
            // If stopped then random
            Vector3 randomPosition = CacheMonsterCharacterEntity.spawnPosition + new Vector3(Random.Range(-1f, 1f) * randomWanderDistance, 0, Random.Range(-1f, 1f) * randomWanderDistance);

            if (CacheMonsterCharacterEntity.Summoner != null)
            {
                randomPosition = CacheMonsterCharacterEntity.Summoner.GetSummonPosition();
            }
            CacheMonsterCharacterEntity.SetTargetEntity(null);
            SetDestination(time, randomPosition);
        }
        public void AggressiveFindTarget(float time, Vector3 currentPosition)
        {
            // Aggressive monster or summoned monster will find target to attack
            if (monsterDatabase.characteristic != MonsterCharacteristic.Aggressive &&
                CacheMonsterCharacterEntity.Summoner == null)
            {
                return;
            }

            BaseCharacterEntity targetCharacter;

            if (!CacheMonsterCharacterEntity.TryGetTargetEntity(out targetCharacter) || targetCharacter.IsDead())
            {
                // If no target enenmy or target enemy is dead, Find nearby character by layer mask
                List <Collider> foundObjects = new List <Collider>(Physics.OverlapSphere(currentPosition, monsterDatabase.visualRange, gameInstance.characterLayer.Mask));
                foreach (Collider foundObject in foundObjects)
                {
                    BaseCharacterEntity characterEntity = foundObject.GetComponent <BaseCharacterEntity>();
                    // Attack target settings
                    if (characterEntity == null || !characterEntity.CanReceiveDamageFrom(CacheMonsterCharacterEntity))
                    {
                        // If character is null or cannot receive damage from monster, skip it
                        continue;
                    }
                    if (CacheMonsterCharacterEntity.Summoner != null &&
                        CacheMonsterCharacterEntity.Summoner != characterEntity.GetTargetEntity())
                    {
                        // If character is not attacking summoner, skip it
                        continue;
                    }
                    if (!CacheMonsterCharacterEntity.IsEnemy(characterEntity))
                    {
                        // If character is not enemy, skip it
                        continue;
                    }
                    // Found target, attack it
                    SetStartFollowTargetTime(time);
                    CacheMonsterCharacterEntity.SetAttackTarget(characterEntity);
                    break;
                }
            }
        }
        public void UpdateAttackTarget(float time, Vector3 currentPosition, BaseCharacterEntity targetEntity)
        {
            // If it has target then go to target
            Vector3 targetEntityPosition = targetEntity.CacheTransform.position;
            float   attackDistance       = CacheMonsterCharacterEntity.GetAttackDistance(false);

            attackDistance -= attackDistance * 0.1f;
            attackDistance -= CacheNavMeshAgent.stoppingDistance;
            if (Vector3.Distance(currentPosition, targetEntityPosition) <= attackDistance)
            {
                StopMove();
                SetStartFollowTargetTime(time);
                // Lookat target then do anything when it's in range
                Vector3 lookAtDirection = (targetEntityPosition - currentPosition).normalized;
                // slerp to the desired rotation over time
                if (lookAtDirection.magnitude > 0)
                {
                    Vector3 lookRotationEuler = Quaternion.LookRotation(lookAtDirection).eulerAngles;
                    lookRotationEuler.x = 0;
                    lookRotationEuler.z = 0;
                    CacheMonsterCharacterEntity.CacheTransform.rotation = Quaternion.RotateTowards(CacheMonsterCharacterEntity.CacheTransform.rotation, Quaternion.Euler(lookRotationEuler), CacheNavMeshAgent.angularSpeed * Time.deltaTime);
                }
                CacheMonsterCharacterEntity.RequestAttack(false, targetEntity.OpponentAimTransform.position);
                // TODO: Random to use skills
            }
            else
            {
                // Following target
                if (oldDestination != targetEntityPosition &&
                    time - setDestinationTime >= setTargetDestinationDelay)
                {
                    SetDestination(time, targetEntityPosition);
                }
                // Stop following target
                if (time - startFollowTargetTime >= followTargetDuration)
                {
                    RandomWanderTarget(time);
                }
            }
        }
Пример #6
0
        public void UpdateAttackTarget(float time, Vector3 currentPosition, BaseCharacterEntity targetEntity)
        {
            // If it has target then go to target
            var targetEntityPosition = targetEntity.CacheTransform.position;
            var attackDistance       = CacheMonsterCharacterEntity.GetAttackDistance();

            attackDistance -= attackDistance * 0.1f;
            attackDistance -= stoppingDistance;
            if (Vector3.Distance(currentPosition, targetEntityPosition) <= attackDistance)
            {
                StopMove();
                SetStartFollowTargetTime(time);
                // Lookat target then do anything when it's in range
                var targetDirection = (targetEntity.CacheTransform.position - CacheMonsterCharacterEntity.CacheTransform.position).normalized;
                if (targetDirection.magnitude != 0f)
                {
                    CacheMonsterCharacterEntity.UpdateCurrentDirection(targetDirection);
                }
                CacheMonsterCharacterEntity.RequestAttack();
                // TODO: Random to use skills
            }
            else
            {
                // Following target
                if (oldDestination != targetEntityPosition &&
                    time - setDestinationTime >= setTargetDestinationDelay)
                {
                    SetDestination(time, targetEntityPosition);
                }
                // Stop following target
                if (time - startFollowTargetTime >= followTargetDuration)
                {
                    RandomWanderTarget(time);
                }
            }
        }
        protected void UpdateActivity(float time)
        {
            if (!CacheMonsterCharacterEntity.IsServer || CacheMonsterCharacterEntity.Identity.CountSubscribers() == 0 || monsterDatabase == null)
            {
                return;
            }

            if (CacheNavMeshAgent.velocity.magnitude > 0)
            {
                CacheMonsterCharacterEntity.MovementState = MovementState.Forward | MovementState.IsGrounded;
            }
            else
            {
                CacheMonsterCharacterEntity.MovementState = MovementState.IsGrounded;
            }

            if (CacheMonsterCharacterEntity.IsDead())
            {
                StopMove();
                CacheMonsterCharacterEntity.SetTargetEntity(null);
                return;
            }

            Vector3 currentPosition = CacheMonsterCharacterEntity.CacheTransform.position;

            if (CacheMonsterCharacterEntity.Summoner != null &&
                Vector3.Distance(currentPosition, CacheMonsterCharacterEntity.Summoner.CacheTransform.position) > gameInstance.minFollowSummonerDistance)
            {
                // Follow summoner with stat's move speed
                FollowSummoner(time);
                return;
            }

            if (CacheMonsterCharacterEntity.Summoner == null && CacheMonsterCharacterEntity.isInSafeArea)
            {
                // If monster move into safe area, wander to another place
                RandomWanderTarget(time);
                return;
            }

            BaseCharacterEntity targetEntity;

            if (CacheMonsterCharacterEntity.TryGetTargetEntity(out targetEntity))
            {
                if (targetEntity.IsDead() || targetEntity.isInSafeArea)
                {
                    // If target is dead or in safe area stop attacking
                    CacheMonsterCharacterEntity.SetTargetEntity(null);
                    return;
                }
                UpdateAttackTarget(time, currentPosition, targetEntity);
            }
            else
            {
                // Find target when it's time
                if (time >= findTargetTime)
                {
                    SetFindTargetTime(time);
                    AggressiveFindTarget(time, currentPosition);
                    return;
                }

                // Wandering when it's time
                if (time >= wanderTime)
                {
                    RandomNextWanderTime(time);
                    RandomWanderTarget(time);
                    return;
                }
            }
        }