原カバンは鞄のお店ではありません。

Unityを使ったゲーム制作のあれこれを綴っていきます。

【Unity】メッシュに沿ってパーティクルを放出する

よもやよもやだ

先週は月曜日もお休みして4連休だったので今話題の鬼滅の刃の映画を観に行ったら本編より先にドラえもんの予告編で泣きそうになった皆さんこんにちは。なんならポケモンの予告編でも泣きそうになった。

 

まるで橋田壽賀子ドラマのようにキャラクターが一から十まで状況と心情を事細かく説明することで誰にでもわかりやすくなっており、それに(性格的に)完全無欠の主人公と涙を誘うストーリーが相まって、子供から老人まで人気のあるコンテンツになっているのだと思いました。

一昔前のジャンプなら善逸のようなキャラクター(普段弱くて覚醒すると強い)を主人公に据えそうなのに、どこまでも真っすぐで優しい炭治郎を主人公としたのは英断だったと思います。

 

メッシュパーティクルエミッター

f:id:Karvan:20201110221101p:plain

 

Unityではパーティクルを放出するモジュールの形状(Shape)を幾つか選択することが出来ます。

その中でMesh/Mesh Renderer/Skinned Mesh Rendererを選択すると指定した3Dモデルの周囲からパーティクルが放出されるようになります。

 f:id:Karvan:20201110221600p:plain

これはゲーム内ではキャラクターの周りで発せられるオーラや武器のエンチャントを表現する手法として使われることが多く、その様な目的用のアセットも販売されています。

 

 

f:id:Karvan:20201110221644g:plain

剣のモデルを使用したアセット

今回はこれを利用してなにか面白い演出とならないか試行錯誤したお話。

 

消えるモデル

3Dモデルの周囲からパーティクルが放出できるという事はモデルの周りに速度が0のパーティクルを大量に放出すればパーティクルがモデル表面を覆うため、パーティクルだけでモデルの形状を表すことが出来そうです。その状態でパーティクルを停止すれば雲が消えるような感じでモデルが消えて見えるのではないか、そう思ったわけです。

早速、下のモデルに対してパーティクルを放出してみます。

f:id:Karvan:20201110221925p:plain

 

実行!

 

f:id:Karvan:20201110222108g:plain

 ん~・・・モデルの後ろからパーティクルが放出しているように見える。

 どうやら3Dモデルのシェーダによってはパーティクルより後に描画されることがあるみたい。

描画順はRender Queueによって指定できますが、現在のシェーダでは変更できないのでこれをUnlitに変更

f:id:Karvan:20201110222224p:plain

 

実行!

 

f:id:Karvan:20201110222251g:plain

おぉ、なんかキモくていい感じ!

 

さらにもう一つ同じようなShapeにマスクのメッシュをしてしたパーティクルを用意して、そちらにはGravity Modifierで重力が影響するようにします
これを表面を覆うパーティクルの停止と同時に開始→数秒後に停止を行うと・・・

f:id:Karvan:20201110222414g:plain

霧散するって感じになりました。

 

利用する

折角作ったので現在制作中の脱出ゲームの中で使ってみることにしました。

 

f:id:Karvan:20201110223308g:plain

結構面白い演出になったのではないかと思います。

【Unity】影シェーダーを使ってみる

意外な結果

去年から出勤で歩く距離を増やしたり、食後に軽い運動をしたりと、色々頑張っていたのに健康診断に行ってみると体重もウエストも去年より増加していた皆さんこんにちは。食べる量が増えた記憶はないんですが、振り返ってみると週一ペースでポテチ食ってた。以後禁止します。

 

さて、Voodooのランゲームコンテストが終わったと思ったら、次は講談社のゲームクリエイターラボの応募が締め切り間近となっています。

 

daysneo.com

こちらは必ずしもプロトタイプのリリースが必要なわけでなくて企画書のみでも応募可能です。

ゲームクリエイターラボのメンバーに選ばれると、少なくとも2年間は制作支援(制作資金、作業スペース提供、宣伝広告等)が受けられるようなので、私のような名もない開発者には有難い企画ですね。まぁ相当な数の応募があるでしょうが。

 

影を表示する

以前までは開発のターゲットをスマホゲームにしていたので、負荷の大きい"影"については極力表示しない方向で制作を進めていました。

