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

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

【Unity】ベジェ曲線を求めて放物線を描く

f:id:Karvan:20210720193626p:plain

決意と怠惰

今日こそは家に帰ったら速攻でゲーム制作に取り掛かるぞ、と決心したものの夕飯を食べて一息ついたら何故かPSのコントローラーを握っている皆さんこんにちは。最近、UBI製ゼルダの伝説とでも言うべき「イモータルズ フィニクス ライジング」というゲームを購入して見事に土日が潰れました。キャラクター同士の会話内容はちっとも分からないんですが、とにかく探索が楽し過ぎてメインストーリーを進めずに寄り道ばかりしています。熊さん強すぎ。

 

ベジェ曲線

下の図のように移動する鳥が移動方向斜め前にあるリングの中を通る動作を作りたい場合、通常なら目的地のリングに向かって一直線に飛ばせばよいのですが、それだとちょっと面白くない。もう少し動きを加えて放物線を描きながらリングを通過させたい。

f:id:Karvan:20210720194213p:plain

そういった場合の放物線(曲線)の計算方法は色々あるかと思うのですが、その中でもメジャーな手法としてベジェ曲線を使った手法があります。

ベジェ曲線とはコンピュータ上で滑らかな曲線を表現できる計算方法で、最も単純な「2次ベジェ曲線」の場合だと曲線の始点と終点、その間にある中継点を指定するだけで曲線を作る事ができます。

f:id:Karvan:20210720194106p:plain

Google先生に尋ねると色々な解説が各所で掲載されているので詳細はそちらを参考にしてもうとして、この「2次ベジェ曲線」をUnity上で計算する場合はVector3のLerpを使います。

f:id:Karvan:20210720194123p:plain

上記の関数の引数tは始点と終点の距離を1とした時の距離でこの値を0~1に変えることで曲線上にある点を求めることが出来ます。
ここで重要なのは中継点の位置で、始点と終点の中間地点から上(Y軸)へ距離を取った地点を中継点とすると

 

f:id:Karvan:20210720194154p:plain

こんな感じの曲線が求められます。

もちろんこの曲線上を移動するようにしても問題ないのですが、この場合、最初に鳥はリングに向かって斜め方向に飛び、リングに到達すると進行方向(Z軸方向)に一旦向きを直して移動することになり、ちょっとぎこちない動作になります。

f:id:Karvan:20210720194416p:plain

 

垂線を求める

スムーズに方向を変えるような曲線にしたい場合は、中継点を中間地点の上(Y軸)に置くのではなく、始点から終点へ向かうベクトルの(XZ平面の)垂線上に置くことが必要になります。

f:id:Karvan:20210720194531p:plain

こうした指定したベクトルの垂線を求めたい場合にはVector3のProjectを使います。

f:id:Karvan:20210720194626p:plain

Vector3.ProjectはUnityのリファレンスによれば「ベクトルを別のベクトルに投影します。」と書かれています。
つまり、上の式のProjectionは「vectorベクトルの垂線」と「onNormalベクトル」の交点を表すと考えることができます。

f:id:Karvan:20210720194651p:plain

なので、投影ベクトルのProjectionから投影元のvectorの差分ベクトルを求めればonNormalベクトルの垂線ベクトルを求めることが出来ます

f:id:Karvan:20210720194706p:plain

後は中間点からこのベクトルに沿って距離を取った地点を中継点に置けばスムーズに方向を変える曲線を求めることが出来ます。

 

f:id:Karvan:20210720194853p:plain

上から見るとこんな感じ

f:id:Karvan:20210720194922p:plain

 仕上げ

垂線ベクトルに沿った点を求めることができたので、その地点から上(Y軸)へ距離を取った地点を最終的な中継点としてベジェ曲線を求めました。

f:id:Karvan:20210720195047p:plain

ちょっと見ずらい・・・
後ろから見るとこんな感じ

f:id:Karvan:20210720195116p:plain

この求めた曲線に沿って鳥を移動させます。

f:id:Karvan:20210720195240g:plain

こんな感じ。一直線に進むよりも結構ダイナミックな動きになったと思います。

 

 

【進捗報告】アレコレ手を出し過ぎて頭が痛い

f:id:Karvan:20210713211430p:plain

夏が始まる

