【Unity7】タッチパネルに対応させたい!【2Dローグライク14(Fin)】
Unity5.0.0f4 Personal(2015年6月)
前回の続きです〜
前回まででゲームは完成したのですが、最後にタッチパネルに対応させ、スマホでも遊べるようにしたいと思います〜
【目標】スマホに対応させる!
2D Roguelike 14 of 14 : Mobile - YouTube
①ビルドの設定
まずはビルドの設定を行います〜ビルドとは、開発環境から実際にパソコンやスマホなどで動かせるファイルに変換する作業です〜
それではまずは、File>Build Settingsを選択します〜
File>Build Settings
現在のシーンをAddCurrentし、Buildの対象にします〜
Add Current
PlatformをiOSにしSwitch Platformボタンを押します〜これで、iOS用のファイルを作成する準備が整いました〜
PlatformをiOSに変更
②Playerスクリプトを修正
続いてプレイヤーを動かすPlayerスクリプトを修正していきます〜以下ソースです〜
using UnityEngine; using System.Collections; using UnityEngine.UI; public class Player : MovingObject { public int wallDamage = 1; public int pointsPerFood = 10; public int pointsPerSoda = 20; public float restartlevelDelay = 1f; public Text foodText; public AudioClip moveSound1; public AudioClip moveSound2; public AudioClip eatSound1; public AudioClip eatSound2; public AudioClip drinkSound1; public AudioClip drinkSound2; public AudioClip gameOverSound; private Animator animator; private int food; //********** 開始 **********// //タッチ位置の初期位置 Vector2(-1.0, -1.0) private Vector2 touchOrigin = -Vector2.one; //********** 終了 **********// protected override void Start () { Debug.Log(touchOrigin); animator = GetComponent<Animator>(); food = GameManager.instance.playerFoodPoints; foodText.text = "Food: " + food; base.Start(); } private void OnDisable () { GameManager.instance.playerFoodPoints = food; } void Update () { if (!GameManager.instance.playersTurn) return; int horizontal = 0; int vertical = 0; //プラットフォームを判定し処理を選択する //キーボードでの操作 #if UNITY_STANDALONE || UNITY_WEBPLAYER horizontal = (int)Input.GetAxisRaw ("Horizontal"); vertical = (int)Input.GetAxisRaw ("Vertical"); if (horizontal != 0) { vertical = 0; } //タッチ操作 #else //タッチ数が1以上、つまり画面がタッチされたら if (Input.touchCount > 0) { //touches配列のうち、1番目のみを使う = シングルタッチのゲームだから Touch myTouch = Input.touches[0]; //タッチ開始時なら if (myTouch.phase == TouchPhase.Began) { //touchOriginにタッチ位置を取得 touchOrigin = myTouch.position; } //画面から指を離した&Xの位置(横向き)が0以上なら else if (myTouch.phase == TouchPhase.Ended && touchOrigin.x >= 0) { //指を離した位置を取得 Vector2 touchEnd = myTouch.position; //touchEnd.xからtouchOrigin.xを引き、横の移動幅を出す float x = touchEnd.x - touchOrigin.x; //touchEnd.yからtouchOrigin.yを引き、縦の移動幅を出す float y = touchEnd.y - touchOrigin.y; //このif文に再度入らないようにtouchOrigin.xを変更 touchOrigin.x = -1; //移動幅xの絶対値のほうが長い時はhorizontal(横)を設定 if (Mathf.Abs(x) > Mathf.Abs(y)) //xが0より大きければ1(右移動)、小さければ-1(左移動) horizontal = x > 0 ? 1 : -1; //移動幅yの絶対値のほうが長い時はvertical(縦)を設定 else //yが0より大きければ1(上移動)、小さければ-1(下移動) vertical = y > 0? 1 : -1; } } //プラットフォーム判定の終了 #endif if (horizontal != 0 || vertical != 0) { AttemptMove<Wall>(horizontal, vertical); } } protected override void AttemptMove <T> (int xDir, int yDir) { food--; foodText.text = "Food: " + food; base.AttemptMove <T> (xDir, yDir); RaycastHit2D hit; if (Move (xDir, yDir, out hit)) { SoundManager.instance.RandomizeSfx(moveSound1, moveSound2); } CheckIfGameOver(); GameManager.instance.playersTurn = false; } protected override void OnCantMove <T> (T component) { Wall hitWall = component as Wall; hitWall.DamageWall(wallDamage); animator.SetTrigger("PlayerChop"); } private void OnTriggerEnter2D (Collider2D other) { if (other.tag == "Exit") { Invoke ("Restart", restartlevelDelay); enabled = false; } else if (other.tag == "Food") { food += pointsPerFood; foodText.text = "+" + pointsPerFood + " Food: " + food; SoundManager.instance.RandomizeSfx(eatSound1, eatSound2); other.gameObject.SetActive(false); } else if (other.tag == "Soda") { food += pointsPerSoda; foodText.text = "+" + pointsPerSoda + " Food: " + food; SoundManager.instance.RandomizeSfx(drinkSound1, drinkSound2); other.gameObject.SetActive(false); } } private void Restart () { Application.LoadLevel(Application.loadedLevel); } public void LoseFood (int loss) { animator.SetTrigger("PlayerHit"); food -= loss; foodText.text = "-" + loss + " Food: " + food; CheckIfGameOver(); } private void CheckIfGameOver () { if (food <= 0) { SoundManager.instance.PlaySingle(gameOverSound); SoundManager.instance.musicSource.Stop(); GameManager.instance.GameOver(); } } }
Player.cs
まずはメンバー変数にtouchOriginというVector2型の変数が追加されました〜
touchOriginは、画面をタッチした時の指の位置を記録します〜
「-Vector2.one」は、(-1.0f, -1.0f)の位置を意味し、初期値をマイナスの値にしておくことで後述するif文の条件に合致しないようにしています〜
続いてUpdateメソッドです〜こちらに#ifや#else、#endif等見慣れない言葉が追加されていますが、これはプラットフォームによってコードを使い分けています〜
以前書いたGetAxisRawを使ったキーボード入力はUNITY_STANDALONEかUNITY_WEBPLAYERのみで有効にし、それ以外のタッチ操作が必要なプラットフォームの場合は、#else文の中を実行します〜
#else文の中では、まずはじめにInput.touchCountを使い、画面がタッチされているかの判定をしています〜
続いてInput.touches配列の先頭の配列をTouch型のmyTouch変数に保存しています〜このゲームはシングルタッチのゲームのため、2本目、3本目の指でのタッチを無視する必要があるためです〜
続いて「myTouch.phase」でタッチの状態を判定し、タッチし始め(TouchPhase.Began)である場合は、touchOriginに現在のタッチ位置を保存します〜
タッチの状態がタッチ終了(TouchPhase.Ended)であり、また、touchOrigin.xの位置が0以上である場合、移動方向を決める処理に入ります〜
まずは指を離した時の位置情報をtouchEndというVector2型の変数に保存します〜
次にtouchEnd.xからtouchOrigin.x(タッチし始めの位置)をマイナスし、2点間の距離を出します〜yについても同様です〜
次にtouchOrigin.xを-1にしています〜このif文に入る条件としてtouchOrigin.x >= 0がありますので、-1にすることによりif文に何度も入らないようにしています〜
続いて縦の移動幅(y)と横の移動幅(x)の大小関係を判定し、横移動のほうが大きければ、更にxの値が0より大きいかを判定し、0より大きい場合は1を、そうでない場合は-1をhorizontalに保存しています〜縦の移動幅のほうが大きければ、yについて同様の処理を行います〜
Mathf.Abs()は、絶対値を取得する関数です〜例えば引数に3入れると3を返しますし、-3を入れた時も、マイナスを除いた3を返します〜
horizontal = x > 0 ? 1 : -1;という見慣れない形がありますが、こちらは「条件判定 ? trueの場合の戻り値: falseの場合の戻り値;」を意味しています〜
これでひと通りのゲーム機能と、タッチ機能が備わりました〜
長い時間ありがとうございました〜
【Unity開発7】Unity公式チュートリアル2Dローグライクの導入【2Dローグライク1】
【Unity開発7】アニメーションを作りたい!【2Dローグライク2】
【Unity開発7】Floorやアイテムを作成したい!【2Dローグライク3】
【Unity開発7】床や敵キャラ、アイテム等を自動生成させたい!【2Dローグライク4】
【Unity開発7】BoardManagerを呼び出すGameManagerを作成する【2Dローグライク5】
【Unity開発7】キャラクターを動かすための抽象クラス作成【2Dローグライク6】
【Unity開発7】破壊可能な壁(Wall)を作成したい!【ローグライク7】
【Unity開発7】プレイヤーのアニメーターを設定したい!【ローグライク8】
【Unity開発7】プレイヤー用のスクリプトを設定したい!【ローグライク9】
【Unity開発7】敵キャラクターのスクリプトを作成したい!【2Dローグライク10】
【Unity開発7】敵キャラクターのアニメーターを設定したい!【2Dローグライク11】
【Unity開発7】uGUIでUIの表示とレベル機能を実装したい!【2Dローグライク12】