Unity용 RTS 및 MOBA 플레이어 컨트롤러

비디오 게임에서 RTS라는 용어는 실시간 전략을 의미합니다.

RTS와 기존 1인칭/3인칭 슈팅 게임의 차이점은 일반적인 W, A, S, D 버튼이 아닌 마우스 포인터를 사용하여 캐릭터를 제어한다는 점입니다.

플레이어는 군대를 직접 조종하지 않고도 군대에 명령을 내릴 수 있는 능력을 통해 전장을 한눈에 볼 수 있습니다. RTS 게임의 예로는 Warcraft, Starcraft, Cossacks 등이 있습니다.

워크래프트 3 게임 플레이 스크린샷

반면, MOBA는 Multiplayer Online Battle Arena의 약자로, 플레이어가 여러 캐릭터가 아닌 단 한 명의 캐릭터만 제어하는 ​​RTS 게임의 다소 새로운 하위 장르입니다.

이러한 게임의 예로는 리그 오브 레전드(League of Legends)와 도타 2(Dota 2)가 있습니다.

이 튜토리얼에서는 Unity에서 RTS/MOBA 스타일 컨트롤러를 만드는 방법을 보여 드리겠습니다.

1단계: 필요한 스크립트를 만들어 보겠습니다.

이 튜토리얼은 하나의 스크립트만 필요하므로 매우 간단합니다.

RTSPlayerController.cs

//You are free to use this script in Free or Commercial projects
//sharpcoderblog.com @2018

using UnityEngine;
using UnityEngine.AI;

[RequireComponent(typeof(NavMeshAgent))]

public class RTSPlayerController : MonoBehaviour
{
    public Camera playerCamera;
    public Vector3 cameraOffset;
    public GameObject targetIndicatorPrefab;
    NavMeshAgent agent;
    GameObject targetObject;

    // Use this for initialization
    void Start()
    {
        agent = GetComponent<NavMeshAgent>();
        //Instantiate click target prefab
        if (targetIndicatorPrefab)
        {
            targetObject = Instantiate(targetIndicatorPrefab, Vector3.zero, Quaternion.identity) as GameObject;
            targetObject.SetActive(false);
        }
    }

    // Update is called once per frame
    void Update()
    {
#if (UNITY_ANDROID || UNITY_IOS || UNITY_WP8 || UNITY_WP8_1) && !UNITY_EDITOR
            //Handle mobile touch input
            for (var i = 0; i < Input.touchCount; ++i)
            {
                Touch touch = Input.GetTouch(i);

                if (touch.phase == TouchPhase.Began)
                {
                    MoveToTarget(touch.position);
                }
            }
#else
        //Handle mouse input
        if (Input.GetKeyDown(KeyCode.Mouse0))
        {
            MoveToTarget(Input.mousePosition);
        }
#endif

        //Camera follow
        playerCamera.transform.position = Vector3.Lerp(playerCamera.transform.position, transform.position + cameraOffset, Time.deltaTime * 7.4f);
        playerCamera.transform.LookAt(transform);
    }

    void MoveToTarget(Vector2 posOnScreen)
    {
        //print("Move To: " + new Vector2(posOnScreen.x, Screen.height - posOnScreen.y));

        Ray screenRay = playerCamera.ScreenPointToRay(posOnScreen);

        RaycastHit hit;
        if (Physics.Raycast(screenRay, out hit, 75))
        {
            agent.destination = hit.point;

            //Show marker where we clicked
            if (targetObject)
            {
                targetObject.transform.position = agent.destination;
                targetObject.SetActive(true);
            }
        }
    }
}

2 단계

이제 플레이어 컨트롤러와 게임 레벨을 설정해 보겠습니다.

  • 새로운 GameObject를 생성하고 호출합니다. 'RTSPlayer'
  • RTSPlayerController.cs 스크립트를 연결합니다(참고: 연결 시 NavMeshAgent라는 다른 구성 요소가 자동으로 추가됩니다. 이 구성 요소는 나중에 필요합니다)

  • 플레이어 본체를 추가합니다(제 경우에는 큐브가 포함된 간단한 캡슐을 사용하지만 플레이어 모델이 있으면 추가할 수 있습니다). 원하는 크기가 될 때까지 크기를 줄입니다.
  • 플레이어 모델을 'RTSPlayer' GameObject 내부로 이동합니다. (참고: 부모 역할을 하기 전에 'RTSPlayer'이 플레이어 모델 하단에 배치되어 있는지 확인하세요.)

  • 'RTSPlayer'을 선택하고 NavMeshAgent에서 플레이어 모델과 일치할 때까지 반경 및 높이를 조정합니다.

  • 다음은 대상 표시기 prefab를 만드는 것입니다. 이것은 지도에서 클릭한 위치를 나타내는 쿼드가 있는 단순한 게임 개체입니다.

아래 텍스처를 사용할 수 있습니다.

실시간 전략 타겟 지표

  • 마지막으로 'RTSPlayer'을 선택하고 RTSPlayerController 스크립트에 필요한 모든 변수를 할당합니다.

플레이어 카메라 - 설명이 필요 없으며 모든 카메라가 가능합니다.

카메라 오프셋 - 카메라가 플레이어로부터 얼마나 멀리 떨어져 있어야 하는지

Target Indicator Prefab - 방금 생성한 프리팹

플레이 모드에서는 지도를 클릭해도 플레이어가 움직이지 않는다는 것을 알 수 있습니다. 마지막으로 해야 할 일이 하나 있기 때문입니다. 바로 내비게이션 메시(Navmesh)를 굽는 것입니다.

  • 지도의 일부인 모든 객체를 선택하고 정적으로 표시합니다.

  • 창 -> AI -> 탐색으로 이동합니다.

  • Bake 탭에서 Agent Radius 및 Agent Height 값(NavMeshAgent의 값과 일치해야 함)을 변경한 다음 Bake를 클릭합니다.

  • 베이킹이 완료되면 걸어갈 수 있는 영역을 나타내는 파란색 윤곽선의 메시가 표시됩니다.

참고: 플레이어가 언덕 위로 걷는 것을 방지하려면 굽기 탭으로 돌아가서 최대 경사 각도를 줄인 다음 내비메시를 다시 굽습니다.

훨씬 낫다!

마지막으로 플레이 모드로 돌아가서 지도의 아무 곳이나 마우스 왼쪽 버튼으로 클릭하세요.

이제 플레이어는 장애물을 피하면서 목표를 향해 움직여야 합니다.

Sharp Coder 비디오 플레이어

팁: NavMeshagent에서 필요에 맞게 속도, 각속도 및 가속도 값을 조정하세요.