actionScript書きの日記

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

エフェクト考 その1

前回のブログで「主にパーティクルのエフェクトに関して、その画像素材をいかにして作成するか」というような内容を書いたが、もう少しそこに補足をしておきたい。

大前提として、制作者が以下の状態であるとする。

 

 

この条件で、一体自分に何が出来るか、どのように学習を進めていくべきかを考える必要がある。

 

まず、最初に検討したいのは、基本図形のみでどこまでのエフェクトが作成可能なのか、という点である。ここでいう基本図形とは「円(楕円含む)」「四角」「三角」「その他多角形」およびそこから作成されるグラデーション、ということになる。

前回もアップしたが、最もシンプルな形態となるとこのような形になるだろう。

 

youtu.be

 

業務でshurikenを使用してみて実感するが、意外とこの「グラデの掛かった円」というパーティクルは利用シーンが広く、侮れないという印象。こうした基本図形のみでどこまでエフェクトを作成できるのかということは、突き詰めて考えていくべきだろう。また、この手のエフェクトはある程度の作例がネットでも公開をされている。

 

次に検討したいのが、PhotoshopおよびAfterEffectsに搭載されたフィルタを使用した素材作りである。

個人的には、絵の描けない人間はここに全振りするしかなかろうと思うのだが、ネット上にはこれに関する情報があまり見当たらない(あるいは自分の調べ方が悪いのかもしれないが)。

取っ掛かりが難しいという印象があるのだが、全く何もない状態から使用できる主だったフィルタは、大別すると以下の二つのみとなる。

  • 雲模様
  • ノイズ

また、このあたりを足がかりに作成した画像に対して多用されるフィルタとして

あたりが挙げられるかと思う。まずはこのあたりの組み合わせからどのようなエフェクトを生成できるか、を考えていくのが出発点となるだろう。

今回は、以下の手順で簡単なテクスチャ画像を作成し、エフェクトに使用してみた。

白と黒の二色で、1024px四方のサイズで雲模様を実行

その画像を256*256のサイズに縮小

中心から周囲にかけてグラデーションでマスク

これにより作成した画像が以下のようになる。

f:id:goodbyegirl1974:20180310103703p:plain

f:id:goodbyegirl1974:20180310103706p:plain

二枚目は、上記の画像にノイズを加え、斜め方向にブラーをかけたものとなる。

これらを組み合わせて作成した炎のエフェクトが以下になる。

 

youtu.be

 

最初のエフェクトに比べて、幾ばくか情報量が増えているのがお分かりいただけるだろうか。

 

最後に、簡単な絵を描く、という選択肢があるのだが、これはいったん後回しとしたい。まずは前の2つに関して、いろいろと試行錯誤していきたいと思う。

エフェクト考 その0

前回からまた間が空いた。2Dゲームの課題ファイル自体は作成して授業で使用はしたものの、記事にするだけの時間的余裕がなく、一時中断となった。

今回のタイトルは「エフェクト考」である。2Dゲームは少し置いておいて、自分の業務上でエフェクト作成と向き合う必要が出てきたため、こうしたタイトルで新たに記事を起こした。

2017年より自分の業務に本格的にUnityが入ったが、そこでのメインの業務はshurikenを使用したエフェクトの作成だった。

既存コンテンツにおいてエフェクトを作成している間は、有り物から複数のパーツを引っ張ってきて並べるだけでもなんとかなっていたのだが、新規コンテンツの制作が入るかも、という段階になって、それだけではたち行かなくなってきた。

加えて、新たにエフェクト部分のマネージャーとして参画して来た方が非常に優秀な方で、AfterEffectsやMayaをしっかり使いこなしてエフェクトを作成する方なので、これまでの流用メインでの方法論では早晩限界が来てしまい、自分自身で再度自分の業務内容を見つめ直す必要が出た。

自分自身が業務委託のフリーランス扱いなので、いつまで現在の業務に従事するかも分からないのだが、職を変わるにしても、エフェクトに関して学習し、まとめておくのも、無駄ではないだろう。

というわけでエフェクト考なのだが、今回は通し番号に0をつけた。これは、実際のエフェクト作成に関してではなく、その前段階、学習開始の段階で自分が迷ったり困ったりしていることを書いておこうと思ったからである。

 

エフェクト作成に関して、普段使用しているUnityのshuriken、およびこれから使用するであろうAfterEffectsに関する情報をWebで集めていくとき、一番情報が不足するのは、「エフェクトで使用する素材画像の作成方法」だ。

例えば炎のエフェクトを作成する場合、最も初歩的なケースだと、中心部から外縁部にかけて白からオレンジに変化するグラデーションをかけた円の画像を用意して、それを乗算で重ねて表示することで炎を表現する、ということになるだろう。例えば、以下の様なものだ。


youtu.be

 

このくらいなら、いくら自分でも素材を作成することは可能である。まあ上記の映像を見ても分かる通り色使いのセンスは目を覆う感じではあるけれども、作例としては成立する程度にはなるだろう。

では、以下の動画のエフェクトであればどうだろうか。

 

youtu.be

 

もし、このレベルを抵抗なく独力で作成することが出来る方であれば、この記事を読むのは時間の無駄であるので、他のブログに当たられたい。

さて、仮に独力でこのレベルを作成することが難しいとしよう。ではこの作り方を独力で学ぼう、と考えて、その方法は二つある。何か参考書などの資料を購入するか、ネットで検索するか、だ。だが、どちらのケースでも大きな問題が発生する。使用するテクスチャの画像である。

ネット上のチュートリアルでも、エフェクト作成を解説した参考書・技術書であっても、テクスチャの画像に関してはほとんどの場合、作成方法が記述されないのである。エフェクト作成のプロセスの中でしれっと、例えば次のように著される。

続いて画像を用意する。今回は以下の画像を使用した。

 

f:id:goodbyegirl1974:20180216220342p:plain

 いやいやいや、ちょっと待って下さいよ、と言いたくなる。その画像が作成できたんだったら、後はUnityのマニュアル見てshurikenで表示しますよ。そこが作れないから困っているわけだし、そこが作れないから「よし、勉強しよう!」となってるのに。君は一体何しちゃってるんですか、と。料理番組なら、下ごしらえの部分を全部端折って、フライパンとガスコンロの使い方で番組を埋めてるようなもんだろ、と思うわけです。

しかし、逆に考えれば、この公開しない部分こそが、エフェクトデザイナーと呼ばれる人々のおそらくは「飯の種」なんだろうと思う。そう考えれば、そりゃ自分の飯の種を無料でネットで公開したりはしないわな、と思う。

つまり、ネット上になかなか直接的な情報が出ず、なおかつ自分がエフェクト学習の際に困っている部分こそが、エフェクト作成の一番の肝なのだろう。

というわけで、備忘録的に、自分がこの肝の部分をどのように学習していくかを書いていきたいと思う。もちろん、自分にとってもこれが「飯の種」になる可能性はあるわけで、その場合はぼかしながらの記載にはなるであろうが。

取り急ぎ、上記のような画像を作成するには、毎度おなじみ雲模様を使用するのが定番である。加えて、AfterEffectsだとPhotoshopよりも更にいろいろといじれるようでもある。取っ掛かりとして、このあたりを手がかりに学習を進めていきたいと思う。

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」メニューから自動でスライスを生成することが可能だ。

     

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

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