しかし、先日のVoodooランゲームコンテスト用のゲームでは、ジャンプしながら移動するという仕様上、プレイヤーがジャンプ中の自機の位置を見失ってしまう恐れがあったため、地面に自機の影が落ちるようにしました。

 

f:id:Karvan:20201013214849g:plain

 

で、やっぱり影があったほうがゲーム画面が映えるなぁ、と思ったわけです。

とは言えリアルタイムに影を表示するのはスマホでは高負荷には変わりないので、できるだけ軽く実装できる方法はないのか探っていました。

 

影シェーダー

github.com

上記はGitHubで公開されているシェーダーで、3Dモデルを影のように表示する事ができるシェーダーです。

「影のように表示する」とはどういう事かというと、Directional LightからY座標0の位置にオブジェクトを投影させて描く、という意味です。

つまりこのシェーダーを適用したオブジェクトはY座標0の平面に投影図として表示されることになります。

f:id:Karvan:20201027220745p:plain

ザックリとした説明図

 

このため使い方としては、影を表示させいオブジェクトと全く同じオブジェクトを子オブジェクトとして配置して、そのオブジェクトにこのシェーダー(Custom/PlanarShadow)を適用します。

 

f:id:Karvan:20201027220927g:plain

上の動画では恐竜のオブジェクトに影用の恐竜オブジェクトが子オブジェクトとして配置されています。

 

 この影は通常の影のように地面に描かれているわけでなく、単にオブジェクトを投影図として表示しているだけなので負荷を低く抑えることができます。

ただ、投影するY座標はシェーダーのプロパティによって変更可能ですが、あくまで平面に対する投影図となる事は注意が必要です。

 

ただし、影を反映させる平面オブジェクトは必要ないため、地面の下が透けてみるような絵を簡単に作ることができます。

 

f:id:Karvan:20201027221618g:plain

こんな感じのやつ、これをベースイメージとしてゲームクリエイターラボ向けの企画書を一つ作ろうかと思っています。

 

【Unity】小ネタ:スクリプトでテクスチャ座標を動かす

私はロボットではありません

Googleの「私はロボットではありません」のチェックの後に続く写真の選択問題が絶妙に難しいと感じている皆さんこんにちは。

「横断歩道を全て選べ」って、左端に小さくかすっているのは選ばなくても大丈夫ですよね?ああ、選ばないとダメなんですか、ごめんなさい。

 

そういえば前回の記事で「応募までの作業が難しくてエントリーできないかも」と書いていましたが、無事なんとかエントリーまでこぎつける事ができました。

ただ、もう一回同じ作業をしろと言われたら無理ですが。

 

スクロール

例えばこんな

f:id:Karvan:20201020222136p:plain

水のブロックなどについてテクスチャがスクロールできれば水が流れるような表現ができそうです。

 

こんな場合はMaterialのmainTextureOffsetを使ってテクスチャの座標をずらしていくことでスクロールさせます。

 

void Update() 
{        
        float offsetX = Time.time * scrollSpeed_X;
        float offsetY = Time.time * scrollSpeed_Y;
        this.GetComponent<Renderer>().material.mainTextureOffset = new Vector2(offsetX, offsetY);
}

実際に動かしてみるとこんな感じになります。

f:id:Karvan:20201020222444g:plain

 

【雑記】Voodooランゲームコンテストの応募ハードルが高すぎた話

欲しいもの

これだけ世間で話題になりキャラクターの名前や、柱や下弦上弦などのワードを把握していても本編は一分も見たことない皆さんこんにちは。今週末から映画版が公開らしく、TVでダイジェスト版が放送されてたりしましたが、FIFA21をやっていたら放送時間過ぎてた。

 

ファンの人から話を聞くと面白そうで見たら自分もハマりそうなんですが、なんせ今秋はOculus Quest2が発売されるし、Pixel5も発売されるし、PS5も発売されるし欲しいものだらけで、これでアニメにハマるとなるとゲーム制作の時間が無くなりそうなので自重しています。

 

Voodooランゲームコンテスト

さて以前、このブログでも紹介しましたが、Voodooのランゲームコンテストが開催されています。

 

