2D 총게임 반동 표시

이미지
  보시다시피 반동을 표시하는 간단한 indicator( 지시계 ) 다. 일단 만드는 공식은 간단하다 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 using   System .Collections; using   System .Collections.Generic; using  UnityEngine; using  UnityEngine.InputSystem; public   class  MouseIndicator : MonoBehaviour {     LineRenderer lineRenderer;     [SerializeField]FireArm fireArm;     [Range( 6 , 60 )]      public   int  resolution  =   100 ;      public   float  width  =  1f;        private   void  Start() {         lineRenderer  =  GetComponent < LineRenderer > ();         lineRenderer.loop  =   true ;     }        private   void  Update() {         VisualizeRecoil(fireArm);     }      public   void  VisualizeRecoil(FireArm fireArm)     {                  Vector2 mousePos  =  Camera.main.ScreenToWorldPoint(Mouse.current.position.ReadValue());          // Mouse.current.position.ReadValue()는 Input.mousePosition과 하는 일이 같다

좀비게임-1 = 조잡한 계획 그리고 또 다른 길찾기 문제

가장 기본이 되는 적부터 계획해봤다, 적의 행동양식은 Idle, Search, Attack 상태로 나누어진다 기본적으로 적은 Idle로부터 시작한다 Idle은 말 그대로 할 능력은 있지만 목적이 없는 것 마냥  주변을 걸어다니거나 가만히 있는다 이 상태에서 무언가 흥미를 끄는 것( 소리, 불빛 ) 봤거나 플레이어에게 공격당했다면 Search로 전환하고 플레이어를 발견했다면 Attack로 전환한다. Search는 어떠한 목적이 있어 탐색하러 어떠한 곳으로 이동한다 도착한뒤 그 근방을 기준으로 배회하는데 30초 후 Idle로 전환한다 Attack의 트리거는 Idle과 동일하다 Attack은 플레이어가 보이는 상태이며 공격하기 위해 쫒아가는 행동이다 지정된 거리의 동료를 Search 상태로 변환해 Attack 상태로 되어있는 것을 따라간다 플레이어가 빠르게 도망쳐 보이지 않는 상태가 되면  마지막으로 보인 곳을 탐색하다 파괴할 것이 있다면 파괴한다 파괴할 것이 없다면 근처를 배회하고 30초후 Idle로 전환한다. 시작과 목표가 각각 하나라면 A*으로 충분하지만 시작이 여러명이면 어떻게 해야할지 모르기에 검색해본 결과 RVO, flowfield, flocks/boid 가 중심이 되었다 그중에  RVO는 reciprocal velocity obstacle 이란 뜻인데,  구현하는 거 설명 들어봤더니 뭐라 하는지 이해가 안돼 포기했다 나머지는 다행이 이해가 됐다 이해한 뒤 얻어낸 결론으로 Navmesh와 A*만으로도 충분하다는 계산이 나왔다 맵이 매우 크고 복잡하거나 스크린에 나오는 유닛들이 수백개 이상이면 HPA* 의 캐싱으로 나눠진 섹터들로 A*하여 이어진 섹터들을 Flowfield로  길찾기 하거나, 간단하게 Navmesh와 flowfield만으로도 충분히 작동될 수 있겠다 허나 본인이 감당가능할 정도의 단순하고 작은 맵에  유닛도 약 백마리도 안되는 간단한 게임이라 일단 완성해놓고 필요하다면 최적화할 생각이다

Navmesh 후기

이미지
  Constrainted Delaunay Triangulation + A* + Simple Stupid Funnel를 합한 NavMesh다. 오늘날에 흔히 쓰이는 길찾기 휴리스틱 알고리즘를 만들 수 있어 기쁘다. 참 오래 걸린 알고리즘이였다, 4~6개월쯤 날렸나? 여기에 local avoidance, douglass peucker line simplication, 3D화(예시로 계단이라던가) ... 등등 해야할 것들이 많지만 이걸 만드느라 게임을 못 만들었기에 넘어가고 빨리 배운 걸 응용할거다 그래, 좀비생존게임이나 만들어볼까...

Constrainted Delaunay Triangulation 후기

CDT는 모든 점 중에서 특정한 점들이 모여 만든 다각형들만 제외/분별하여 DT하는 알고리즘이다. 힘들었다. https://www.jdxdev.com/blog/2021/07/06/rts-pathfinding-2-dynamic-navmesh-with-constrained-delaunay-triangles/   https://forum.unity.com/threads/programming-tools-constrained-delaunay-triangulation.1066148/ 링크로부터 개념을 배워 적용하기에 많은 어려움이 있었다 일반적인 예로 작은 장애물 여러가지가 있는데 큰 장애물을 새로 덮어 씌울 때 어떻게 해야 하는가? 그 반대는 어떻게 처리해야 하는가? 게다가 정밀성 오류가 터지니 대체 어떤 곳이 틀렸는지 고생했다 결국에는 해당 알고리즘의 자료 구조를 능숙하게 아는 것이 중요하다 또 유닛 테스트는 가장 느려보이지만 먼 거리를 가장 빠르게 가는 방법이다 이런 값비싼 교훈을 얻었다.  디버깅 실력을 더 키워야겠다

Delaunay Triangulation 후기

이 알고리즘에 대해 설명하자면 직역해 들로네 삼각분할 이라 하고 주어진 모든 점으로부터 삼각형을 만드는데  전체적인 형태가 정삼각형인 것으로 해주는 것이다. 정보가 많아 구현하기 쉬웠다. 해깔리는 점들을 나열하자면 -  - 위키에서 Boyer-Watson식과 기본 Incremental식과 차이점, Incremental은 점을 포함하는 삼각형의 점들과 이어 만든 삼각형들에게 Flip을 적용하는 것이고 Boyer-Watson은 점을 포함하는 삼각형을 기점으로 주변을 살펴  점이 외접원에 포함되는 것만 따로 모은 삼각형들, 즉 나쁜 삼각형들에게  3변 하나씩 나쁜 삼각형들과 포함하지 않는 변들만 점과 이어 새로운 삼각형을 만든다. 두 방식들 모두 삼각형의 탐색방법에 따라 O(n^2) ~ O(nlogn) 정도 걸린다. - Mesh 데이터구조 HalfEdge 구조인데 시간을 아끼기 위해 충분한 이해 없이 무작정 베끼다가 오류가 터졌을 때 뭐가 틀렸는지 도저히 이해가 안돼 문제점을 찾을 때 까지 고생 좀 했다.  꽤 좋은 경험이였다.

Simple Stupid Funnel 후기

이미지
절대 Simple하고 Stupid하지 않았다. 알고리즘을 만들어낸 사이트  를 찾아냈는데 봐도 이해를 못해 다른 웹사이트 로부터 그림으로 쉽게 설명해서 기본적인 이해도로 구현해봤는데 제대로 작동이 안됐다. 작동이 안되는 이유를 찾기위해 더욱 더 검색해 일본인 웹사이트  까지 번역기 돌려서 봤는데 내가 찾던 문제점과는 맞지 않았다. 결국 검색을 포기하고 수많은 시도 끝에 겨우 만들어 냈다. 이것도 어떠한 이유로 작동 안될 수도 있지만 전보다는 훨씬 낫기에 쓴다 답을 찾아 여기까지 온 불행한 영혼을 위해 설명은 영어로 썼다. GITHUB

Flow chart : 실행이나 작업순서의 단계, 순서, 의사 결정을 나타내는 다이어그램

스크립트를 짜다가 정리할 필요가 느껴져서 글을 써본다 수백줄, 수천줄로 된 스크립트 하나씩 보여주는 것 보다 한 사진으로 된 플로챠트로 실행 순서를 간단하게 파악할 수 있다 아래링크는 draw.io 라고 하는데 무료로 다이아그램을 쉽게 표현해주는 사이트이다. https://app.diagrams.net/