/** * 2.Przechodzenie do następnego punktu * -NavAgent otrzymuje punkt do zrealizowania i przesuwa aktora w jego stronę. * -W przypadku spostrzeżenia celu następuje jego obsługa. * */ private void MoveToNextPoint() { if (!isTargetToResolve()) { if (Vector3.Distance(transform.position, patrolPoints[patrolPointsIndex]) > destinationTolerence) { navAgent.destination = patrolPoints[patrolPointsIndex]; } else { if (rightListMovement) { patrolPointsIndex++; } else { patrolPointsIndex--; } aiState = PatrolAI_States.DETERMINE_NEXT_POINT; } } else { prepareTargetResolve(); } }
private void prepareTargetResolve() { if (aiState == PatrolAI_States.DETERMINE_NEXT_POINT || aiState == PatrolAI_States.MOVE_TO_POINT) { lastAgentLocationOnPath = transform.position; } aiState = PatrolAI_States.RESOLVE_TARGET; }
/** * 3.3.Poszukiwanie celu * -Gdy utracimy cel z zasięgu zmysłów, idziemy do jego ostatniej znanej pozycji. * -Po dojściu do niej przerywamy poszukiwania. * -Można w przyszłości zaimplementować inne rozwiązania * */ private void SearchTarget() { standByTimeElapsed += Time.deltaTime; if (Vector3.Distance(transform.position, lastTargetLocation) > destinationTolerence && standByTimeElapsed < searchTime) { navAgent.destination = lastTargetLocation; } else { standByTimeElapsed = 0; targetResolve = TargetResolveEnum.DONE; aiState = PatrolAI_States.STAND_BY; } }
/** * 4.Odczekanie * -Następuje po obsłudze celu. * -Aktor odczekuje kilka sekund. * -Jeśli w czasie ich trwania nie wykryte zostaną następne cele, to następuje powrót na scieżkę. * -Jeśli zostaną wykryte cele, następuje ich obsługa. * */ private void StandBy() { if (!isTargetToResolve()) { standByTimeElapsed += Time.deltaTime; if (standByTimeElapsed >= standByTime) { standByTimeElapsed = 0; aiState = PatrolAI_States.RETURN_TO_PATH; } } else { prepareTargetResolve(); } }
/** * 5.Powrót na scieżkę * -Następuje po odczekaniu. * -Aktor powraca na zapamiętaną pozycję by wznowić patrolowanie. * -Jeśli zostaną wykryte cele, następuje ich obsługa. * */ private void ReturnToPatrolPath() { if (!isTargetToResolve()) { if (Vector3.Distance(transform.position, lastAgentLocationOnPath) > destinationTolerence) { navAgent.destination = lastAgentLocationOnPath; } else { aiState = PatrolAI_States.DETERMINE_NEXT_POINT; } } else { prepareTargetResolve(); } }
/** * Restartuje zachowanie agenta. * */ private void RestartState() { patrolPointsIndex = 0; aiState = PatrolAI_States.DETERMINE_NEXT_POINT; rightListMovement = true; }
/** * 3.Obsługa celu * -Następuje gdy jedna z dostępnych broni wykryje poprawny dla niej cel. * -Bieżąca pozycja aktora jest zapamiętywana, by można było powrócić do niej celem kontynuowania scieżki patrolu. * -Obsługa ma trzy możliwe wersje: pościg(A), obrona(B) i utrzymanie pozycji(C). * -Po zakończeniu obsługi następuje odczekanie. * */ private void TargetResolve() { switch (targetResolvePolicy) { /** * * 3A.Pościg * -Rozpoczyna się od zbliżania do celu. * -Zbliżanie do celu dpoóki: nie jest w zasięgu i jest widoczny i żyje. * -Interakcja z celem dopóki: jest w zasięgu i jest widoczny i żyje. * -Poszukiwanie celu dopóki: nie jest widoczny i skończą się poszukiwania. * -Zakończenie obsługi gdy: cel nie żyje lub nie odnaleziono celu po zgubieniu. * */ case TargetResolvePolicy.CHASE: if (equipmentAI.currentTarget == null) { //zgubiono cel targetResolve = TargetResolveEnum.SEARCH_TARGET; } else { standByTimeElapsed = 0; if (Vector3.Distance(transform.position, equipmentAI.currentTarget.transform.position) > equipmentAI.optimalDistanceToTarget) { //trzeba zbliżyć się do celu targetResolve = TargetResolveEnum.CLOSE_IN_ON_TARGET; } else { //jesteśmy dostatecznie blisko celu targetResolve = TargetResolveEnum.TARGET_INTERACTION; } } break; /** * * 3B.Obrona * -Rozpoczyna się od zbliżania do celu. * -Zbliżanie do celu dpoóki: nie jest w zasięgu i jest widoczny i żyje i nie oddalimy się zanadto od scieżki patrolu. * -Interakcja z celem dopóki: jest w zasięgu i jest widoczny i żyje. * -Poszukiwanie celu dopóki: nie jest widoczny i skończą się poszukiwania i nie oddalimy się zanadto od scieżki patrolu. * -Zakończenie obsługi gdy: cel nie żyje lub nie odnaleziono celu po zgubieniu lub oddaliliśmy się zanadto od scieżki patrolu. * */ case TargetResolvePolicy.DEFEND: if (equipmentAI.currentTarget == null) { //cel niewidoczny if (Vector3.Distance(lastAgentLocationOnPath, lastTargetLocation) <= defendChaseDistance) { //ostatnia pozycja w zasięgu pogoni targetResolve = TargetResolveEnum.SEARCH_TARGET; } else { //ostatnia pozycja poza zasięgiem pogoni targetResolve = TargetResolveEnum.DONE; } } else { //cel widoczny if (Vector3.Distance(lastAgentLocationOnPath, equipmentAI.currentTarget.transform.position) <= defendChaseDistance) { //można się zbliżyć if (Vector3.Distance(transform.position, equipmentAI.currentTarget.transform.position) <= equipmentAI.optimalDistanceToTarget) { //cel w pożądanym zasięgu targetResolve = TargetResolveEnum.TARGET_INTERACTION; } else { //cel poza pożądanym zasięgiem targetResolve = TargetResolveEnum.CLOSE_IN_ON_TARGET; } } else { //nie można się zbliżyć if (Vector3.Distance(transform.position, equipmentAI.currentTarget.transform.position) <= equipmentAI.maximalDistanceToTarget) { //cel w dopuszczalnym zasięgu targetResolve = TargetResolveEnum.TARGET_INTERACTION; } else { //cel poza pożądanym zasięgiem targetResolve = TargetResolveEnum.DONE; } } } break; /** * * 3C.Utrzymanie pozycji * -Rozpoczyna się od interakcji z celem. * -Interakcja z celem dopóki: jest w zasięgu i jest widoczny i żyje. * -Zakończenie obsługi gdy: cel nie żyje lub nie jest w zasięgu lub nie jest widoczny. * */ case TargetResolvePolicy.HOLD_POSITION: if (equipmentAI.currentTarget == null) { //zgubiono cel targetResolve = TargetResolveEnum.DONE; } else { standByTimeElapsed = 0; if (Vector3.Distance(transform.position, equipmentAI.currentTarget.transform.position) > equipmentAI.maximalDistanceToTarget) { //cel poza zasięgiem targetResolve = TargetResolveEnum.DONE; } else { //jesteśmy dostatecznie blisko celu targetResolve = TargetResolveEnum.TARGET_INTERACTION; } } break; /** * Nigdy nie powinno mieć miejsca. * */ default: //Assert(true, "Default call in TargetResolve()"); break; } switch (targetResolve) { case TargetResolveEnum.CLOSE_IN_ON_TARGET: CloseOnTarget(); break; case TargetResolveEnum.TARGET_INTERACTION: TargetInteraction(); break; case TargetResolveEnum.SEARCH_TARGET: SearchTarget(); break; case TargetResolveEnum.DONE: standByTimeElapsed = 0; aiState = PatrolAI_States.STAND_BY; break; default: break; } if (equipmentAI.currentTarget != null) { lastTargetLocation = equipmentAI.currentTarget.transform.position; } }
/** * Restartuje zachowanie agenta. * */ private void RestartState() { patrolPointsIndex = 0; aiState = PatrolAI_States.DETERMINE_NEXT_POINT; rightListMovement = true; }
/** * 1.Określanie następnego punktu do którego należy się poruszyć * -Na podstawie dostarczonej listy punktów do przejścia i obecnej pozycji aktora określa się punkt w przestrzeni który należy podać NavAgent'owi * do realizacji. * -W przypadku gdy zrealizowano ostatni punkt z listy aktor może: przejść w bezczynność, powtórzyć scieżkę w odwrotnej kolejności, * powtórzyć scieżkę od pierwszego punktu. * -W przypadku spostrzeżenia celu następuje jego obsługa. * */ private void DetermineNextPoint() { if (!isTargetToResolve()) { if (patrolPoints.Count > 0) { if (patrolPointsIndex < 0) { //Przekroczenie listy punktów z lewej strony switch (patrolEndingPolicy) { case PatrolEndingPolicy.IDLE: patrolPoints.Clear(); navAgent.destination = transform.position; break; case PatrolEndingPolicy.REVERSE: patrolPointsIndex = 0; rightListMovement = !rightListMovement; aiState = PatrolAI_States.MOVE_TO_POINT; break; case PatrolEndingPolicy.CYCLE: patrolPointsIndex = patrolPoints.Count - 1; aiState = PatrolAI_States.MOVE_TO_POINT; break; default: patrolPoints.Clear(); navAgent.destination = transform.position; break; } } else if (patrolPointsIndex >= patrolPoints.Count) { //Przekroczenie listy punktów z prawej strony switch (patrolEndingPolicy) { case PatrolEndingPolicy.IDLE: patrolPoints.Clear(); navAgent.destination = transform.position; break; case PatrolEndingPolicy.REVERSE: patrolPointsIndex = patrolPoints.Count - 1; rightListMovement = !rightListMovement; aiState = PatrolAI_States.MOVE_TO_POINT; break; case PatrolEndingPolicy.CYCLE: patrolPointsIndex = 0; aiState = PatrolAI_States.MOVE_TO_POINT; break; default: patrolPoints.Clear(); navAgent.destination = transform.position; break; } } else { aiState = PatrolAI_States.MOVE_TO_POINT; } } } else { prepareTargetResolve(); } }
/** * 4.Odczekanie * -Następuje po obsłudze celu. * -Aktor odczekuje kilka sekund. * -Jeśli w czasie ich trwania nie wykryte zostaną następne cele, to następuje powrót na scieżkę. * -Jeśli zostaną wykryte cele, następuje ich obsługa. * */ private void StandBy() { if(!isTargetToResolve()) { standByTimeElapsed += Time.deltaTime; if(standByTimeElapsed >= standByTime) { standByTimeElapsed = 0; aiState = PatrolAI_States.RETURN_TO_PATH; } } else { prepareTargetResolve(); } }
/** * 5.Powrót na scieżkę * -Następuje po odczekaniu. * -Aktor powraca na zapamiętaną pozycję by wznowić patrolowanie. * -Jeśli zostaną wykryte cele, następuje ich obsługa. * */ private void ReturnToPatrolPath() { if(!isTargetToResolve()) { if(Vector3.Distance(transform.position, lastAgentLocationOnPath) > destinationTolerence) { if(navAgent != null) { navAgent.destination = lastAgentLocationOnPath; } } else { aiState = PatrolAI_States.DETERMINE_NEXT_POINT; } } else { prepareTargetResolve(); } }
/** * 3.3.Poszukiwanie celu * -Gdy utracimy cel z zasięgu zmysłów, idziemy do jego ostatniej znanej pozycji. * -Po dojściu do niej przerywamy poszukiwania. * -Można w przyszłości zaimplementować inne rozwiązania * */ private void SearchTarget() { standByTimeElapsed += Time.deltaTime; if(Vector3.Distance(transform.position, lastTargetLocation) > destinationTolerence && standByTimeElapsed < searchTime) { if(navAgent != null) { navAgent.destination = lastTargetLocation; } } else { standByTimeElapsed = 0; targetResolve = TargetResolveEnum.DONE; aiState = PatrolAI_States.STAND_BY; } }
/** * 3.Obsługa celu * -Następuje gdy jedna z dostępnych broni wykryje poprawny dla niej cel. * -Bieżąca pozycja aktora jest zapamiętywana, by można było powrócić do niej celem kontynuowania scieżki patrolu. * -Obsługa ma trzy możliwe wersje: pościg(A), obrona(B) i utrzymanie pozycji(C). * -Po zakończeniu obsługi następuje odczekanie. * */ private void TargetResolve() { switch (targetResolvePolicy) { /** * * 3A.Pościg * -Rozpoczyna się od zbliżania do celu. * -Zbliżanie do celu dpoóki: nie jest w zasięgu i jest widoczny i żyje. * -Interakcja z celem dopóki: jest w zasięgu i jest widoczny i żyje. * -Poszukiwanie celu dopóki: nie jest widoczny i skończą się poszukiwania. * -Zakończenie obsługi gdy: cel nie żyje lub nie odnaleziono celu po zgubieniu. * */ case TargetResolvePolicy.CHASE: if(equipmentAI.currentTarget == null) { //zgubiono cel targetResolve = TargetResolveEnum.SEARCH_TARGET; } else { standByTimeElapsed = 0; if(Vector3.Distance(transform.position, equipmentAI.currentTarget.transform.position) > equipmentAI.optimalDistanceToTarget) { //trzeba zbliżyć się do celu targetResolve = TargetResolveEnum.CLOSE_IN_ON_TARGET; } else { //jesteśmy dostatecznie blisko celu targetResolve = TargetResolveEnum.TARGET_INTERACTION; } } break; /** * * 3B.Obrona * -Rozpoczyna się od zbliżania do celu. * -Zbliżanie do celu dpoóki: nie jest w zasięgu i jest widoczny i żyje i nie oddalimy się zanadto od scieżki patrolu. * -Interakcja z celem dopóki: jest w zasięgu i jest widoczny i żyje. * -Poszukiwanie celu dopóki: nie jest widoczny i skończą się poszukiwania i nie oddalimy się zanadto od scieżki patrolu. * -Zakończenie obsługi gdy: cel nie żyje lub nie odnaleziono celu po zgubieniu lub oddaliliśmy się zanadto od scieżki patrolu. * */ case TargetResolvePolicy.DEFEND: if(equipmentAI.currentTarget == null) { //cel niewidoczny if(Vector3.Distance(lastAgentLocationOnPath, lastTargetLocation) <= defendChaseDistance) { //ostatnia pozycja w zasięgu pogoni targetResolve = TargetResolveEnum.SEARCH_TARGET; } else { //ostatnia pozycja poza zasięgiem pogoni targetResolve = TargetResolveEnum.DONE; } } else { //cel widoczny if(Vector3.Distance(lastAgentLocationOnPath, equipmentAI.currentTarget.transform.position) <= defendChaseDistance) { //można się zbliżyć if(Vector3.Distance(transform.position, equipmentAI.currentTarget.transform.position) <= equipmentAI.optimalDistanceToTarget) { //cel w pożądanym zasięgu targetResolve = TargetResolveEnum.TARGET_INTERACTION; } else { //cel poza pożądanym zasięgiem targetResolve = TargetResolveEnum.CLOSE_IN_ON_TARGET; } } else { //nie można się zbliżyć if(Vector3.Distance(transform.position, equipmentAI.currentTarget.transform.position) <= equipmentAI.maximalDistanceToTarget) { //cel w dopuszczalnym zasięgu targetResolve = TargetResolveEnum.TARGET_INTERACTION; } else { //cel poza pożądanym zasięgiem targetResolve = TargetResolveEnum.DONE; } } } break; /** * * 3C.Utrzymanie pozycji * -Rozpoczyna się od interakcji z celem. * -Interakcja z celem dopóki: jest w zasięgu i jest widoczny i żyje. * -Zakończenie obsługi gdy: cel nie żyje lub nie jest w zasięgu lub nie jest widoczny. * */ case TargetResolvePolicy.HOLD_POSITION: if(equipmentAI.currentTarget == null) { //zgubiono cel targetResolve = TargetResolveEnum.DONE; } else { standByTimeElapsed = 0; if(Vector3.Distance(transform.position, equipmentAI.currentTarget.transform.position) > equipmentAI.maximalDistanceToTarget) { //cel poza zasięgiem targetResolve = TargetResolveEnum.DONE; } else { //jesteśmy dostatecznie blisko celu targetResolve = TargetResolveEnum.TARGET_INTERACTION; } } break; /** * Nigdy nie powinno mieć miejsca. * */ default: //Assert(true, "Default call in TargetResolve()"); break; } switch(targetResolve) { case TargetResolveEnum.CLOSE_IN_ON_TARGET: CloseOnTarget(); break; case TargetResolveEnum.TARGET_INTERACTION: TargetInteraction(); break; case TargetResolveEnum.SEARCH_TARGET: SearchTarget(); break; case TargetResolveEnum.DONE: standByTimeElapsed = 0; aiState = PatrolAI_States.STAND_BY; break; default: break; } if( equipmentAI.currentTarget != null) { lastTargetLocation = equipmentAI.currentTarget.transform.position; } }
private void prepareTargetResolve() { if(aiState == PatrolAI_States.DETERMINE_NEXT_POINT || aiState == PatrolAI_States.MOVE_TO_POINT) { lastAgentLocationOnPath = transform.position; } aiState = PatrolAI_States.RESOLVE_TARGET; }
/** * 2.Przechodzenie do następnego punktu * -NavAgent otrzymuje punkt do zrealizowania i przesuwa aktora w jego stronę. * -W przypadku spostrzeżenia celu następuje jego obsługa. * */ private void MoveToNextPoint() { if(!isTargetToResolve()) { if(Vector3.Distance(transform.position, patrolPoints[patrolPointsIndex]) > destinationTolerence) { if(navAgent != null) { navAgent.destination = patrolPoints[patrolPointsIndex]; } } else { if(rightListMovement) { patrolPointsIndex++; } else { patrolPointsIndex--; } aiState = PatrolAI_States.DETERMINE_NEXT_POINT; } } else { prepareTargetResolve(); } }
/** * 1.Określanie następnego punktu do którego należy się poruszyć * -Na podstawie dostarczonej listy punktów do przejścia i obecnej pozycji aktora określa się punkt w przestrzeni który należy podać NavAgent'owi * do realizacji. * -W przypadku gdy zrealizowano ostatni punkt z listy aktor może: przejść w bezczynność, powtórzyć scieżkę w odwrotnej kolejności, * powtórzyć scieżkę od pierwszego punktu. * -W przypadku spostrzeżenia celu następuje jego obsługa. * */ private void DetermineNextPoint() { if(!isTargetToResolve()) { if(patrolPoints.Count > 0) { if(patrolPointsIndex < 0) { //Przekroczenie listy punktów z lewej strony switch (patrolEndingPolicy) { case PatrolEndingPolicy.IDLE: patrolPoints.Clear(); if(navAgent != null) { navAgent.destination = transform.position; } break; case PatrolEndingPolicy.REVERSE: patrolPointsIndex = 0; rightListMovement = !rightListMovement; aiState = PatrolAI_States.MOVE_TO_POINT; break; case PatrolEndingPolicy.CYCLE: patrolPointsIndex = patrolPoints.Count-1; aiState = PatrolAI_States.MOVE_TO_POINT; break; default: patrolPoints.Clear(); if(navAgent != null) { navAgent.destination = transform.position; } break; } } else if (patrolPointsIndex >= patrolPoints.Count) { //Przekroczenie listy punktów z prawej strony switch (patrolEndingPolicy) { case PatrolEndingPolicy.IDLE: patrolPoints.Clear(); if(navAgent != null) { navAgent.destination = transform.position; } break; case PatrolEndingPolicy.REVERSE: patrolPointsIndex = patrolPoints.Count-1; rightListMovement = !rightListMovement; aiState = PatrolAI_States.MOVE_TO_POINT; break; case PatrolEndingPolicy.CYCLE: patrolPointsIndex = 0; aiState = PatrolAI_States.MOVE_TO_POINT; break; default: patrolPoints.Clear(); if(navAgent != null) { navAgent.destination = transform.position; } break; } } else { aiState = PatrolAI_States.MOVE_TO_POINT; } } } else { prepareTargetResolve(); } }