この講座はUnityとC#で作るSRPGのプログラミング開発講座の第12回です。
前回の記事で敵の行動AIパターンやターン変更システムの実装まで完了し、一通り最低限の形でターン制戦略シミュレーションゲームが遊べるようになりました。
前回の記事:
この章からははより遊びやすくするために各所に改良を施していきます。
具体的には、スマホアプリ化にも対応しているカメラ移動の処理・属性攻撃システムの実装・BGMと効果音の実装を行います。
画面を押しっぱなしにする処理を作り、カメラ移動処理を実装する
現在メインカメラは斜め上からマップ中央を向く形で位置しています。
この位置関係をそのままに、横や後ろから回り込めるように移動できるようにさせましょう。
ゲームの操作的には「画面上のボタンを押している間だけカメラが移動する」ように制作しますが、Unity標準のButtonコンポーネントにはボタンが押されたままの状態を検知する機能がありませんのでButtonではない方法を使用します。
まずは左方向に移動するボタンとしてImage UIオブジェクト「CameraButton_Left」をCanvas以下に追加します。
[Source Image]には同名の画像素材(CameraButton_Left)を指定し、画面の左上付近に配置しましょう(AnchorsとPivotの値も変わっていることに注意)。そしてこのオブジェクトをコピー&ペーストし、右移動用のボタンとしてCameraButton_Rightを配置します。こちらの画像素材は同じものを使用し、オブジェクトを左右反転させることで右向きの矢印として見せます。
ボタンが押されている間カメラが移動するスクリプト
以上の画像UIがタップされている間だけ実行される移動処理を先に用意しておきます。
カメラオブジェクトを制御するための新クラスCameraControllerを作成しましょう。
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 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 |
using System.Collections; using System.Collections.Generic; using UnityEngine; public class CameraController : MonoBehaviour { // カメラ移動用変数 private bool isCameraRotate; // カメラ回転中フラグ private bool isMirror; // 回転方向反転フラグ // 定数定義 const float SPEED = 30.0f; // 回転速度 void Update () { // カメラ回転処理 if (isCameraRotate) { // 回転速度を計算する float speed = SPEED * Time.deltaTime; // 回転方向反転フラグが立っているなら速度反転 if (isMirror) speed *= -1.0f; // 基点の位置を中心にカメラを回転移動させる transform.RotateAround ( Vector3.zero, // 基点の位置(0, 0, 0) Vector3.up, // 回転軸 speed // 回転速度 ); } } /// <summary> /// カメラ移動ボタンが押し始められた時に呼び出される処理 /// </summary> /// <param name="rightMode">右向きフラグ(右移動ボタンから呼ばれた時trueになっている)</param> public void CameraRotate_Start (bool rightMode) { // カメラ回転中フラグをON isCameraRotate = true; // 回転方向反転フラグを適用する isMirror = rightMode; } /// <summary> /// カメラ移動ボタンが押されなくなった時に呼び出される処理 /// </summary> public void CameraRotate_End () { // カメラ回転中フラグをOFF isCameraRotate = false; } } |
UIは「タップされている間」を直接検知することは出来ませんが、「タップされた瞬間」と「タップした手が離れた瞬間」にそれぞれ処理を呼び出せるので2つのpublicメソッド(移動の開始と終了)を用意しています。
それではメソッド呼び出しのためにオブジェクト側の設定を変更します。まずはMain Cameraオブジェクトに今作成したスクリプトをアタッチしましょう。
続いてボタンUIのCameraButton_Leftを選択し、Event Triggerコンポーネントを追加しましょう。
このコンポーネントによって「タップの開始(Pointer Down)」「タップの終了(Pointer Up)」というタイミングをイベントとして処理し、先ほどのメソッドを呼び出せるようになります。
まずはタップされた時にCameraRotate_Startメソッドを呼び出す設定をします。[Add New Event Type]をクリックしてPointer Downを選択します。
新しい枠が追加されるので、右下の+ボタンを押してメソッドの指定を行いましょう。以下のように設定できればOKです。
これでこの画像がタップされた瞬間にカメラが左移動を開始するようになりました。続いて移動停止メソッドを呼び出す設定も行います。
[Add New Event Type]を再度クリックし、Pointer UPを選択します。こちらではCameraRotate_Endメソッドを指定しましょう。これにて左方向へのカメラ移動が実装できました。右移動UI(CameraButton_Right)にもほぼ同じ設定を行うため、以下の手順でコンポーネントのコピー&ペーストを行いましょう。
左移動UI側のEvent Triggerコンポーネントの右上「…」ボタンをクリックし、[Copy Component]を選択します。その後右移動UI側の任意のコンポーネントで同じボタンをクリックし、[Paste Component As New]を選択すれば複製完了です。
こちらのボタンが押された場合には移動方向を反転させるため、引数で用意していた右向きフラグ(rightMode)をtrueにさせます。
これでカメラの移動操作が行えるようになりました。
(任意)ピンチイン・ピンチアウト操作の実装
スマートフォン上でのピンチイン・ピンチアウト操作をゲーム内カメラにも反映させる事が可能です。
以下の新クラスCameraZoomはその処理の一例となります。
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 36 37 38 39 40 41 42 43 |
using UnityEngine; public class CameraZoom : MonoBehaviour { // メインカメラ private Camera mainCamera; // 定数定義 const float ZOOM_SPEED = 0.1f; // ズーム速度 const float ZOOM_MIN = 40.0f; // カメラの最小の視野 const float ZOOM_MAX = 60.0f; // カメラの最大の視野 void Start () { mainCamera = GetComponent<Camera> (); // カメラの参照を取得 } void Update () { // マルチタッチ(2点同時タッチ)でないなら終了 if (Input.touchCount != 2) return; // 2点のタッチ情報を取得する var touchData_0 = Input.GetTouch (0); var touchData_1 = Input.GetTouch (1); // 1フレーム前の2点間の距離を求める float oldTouchDistance = Vector2.Distance ( // Vector2.Distanceで2点間の距離を取得 touchData_0.position - touchData_0.deltaPosition, // (deltaPositionには1フレーム前のタッチ位置が入っている) touchData_1.position - touchData_1.deltaPosition ); // 現在の2点間の距離を求める float currentTouchDistance = Vector2.Distance (touchData_0.position, touchData_1.position); // 2点間の距離の変化量に応じてズームする(カメラの視野の広さを変更する) float distanceMoved = oldTouchDistance - currentTouchDistance; mainCamera.fieldOfView += distanceMoved * ZOOM_SPEED; // カメラの視野を指定の範囲に収める mainCamera.fieldOfView = Mathf.Clamp (mainCamera.fieldOfView, ZOOM_MIN, ZOOM_MAX); } } |
- UnityのInputの機能ではマルチタッチ(複数の指での同時タッチ)も扱うことができます。Touch型には様々な情報が入っているのでこれをもとにピンチイン・ピンチアウトの操作を検出します。
このクラスをMain CameraオブジェクトにアタッチすればOKです。動作確認には実機へのビルドが必要になります。
属性間の相性を設定する
これまでキャラクター側にそれぞれ属性(水・火・風・土)を設定して表示してきましたが、ゲームには特に影響を与えず見た目だけの設定となっていました。
ここで属性間の相性を設定し、戦闘ダメージに影響を与えるように変更していきましょう。
相性についてはそれぞれ以下のように定義します。
- 水属性:火に強く土に弱い
- 火属性:風に強く水に弱い
- 風属性:土に強く火に弱い
- 土属性:水に強く風に弱い
それぞれ相性が良い相手には戦闘ダメージが1.2倍、苦手な相手には0.8倍とした時、以下のようなメソッドで適切なダメージ倍率を取得できるようになります。
まとめ
追加機能が多くなってきたので一旦ここでまとめます。
- Event Triggerを設定することでタッチ操作に関する処理を幅広く実装しました。
- 戦闘式に場合分け処理を組み込むことで属性攻撃システムを実装しました。
- Audio SourceコンポーネントやDo.Tweenを使用することでBGMやSEを自由に再生可能。
次回はキャラクターの移動範囲パターンの拡張とコマンドを途中キャンセルする処理を実装します。
次の記事:
コメント