/*enum MeleeFighterState * { * TooFar, * TooNear, * InMeleeDistance * } * * MeleeFighterState state;*/ protected override void Update() { if (Time.time > nextDistanceCheckTime) { nextDistanceCheckTime = Time.time + distanceCheckingInterval; myWidth = entity.width; enemyWidth = enemySensing.nearestEnemy.width; Vector3 nearestEnemyPosition = enemySensing.nearestEnemy.transform.position; Vector3 myPosition = entity.transform.position; float widthFactor = myWidth + enemyWidth; //multiply the resulting distanceVectorBythisFactor to also use width Vector3 distanceVector = nearestEnemyPosition - myPosition; //float distanceToEnemySquared = (distanceVector - distanceVector.normalized * widthFactor).sqrMagnitude; float distanceToEnemy = (distanceVector - distanceVector.normalized * widthFactor).magnitude; //if the enemy is moving, we move to the position he will be at the time we arrive EC_Movement enemyMovement = enemySensing.nearestEnemy.GetComponent <EC_Movement>(); if (enemyMovement.IsMoving()) { //heuristically calculae future position //1. how long will it take for me to reach the enemy? float timeToReachEnemy = distanceToEnemy / movement.GetMaxSpeed(); //2. where will the enemy be after this time Vector3 futurePosition = nearestEnemyPosition + enemyMovement.GetCurrentVelocity() * timeToReachEnemy; movement.MoveTo(futurePosition); } else { movement.MoveTo(nearestEnemyPosition + (myPosition - nearestEnemyPosition).normalized * (perfectMeleeDistance + myWidth + enemyWidth)); } if ((nearestEnemyPosition - myPosition).sqrMagnitude > maxMeleeDistance) { inRange = false; movement.StopLookAt(); } else { inRange = true; movement.LookAt(enemySensing.nearestEnemy.transform); } } if (inRange) { if (weapon.CanAttack()) { weapon.Attack(); } } }
void Posess() { unitIsPosessedByPlayer = true; unitAI.posessedByPlayer = true; movement.StopLookAt(); cam.GetComponent <SmoothCameraFollow>().enabled = true; // movement.Posess(); }
protected override void Update() { if (Time.time > nextDistanceCheckTime) { nextDistanceCheckTime = Time.time + distanceCheckingInterval; myWidth = entity.width; enemyWidth = enemySensing.nearestEnemy.width; Vector3 nearestEnemyPosition = enemySensing.nearestEnemy.transform.position; Vector3 myPosition = entity.transform.position; float widthFactor = myWidth + enemyWidth; //multiply the resulting distanceVectorBythisFactor to also use width Vector3 distanceVector = nearestEnemyPosition - myPosition; float distanceToEnemy = (distanceVector - distanceVector.normalized * widthFactor).sqrMagnitude; movement.MoveTo(nearestEnemyPosition + (myPosition - nearestEnemyPosition).normalized * (perfectShootingDistance + myWidth + enemyWidth)); if ((nearestEnemyPosition - myPosition).sqrMagnitude > maxShootingDistance) { inRange = false; movement.StopLookAt(); weapon.StopAiming(); //Debug.Log("stop aim"); } else { inRange = true; // Debug.Log("start aim"); movement.LookAt(enemySensing.nearestEnemy.transform); weapon.AimAt(enemySensing.nearestEnemy); } } if (inRange) { if (weapon.CanShoot()) { weapon.Shoot(); } } }
public override void BehaviourUpdate() { //Profiler.BeginSample("BehaviourUpdate"); #region debug if (Input.GetKeyDown(KeyCode.B)) { combat.Block(currentStance.blocks[0]); } if (Input.GetKeyDown(KeyCode.N)) { combat.B_BlockFlinch(); } if (Input.GetKeyDown(KeyCode.M)) { combat.Evade(currentStance.evades[1]); } if (Input.GetKeyDown(KeyCode.L)) { combat.MeleeAttack(null, currentStance.attacks[1]); } #endregion //cache some variables for later nearestEnemy = sensing.nearestEnemy; currentStance = unitAI.currentStance; myTransformPosition = entity.myTransform.position; enemyIsNull = nearestEnemy == null; //1. look at the enemy, if no enemy present -> continue looking in the movement direction if (!enemyIsNull) { //but only if something chenged if (nearestEnemyLastFrame != nearestEnemy) { nearestEnemysTransform = nearestEnemy.myTransform; movement.LookAt(nearestEnemysTransform); } nearestEnemyPosition = nearestEnemysTransform.position; currentSquaredDistanceToNearestEnemy = (nearestEnemyPosition - myTransformPosition).sqrMagnitude; } else { if (nearestEnemyLastFrame != nearestEnemy) { movement.StopLookAt(); } } switch (meleeAttackBehaviourState) { //2. if theres an enemy -> walk towards him case MeleeAttackBehaviourState.Idle: if (!enemyIsNull) { movement.MoveTo(nearestEnemyPosition); meleeAttackBehaviourState = MeleeAttackBehaviourState.MovingToNearestEnemy; } break; case MeleeAttackBehaviourState.MovingToNearestEnemy: //check if the enemy is still alive if (enemyIsNull) { meleeAttackBehaviourState = MeleeAttackBehaviourState.Idle; movement.Stop(); } //else check if we reached the destination else if (currentSquaredDistanceToNearestEnemy < rangeToEnterMeleeCombatSquared) { meleeAttackBehaviourState = MeleeAttackBehaviourState.InMeleeFight; } //if not, check if we need to update the destination else { if (Time.time > nextUpdateDestinationTime) { nextUpdateDestinationTime = Time.time + updateDestinationInterval; movement.MoveTo(nearestEnemyPosition); } } break; case MeleeAttackBehaviourState.InMeleeFight: //check if the enemy is still alive if (enemyIsNull) { meleeAttackBehaviourState = MeleeAttackBehaviourState.Idle; movement.Stop(); } //check if the enemy has not escaped else if (currentSquaredDistanceToNearestEnemy > rangeToEnterMeleeCombatSquared) { if (combat.currentCombatState == CombatState.CombatIdle) { movement.MoveTo(nearestEnemyPosition); meleeAttackBehaviourState = MeleeAttackBehaviourState.MovingToNearestEnemy; } } //else check if i am in range for an attack - fix range and attack else { //decision making .- thats the tricky part here if (combat.currentCombatState == CombatState.CombatIdle) { //check if we should block because our adversary was faster if (nearestEnemy.combat.currentCombatState == CombatState.PreparingMeleeAttack) { //if he is lucky he will block or evade, if not then not :D if (Random.Range(0, 2) == 0) { if (Random.Range(0, 2) == 0) { combat.Block(currentStance.blocks[0]); } else { combat.Evade(currentStance.evades[0]); } } else { combat.MeleeAttack(nearestEnemy, currentStance.attacks[Random.Range(0, currentStance.attacks.Length)]); } } else { combat.MeleeAttack(nearestEnemy, currentStance.attacks[Random.Range(0, currentStance.attacks.Length)]); } } else if (combat.currentCombatState == CombatState.Blocking) { //check if we can stop blocking and attack if (nearestEnemy.combat.currentCombatState != CombatState.PreparingMeleeAttack) { combat.MeleeAttack(nearestEnemy, currentStance.attacks[Random.Range(0, currentStance.attacks.Length)]); } } } break; } nearestEnemyLastFrame = nearestEnemy; // Profiler.EndSample(); }
public override void UpdateComponent() { switch (state) { case MissileFighterState.Idle: if (sensing.nearestEnemy != null) { state = MissileFighterState.AttackingEnemy; } break; case MissileFighterState.AttackingEnemy: break; case MissileFighterState.AttackingBase: break; } switch (shootingState) { case ShootingState.TooNear: if (Time.time > nextCheckTime) { nextCheckTime = Time.time + checkingInterval; float distanceToEnemy = (sensing.nearestEnemy.transform.position - transform.position).sqrMagnitude; if (distanceToEnemy > minimalShootingDistance) { shootingState = ShootingState.InShootingDistance; movement.Stop(); } else { //move to a position perfectly in the shooting range movement.MoveTo((transform.position - sensing.nearestEnemy.transform.position).normalized * (minimalShootingDistance + (maximalShootingDistance - minimalShootingDistance) / 2)); weapon.AimAt(sensing.nearestEnemy); if (weapon.CanShoot()) { weapon.Shoot(); } } } break; case ShootingState.TooFarAway: if (Time.time > nextCheckTime) { nextCheckTime = Time.time + checkingInterval; float distanceToEnemy = (sensing.nearestEnemy.transform.position - transform.position).sqrMagnitude; if (distanceToEnemy < maximalShootingDistance) { shootingState = ShootingState.InShootingDistance; movement.LookAt(sensing.nearestEnemy.transform); weapon.AimAt(sensing.nearestEnemy); movement.Stop(); } else { movement.MoveTo((transform.position - sensing.nearestEnemy.transform.position).normalized * (minimalShootingDistance + (maximalShootingDistance - minimalShootingDistance) / 2)); } } break; case ShootingState.InShootingDistance: //1. check if we need to change state if (Time.time > nextCheckTime) { nextCheckTime = Time.time + checkingInterval; float distanceToEnemy = (sensing.nearestEnemy.transform.position - transform.position).sqrMagnitude; if (distanceToEnemy < minimalShootingDistance) { shootingState = ShootingState.TooNear; movement.LookAt(sensing.nearestEnemy.transform); movement.MoveTo((transform.position - sensing.nearestEnemy.transform.position).normalized * (minimalShootingDistance + (maximalShootingDistance - minimalShootingDistance) / 2)); } else if (distanceToEnemy > maximalShootingDistance) { shootingState = ShootingState.TooFarAway; movement.StopLookAt(); weapon.StopAiming(); movement.MoveTo((transform.position - sensing.nearestEnemy.transform.position).normalized * (minimalShootingDistance + (maximalShootingDistance - minimalShootingDistance) / 2)); } else { if (weapon.CanShoot()) { weapon.Shoot(); } } } break; } }