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

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

【Unity】DOTweenのPuchについて

新入社員

今年はコロナ禍により仕事はテレワーク中心になり、大規模な会議や飲み会は開かれず仕舞いだったので、顔も名前も覚えていない新入社員がいつの間にか辞めていた皆さんこんにちは。急に退職のお知らせメールが廻ってきてビックリ、自己紹介された記憶もないです。来年はどうなるんでしょうか。

 

Puchメソッド

f:id:Karvan:20201201221543g:plain

上の動画はDOTweenのDOPunchPositionを使ってオブジェクトを左右に振動させたアニメーションです。

このようにPunchとは指定された値とその反対方向の値の間(100なら100~-100の間)を減衰しながら振動して元の値に戻る、というTweenを行うときに使用します。

 

主にオブジェクトのTransformに対してDOPunchPositionやDOPuchScale,DOPuchRotateを使うケースが多いかと思いますが、staticメソッドとしてPunchメソッドも用意されており、このメソッドではプロパティの値を指定した値の間で増減させることができます。

 

DOTween.Punch(getter, setter, Vector3 direction, float duration, int vibrato, float elasticity)

getter:プロパティの値をトゥイーンに返すデリゲート
setter:プロパティの値をトゥイーンに設定するデリゲート
direction:パンチの方向と強さ
duration:トゥイーンの持続時間
vibrato:パンチの振動数(省略可)
elasticity:後方にバウンドする時の開始位置を超える量。0を指定すると開始位置と減衰方向の間でのみ振動します。(省略可)

 

 下の場合はmyVectorの値が(100,100,100)~(-100,-100,-100)の間を2秒間減衰しながら振動します。

// Punch upwards a Vector3 called myVector in 2 second
DOTween.Punch(()=> myVector, 
       x=> myVector = x,
       new Vector3(100,100,100),
       2);

 実際に動作させてみると・・・

f:id:Karvan:20201201222221g:plain

 早くて分かりづらいですが、振動中のベクトル要素のX,Y,Zは全て同じ値となっています。


では、directionで指定するVectorの値を(100,200,300)とX,Y,Zで異なる値にした場合はどうでしょう。

f:id:Karvan:20201201222310g:plain

これも早くて分かりづらいのですが、振動中のベクトル要素のX,Y,Zはdirectionで指定した値の比と等しい値となっています。

 どうやらPunchメソッドではX,Y,Zそれぞれでランダムな値で振動する、という事はないようです。

 

ではなぜPuchメソッドについて調べたかというと、現在製作中のゲーム内で一人称視点のカメラが振動するような演出を加えたかったからです。

 

画面効果に使う

当初はカメラそのものをDOPunchPositionで動かそうと考えたのですが画面酔いを起こしそうになるのと、Tween中のカメラ操作の影響が面倒だったのでカメラを動かすのではなく、ポストエフェクトを使って色収差のズレを振動せることにしました。

 

色収差ついては以前ブログの記事にも書きましたが、画面の色成分(RBG)をそれぞれずらして表示するというエフェクトです。

www.karvan1230.com

上の記事では「Fast Chromatic Aberration」(注)というアセットを使用して色収差のエフェクトを実装しています。

このアセットではRGBそれぞれで色ずれの量を指定することができるので、Punchメソッドを使って振動させたVectorの値をRGBそれぞれに指定するようにしました。

 

f:id:Karvan:20201201222632g:plain

どうでしょう。画面そのものは動いてませんが色ずれの量が変動することで画面全体が揺れているように見えると思います。
今回はPunchメソッドの使用例の紹介でした。

 

(注)このアセットはバージョンアップにて魚眼レンズ効果も追加されており、現在のところ、その効果を0にすることができない(画面端が必ず歪む)ようです。そのため色収差のみのエフェクトを期待する場合は注意が必要です。

【Unity】UIEffectを使ったuGUIのディゾルブ

忘年会シーズン