最近、通勤途中にすれ違う女性からちょくちょく視線を感じるので髪切ったせいかなぁ、モテ期がとうとう・・・とか思っていたら、首に掛けた扇風機のお陰だと気づいた皆さんこんにちは。首掛け扇風機ってもっと普及していると思っていたのですが以外に見かけませんね。この蒸し暑い中、マスクをつけて歩くのに扇風機がないとかどんな苦行だよ。

 

脱出ゲームを作っている

このブログの中でも度々紹介していますが、去年の夏頃からPC向けの脱出ゲームを作っています。開発期間はもう一年近くになりますが未だ進捗度は50~60%ぐらい。
完成までの道のりは長そうですが、先日のIndie Live Expoでは「2021年11月リリース」と紹介してもらったのでそれ迄には完成させたいと思っています。

f:id:Karvan:20210713211640g:plain

 

直近の作業としては、上の動画にあるようにエレベーターを追加し、それに乗る事で新ステージへ移動する(別シーンへ遷移する)ようにしました。

これまでは一つのシーン内で各ステージを作っていたのですが、オブジェクトがドンドン増えていくと負荷も増えていくし、シーンビュー内もごちゃごちゃして分からりづらくなるしで、作業が辛くなっていたので思い切って新しいシーンを作る事にしました。
使っているフレームワーク(アセット)の仕様上、シーン遷移を挟むとどうしても「Loading画面」が表示されてしまうのですが、それが出来るだけ不自然に見えないようにプレイヤーにはエレベーターに乗ってもらう事にしました。ほんとはシームレスに遷移するのが理想なんですが。

 

 また、当然ながら新パズルも作っています。

f:id:Karvan:20210713211919p:plain

 

f:id:Karvan:20210713211939p:plain

こういう問題や

 

f:id:Karvan:20210713212103p:plain

 

f:id:Karvan:20210713212114p:plain

こういう問題

 

f:id:Karvan:20210713212306p:plain

こういった問題。これはパズルと言うより数学の問題に近いですが、そこはユーザに優しく救済ルートも用意しています。

 

f:id:Karvan:20210713212439p:plain

まぁ、指示の通り箱を開けたらどうなるかはお楽しみ。

 

 カジュアルゲームを作っている

そんな感じで11月リリース目標で脱出ゲームを作っている中、直近のunity1weekに投稿した作品(The two met)がそこそこ好評だったので調子に乗ってスマフォ向けのカジュアルゲームとして開発しています。

f:id:Karvan:20210622205053p:plain

 

f:id:Karvan:20210713212903g:plain

unity1weekではフラットな画面で二個の球を操作するゲームでしたが、製品版ではそれに加えて上の動画のようにペンギンを主人公にしたステージとクォータービューで立体的に見えるステージを用意する予定です。

当初はこの夏の間に開発してリリースする予定だったのですが後述の理由によりちょっと無理そう。

 

 集英社の企画に挑戦する

前回のブログでも紹介しましたが、現在、集英社の方でインディーゲーム企画の募集が行われています。

game-creators.camp

大賞は賞金100万円と開発資金援助なので狙いに行かない理由はありません。
今年の初めにunity1weekで投稿した作品(Supra animus quo)が思いのほか高評価で色んな方が褒めてくるので、これをベースにストーリーパートを加えたゲームを企画しようと思っています。

f:id:Karvan:20210713213313p:plain

まぁ企画書だけでも応募可能なのですが、なんせ説明するのが難しいゲームなのでプロトタイプ版でも実際にゲームを作って審査員に遊んでもらってアピールするか、プレイ動画を見せてアピールする以外に賞レースに勝ち残れないと思っています。

締切が9/30までなので、それまでにデモ版がプレイ動画を作成しないといけません。それにSTG系のゲームも別企画として応募したい。もちろんプレイ動画を添えて。

 

脱出ゲームも作り、カジュアルゲームも作り、コンテスト用のゲームも作る・・・アレコレ手を出し過ぎて頭が痛い、という話でした。

 

【Unity】お手軽なCinemachineのVirtualCamera切替

f:id:Karvan:20210706212743p:plain

出費過多

いつまでたってもiPadのDaznが「しばらくお待ちください。」エラーのまま改善されないのでiPadAirに買い直して、ついでに保護フィルムとカバーケースを購入していたら、アセットストアの半額セールにつられて衝動買いを抑えらえずにいて、尚且つ五年使ったスマホのバッテリーがいよいよ限界らしく機種変更をしないといけないし、腕時計も調子が悪いし云々で出費過多な皆さんこんにちは。