■概要
・iOSでプロトタイプを提出
・ランゲーム&物理演算を利用したゲーム
・賞金 100,000ドル

 

以前のブログでは10/12締め切りと記載していましたが、実際は10/16が締め切りでした。

ただし、応募には事前にVoodooのPublishing Programへ登録が必要で、この登録が申請から承認されるまで一日ぐらい要します。

また、Publishing Programが完了してもランゲームコンテストの応募までにはアレコレと作業が必要で、私も現在(10/13)時点でゲームは出来上がっているものの、コンテストの応募までには至っていません。

今日はそのお話。

 

ちなみにこんな感じのゲームです。

f:id:Karvan:20201013214849g:plain

 

事前作業

まず、前述のようにPublishing Programへの登録が必要ですが、その際に応募するゲームのゲームプレイ動画を公開しているアドレスを求められます。つまり事前にプレイ動画を作成し、Youtube等にアップしておく必要があります。

また、自身の作品等を紹介するようなサイト(Portfolio link)やSkypeのIDも求められます。私はSkypeのIDは持っていないので「No ID」と入力しましたが、特に問題なかったようです。

 

これらを入力して送信すると、一日後ぐらいにVoodoo側からPublishing ProgramにアクセスするURL付きのメールが送られてくるので、そのURLからPublishing Programにアクセスしてランゲームコンテストへの応募が可能となります

 

応募に至るまでのハードル

私の勝手なイメージとしてはunityroomのようにUnityからビルドしたXcode Porjectをどこかのサーバにアップするのかな、と考えていたのですが、実際には以下のような幾つもの作業を完了させて応募完了となるようです。

 

  • FaceBookのビジネスアカウントと広告アカウントを作成する
  • 広告アカウントの管理者にVoodooが指定するuserを追加する
  • 応募ゲームにGameAnalyticsを導入する(←今ココ)
  • アップルストアに応募ゲームを登録申請する
  • ゲームのテスタとしてVoodooを申請

つまり応募前にXcode Porjectの作成までは終えていても、GameAnalyticsのプラグインを導入&設定して再ビルドする必要があるし、そのプロジェクトをアップルストアに登録申請する必要があります

 

GameAnalyticsの導入自体はUnityにそれ用のアセットがあるので、ダウンロードとしてImportすればよいのですが、現在は設定の仕方に手間取っている感じです。

 

また、設定を終えても動作確認を行う必要があるのでアップルストアに登録申請するまで時間が掛かるし、仮に順調に動作確認を終えたとしても、アップルストアへの申請にはアイコンやスクリーンショットを複数種類用意したりと色々と面倒(幸い開発者アカウントはあります)で、締め切りの10/16までにすべての作業を終えられる気がしない。。。

 

ちなみにVoodooの応募用ページには上記の手順について、絵付きで丁寧に操作&設定手順が載せられているので、英語が読める方なら難なく応募までの作業を終えられると思います。

 

もっと早くから準備すべきだったなぁ・・・

【Unity】DOOffsetCharを使って文字を円状に配置

衣替え

今年も早いもので衣替えのシーズンとなってきましたが、夏場に購入した制汗シートが未だに消費しきれず、無理に使って風邪をひきそうになった皆さんこんにちは。秋なのに"氷結"タイプとか何の修行だよ。

 

DOTweenPro

さて、以前記事でも紹介しましたが、近頃DOTweenProがアップデートされてTextMeshに対して文字単位にアニメーションを行えるようになりました。

 

www.karvan1230.com

この文字単位のアニメーションには当然ながら平行移動(DOOffsetChar)の機能も含まれているので、これを使用すれば文字を好きな位置へ移動させることが出来ます。

なので、これまでは編集した画像を用意するしかなかった「円状に並んだ文字列」というUIもDOOffsetCharを使えば動的に実装できるかもしない、そう考えたわけです。

 

円状に配置させるには

各文字の円周上の座標は、文字列の中心を原点とすれば簡単に算出することができるので、各文字の位置から円周上の位置への移動ベクトル(オフセット量)を計算できれば文字を円状に配置させることができます。

 

f:id:Karvan:20201006212608p:plain

 

この移動ベクトルは「文字列の中心から円周上の位置へのベクトル」と「文字列の中心から文字の位置へのベクトル」との差分となります。

