protected override void Update() { if (sensing.nearestEnemy != null) { movement.MoveTo((entity.transform.position - sensing.nearestEnemy.transform.position).normalized * 5); } else { movement.Stop(); } }
//we choose who should be attacked and whit which attack public void MeleeAttack(GameEntity target, CA_MeleeAttack attack) { //Profiler.BeginSample("MeleeAttackBeginn"); currentAttack = attack; if (target != null) { currentTarget = target; currentTargetsUnitAI = currentTarget.unitAI; } //Profiler.EndSample(); movement.Stop(); //Profiler.BeginSample("PrepareMeleeAttack"); MA_PrepareMeleeAttack(); //Profiler.EndSample(); }
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(); }
protected override void Update() { switch (state) { case WorkerState.Idle: if (Time.time > nextIdleMovementTime) { nextIdleMovementTime = Time.time + idleMovementInterval; Vector3 wanderPoint = UnityEngine.Random.insideUnitSphere * 4; wanderPoint.y = entity.transform.position.y; wanderPoint += entity.transform.forward * 4 + entity.transform.position; Vector3 basePosition = BuildingSystem.Instance.playersBaseLocation.position; //if he would stray off to far, bring him back to base if (Vector3.Distance(basePosition, wanderPoint) > maxDistanceToBaseForWander) { wanderPoint += (basePosition - wanderPoint) / 4; } movement.MoveTo(wanderPoint); } break; case WorkerState.Construction: switch (constructionState) { case ConstructionState.Idle: //if idle /first get nearest Building which needs construction, if there is no we just chill beside the base if (Time.time > nextScanTime) { nextScanTime = Time.time + scanInterval; if (BuildingSystem.Instance.AreThereBuildingsToConstruct()) { standingBesideBaseAndWaiting = false; BuildingInConstruction nearestBuildingToConstruct = null; float nearestDistance = Mathf.Infinity; foreach (BuildingInConstruction building in BuildingSystem.Instance.GetBuildingsWaitingForConstruction()) { float currentDistance = (building.transform.position - entity.transform.position).sqrMagnitude; if (currentDistance < nearestDistance) { nearestDistance = currentDistance; nearestBuildingToConstruct = building; } } assignedBuildingToBuild = nearestBuildingToConstruct; //we move to a position from where we can build, not to a position inside the building Vector3 targetPosition = nearestBuildingToConstruct.transform.position + (entity.transform.position - nearestBuildingToConstruct.transform.position).normalized * nearestBuildingToConstruct.width / 2; movement.MoveTo(targetPosition); constructionState = ConstructionState.MovingToBuilding; } else if (!standingBesideBaseAndWaiting) { Vector3 positonToMoveTo = UnityEngine.Random.insideUnitSphere * 8; positonToMoveTo += BuildingSystem.Instance.playersBaseLocation.position; standingBesideBaseAndWaiting = true; movement.MoveTo(positonToMoveTo); } } break; case ConstructionState.MovingToBuilding: if (Time.time > nextScanTime) { nextScanTime = Time.time + scanInterval; if (assignedBuildingToBuild != null) { if (Vector3.Distance(entity.transform.position, assignedBuildingToBuild.transform.position) < assignedBuildingToBuild.width + constructionRange) { movement.Stop(); constructionState = ConstructionState.Constructing; constructionTool.StartAnimation(); nextConstructionTime = Time.time + constructionInterval; } } else { constructionState = ConstructionState.Idle; } } break; case ConstructionState.Constructing: if (Time.time > nextConstructionTime) { //check if it istn completed yet if (assignedBuildingToBuild != null) { nextConstructionTime = Time.time + constructionInterval; assignedBuildingToBuild.Construct(constructionPoints); } else { constructionState = ConstructionState.Idle; constructionTool.StopAnimation(); } } break; } break; case WorkerState.Harvesting: switch (harvestingState) { case HarvestingState.Idle: //check if there are some ressources in the area - should it check with physics check or get the nearest from the ressourcesmanager? if (Time.time > nextScanTime) { nextScanTime = Time.time + scanInterval; HashSet <Ressource> ressources = RessourcesManager.Instance.GetRessources(assignedHarvesterType); if (ressources.Count > 0) { standingBesideHarvesterAndWaiting = false; Ressource nearestRessource = null; float nearestDistance = Mathf.Infinity; foreach (Ressource ressource in ressources) { float currentDistance = (ressource.transform.position - assignedHarvester.transform.position).sqrMagnitude; if (currentDistance < nearestDistance) { nearestDistance = currentDistance; nearestRessource = ressource; } } currentSelectedRessource = nearestRessource; Vector3 targetPosition = currentSelectedRessource.transform.position + (entity.transform.position - currentSelectedRessource.transform.position).normalized * currentSelectedRessource.width / 2; movement.MoveTo(targetPosition); harvestingState = HarvestingState.MovingToRessource; } else if (!standingBesideHarvesterAndWaiting) { Vector3 positonToMoveTo = UnityEngine.Random.insideUnitSphere * 5; positonToMoveTo += assignedHarvester.transform.position; standingBesideHarvesterAndWaiting = true; movement.MoveTo(positonToMoveTo); } } break; case HarvestingState.MovingToRessource: if (Time.time > nextScanTime) { nextScanTime = Time.time + scanInterval; if (currentSelectedRessource != null) { if (Vector3.Distance(entity.transform.position, currentSelectedRessource.transform.position) < currentSelectedRessource.width) { movement.Stop(); harvestingState = HarvestingState.GatheringRessource; //activate the tool if (assignedHarvesterType == RessourceType.fer) { ferHarvestingTool.StartAnimation(); } else if (assignedHarvesterType == RessourceType.mer) { merHarvestingTool.StartAnimation(); } nextRessourceGatheringTime = Time.time + ressourceGatherInterval; } } else { harvestingState = HarvestingState.Idle; ferHarvestingTool.StopAnimation(); merHarvestingTool.StopAnimation(); } } break; case HarvestingState.GatheringRessource: if (Time.time > nextRessourceGatheringTime) { //check if it istn completed yet if (currentSelectedRessource != null) { nextRessourceGatheringTime = Time.time + ressourceGatherInterval; //gather but check how much will fit if (ressourceInventory.currentRessourceTransportLoad + ressourceGatheringPower > ressourceInventory.ressourceTransportLoad) { ressourceInventory.AddRessource(currentSelectedRessource.type, currentSelectedRessource.TakeRessource(ressourceInventory.ressourceTransportLoad - ressourceInventory.currentRessourceTransportLoad)); } else { ressourceInventory.AddRessource(currentSelectedRessource.type, currentSelectedRessource.TakeRessource(ressourceGatheringPower)); } //if the sack is full, go back if (ressourceInventory.currentRessourceTransportLoad == ressourceInventory.ressourceTransportLoad) { Vector3 targetPosition = assignedHarvester.transform.position + (entity.transform.position - assignedHarvester.transform.position).normalized * assignedHarvester.width / 2; movement.MoveTo(targetPosition); // movement.MoveTo(assignedHarvester.transform.position); harvestingState = HarvestingState.TransportingRessourceToHarvester; ferHarvestingTool.StopAnimation(); merHarvestingTool.StopAnimation(); } } else { ferHarvestingTool.StopAnimation(); merHarvestingTool.StopAnimation(); if (ressourceInventory.currentRessourceTransportLoad > 0) { Vector3 targetPosition = assignedHarvester.transform.position + (entity.transform.position - assignedHarvester.transform.position).normalized * assignedHarvester.width / 2; movement.MoveTo(targetPosition); //movement.MoveTo(assignedHarvester.transform.position); harvestingState = HarvestingState.TransportingRessourceToHarvester; } else { harvestingState = HarvestingState.Idle; } } } break; case HarvestingState.TransportingRessourceToHarvester: if (Time.time > nextScanTime) { nextScanTime = Time.time + scanInterval; if (Vector3.Distance(entity.transform.position, assignedHarvester.transform.position) < assignedHarvester.width) { movement.Stop(); assignedHarvester.DepotRessource(ressourceInventory.currentRessourceTransportLoad); ressourceInventory.Clear(); if (currentSelectedRessource != null) { harvestingState = HarvestingState.MovingToRessource; movement.MoveTo(currentSelectedRessource.transform.position); } else { harvestingState = HarvestingState.Idle; } } } break; } break; case WorkerState.Depositing: if (Time.time > nextScanTime) { nextScanTime = Time.time + scanInterval; if (despositionBuilding != null) { if (Vector3.Distance(entity.transform.position, despositionBuilding.transform.position) < despositionBuilding.width) { despositionBuilding.GetComponent <IDepositioneable <B_Worker> >().DepositionWorker(this); } } else { AssignToIdle(); } } break; } }
public override void OnBehaviourExit() { movement.Stop(); movement.StopLookAt(); inRange = false; }
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; } }