관리 메뉴

도드넷

게임 제작 일지#7 - 유니티 네비게이션 2D 패스 파인딩 길찾기!! 본문

창고/게임 제작 [시즌2]

게임 제작 일지#7 - 유니티 네비게이션 2D 패스 파인딩 길찾기!!

도드! 2016. 10. 7. 01:41
반응형





게임 제작 일지#7 - 유니티 네비게이션 2D 패스 파인딩 길찾기!!




Wunderbar!


드디어 해냈다!


네비게이션, 베이킹 맵핑, 유료 애드온이나 스크립트 없이 나만의 2D 패스파인딩 시스템 만들기!

(물론 앞으로 버그등도 있을수 있겠지만 지금으로썬 완벽 그자체!)


애플잭 하고 결혼하게 해주세요!! >ㅂ<


하루종일 걸리더라도 스스로의 힘으로 스크립팅 원하는대로 해내는 바로 이맛 캬..


포니 + 게임 + 게임제작 = 내운명


#1 도드의 유니티 2D 네비게이션 기본 알고리즘


동그란 원이 주황색 표창까지 가야하는데 콜라이더 2개가 가로막는 상황에서 나의 네비 시스템은 커스텀 콜라이더

양옆에 부착된 대체 위치를 파악, 도착점(표창모양)과 가장 가까운 분홍 세모(대체위치)로 이동해서 충돌 표면에서

빠져나오게 된다.


빨간 선은 레이 캐스트로 유닛보다 먼저가서 막혀있는지를 검사해서 목적지와

가장까운 분홍색 세모 대체 위치를 목적지로 이동하게 된다.


이동이 완료되면 방금 도착한 목적지가 최종목적지인지 검사하고 아니면

다시한번 레이 캐스팅을해서 대체 위치를 찾아낸다! 만약 충돌이 없으면 그대로가고 있으면 최적 위치로 이동하게 된다.



#2 도드의 2D 패스파인딩 스크립트


            Vector3 dir = (Final_Destination - This_Transform.position).normalized;
            float distance = Vector3.Distance(This_Transform.position, Final_Destination);

            // 레이 캐스팅!
            RaycastHit2D[] Raycasted_Info = Physics2D.RaycastAll(This_Transform.position, dir, distance, mask);

            // 충돌이 일어남!
            if (Raycasted_Info.Length > 0)
            {
                // 현재 가상위치 설정!
                Vector3 CP = This_Transform.position;

                // 첫번째 충돌 물체 정의!
                The_First_OBS = Raycasted_Info[0].collider.gameObject;

                // 해당 콜라이더의 대체(Alternative) 위치 모두 가져오기!
                for (int N = 0; N < The_First_OBS.GetComponent<OBS_Points>().Alternative_Points.Count; N++)
                {
                    AL_Points.Add(The_First_OBS.GetComponent<OBS_Points>().Alternative_Points[N]);
                }

                for (int N = 0; N < AL_Points.Count; N++)
                {
                    Distances.Add(0.0F); // 가수 입력
                }

                // 거리 넣기
                for (int N = 0; N < AL_Points.Count; N++)
                {
                    Distances[N] = Vector3.Distance(Final_Destination, AL_Points[N].GetComponent<Transform>().position);
                }

                Smallist = Distances[0];

                // 최소값 구하기
                for (int N = 0; N < Distances.Count; N++)
                {
                    for (int M = 0; M < Distances.Count; M++)
                    {
                        if (Smallist > Distances[M])
                        {
                            Smallist = Distances[M];
                        }
                    }
                }

                // 최소값에 해당하는 원소번호 구하기
                for (int N = 0; N < Distances.Count; N++)
                {
                    if (Distances[N] == Smallist)
                    {
                        Choice = N;
                    }
                }

                Order = "Move";
                Destination = AL_Points[Choice].GetComponent<Transform>().position;
            }
            else
            {
                Order = "Move";
                Destination = Final_Destination;
            }

            Distances.Clear();
            AL_Points.Clear();
        }


#3 이번 스크립팅으로 알아낸 몇가지 팁들


1) 리스트 = 리스트를 해줄경우 리스트가 연결되어 버린다! (주의)

고로, 리스트를 복사하고 싶다면 직접 for문과 Add 메소드 를 통해 하나씩 다 넣어줘야한다.


2) 최소값 구하는 알고리즘


                for (int N = 0; N < Distances.Count; N++)
                {
                    for (int M = 0; M < Distances.Count; M++)
                    {
                        if (Smallist > Distances[M])
                        {
                            Smallist = Distances[M];
                        }
                    }
                }


이와중에 스몰리스트 철자틀린거 보소 //ㅅ// 아 애플잭이랑 결혼해야 되는데 영어를 이리못해서야..


3) 유닛 콜라이더는 원형 콜라이더를 사용해야한다.

- 사소하게 걸리는거 없애주고 패스파인딩이랑 같이 표면 충돌을 유연하게 처리하게 도와줌.


4) 리지드바디의 마찰을 0으로 해도 걸리는것을 방지할 수 있다.










반응형
Comments