コロナ禍で唯一良かったこと言えば社内の無駄な飲み会が無くなったという事なのに突然社長がオンラインで忘年会をやろうと言い出して連休明けの憂鬱な気分が更に憂鬱になった皆さんこんにちは。絶対地獄やん、勘弁してください。

 

UIEffect

さて、世の中には才能があるのに度量も優れている方がいるようで、かなり便利なアセット群がストア販売ではなくGithub等で無料で公開されています。

「UIEffect」もその一つで、このアセットをUnityプロジェクトに導入することでuGUIに対する17種類以上のシェーダが使用できるようになります

 

github.com

上記リンクからunitypackageファイルをダウンロードし、UnityのメニューからAssets→Import Package→Custom PackageよりUnityプロジェクトに導入することができます。

 

ディゾルブ

"Dissolve"というのは「溶解する」という意味ですが、その意味通り表面が溶けて燃え落ちているような演出をディゾルブと呼びます。

Unityでは3Dモデルに対するディゾルブのシェーダーがアセットストアで販売されていますが、UIEffectではPanelやImageといったuGUIに対してディゾルブの演出を行うことができます。

 

使い方は簡単でディゾルブ効果を付与したいuGUIオブジェクトに対してUIDissolveのコンポーネントをアタッチするだけ。

ディゾルブパターンや縁取りの色などをInspectorで設定します。

 

f:id:Karvan:20201124212831p:plain

 

項目 内容
Effect Factor 効果の強さ
Width 縁の太さ
Softness 縁のぼかしの強さ
Color 縁の色
Color Mode 縁の色のブレンドモード
Noise Texture ノイズテクスチャ

 

ディゾルブパターンはNoise Texture欄に白黒画像のTextureを指定します。

f:id:Karvan:20201124212922p:plain

 

この指定した画像に準じてuGUIが「溶けていく」=「消えていく」ことになりますが、逆に消えている状態から表示したい場合はEffectFactor欄の値を「1」に設定し、Reverseの欄をチェックします。

 

 スクリプトから実行

ディゾルブ演出を実行するにはスクリプトでUIDissolveのPlayメソッドをコールします。

 

using Coffee.UIExtensions;

public GameObject dissolvePanel;

public void PlayDissolve()
{

    UIDissolve panelDisolve = dissolvePanel.GetComponent<UIDissolve>();
    
    panelDisolve.Play();
    
}

 

このuGUIに対するディゾルブは全面表示のPanelに適用することで場面展開などの演出に使えます。

現在作成中の脱出ゲームでは制限時間切れによるゲームオーバーの場面で使っています。

 

f:id:Karvan:20201124213152g:plain

ホラーゲームではないのですがちょっとホラーっぽくなりました。

 

【Unity】破壊系ツール「RayFire」を使ってみよう

急に

11月に入り朝夕の冷え込みが厳しくなってこのまま寒い冬へ突入していくのかなぁと思っていたら、季節が戻ったかのような急な温かさで戸惑っている皆さんこんにちは。私の人生もそうあって欲しいものです。

 

独身の日セール

さて、11月11日は中国では「独身の日」だそうで、それに併せてUnityのアセットストアでは中国だけなく日本を含むアジア圏で大幅なセールが行われていました。

数多くのアセットが50%オフ、70%オフで出品されておりセールというよりは投げ売りに近い状態、中国さん有難う、日本人は中国の歴史も文化も料理も大好きです、ただ、共産党が嫌いなだけです。

 

というわけで、前から欲しかったけど高額で手が出なかったアセットを幾つか購入したのですが、今回はその中でも最も高価だった「RayFire」のご紹介

 

RayFireとは

元々、3DCGの分野では破壊系ツールとして比較的有名だったようで、映画、映像の分野で頻繁に使用されており、実際に「RayFire」をキーに検索してみると3dsMaxでの使い方を紹介するページが数多く検索されます。そしてそのUnity版が「RayFire for Unity」となります。

 

assetstore.unity.com

オブジェクトの破壊や粉砕、崩壊などのシミュレーションを簡単に行うことができるツールで、わざわざメッシュ分割したモデルを用意しなくてもこのツールを使えば破壊によるメッシュ分割から物理演算による破片の飛散まで実装することができます。

