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; } } } }
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); } } }
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; } } }