コロナ禍で外に出掛けることが少なくなり一時期出費は抑えられていたのですが、気が付けば貯金が減っていきます。先日はPCも購入したし(未だ納品されない)、どうしよう。

 

集英社ゲーム企画コンテスト

講談社に続き集英社の方でもインディーゲームを対象としたオリジナルゲームコンテストが開催されています。

www.koubo.co.jp

募集期間:~2021/09/30 23:59 まで
応募内容:JPEGかPDFで企画書を提出(任意でゲーム動画かデモ版を提出可)
賞・特典:大賞100万円 優秀賞10万円

 

応募者は事前に「集英社ゲームクリエイターズCAMP」に登録する必要があります。また、大賞作品には開発資金も提供されるようです。

こういった大手企業からのインディーゲームに対する支援企画がどんどん立ち上がってくるのは大変有難い事ですね。
きっと講談社と同じように応募が殺到すると思いますが私もチャレンジしたいと思います。

 

VirtualCameraの切り替え

前回の記事ではBlend List Cameraを使ってVirtualCameraの切替を行いましたが、CinemachineにおけるVirtual Cameraの切り替えは優先順位付けにより行われるのでBlend List Cameraを使わずとも優先順位(=Priorityプロパティ)を変更するだけでVirtualCameraの切り替えを行う事ができます。
しかもCinemachineは優秀なのでVirtualCameraの切替をスムーズな形で行ってくれます。

 

 「スムーズな」というのは例えばカメラA→カメラBに切り替えを行った場合、カット割りのようにカメラAの映像→カメラBの映像を切り替えるのではなく、カメラAの映像からカメラBの映像の間を補完しながら映像を切り替えてくれます。

なのでユーザ側から見ればカメラがA→B切り替わったとは感じず、一台のカメラがAの位置からBの位置へ移動したように見えます。

f:id:Karvan:20210622205238p:plain

 

f:id:Karvan:20210622211337g:plain

 

TriggerEnterで切り替える

具体例として下の図ような移動する鳥を追いかけるCameraAと地面を写すCameraBの切り替えを作ってみます。

f:id:Karvan:20210706214458p:plain

 

最初はCameraBが地面を捉えた画像を表示し、

f:id:Karvan:20210706214524p:plain

 

移動する鳥がフレームインしたらCameraAへ切り替えます。

f:id:Karvan:20210706214606p:plain

 

切替のタイミングは前方に設置したBoxCollider内に鳥のオブジェクトが侵入した瞬間とするのでTriggerEnter内でCameraAのPriorityを高い値に変更します。

f:id:Karvan:20210706214641p:plain

 

実行結果

作っている最中にちょっと欲が出たので、鳥の移動が終了したら鳥を前方から映すCameraCに切り替わるようにもしました。

 f:id:Karvan:20210706220112p:plain

 

実行結果はこんな感じ。
スクリプトではVirtualCameraのPriorityを変更してるだけですが、かなり良い感じにカメラが遷移してくれます。

 

f:id:Karvan:20210706220334g:plain

 

【Unity】Cinemachine Blend List Cameraでカメラを順に切り替える

f:id:Karvan:20210622205053p:plain

バックアップは大事

Unityのアップデートをしたら何故かプロジェクト内のプレハブの設定が全て初期化されて絶望の淵に立った皆さんこんにちは。
ややこしいのはフレームワークとして購入したアセットのプレハブも同様に設定値やらオブジェクトの指定やらが吹き飛んだ事で、アセットストアから再インストールしようとしても「現在は最新バージョンになってます」的なメッセージが表示されてインストールできないし、フレームワークとして使っているから一旦アンインストールするとか怖くてできないし、修復しようにも正しい設定値が分からないしで、本当に目の前が真っ暗になったのですが、サブHDDの方にバックアップがある事を思い出して何とか元に戻すことができました。バックアップは大事。

 

カメラの切替

Unityではシーン内のオブジェクトの動作は一旦カメラで撮影してその映像を画面に表示する、という形式のため、場面を大きく変える、違う角度から物をみる、といった時にはそれに応じてカメラを切り替える必要があります。

 

f:id:Karvan:20210622205238p:plain

 

