actionScript書きの日記

アラフォーFlashデベロッパのブログ。actionscriptやobjective-cを経て、現在はUnity、Spine、AfterEffectsがメイン。

Unityちゃん (2D)を使用して、2Dゲームを作ってみる 番外編1

2Dのキャラの動かし方をずっといろいろ試していたんだけど、初めて気がついて詰まってしまった点があったので、備忘録として。

 

「GameManager」というクラスを実装すると同時に、2Dアクションゲームの敵役として「missile_horizonal」というプレハブを用意しておく。

この「missile_horizonal」には同名のスクリプトファイルがAdd Componentされており、プレハブは「GameManager」から動的に生成できるように「Resources」フォルダ内に配置されている。

「GameManager」内で「createMissile」という関数を実行している。ここで動的に「missile_horizonal」のインスタンスを生成し、画面に表示している。

ここで問題になるのが、関数「createMissile」内で「missile_horizonal」内の「init」という関数を実行していることだ。


GameObject missile = (GameObject)Resources.Load ("missile_horizonal");
int dir = Random.Range (0, 2);

//中略

Instantiate (missile, position, Quaternion.identity);
missile_horizonal mh = missile.GetComponent ();
mh.init (dir);

要は変数「dir」の値に応じて挙動を変更したいために、生成したインスタンス内の関数「init」を外部から実行しようとしている。


bool setFlg = false;

//中略

void Update ()
{
	if (!setFlg) {
		return;
	}
	//中略
}

//中略

public void init (int dir)
{
	Debug.Log ("missile_init");
	dirVec = Vector2.left;
	if (dir == 1) {
		this.transform.Rotate (new Vector3 (0.0f, 180.0f, 0.0f));
	}
	setFlg = true;
}

関数「init」の中身はこんな感じ。
ここで問題になるのが、変数「setFlg」の中身なのだが、各関数の実行順を見てみると、

  1. 「missile_horaizonal」内の「Awake」
  2. 外部から実行される、「missile_horaizonal」内の「Init」
  3. 「missile_horaizonal」内の「Start」

という順番になっており、どうやらこの「Start」の段階で変数の中身が初期化されてしまうらしい。 つまり関数「init」内でtrueが代入された変数「setFlg」の値が、関数「Start」内で初期化されて再度falseに戻ってしまうようなのだ。

従ってUpdateのreturn文以降の処理はいつまでたっても実行されず。。。。ちょっと予想していない挙動だったので、念のために書き留めておく。

Unityちゃん (2D)を使用して、2Dゲームを作ってみる その 4 GetAxis

前回はキー入力の受付処理を書いたが、Unityちゃん2Dのサンプルにおいては、別の形でキー入力をキャラの移動に反映させている。


float x = Input.GetAxis("Horizontal");
bool jump = Input.GetButtonDown("Jump");
Move(x, jump);
jumpに関しては「GetButtonDown」を使用しているが、GetKey系とGetButton系の処理の違いに関しては、以下の記事がよくまとめてくださっている。

http://qiita.com/RyotaMurohoshi/items/688fe33f44de8339c497

GetButton系の処理の方が、キーアサインをユーザーも上書きできる点が優れている、ということのようだ。

続いて、GetAxisに関して見ていきたい。 これは、事前に設定したキー操作に応じて-1〜1の間で変化する値を取得する関数である。 Inputの設定画面は、「Edit」→「Project Settings」→「Input」から呼び出す。

f:id:goodbyegirl1974:20170401183806p:plain

呼び出されたInputの設定画面を確認すると、Axisに関しては既に設定がされている。

f:id:goodbyegirl1974:20170404085708p:plain

「Horizonal」の欄を見ると、「Negative Button」に「left」、「Positive Button」に「right」が設定されている。 これによって、対応する値が-1から1の間で変化する。左矢印を押せば値が減り、右矢印を押せば値が増加する。 この辺りは、ゲーム制作への使用を前提とした機能と言えるだろう。便利だが、初見ではちょっと分かりにくい。

ユニティちゃん2Dのサンプルファイルでは、この「GetAxis」が使用されている。

Unityちゃん (2D)を使用して、2Dゲームを作ってみる その3 ユーザー入力の受付

前回までで画像の設定とアニメーションの作成方法を一通り見たので、そのようにして作成したGameObjectを、ユーザーからの入力に応じて動かしてみることにする。

今回はPCでの入力を主に見ていくが、スマートホンなどのケースも少しずつ触れていくことにする。

■PCでの入力受付