まぁ、お値段はそれなり($170.0)にするのですが、今回はそれが70%オフ=6,000円ぐらいで購入できるということで、本当に中国さん有難う、日本人は中国の歴史も文化も料理も大好きです、ただ、共産党が・・・

 

使ってみよう

ゲーム内のオブジェクトを破壊するには、RayFireを使って事前にオブジェクトを破壊(メッシュ分割した)したオブジェクトを作成しておくパターンと、ゲーム実行中にRayFireを使ってリアルタイムに破壊するパターンがあります。

どちらもそれを行うには当然ながらそれなりの設定が必要なのですが、今回は事前に破壊(メッシュ分割)したオブジェクトを作成するパターンを紹介します。

 

1.オブジェクトを用意する

今回は壁っぽいCUBEのオブジェクトを使用します。

f:id:Karvan:20201117203647p:plain

 

このオブジェクトにRayfire Shatterコンポーネントをアタッチ

f:id:Karvan:20201117203804p:plain

「Fragment」ボタンを押すとこのオブジェクトを元にメッシュ分割したオブジェクトが新しく生成されます

 

f:id:Karvan:20201117203924p:plain

 こんな感じに分割されたオブジェクトが作成されます。

このメッシュ分割されるパターンは先程のInspector内のFragments Typeから選択でき、

f:id:Karvan:20201117204104p:plain

こんな感じや

f:id:Karvan:20201117204134p:plain

こんな感じにも分割できます。(他にもパターンがあります)

 

2.Rigidコンポーネントをアタッチ

メッシュ分割したオブジェクトが作成出来たら、そのオブジェクトにRayFire Rigidコンポーネントをアタッチし、ObjectTypeに「Mesh Root」を指定します。

f:id:Karvan:20201117204306p:plain

これにより子オブジェクトとして配置されている分割オブジェクトに物理演算が適用され、RayFireコンポーネントがアタッチされたオブジェクト同士の接触判定が行われるようになります。
 

通常、Unityでこのような動作を行う場合、分割オブジェクトそれぞれにColiderとRigidbodyのアタッチと設定を行う必要がありますが、RayFireでは親オブジェクトにRayFire Rigidコンポーネントをアタッチするのみで、子オブジェクトにColiderとRigidbodyをアタッチする必要はありません

 

3.初期化モードを決める

次に初期化モード(Initialization)を決めます。

これはRayFire Rigidの動作をゲーム開始直後から適用させるのか(At Start)、Script側からメソッドをコールすることで適用開始とするのか(By Method)、のモードで例えばゲーム内のイベントを発火点にオブジェクトの破壊を有効にしたい場合は動作開始モードに「By Method」を指定します。

 

4.シミュレーションタイプを決める

最後にSimulation Typeの設定でRayFire Rigidの動作が適用となった後、実際に物理演算を働かせる着火点を決めます

直ぐにでも物理演算を有効にするには「Dynamic」を、弾丸等の他のオブジェクトとの接触後に有効にする場合は「Sleeping」を指定します。(他にもいくつか設定があります)

 

 ここまでの設定を行うと準備完了です。実際に動作させるとこんな感じになります。

(初期化モードには「At Start」を指定)

 

・シミュレーションタイプがDynamicの場合

 f:id:Karvan:20201117205022g:plain

ゲーム開始と同時に自重によって壁が崩れ落ちます。

 

・シミュレーションタイプがSleepingの場合

f:id:Karvan:20201117205149g:plain

落下物との衝突で壁が崩れるようになります。

 

どちらもかなりリアルな破壊挙動になっていると思います。

RayFireではこれ以外にも爆風による破壊シミュレーション等色々な処理を行うことが出来るみたいなので、また詳しい事が分かったらこのブログで取り上げたいと思います。

 

 

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

 

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

◇プライバシーポリシー

●個人情報の利用目的

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

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

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

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

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

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

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

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

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

●免責事項

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

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

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

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

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

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