f:id:Karvan:20201006212646p:plain

 

しかし、「文字列の中心から文字の位置へのベクトル」に関しては正確なベクトルを得るすべは現在のところありません。

最初はGetCharOffsetメソッドで取得できるかと思っていたのですが、これは「各文字の初期位置からのオフセット量」を取得するメソッドらしく、文字列の中心位置からのオフセット量が取得できるわけではありませんでした。

 

よって暫定としてTextMeshのRecttransformからTextMeshの幅を文字数で割ったものを基準として算出します。

f:id:Karvan:20201006212722p:plain

このためTextMeshの幅は文字列が一列で表示できるギリギリの幅を設定しておく必要があります。

まぁ、そのように設定してもフォントによっては各文字の幅は均等でないため、必ずしも正確な「文字列の中心から文字の位置へのベクトル」が算出できるわけではありません。あくまで暫定のベクトルになります。

 

 まぁ、それなりに・・・

実際に実装してみた結果はこんな感じになります。奇麗な円ではありませんが、それなりに表示させることはできました。

f:id:Karvan:20201006213031g:plain

 

ソースはこんな感じ、Y座標最高点を開始位置にして時計回りに配置したかったので円周位置は90度から減算させて計算しています。また、移動に合わせてDORotateCharを使って文字を回転させています。

 

    private List<Vector3> GetCirclePosList(float cirRad, int chNum)
    {
        List<Vector3> retList = new List<Vector3>();

        float radInc = 360.0f / (float)chNum;

        for (int iCnt = 0; iCnt < chNum; iCnt++)
        {
            float curShita = 90.0f - (radInc * iCnt);

            float modx = cirRad * Mathf.Cos(curShita * Mathf.Deg2Rad);
            float mody = cirRad * Mathf.Sin(curShita * Mathf.Deg2Rad);

            retList.Add(new Vector3(modx, mody, 0));
        }

        return retList;
    }

    public void CircleTextAnim()
    {
        RectTransform TargeTextRect = TargeTextMesh.GetComponent<RectTransform>();
        float TextMeshWidh = TargeTextRect.sizeDelta.x;

        DOTweenTMPAnimator tmproAnimator = new DOTweenTMPAnimator(TargeTextMesh);

        int chNum = tmproAnimator.textInfo.characterCount;
        float radInc = 360.0f / (float)chNum;

        List<Vector3> cirOffsetList = GetCirclePosList(CircleRadius, chNum);

        int halfIndex = chNum / 2;
        float wordInt = (TextMeshWidh / 2.0f) / halfIndex;

        for (int i = 0; i < tmproAnimator.textInfo.characterCount; ++i)
        {
            float xOffset = 0.0f;
            if (i <= halfIndex)
            {
                xOffset = -1 * (halfIndex - (i + 0.5f)) * wordInt;
            }
            else
            {
                xOffset = ((i - halfIndex) + 0.5f) * wordInt;
            }

            // X方向のオフセット
            Vector3 currCharOffset = new Vector3(xOffset, 0.0f, 0.0f);

            // 円周位置
            Vector3 cirOffset = cirOffsetList[i];

            // オフセットベクトル取得
            Vector3 modOffset = cirOffset - currCharOffset;

            // 文字単位のオフセット
            tmproAnimator.DOOffsetChar(i, modOffset, 2.0f);

            // 文字単位の回転
            tmproAnimator.DORotateChar(i, new Vector3(0.0f, 0.0f, -1 * radInc * i), 2.0f);
        }
    }

 

ちなみに円状に配置した後にDOOffsetCharでオフセット量にゼロ(=Vector3.zero)を指定すると元の位置へ戻すことができます。DORotateCharも同様にします。

f:id:Karvan:20201006213158g:plain

 


 

【雑記】ハイパーカジュアルできるかな

行楽シーズン

最近は朝夕の空気が肌寒く感じられ、日中も気温が上がらず過ごしやすい季節となってきて正に行楽シーズン到来と言えますが、そんなものとは縁遠く相変わらず週末は自分の部屋に引きこもっている皆さんこんにちは。

先週の四連休は一度だけ繁華街に買い物へ出かけたのですが、何気に立ち寄ったアニメイトが女性だらけでビックリしました。何をそんなに行列を作って買っているのですか?

 

