Unity 用 RTS および MOBA プレーヤー コントローラー
ビデオ ゲームでは、RTS という用語はリアルタイム ストラテジーを表します。
RTS と従来の一人称/三人称シューティング ゲームの違いは、通常の W、A、S、D ボタンではなく、マウス ポインターを使用してキャラクターを制御することです。
プレイヤーは戦場を俯瞰的に見ることができ、軍隊を直接制御することなく軍隊に命令を与えることができます。RTS ゲームの例としては、Warcraft、Starcraft、Cossacks などがあります。
一方、MOBA は Multiplayer Online Battle Arena の略で、プレイヤーが多数のキャラクターではなく 1 つのキャラクターだけを操作する、RTS ゲームのやや新しいサブジャンルです。
このようなゲームの例としては、League of Legends や Dota 2 があります。
このチュートリアルでは、Unity で RTS/MOBA スタイルのコントローラーを作成する方法を説明します。
ステップ 1: 必要なスクリプトを作成しましょう
このチュートリアルは非常に簡単で、必要なスクリプトは 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
次に、プレーヤー コントローラーとゲーム レベルを設定しましょう。
- 新しいゲームオブジェクトを作成して呼び出します 'RTSPlayer'
- に RTSPlayerController.cs スクリプトをアタッチします (注: アタッチすると、NavMeshAgent という別のコンポーネントが自動的に追加されます。このコンポーネントは後で必要になります)
- プレーヤー本体を追加します (私の場合、cube を持つ単純なカプセルを使用しますが、プレーヤー モデルがある場合は追加できます)。希望のサイズまで縮小します。
- プレーヤー モデルを 'RTSPlayer' ゲームオブジェクト内に移動します (注: ペアレント化する前に、'RTSPlayer' がプレーヤー モデルの一番下に配置されていることを確認してください)
- 'RTSPlayer' を選択し、NavMeshAgent でプレーヤー モデルと一致するまで半径と高さを微調整します。
- 次に、ターゲット インジケーター prefab を作成します。これは、マップ上のクリックした場所を示すクワッドを備えた単純なゲームオブジェクトです。
以下のテクスチャを使用できます。
- 最後に、'RTSPlayer' を選択し、RTSPlayerController スクリプトに必要な変数をすべて割り当てます。
Player Camera - 説明の必要はありません。これは任意のカメラです。
Camera Offset - カメラとプレーヤーの距離
ターゲット インジケーター Prefab - 先ほど作成したプレハブ
プレイ モードでは、マップをクリックしてもプレーヤーが移動しないことがわかります。それは、最後にやるべきことが 1 つあるためです。それは、ナビゲーション メッシュ (Navmesh) をベイク処理することです。
- マップの一部であるすべてのオブジェクトを選択し、静的マークを付けます。
- [ウィンドウ] -> [AI] -> [ナビゲーション] に移動します。
- [Bake] タブで、[Agent Radius] と [Agent Height] の値を変更し (これらは NavMeshAgent からの値と一致する必要があります)、[Bake] をクリックします。
- ベイク処理が完了すると、歩行可能な領域を表す青みがかった輪郭のメッシュが表示されます。
注: プレイヤーが丘の上を歩くのを防ぐには、[ベイク] タブに戻り、[最大傾斜角] を減少させてから、ナビメッシュを再ベイクします。
ずっといい!
最後に、再生モードに戻り、マップ上のどこかを左クリックします。
プレイヤーは障害物を避けながらターゲットに向かって移動する必要があります。
ヒント: ニーズに合わせて、NavMeshagent で速度、角速度、加速度の値を調整します。