[Part 8] 주차장 맵 제작 및 이벤트 구현: Waypoint System

<화면 설계 바탕으로 주차장 맵 제작>

  • 난이도 하: 사용자는 붉은 선으로 표시된 공간에 주차를 해야 성공한다. 양 옆의 공간에 아무런 차량이 없다. 
  • 난이도 중:  도로 갓길 공간에 주차한다. 
  • 난이도 상: 자동차가 많은 공간에 주차한다. 

난이도 하의 주차 공간
난이도 중의 주차 공간
난이도 상 주차 공간

<주차장 이벤트 구현>

기존에 주차장 난이도 설계에서 주차 공간에 따라 난이도를 조절하는 것 뿐만 아니라 랜덤 이벤트를 추가하여 난이도 조절를 하기로 하였다. 

  • 보도에 돌아다니는 사람 NPC, 도로에서 주행 중인 차량 NPC를 구현하기 위해 Unity를 이용하여 Waypoint System을 구현하였다. 이 부분은 먼저 구현을 시작한 해울이가 작성한 코드를 참고하여 개발함.
  • 참고 영상: https://www.youtube.com/watch?v=MXCZ-n5VyJc
  • 유니티의 UnityWindow기능을 이용하여 게임 Scene 안에서 Waypoint를 보다 쉽게 구현하기 위해 편집기 창을 커스텀하여 사용
  • Gizmos 기능을 이용하여 Waypoint를 사용자가 알 수 있게 시각화 하였다. 
  • waypoint를 이용하여 지정된 공간 내에 랜덤한 지역에 Object를 움직이게 한다. 이때 Navigator를 통해 Object의 방향을 랜덤하게 선택하게 하며, Controller를 통해 Object의 속도 또한 랜덤하게 움직이도록 한다. 
  • Waypoint에 Branch를 추가하여 Object가 Branch에 다가올때 랜덤한 확률로 Branch로 갈지 기존의 Waypoint로 갈지 선택하게 하도록하여 NPC에 더 동적인 변화를 준다. 
    public Vector3 GetPosition() 
    {
        /*
         Vector3 minBound = transform.position + transform.right * width / 2f;
         Vector3 maxBound = transform.position - transform.right * width / 2f;
         return Vector3.Lerp(minBound, maxBound, Random.Range(0f, 1f));
         */
        Vector3 minBound = transform.position + transform.right;
        Vector3 maxBound = transform.position - transform.right;
        return Vector3.Lerp(minBound, maxBound, Random.Range(0f, 1f));
    }

Waypoint의 일부 코드: 최대 Bound와 최소 Bound 사이에서 랜덤한 값을 불러옴

            controller_pedestrians.SetDestination(currentWaypoint.GetPosition());
            //direction을 통해 0이나 1값을 받는다. 
            direction = Mathf.RoundToInt(Random.Range(0f, 1f));

Navigator의 일부 코드: 랜덤한 방향으로 설정

        if (percent = Random.Range(0f, 1f) <= 0.5f ? true : false)
        {
            randnum = Random.Range(0.5f, 1f);
            animator.SetFloat("walk_run_ratio", randnum);
            animator.Play("Walk_Run");
            //움직이는 속도 랜덤값 주기
            movementSpeed = Random.Range(1.5f, 2f);
        }
        else
        {
            randnum = Random.Range(0f, 0.5f);
            animator.SetFloat("walk_run_ratio", randnum);
            animator.Play("Walk_Run");
            movementSpeed = Random.Range(1.5f, 1f);
        }
            Vector3 destinationDirection = destination - transform.position;
            destinationDirection.y = 0;
            // 목적지까지의 거리 변수
            float destinationDistance = destinationDirection.magnitude;
            if (destinationDistance >= stopDistance)
            {
                reachedDestination = false;
                // destinationDirectin으로 방향 회전하고, 이동
                Quaternion targetRotation = Quaternion.LookRotation(destinationDirection);
                transform.rotation = Quaternion.RotateTowards(transform.rotation, targetRotation, rotationSpeed * Time.deltaTime);
                transform.Translate(Vector3.forward * movementSpeed * Time.deltaTime);
            }

Controller의 일부 코드: 랜덤한 속도로 목적지까지 가도록 한다. 

            if (controller_cars.reachedDestination)
            {
                bool shouldBranch = false;
                // check if there's a branch on our current waypoint. if it is let's do a random chec
                // against the branch ratio to determine whether the branch should be taken or not 
                if (currentWaypoint.branches != null && currentWaypoint.branches.Count > 0)
                {
                    shouldBranch = Random.Range(0f, 1f) <= currentWaypoint.branchRatio ? true : false;

                }
                // so then if we are choosing to branch let's randomly pick a barnch as the next waypoint position
                if (shouldBranch)
                {
                    if (currentWaypoint.left_or_right == 1)
                    {
                        LeftRight = 1;
                    }
                    else if (currentWaypoint.left_or_right == 2)
                    {

                        LeftRight = 2;
                    }
                    
                    currentWaypoint = currentWaypoint.branches[Random.Range(0, currentWaypoint.branches.Count - 1)];
                    
                }

Navigator의 일부 코드: 목적지에 도달했을때, 랜덤한 확률로 Branch에 가도록 한다.