ただ場面に応じてカメラを逐一用意するとなるとリソースを無駄に食うし、スクリプトで切り替え処理を作るのも面倒くさい。
そういった場合にはCinemachineを利用してVirtual Cameraの切り替えをTimeline等で行う方が効率が良いと思います。
Cinemachineはunity標準のカメラ制御用のアセットでPackageMangerからインストールすることができます。
使い方についても色々なサイトで紹介されているので、それを参考にすれば導入は難しくないと思います。

 

【Unity】CinemachineのVirtual Camera切替をコントロールする - テラシュールブログ

【Unity】【Cinemachine】Virtual Cameraをブレンドしながら切り替える方法まとめ - LIGHT11

 

Blend List Camera

複雑なカメラ割やカットシーンを多投する場合はTimelineを組んで作成した方がよさそうですが、例えばステージクリア時の演出など一回限りのカメラワーク再生で良い場合は「Cinemachine Blend List Camera」を使う方が便利です。
Cinemachine Blend List Camera コンポーネントは、指定したVirtual Cameraの切り替えを指定通り行ってくれるコンポーネントです。但し、そのVirtual CameraはCinemachine Blend List Cameraの子オブジェクトとなっている必要があります

メニューから、Cinemachine > Create Blend List Camera を選択すると

f:id:Karvan:20210622205447p:plain

 Cinemachine Blend Camera コンポーネントが付与された親オブジェクトと、その子オブジェクトとしてVirtualCameraが付与された2つのオブジェクトが出来ます。

f:id:Karvan:20210622205637p:plain

 

子オブジェクトのVirtualCameraをそれぞれ表示したい位置に設置し、角度やsize等を設定します。

f:id:Karvan:20210622205722p:plain

 

f:id:Karvan:20210622205740p:plain

 

Cinemachine Blend Camera側では切り替えの設定を行います。

 

f:id:Karvan:20210622205943p:plain

[Hold]カメラを有効する時間
[sec]次のカメラに切り替わる時間
カメラ切り替わり時のEasingもプルダウンから指定できます。

 

設定が終われば実行するだけですがBlend List Cameraはこのコンポーネントが有効化されたときに一度限り再生されます。
この為、スクリプトで再生したいタイミングでBlend List Cameraを有効にする必要があります。
有効化はオブジェクトをアクティブにするかコンポーネントのenabledをtrueにします。

 

using Cinemachine;

CinemachineBlendListCamera _blendListCamera;

{
    …
    // 再生タイミング
    _blendListCamera.enabled = true;
    …
}

 

実行結果

実際の動作はこんな感じになります。

f:id:Karvan:20210622211337g:plain

動画ではカメラが移動してズームイン/アウトしていますが、これらはCinemachine側で行ってくれます。
同じような処理を自力でスクリプトを組むとなると少し面倒なのでこれは便利ですね。

【Unity-C#】Interfaceの利点を学ぶ

f:id:Karvan:20210615212000p:plain

 

ありがとうIndie Live Expo

ブログの閲覧数がやたら増えているなぁと不思議に思っていたらIndie Live Expoで紹介されたお陰だと気づいた皆さんこんにちは。6時間近く放送された番組の中で15秒ちょっと映っただけなんですがね、紹介されたところで誰も気に掛けないだろう、とやさぐれていた自分が恥ずかしいです。どうも有難うございます。Twitterのフォロワーもちょくちょく増えてほんとビックリ。

 

Interface

さて、UnityのスクリプトはC#が標準なのでInterfaceを定義して使う事ができます。
InterfaceとはC#の参考書などによれば「クラス外部からみた規約だけを定めるもの」とうたわれており、それがピンとこない場合は「実装がないメソッド定義をアチコチで使い回すもの」とでも思えば良いです。

 

例えばゲーム内に敵A、敵Bがおり、それぞれに独自の制御用クラス(EnemyA_Control,EnemyB_Control)が実装されているケースを考えてみます。

Manager的なクラスが敵A,Bにゲーム内のイベント(ゲーム開始や終了等)に応じた処理を依頼する場合、ManagerクラスはEnemyA_Control,EnemyB_Controlそれぞれのクラスを意識して「EnemyA_Controlのゲーム開始時処理」「EnemyB_Controlのゲーム開始時処理」をコールする必要があります。

f:id:Karvan:20210615212336p:plain

 

 敵が二種類しかいない場合はそれでも構いませんが、敵の数が増えていくと面倒くさいことこの上ない。
処理を依頼するタイミングは同じなのだから(クラスは違えど)コールするメソッドも同じにすることができればコーディングの量も減って以後の作業も楽になります。
なので、そういった要望を実現するためにInterfaceは使用されます。

