著者:山内 真仁
以前、ゲームエンジン「Unity」を使ったレースゲームをSLPのチーム活動で
作成しました。その経験を生かして今回は、Unityとプログラミング言語「C#」を使って、簡単なレースゲームを作成する方法を紹介します。Unityの物理エンジンを使用することで、複雑なコードを書かなくてもリアルな挙動のゲームを作成できます。
シェルスクリプトマガジン Vol.67は以下のリンク先でご購入できます。
図12 「CarController.cs」ファイルに記述する内容
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 |
using UnityEngine; public class CarController : MonoBehaviour { public GameObject[] wheelMeshes = new GameObject[4]; // ホイールオブジェクトを格納する配列 public WheelCollider[] wheelColliders = new WheelCollider[4]; // Wheel Colliderを格納する配列 public float maxMotorTorque = 300f; // 車輪に加える最大トルク public float brakeTorque = 500f; // ブレーキのトルク public float maxSteerAngle = 25f; // ステアリングの最大舵角 float accel, steer; // アクセルとステアリングの入力値 bool brake; // ブレーキをかけているかどうか // 画面を描画するたびに実行されるメソッド(実行間隔はフレームレートに依存) void Update() { steer = Input.GetAxis("Horizontal"); // ←→で旋回 accel = Input.GetAxis("Vertical"); // ↑↓でアクセル brake = Input.GetKey(KeyCode.Space); // スペースでブレーキ // Wheel Colliderの動きを見た目に反映する for (int i = 0; i < 4; i++) { wheelColliders[i].GetWorldPose(out Vector3 position, out Quaternion rotation); wheelMeshes[i].transform.position = position; wheelMeshes[i].transform.rotation = rotation; } } // フレームレートに依存せず、定期的に実行されるメソッド(0.02秒に1回) void FixedUpdate() { // Wheel Colliderに各パラメータを代入 for(int i = 0; i < 4; i++) { if (i < 2) wheelColliders[i].steerAngle = steer * maxSteerAngle; // ステアリング(前輪) wheelColliders[i].motorTorque = accel * maxMotorTorque; // アクセル wheelColliders[i].brakeTorque = brake ? brakeTorque : 0f; // ブレーキ } } } |
図14 CarController.csファイルに追加する記述
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
GameObject brakeLight, headLight; // ランプ類のオブジェクトを格納する変数 // ゲーム開始時に1回のみ実行されるメソッド void Start() { // ランプ類のオブジェクトを探して取得 brakeLight = GameObject.Find("SkyCarBrakeLightsGlow"); headLight = GameObject.Find("SkyCarHeadLightsGlow"); } void Update() { // ランプ類の点灯・消灯 brakeLight.SetActive(brake); if (Input.GetKeyDown(KeyCode.H)) { headLight.SetActive(!headLight.activeSelf); } |
図16 「Timer.cs」ファイルに記述する内容
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 |
using UnityEngine; using UnityEngine.UI; using UnityEngine.SceneManagement; public class Timer : MonoBehaviour { public Text timeText; // タイム表示用のテキスト float startTime; // 計測開始の時刻 bool start, check, goal; // 各地点の通過フラグ void Start() { // オブジェクトのコンポーネントを取得 timeText = GameObject.Find("TimeText").GetComponent<Text>(); timeText.text = "TIME 00.000"; // テキストの初期化 } void Update() { // スタートしてからゴールするまでタイムを表示 if (!goal && start) timeText.text = "TIME " + (Time.time - startTime).ToString("00.000"); // ゴール後に[R]キーを押すとリスタート if (goal && Input.GetKey(KeyCode.R)) SceneManager.LoadScene(SceneManager.GetActiveScene().name); } // トリガーオブジェクトに侵入した時に呼び出されるメソッド void OnTriggerEnter(Collider other) { if (other.gameObject.name == "StartPoint") { if (check) { goal = true; // チェックポイント通過済みならゴール timeText.color = Color.red; } else if (!start && !check) { start = true; // チェックポイントを通過していない場合、タイム計測開始 startTime = Time.time; } } else if (start && other.gameObject.name == "CheckPoint") check = true; // チェックポイントを通過 } } |