private void FindClosestEnemy() { targetObject = null; if (objectsClose.Count == 0) { return; } foreach (GameObject obj in objectsClose) { if (obj == null) { continue; } if (obj == gameObject) { continue; } float tmp = Vector3.Distance(transform.position, obj.transform.position); if (obj.CompareTag(destroyerTag)) { targetObject = obj; mState = StateMachine.MovementState.Flee; break; } if (obj.CompareTag(cubeTag) && team == HelperFunctions.Team.Sphere || obj.CompareTag(sphereTag) && team == HelperFunctions.Team.Cube) { //TODO: Same if as statue, but with new script for units if (tmp < targetObjectDistance) { targetObject = obj; targetObjectDistance = tmp; } } else if (obj.CompareTag(statueTag) && targetObject == null) { StatueScript ss = obj.GetComponent <StatueScript>(); if (team != ss.Team) { targetObject = obj; statueScript = ss; } } } }
private void Update() { if (hpC.HP <= 0) { cState = StateMachine.CombatState.Death; } //If this object is dead, dont check anything if (isDead) { return; } rotSpeed = speed / maxSpeed; if (cState == StateMachine.CombatState.Attack) { //Super acceleration if in attack mode :D speed += (acceleration * 3) * Time.deltaTime; } else { speed += acceleration * Time.deltaTime; } if (speed >= maxSpeed) { speed = maxSpeed; } objectScanTimer += Time.deltaTime; if (objectScanTimer >= objectScanDelay) { objectScanTimer = 0; //Heavy process, dont run too often objectsClose = HelperFunctions.GetObjectsInRange(transform.position, findObjectRange, findObjectMask); } delayTimer += Time.deltaTime; if (delayTimer >= delayTime) { } delayTimer = 0; result = oba.AvoidObstacles(speed, maxSpeed, rotateDir); if (result.speed >= 0) { speed = result.speed; } if (defenceTarget == null) { statueScript = null; } else { if (statueScript == null) { statueScript = defenceTarget.GetComponent <StatueScript>(); } } StateCheck(); StateAction(); if (mState == StateMachine.MovementState.Idle) { return; } RotateObject(result.rotDir); }
private void StateAction() { switch (cState) { case StateMachine.CombatState.Defend: break; case StateMachine.CombatState.Attack: if (Vector3.Distance(transform.position, targetObject.transform.position) > attackRange) { if (!AvoidObstacle()) { RotateObject(targetObject.transform.position); } } else { if (targetObject == null) { cState = StateMachine.CombatState.Idle; mState = StateMachine.MovementState.Wander; break; } if (targetScript == null) { targetScript = targetObject.GetComponent <FSMController>(); if (targetScript == null) { targetObject = null; //Debug.LogError("No target script found!"); return; } } //Start attack animation if not running targetScript.DealDamage(dps * Time.deltaTime); } break; case StateMachine.CombatState.Death: Collider c = GetComponent <BoxCollider>(); if (c == null) { GetComponent <SphereCollider>().enabled = false; } else { c.enabled = false; } if (defenceTarget != null) { defenceTarget.GetComponent <StatueScript>().ReduceDefenderCount(); } isDead = true; SpawnController.DestroyObject(gameObject); break; case StateMachine.CombatState.Capture: //TODO: BUG: Still not working if (statueScript == null) { statueScript = targetObject.GetComponent <StatueScript>(); if (statueScript == null) { //Debug.LogError("No target script found!"); return; } } if (statueScript.Team == team) { targetObject = null; statueScript = null; cState = StateMachine.CombatState.Idle; mState = StateMachine.MovementState.Wander; break; } if (Vector3.Distance(transform.position, targetObject.transform.position) > 3f) { RotateObject(targetObject.transform.position); //Walk forward with fixed update } else { statueScript.DoCapture(team, (int)hpC.MaxHp); cState = StateMachine.CombatState.Death; } break; } switch (mState) { case StateMachine.MovementState.Wander: //TODO: Check obstacle avoidance, then rotate else wander rotate if (!AvoidObstacle()) { if (!wanderActive) { break; } rotateDir = Wander.Direction(rotSpeed, rotateDir, 10); } break; case StateMachine.MovementState.Seek: //TODO: Check obstacle avoidance, then rotate or move along path? //TODO: Check if enemy is close, then attack or flee if (!AvoidObstacle()) { if (defenceTarget != null) { RotateObject(defenceTarget.transform.position); break; } if (targetObject != null) { Vector3 disVector = targetObject.transform.position - transform.position; if (HelperFunctions.VectorLength(disVector) < seekRange) { if (cState != StateMachine.CombatState.Capture) { RotateObject(disVector); } } } } break; case StateMachine.MovementState.Flee: if (!AvoidObstacle()) { Vector3 disVector = (targetObject.transform.position - transform.position); if (HelperFunctions.VectorLength(disVector) <= fleeDistance) { RotateObject(transform.position - disVector); } } break; case StateMachine.MovementState.Interpose: if (targetObject == null) { mState = StateMachine.MovementState.Wander; break; } if (defenceTarget != null) { Vector3 intercept = ((defenceTarget.transform.position - targetObject.transform.position) / 2) + targetObject.transform.position; RotateObject(intercept); } break; } }
private void StateAction() { switch (cState) { case StateMachine.CombatState.Defend: //TODO: - wander om ikke i range, seek om utenfor range, interpose om destroyer kommer, angripe om enemy kommer if (Vector3.Distance(transform.position, defenceTarget.transform.position) > defendRange) { if (RotateObject(defenceTarget.transform.position, 3)) { //speed = 0.1f; } mState = StateMachine.MovementState.Seek; } /* * if (targetObject.CompareTag()) //hvordan se at det er en kule når man er firkant? * { * cState = StateMachine.CombatState.Attack; * mState = StateMachine.MovementState.Seek; * }*/ if (targetObject.CompareTag(destroyerTag)) { mState = StateMachine.MovementState.Interpose; } else { mState = StateMachine.MovementState.Idle; } break; case StateMachine.CombatState.Attack: if (Vector3.Distance(transform.position, targetObject.transform.position) > attackRange) { if (!AvoidObstacle()) { RotateObject(targetObject.transform.position, 3); } } else { if (targetObject == null) { cState = StateMachine.CombatState.Idle; mState = StateMachine.MovementState.Wander; break; } if (targetScript == null) { targetScript = targetObject.GetComponent <FSMController>(); if (targetScript == null) { Debug.LogError("No target script found!"); return; } } //Start attack animation if not running targetScript.DealDamage(dps * Time.deltaTime); } break; case StateMachine.CombatState.Death: Collider c = GetComponent <BoxCollider>(); if (c == null) { GetComponent <SphereCollider>().enabled = false; } else { c.enabled = false; } if (defenceTarget != null) { defenceTarget.GetComponent <StatueScript>().ReduceDefenderCount(); } //Start death animaiton isDead = true; Destroy(gameObject); break; case StateMachine.CombatState.Capture: if (statueScript == null) { statueScript = targetObject.GetComponent <StatueScript>(); if (statueScript == null) { Debug.LogError("No target script found!"); return; } } if (statueScript.Team == team) { targetObject = null; statueScript = null; cState = StateMachine.CombatState.Idle; mState = StateMachine.MovementState.Wander; break; } if (Vector3.Distance(transform.position, targetObject.transform.position) > 3f) { RotateObject(targetObject.transform.position, 3); //Walk forward with fixed update } else { statueScript.DoCapture(team, (int)hpC.MaxHp); cState = StateMachine.CombatState.Death; } break; } switch (mState) { case StateMachine.MovementState.Wander: //TODO: Check obstacle avoidance, then rotate else wander rotate if (!AvoidObstacle()) { if (!wanderActive) { break; } rotateDir = Wander.Direction(rotSpeed, rotateDir, 10); } break; case StateMachine.MovementState.Seek: //TODO: Check obstacle avoidance, then rotate or move along path? //TODO: Check if enemy is close, then attack or flee if (!AvoidObstacle()) { if (defenceTarget != null) { RotateObject(defenceTarget.transform.position, 4); break; } Vector3 disVector = targetObject.transform.position - transform.position; if (HelperFunctions.VectorLength(disVector) < seekRange) { if (cState != StateMachine.CombatState.Capture) { RotateObject(disVector, 1.5f); } } } break; case StateMachine.MovementState.Flee: //TODO: Check distance to enemies close, move away or resume if (!AvoidObstacle()) { //From target to self, important to calculate target direction to flee to Vector3 disVector = (targetObject.transform.position - transform.position); if (HelperFunctions.VectorLength(disVector) <= fleeDistance) { RotateObject(transform.position - disVector, 4); } } break; case StateMachine.MovementState.Interpose: if (defenceTarget != null) { Vector3 intercept = ((defenceTarget.transform.position - targetObject.transform.position) / 2); RotateObject(intercept + defenceTarget.transform.position, 4); } break; } }
private void StateCheck() { FindClosestEnemy(); switch (cState) { case StateMachine.CombatState.Idle: if (defenceTarget == null) { cState = StateMachine.CombatState.Lookout; } else { cState = StateMachine.CombatState.Defend; } break; case StateMachine.CombatState.Lookout: //TODO: Check if enemies is close //If no objects close, mState wander and break if (targetObject == null) { mState = StateMachine.MovementState.Wander; break; } //Target object is now filtered to never be a friendly unit if (targetObject.CompareTag(cubeTag) || targetObject.CompareTag(sphereTag)) { cState = StateMachine.CombatState.Attack; } else if (targetObject.CompareTag(statueTag)) { mState = StateMachine.MovementState.Seek; cState = StateMachine.CombatState.Capture; } else if (targetObject.CompareTag(destroyerTag)) { cState = StateMachine.CombatState.Lookout; mState = StateMachine.MovementState.Flee; } break; case StateMachine.CombatState.Attack: //TODO: Check if enemy is dead, or im dead mState = StateMachine.MovementState.Seek; if (hpC.HP <= 0) { cState = StateMachine.CombatState.Death; targetObject = null; } else if (targetObject == null) //TODO: This might be a bug if the script is disabled { targetScript = null; if (targetObject == null) { cState = StateMachine.CombatState.Idle; break; } } if (Vector3.Distance(transform.position, targetObject.transform.position) > (attackRange * 1.5f)) { targetObject = null; cState = StateMachine.CombatState.Idle; mState = StateMachine.MovementState.Wander; } break; case StateMachine.CombatState.Defend: //TODO: Check if enemy is close, then attack if (targetObject != null && targetObject.CompareTag(destroyerTag)) { mState = StateMachine.MovementState.Interpose; break; } if (statueScript.Team != team) { defenceTarget = null; statueScript = null; cState = StateMachine.CombatState.Idle; break; } if (!defenceTarget.activeInHierarchy) { cState = StateMachine.CombatState.Lookout; break; } else { if (Vector3.Distance(transform.position, defenceTarget.transform.position) > defendRange) { mState = StateMachine.MovementState.Seek; } else { mState = StateMachine.MovementState.Wander; } } break; case StateMachine.CombatState.Capture: if (targetObject == null) { cState = StateMachine.CombatState.Lookout; } break; } }