f:id:Karvan:20210615212613p:plain

 

定義と使い方

インターフェースを定義するには「interface」を使用します。interface内のメソッドやプロパティなどはすべてpublicとして扱われます。

    interface (インターフェース名){
        メソッド名(引数);
        メンバー変数;
        ...
    }

実装側はクラスの継承定義を同じようにインターフェース名を設定します。

    public class クラス名 : (継承クラス名), (インターフェース名)
    {
        メソッド名(引数);
        メンバー変数;
        ...
    }

ここで実装側はInterfaceが持つメソッド、プロパティなどをすべて実装する必要があることに注意が必要です。
(定義のみで中身は空でもよい)

具体的に、先ほどの敵A、Bにゲーム開始時処理のInterfaceを実装したい場合

    // インターフェース定義
    interface IEnemyInterface {
        void StageStartProc();    // ゲーム開始時処理
    }

上記のインターフェース定義を行った後に、各制御用クラスにインターフェース定義を追加します。

    // 敵A側
    public class EnemyA_Control : MonoBehaviour, IEnemyInterface {
        
        void StageStartProc() {
            // 敵Aのゲーム開始時処理
            
        }
    }

    // 敵B側
    public class EnemyB_Control : MonoBehaviour, IEnemyInterface {
        
        void StageStartProc() {
            // 敵Bのゲーム開始時処理
            
        }
    }

 

マネージャークラス側はGetComponentでクラス名でなくインターフェイス名を指定してコンポーネントを取得、ゲーム開始時処理をコールします。

    public List<GameObject> EnemyList;    // 敵A,Bが格納されたリスト
    
    // ゲーム開始時処理
    void StageStart()
    {
        foreach(GameObject obj in EnemyList)
        {
            // インターフェイス名を指定してコンポーネントを取得
            IEnemyInterface objIF = obj.GetComponent(typeof(IEnemyInterface)) as IEnemyInterface;
            
            // ゲーム開始時処理をコール
            objIF.StageStartProc();
        }
    }

Interfaceを利用するとクラス間の疎結合も可能なので色々と利点が多いと思います。

 

【Unity】ステンシルバッファを使って窓を作る

f:id:Karvan:20210608213544j:plain

全く話題にならない神ゲーム

後学の為に色んな実況者のゲーム実況を観ていたらYouTubeのお勧めが何故かVtuberの切り抜きで溢れている皆さんこんにちは。ロックマン2の実況が面白くて色々観てたらこうなった。でも、Vtuber同じような名前大杉。

そんな中、久しぶりに購入したゲームが神ゲーでした。タイトルは『The Pathless(ザ・パスレス)』。最近流行ってきたトゥーン調のオープンワールドゲームで、『ABZU』の開発会社による新作アクションパズルゲームです。

f:id:Karvan:20210608213647j:plain

美しいグラフィックと爽快感のある操作性が最大の魅力で、フィールド内を移動するだけでも楽しい。加えてフィールド内に点在するパズルもプレイヤーの観察力を問われる内容で程よい難易度。本当に神ゲーと呼ぶにふさわしいと思うのですが、巷では全く話題になってません。実況動画も攻略サイトも殆どないし。

思うにオープンワールドながらもゲームのメインがパズルなのでボス戦以外に戦闘とかないし、NPCと会話や取引するみたいなイベントもなく全く実況向きでない、実際にプレイしてみないと良さが殆ど伝わらない事が原因なのではないかと。

個人的にあまりに惜しいのでこのブログで紹介しています。
とにかく爽快感のあるゲームがやりたい方、異世界を自由に探索するゲームに興味がある方にはうってつけのタイトルだと思いますので、是非、プレイしてください。

 

 ステンシルバッファ

unityのシェーダでステンシルバッファは描画の際に当該のピクセルを画面に表示するかしないかを決める「マスク」を設定する役目を持ちます。

要はマスクなので「描画したい部分」「描画したくない部分」を明確に定義できるというわけです。

ステンシルバッファの操作はStencilのプロパティを使用します。Stencilのプロパティの宣言は次のようになります。

Ref ステンシルに書き込む値
Comp 使用する比較関数
Pass 比較関数が真のときにの操作

 

 ・比較関数