PCでの入力というと、メインとなるのは

  • キー入力
  • マウス入力
  • の二つとなるだろう。これらをそれぞれ見ていくこととする。

    キー入力

    キー入力の場合、やり方が複数ある。順を追って見ていくことにする。

    Input.GetKey, GetKeyDown , GetKeyUp

    指定したキーが該当する状態にあるかどうかを確認するための関数。戻り値はBooleanか?

    名前状態
    Input.GetKeyキーを押している間は常にtrue
    Input.GetKeyDownキーが押されていない状態から押した際にtrue
    InputGetKeyUpキーを押している状態から離した際にtrue

    これらのメソッドを用いて、キーの状態を取得することになる。 具体的に見てみよう。

    クラス「InputManager.cs」を作成し、前回生成したキャラクターのGameObjectにアタッチする。 クラス内の関数「update」内に、キー入力を受け付けるための処理を記述していく。

    void Update () {
    	if (Input.GetKey (KeyCode.RightArrow)) {
    	Debug.Log ("右矢印が押された");
    	}
    }
    

    右矢印キーが押されている間ずっと反応させたい場合、上記のような形になる。 この形で矢印キーによるキャラの移動を実装してみる。

    
    float horizonalSpeed;
    float horizonalMaxSpeed = 6.0f;
    int horizonalDir;
    Rigidbody2D rb2d;
    
    const int DIR_RIGHT = 1;
    const int DIR_LEFT = -1;
    const int DIR_NONE = 0;
    const int DIR_TOP = 1;
    const int DIR_BOTTOM = -1;
    
    const string MOVE_TYPE_HORIZONAL = "horizonal";
    const string MOVE_TYPE_VERTICAL = "vartical";
    
    
    // Update is called once per frame
    void Update ()
    {
    	if (Input.GetKeyDown (KeyCode.RightArrow)) {
    		horizonalDir = DIR_RIGHT;
    	}
    	if (Input.GetKeyDown (KeyCode.LeftArrow)) {
    		horizonalDir = DIR_LEFT;
    	}
    	//キーを離した際の処理。
    	if (Input.GetKeyUp (KeyCode.RightArrow)) {
    		if (!Input.GetKey (KeyCode.LeftArrow)) {
    		stop(MOVE_TYPE_HORIZONAL);
    		}
    	}
    	else if (Input.GetKeyUp (KeyCode.LeftArrow)) {
    		if (!Input.GetKey (KeyCode.RightArrow)) {
    		stop(MOVE_TYPE_HORIZONAL);
    		}
    	}
    	move (horizonalDir, jumpFlg);
    }
    
    /// 
    /// 移動停止処理
    /// 
    /// Type.
    void stop(string type)
    {
    	if (type == MOVE_TYPE_HORIZONAL) {
    		horizonalDir = DIR_NONE;
    		horizonalSpeed = 0.0f;
    	}
    }
    		
    
    /// 
    /// キャラを移動させる関数。
    /// 
    /// Dir.
    void move (int dir, bool jumpFlg)
    {
    	horizonalSpeed += accelSpeed * dir;
    	if (horizonalSpeed > horizonalMaxSpeed) {
    		horizonalSpeed = horizonalMaxSpeed;
    	} else if (horizonalSpeed < -horizonalMaxSpeed) {
    		horizonalSpeed = -horizonalMaxSpeed;
    	}
    	rb2d.velocity = new Vector2 (horizonalSpeed, 0);
    }
    

    これでキャラを矢印キーで左右に動かすことが可能になる。

    Unityちゃんのサンプル内では、ちょっと違った処理を行っている。次回はその処理を解析する。

    Unityちゃん (2D)を使用して、2Dゲームを作ってみる その2

    前回設定を行ったpng画像を用いて、アニメーションを作成してみる。

    前回の設定によって、一枚のpngの中に複数の画像が生成されているのが確認できると思う。

    f:id:goodbyegirl1974:20170328083914p:plain

    上記画像は、画像3つを選択したところ。 この選択した画像を、そのまま「Hierarchy」画面にドラッグすると、選択した画像を使用したアニメーションが自動で生成される。

    f:id:goodbyegirl1974:20170328084228p:plain

    上記ポップアップが表示されるので、場所と名前を設定して保存する。

    作成されるのは2ファイル。AnimationとAnimator Controllerが作成される。

    「Hierarchy」内に生成されたprefabを選択して、Animationウィンドウを開いて確認すると、以下のように表示される。

    f:id:goodbyegirl1974:20170328084905p:plain

    左から右に時間軸が表示され、キーフレームが菱形で表示されているのが分かると思う。 タイムライン上をダブルクリックすれば、キーフレームを追加することができる。

    表示画像を切り替えたい場合は、「Inspector」ウィンドウから設定を行う。

    f:id:goodbyegirl1974:20170328085643p:plain

    このようにして、時間軸に沿って表示画像を切り替えていくことでアニメーションを実装する。 パラパラ漫画の原理と思えば良い。

    Adobe Animateではフレームレートはファイル内で共通の値をとるが、Unityの場合は各Animationごとにフレームレートを設定できる。

    f:id:goodbyegirl1974:20170328085937p:plain

    画像の赤枠内に任意の数値を設定すれば、フレームレートとして反映される。 地味だが便利な機能だ。

     

    次回は、今回生成したキャラクターをキー入力で移動させてみることにする。

    Unityちゃん (2D)を使用して、2Dゲームを作ってみる その1

    随分と間が空いてしまったが、その間に仕事内容は

     

    ActionScriptによるPC用オンラインゲーム開発→Unityによるスマホ用オンラインゲームの開発(主にC#)→Unitysyurikenを使用したエフェクト作成とjenkinsmを使用したビルドへのアセット反映

     

    というように遷移し、現実に対処するのに精一杯の日々となった。

    加えて、副業として行なっている講師としての仕事でも、本年度から本格的にUnityを扱うことになった。

    なので、授業の準備を兼ねて、Unityちゃん(2D)を使用した2Dゲームの作成のサンプルをここに定期的に上げていきたいと思う。

    使用環境は以下の通り

     

    MacBookPro 2016

    Unity5.5.2f1 Personal

     

    ■Unityちゃん素材ダウンロード

    2017年3月現在で、以下のURLからダウンロード可能。

    unity-chan.com

    今回はUnityちゃん2Dのデータを使用する。

     

    ■素材に関する注意点

    ダウンロードしたパッケージファイルをUnityにインポートして使用する。

    インポートの方法は画面上部のメインメニューから「Assets」→「Import Package」→「Custom Package...」を選択して、パッケージファイルを選択する。

     

    f:id:goodbyegirl1974:20170326204711p:plain

     

    インポートすると、Project内の「Assets」以下に「UnityChan2D」というフォルダが作成される。

    ちょっと確認すれば分かるのだが、実はこの中のデータはゲーム作成に必要な最低限の設定が完了している状態となっている。キー操作、アニメーション、物理演算と衝突判定、あたりがその内容。

    それらの使い方に関しては、Project内の「Assets」→UnityChan2D」→「Documents」内の「Introduction.pdf」に詳細が記載されており、その内容に沿って設定を行うだけでも簡単にゲーム作成ができるようになっている。

    だが、ざっと内容を確認してみたのだが、用意されたファイルをそのまま使用してしまうと、残念ながらユーザー入力の受付や物理演算・衝突判定の実装方法、スプライトシートを使用したアニメーションの作成方法の基本部分に関して、あまり理解をせずに作業を進めることになってしまう。

    なので、今回はプロジェクト内の「UnityChan.png」が一枚渡されたのみ、という状態から話を進めていきたいと思う。

    ちなみに画像の場所は「Assets」→「UnityChan2D」→「Sprites」内となる。

    f:id:goodbyegirl1974:20170326204733p:plain

     

    ■Spriteの設定

    画像の設定だが、今回は一枚の画像から複数の素材を切り出して使用することになる。

    なので、Project内でUnityChan.pngを選択したら、Inspector画面で設定を行う必要がある。

    今回の設定内容は以下の通り。

    f:id:goodbyegirl1974:20170326205114p:plain

    「Sprite Mode」を「Multiple」にするのが必須。

    この上で、「Sprite Editor」ボタンをクリックして、エディタを開いて設定を行う。

    f:id:goodbyegirl1974:20170326205306p:plain

    画面上でドラッグを行うことで、一枚の画像を分割することができる。

    一枚一枚手作業で行うことも可能だが、今回は各スライスが64px*64pxで統一されているので、画面左上の「Slice」メニューから自動でスライスを生成することが可能だ。

     

    ここまでで、素材の画像を使用する準備が整ったことになる。

    次回は、アニメの作成を行う。

     

     

     

     

     

     

    actionscriptのインターフェース

    actionScriptにおいて

    IWindow.as

    function hoge():void;

     

    HogeWIndow.as

    public class HogeWindow implements IWindow

    {

      protected function hoge():void

      {

            //処理

      }

    }

    と書くと、implementsされていないとエラーが出る。

    小一時間悩んだが、結論としては、implementsするならpublic しか使えないとのこと。早く言えやそういうことは!

    2013年にやりたいこと

    2013年にやりたいこと

    ブログやってみたいって思ってたので、早速始めてみた。なので、まずは一個達成。

    その他にやってみたいのは、

    ・出社せず、好きな場所で好きな時間に仕事が出来る人になる

    ガンプラを作る(エアブラシで塗装するところまで)

    ・プライベートでスマホアプリリリース

    ってところでしょうか。