【unity + C#】パズルゲームの開発 – その1 フリックイベント

takegami_unity_eyecatch

お疲れ様です、
Headwaters プロダクトデザイン事業部 スタートアップ課の
たけがみです。

以前はTizenの記事を投稿しました。
izenはTizen…

国内で発売する可能性は相当薄くなったTizenですが、
Tizenのことは忘れましょう。

今回からはUnity + C#のパズルゲーム開発のブログを連載しようと思います。

まずは初回なのでどんな設計をしたかと、
フリック操作の判別を行うロジックを書いていきます。

まず、オブジェクトを操作するために用意したのは2つのスレッドです。

Unity + C#は.NETの拡張なので、
System.Threadingを使用することができますが、
UnityでGameObjectを操作できるのは
MonoBehaviourクラスを継承したクラスだけなので、
フリックイベントを受け取り、
アニメーションスレッドに対してイベントを発行する
“MainCamera : MonoBehaviour”と
イベントを受け取り、
オブジェクトを回転させる
“GameLayer : MonoBehaviour”
というクラスを用意しました。
この2つのスレッド間でメッセージをやり取りするために
“Messenger : object”という抽象クラスを継承した
シングルトンクラスにメッセージキューを持たせることにします。

イメージとしては下図のようになります。

takegami_設計イメージ

もっと素敵な実装があるかもしれないですが
今のところこれで上手くいっています。

次にMainCameraクラスの中で、フリックイベントの検知とイベントの発行を行います。

イベント発行先のMessengerの実装は以下のようになってます。

 

/**
 * メッセージ受け渡し基底クラス
 */
abstract public class Messenger : object {

    private Queue _que;

    // メッセージ送信
    public void SendMessage(object p_obj) {
        this._que.Enqueue(p_obj);
    }

    // メッセージ受信
    public object RecvMessage() {
        return this._que.Dequeue();
    }

    // メッセージ数取得
    public int Count { get{ return this._que.Count; } }

    public Messenger() {
        this._que = new Queue();
    }
}

 

この抽象クラスを継承したGameMessengerをシングルトンクラスとして作成します。

 

/**
* フリックイベントメッセンジャー
*/
public class GameMessenger : Messenger {

private static GameMessenger _instance = new GameMessenger();

public static GameMessenger Instance { get{ return _instance; } }
}

 

送信する側は
public void SendMessage(object p_obj);
でメッセージを送信し、

受信する側は
public object RecvMessage();
でメッセージを受信します。

次にMainCameraのフリック検知の実装です。

画面タッチのイベントは
Inputという静的インスタンスの
touchCountというプロパティにはいっています。

今回、マルチタッチは実装しないので、
MainCameraのUpdate()関数の実装は以下のようになります。

if(Input.touchCount > 0) {
Touch _touch = Input.GetTouch(0);

// ダウン
if(_touch.phase == TouchPhase.Began) {
this.onTouchDownEvent(_touch.position);
// アップ
} else if(_touch.phase == TouchPhase.Ended) {
this.onTouchUpEvent();
}
}

 

ちなみに、Input.touchCountは実機でないと動作しないので、
自分の場合はデバッグ用に

if(Input.GetMouseButtonDown(0)) {
this.onTouchDownEvent(Input.mousePosition);
} else if(Input.GetMouseButtonUp(0)) {
this._onTouchMoveStub(Input.mousePosition);
}

 

を実装しています。
GetMouseButtonDown(0)でマウスの
右クリックのイベントを拾うことができます。

各イベントの中の実装は以下のようになってます。

// ダウンイベント
protected void onTouchDownEvent(Vector3 p_position) {
this._startX = (int)p_position.x;
this._startY = (int)p_position.y;
}

// アップイベント
protected void onTouchUpEvent() {
if(this._directionX != (int)DirectionKind.None &&
this._directionY != (int)DirectionKind.None) {
return;
} else if(this._directionX == (int)DirectionKind.None &&
this._directionY == (int)DirectionKind.None) {
return;
}

FlickInfo l_fInfo = new FlickInfo();
l_fInfo.StartX = this._startX;
l_fInfo.StartY = this._startY;
l_fInfo.Direction = ((this._directionX != (int)DirectionKind.None) ?
this._directionX : this._directionY);

// メッセージ送信
GameMessenger.Instance.SendMessage(l_fInfo);

this._startX = 0;
this._startY = 0;
this._directionX = (int)DirectionKind.None;
this._directionY = (int)DirectionKind.None;
}

 

DirectionKindはフリックの方向を定義してある列挙型、
FlickInfoはGameMessengerに送信するフリック情報オブジェクトです。

各イベントの引数であるVector3にタッチした座標情報が入っているので、
ダウンイベントで_startXと_startYにタッチ開始時の座標を保存し、
アップイベントのVector3から離したときの座標座標を取得し、
_startX, _startYの座標と比較を行い、
どの方向にフリックしたのかを判別しています。
GetMouseButtonではMoveイベントは取得できないので、
Moveイベントを実装する場合は、
実機での動作確認をする必要があります。

フリック方向を判別したら、
先ほど実装したGameMessengerにイベントを送信しています。

GameMessenger.Instance.SendMessage(l_fInfo);

これで、フリックイベントの発行の実装は完了です。

少し長くなってしまったので、
イベントの受信の実装は次回の記事で紹介いたします。

以上でーす。

takegami_unity_eyecatch

コメントを残す

メールアドレスが公開されることはありません。