Greater ステンシル値がバッファ値より大きいピクセルのみレンダリング
GEqual ステンシル値がバッファ値以上のピクセルのみレンダリング
Less ステンシル値がバッファ値より小さいピクセルのみレンダリング
LEqual ステンシル値がバッファ値以下のピクセルのみレンダリング
Equal ステンシル値がバッファ値と等しいピクセルのみレンダリング
NotEqual ステンシル値がバッファ値と等しくないピクセルのみレンダリング
Always 常にステンシル テストは成功
Never 常にステンシル テストは失敗

 

・処理

Keep バッファの現在コンテンツを保持します
Zero バッファにゼロを書き込みます
Replace ステンシル値をバッファに書き込みます
IncrSat バッファの現在値を増分させる
DecrSat バッファの現在値を減分させる
Invert すべてのビットを無効にする
IncrWrap バッファの現在値を増分する。値がすでに 255 の場合は 0 にする
DecrWrap バッファの現在値を減分する。値がすでに 0 の場合は 255 にする

 

窓を作る

「描画したくない部分」を作れると言う事は3Dモデルの形状を変更せずに穴を開けられる、と言う事でそれを利用して窓を作ってみます。手順は

  1. 窓となるオブジェクトにStencilでマークするシェーダを適用する
  2. 壁側のオブジェクトにはStencilでマークされた場所以外を描画するシェーダを適用

となります。

まず最初に窓側のオブジェクト用に透明shaderを作ります。

Shader "WriteStencil"
{
    SubShader
    {
        Tags { "RenderType"="Transparent" "Queue"="Transparent" }
        ZWrite Off
        Blend SrcAlpha OneMinusSrcAlpha

        Pass
        {
            CGPROGRAM
           #pragma vertex vert
           #pragma fragment frag
            
           #include "UnityCG.cginc"

            struct appdata
            {
                float4 vertex : POSITION;
            };

            struct v2f
            {
                float4 vertex : SV_POSITION;
            };
            
            v2f vert (appdata v)
            {
                v2f o;
                o.vertex = UnityObjectToClipPos(v.vertex);
                return o;
            }
            
            fixed4 frag (v2f i) : SV_Target
            {
                // 透明にする
                return fixed4(0, 0, 0, 0);
            }
            ENDCG
        }
    }
}

 このシェーダにStencilのプロパティを追加します。(CGPROGRAMの上あたり)

// ステンシルバッファの設定
Stencil
{
    // ステンシルの番号
    Ref 2
    
    // Always: このシェーダでレンダリングされたピクセルのステンシルバッファを「対象」とするという意味
    Comp Always
    
    // Replace: 「対象」としたステンシルバッファにRefの値を書き込む、という意味
    Pass Replace
}

 

壁を作る

壁用に標準的なStandardシェーダを作ります。これはCreateメニューから選んで作ることができます。

f:id:Karvan:20210608215255p:plain

 

この作成したStandardシェーダにStencilのプロパティを追加します。

// 壁側のStencil
Stencil
{
    // ステンシルの番号
    Ref 2
    
    // NotEqual: ステンシル番号がバッファ値と等しくないステンシル番号のピクセルのみレンダリング
    Comp NotEqual
}

 

 結果

作った窓シェーダーと壁シェーダーをそれぞれ3dモデルに適用してみます。

f:id:Karvan:20210608215756g:plain

壁を透過して背景が表示されているのが分かると思います。
ステンシルバッファを利用してモデルを変更することなく窓を作ることができました。

【Unity】総合エフェクトツール「Feel」を使ってみる

f:id:Karvan:20210601214309p:plain

散々

注文したPCの納期が半年後だったり、購入したゲームは画面酔いが酷かったり、無くしものをしたり、落とし物をしたり、贔屓のスポーツチームは負けたり、と散々な日々を過ごしている皆さんこんにちは。
iPad版のDAZNが「問題が発生しました。しばらくたってから再度お試しください」のメッセージを表示するようになって、かれこれもう一週間以上経っているのに未だに「しばらくたってから・・・」のメッセージを表示し続けているのですが、一体どれだけ待てば良いのでしょうかね?
ちなみにアプリを再インストールしても結果は同じでした。

 

Feel

前回の記事で紹介したUnityのアセット「Feel」
どんなアセットかと言うと"ゲーム内で発生する様々なイベントに合わせたエフェクトの詰め合わせ"といった感じのアセット。
音声、カメラ、パーティクル等々を利用したエフェクトを簡単に実装できます。

assetstore.unity.com