コンテスト

さて、ハイパーカジュアルゲームのパブリッシャー「Voodoo」がランゲームのコンテストを開催しています。

 

■ガイドライン

  • iOSでプロトタイプを提出
  • 新規タイトル
  • ランゲーム
  • 物理ゲーム

■スケジュール

  • 2020/9/3:受付開始
  • 2020/10/12:受付終了
  • 2020/10/29:授賞式

■コンテスト概要ページ、参加登録ページ

Voodoo.io | Voodoo Runner Competition

Voodoo.io | Submit your game

 

物理系のゲームといえば、先ごろ「room5gamejam」向けに「切磋琢磨するしかない!」というゲームを制作していて、これが物理演算を使ったジャンプゲームなので、これをハイパーカジュアルゲーム風にリニューアルして提出しようと思っています。

 

まぁ「room5gamejam」では箸にも棒にも掛からぬような評価だったので期待はしていないのですが、他に良いアイデアが思い浮かばない、かつ、自分的には結構苦労して作成したゲームだったりするので、このままお蔵入りするよりは労をねぎらう意味でも応募するつもりです。

 

 ハイパーカジュアルゲーム風

世間でハイパーカジュアルゲームといえば、シンプルなグラフィックに単純な操作で簡単なルールの短いステージを繰り返し遊ぶ、みたいなイメージです。

通勤通学の時間、ちょっとした空き時間を潰すためのゲームとして作られていて、「軽く遊べる」事が重要です。

 

なので、「切磋琢磨するしかない!」では長い1ステージのゲームだったので、これを短いステージをどんどんクリアしていく形に変えないといけません。

また、自機のキャラクターも単純な形状のものに置き換えて、ステージの構成もフラットなデザインのオブジェクトが並ぶような構成に変更しする必要があります。

 

要は元々の機能をグレードダウンさせるだけなんですが、こういった作業はモチベーションが上がりませんね。

だって作品がどんどん没個性化していくから。まぁ、仕方のない事ですが。

 

現段階ではこんな感じになっています。

f:id:Karvan:20200929223736g:plain

 

 操作系の処理は出来上がっているので、あとはUIやステージの構築管理とバランス調整、BGMは必要ないけどSEは追加したいし、バウンドしたときのパーティクルも用意して、あとは・・・間に合うかな?

 

 

【Unity】ParticleのRenderingModeについて

水泡に帰す

気合を入れてゲーム開発をしていたのに、うっかりシーンをセーブすることを忘れて三時間の苦労が水の泡となった皆さんこんにちは。

また同じ作業を同じ時間だけしなきゃいけないと考えると全くモチベーションが上がりません。

 

あと、Kingdom of AmalurのPS4リマスター版を購入しました。難易度選択が「イージー → ノーマル → 困難 → ベリーハード」なのがツボです。

まぁ、UIの翻訳とロード時間以外は神ゲーなんですがストーリーはちっともわかりません。

 

タイトル画面を修正

そんなこんなで週末はゲーム本編を作るのが億劫になったので、気分転換も兼ねてタイトル画面の変更を行っていました。

変更前はunity1weekに間に合わせるために適当に作ったので非常にシンプルな画面でした。

 

f:id:Karvan:20200915220654p:plain

こんな感じ。白地にタイトル文字だけ

 

これだけは味気ないのでアセットストアから画面全体に光子が散らばるようなパーティクルのアセットを購入。

これをベースにして白の背景に黒い光子が漂うような感じに変更しようと挑んだわけです。

 

f:id:Karvan:20200915220745g:plain

これがベースとなったアセットのパーティクル

 

 パーティクルの色を変える

パーティクルの色変える場合、ParticleSystemのstartColorを変える、加えて、colorOverLifeTimeを使っていれば、そちらも変えればよいだけなので簡単に実装できる、と思ったのですが・・・

 

f:id:Karvan:20200915220915g:plain

んー、全然見えない・・・

試しにパーティクルのTextureの方も色を黒に変更してみても同じ状態で、光子が背景の白に溶け込んで全く見えません。

f:id:Karvan:20200915221201p:plainこの画像を

f:id:Karvan:20200915221224p:plain黒に変更してもダメ

 