とは言え、購入したアセット内には導入法等が記載されたドキュメント類は含まれていない為、使い方を知るにはWebサイトを参照する必要がありました。
なので今回の記事では導入手順と簡単な実装例を紹介したいと思います。

 

導入手順

「Feel」のエフェクトをフルで使うには以下のパッケージを事前にプロジェクトに導入しておく必要があります。

  • Cinemachine
  • 2D Animation
  • Post Processing

どのパッケージもPackageManagerからインストールすることが出来ます。(無料です)

「Feel」のエフェクトを使うには空のオブジェクトに「MMFeedbacks」コンポーネントを付与し、このコンポーネントから実装したいエフェクトを追加していきます
この[空のオブジェクト+「MMFeedbacks」コンポーネント]は実装したいエフェクト単位に作る必要があります

例えば「煙のパーティクルが発生する」と「画面(カメラ)が揺れる」エフェクトを同時に再生したいのであれば、一つの「MMFeedbacks」コンポーネントに「パーティクル再生」のエフェクトと「カメラシェイク」のエフェクトを追加します。
f:id:Karvan:20210601214735p:plain

 

別々に再生したいのであれば、[空のオブジェクト+「MMFeedbacks」コンポーネント]を二つ用意して、一つに「パーティクル再生」のエフェクト、もう片方に「カメラシェイク」のエフェクトを追加します。

f:id:Karvan:20210601214749p:plain

 

簡単な実装例

実装例として下の動画のような単純に飛び上がるCubeに対して「Feel」のエフェクトを追加したいと思いまます。

f:id:Karvan:20210601215017g:plain

CubeはAddFroce(Impulse指定)を行う事で飛び上がっています。この時rigidbodyの回転については全軸freezeの設定をしています。

この状態でシーン内に空のGameobject(JumpFeedback)を追加します。

f:id:Karvan:20210601215130p:plain

 

JumpFeedbackにMMFeedbacksコンポーネントを追加します。

f:id:Karvan:20210601215155p:plain

 

このMMFeedbacksコンポーネントにジャンプ中に回転するエフェクトを追加します。
MMFeedbacksコンポーネントの「Add new feedback」を押すと追加するエフェクトが選択できます。今回は「Transform→Rotatin」を選びます。

f:id:Karvan:20210601215252p:plain

 

MMFeedbacksに[Rotation]が追加されるので「Rotation Target」にCubeオブジェクト(Model)を指定します。

f:id:Karvan:20210601215519p:plain

 

「Remap Curve One」に回転角度「90」を指定、X軸周りに廻すので「Animate X」のみにチェックを入れます。

f:id:Karvan:20210601215545p:plain

この状態で再生ボタンを押すと「Playボタン」が有効になるので押してみると

f:id:Karvan:20210601215635g:plain

Cubeが90度回転するのが分かります。

このエフェクトをジャンプ中に再生するようにスクリプトを修正します。今回の場合はJump開始のタイミングで再生します。

f:id:Karvan:20210601215700p:plain

これを実行してみると

f:id:Karvan:20210601215718g:plain

こんな感じ、ジャンプ中にクルッと回るようになりました。

 

さらにエフェクト追加

次は着地時にカメラシェイクのエフェクトを実装します。
最初にCinemachineのバーチャルカメラ(CM vCam1)を作成し、

f:id:Karvan:20210601215922p:plain

このバーチャルカメラに[Cinemachine Impulse Listener]を追加しておきます。

f:id:Karvan:20210601220038p:plain

 

次に空のGameobject(LandingFeedback)を作成→MMFeedbacksコンポーネントを追加します。
「Add new feedback」を押して「Cinemachine Impulse」を追加します。

f:id:Karvan:20210601220113p:plain

 

これをUpdate内でrigidbodyの速度が下向きに転じたあたりでMMFeedbacksを再生するようにします。

f:id:Karvan:20210601220146p:plain

 

実行すると

f:id:Karvan:20210601220208g:plain

着地時に画面が揺れるエフェクトが実装されました。

 

さらにー

同じ手順でLandingFeedbackのMMFeedbacksにポストエフェクトも追加して設定すると、

f:id:Karvan:20210601220255g:plain

最終的にこんな感じになりました。
一番最初の動画と比べてかなり印象が違って見えると思います。

 

◇プライバシーポリシー

●個人情報の利用目的

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

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

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

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

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

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

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

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

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

●免責事項

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

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

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

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

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

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