調べてみるとParticleのRenderingModeも変更する必要があったようです

 

RenderingMode

RenderingModeとは文字通り3Dモデルのメッシュや2Dのイメージなどをレンダリングするモードの事で、MaterialのShaderの設定にあります。

当該のパーティクルは「Particles/Standard Surface」のシェーダーを使っており、このRenderingModeが「Additive」となっていました。

 

f:id:Karvan:20200915221645p:plain

 ■Additive

マテリアルのピクセルを背景のピクセルへ追加して描画するモードのようで、暗い背景の中で光輝くような表現をしたい場合に使用するため、重ねれば重ねるほど白へ近づくらしい。そりゃ今回のような白背景だと見えなくなるわ。

 

■CutOut

アルファテストによりアルファが「Alpha Cutoff」の値より小さい場所が完全に描画されなくなる。つまり半透明の領域がなくてテクスチャが100%見えるか見えないかのどちらかになる。

穴や細かいギザギザがあるようなものを表示するときに使うらしい。試しに今回のパーティクルをCutOutに変更してみると

 

f:id:Karvan:20200915221912g:plain

なるほど、白か黒か、のような世界になる

 

■Transparent

ガラスみたいな半透明な物質に使用する。背景が透過しながらも光源からのハイライトや反射などは表示されるようなります。

Transparentに変更するとこんな感じです

f:id:Karvan:20200915222029g:plain

パッと見ると問題ないように見えますが、よ~く見るとテクスチャの元画像の枠がうっすら見えます。

 

f:id:Karvan:20200915222140p:plain

画像を拡大するとテクスチャの四角い枠が見えます(キャプチャ画像だと分かりづらいかも・・・)

 

■Fade

こちらも半透明を表現するときに使用しますが、Transparentと違いハイライトや反射などはなく、背景に溶け込むように表示されます。

今回の場合はこのModeを使うのが正解だったようです。

 

f:id:Karvan:20200915222250p:plain

画像を拡大、Transparentと違いテクスチャの枠が見えません

 

タイトル画面完成

というわけで完成したタイトル画面がこちら

f:id:Karvan:20200915222433g:plain

 

なんだかホラーっぽくなりました。全然ホラーゲームじゃないのに・・・(脱出ゲームです)

 

◇プライバシーポリシー

●個人情報の利用目的

当ブログでは、メールでのお問い合わせ、メールマガジンへの登録などの際に、名前(ハンドルネーム)、メールアドレス等の個人情報をご登録いただく場合がございます。

これらの個人情報は質問に対する回答や必要な情報を電子メールなどをでご連絡する場合に利用させていただくものであり、個人情報をご提供いただく際の目的以外では利用いたしません。

●個人情報の第三者への開示

当サイトでは、個人情報は適切に管理し、以下に該当する場合を除いて第三者に開示することはありません。

・本人のご了解がある場合
・法令等への協力のため、開示が必要となる場合

個人情報の開示、訂正、追加、削除、利用停止
ご本人からの個人データの開示、訂正、追加、削除、利用停止のご希望の場合には、ご本人であることを確認させていただいた上、速やかに対応させていただきます。

アクセス解析ツールについて

当サイトでは、Googleによるアクセス解析ツール「Googleアナリティクス」を利用しています。

このGoogleアナリティクスはトラフィックデータの収集のためにCookieを使用しています。このトラフィックデータは匿名で収集されており、個人を特定するものではありません。
この機能はCookieを無効にすることで収集を拒否することが出来ますので、お使いのブラウザの設定をご確認ください。

●免責事項

当サイトからリンクやバナーなどによって他のサイトに移動された場合、移動先サイトで提供される情報、サービス等について一切の責任を負いません。

当サイトのコンテンツ・情報につきまして、可能な限り正確な情報を掲載するよう努めておりますが、誤情報が入り込んだり、情報が古くなっていることもございます。

当サイトに掲載された内容によって生じた損害等の一切の責任を負いかねますのでご了承ください。

●プライバシーポリシーの変更について

当サイトは、個人情報に関して適用される日本の法令を遵守するとともに、本ポリシーの内容を適宜見直しその改善に努めます。

修正された最新のプライバシーポリシーは常に本ページにて開示されます。