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

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

【Unity】クロマキーシャーダとRenderTextureで何か作る

f:id:Karvan:20211019201050p:plain

急に秋

ついこの間まで半袖で過ごしていたのに急激な気温低下で慌てて冬物の衣服を取り出した皆さんこんにちは。天気予報で「だんだんと秋の気配が濃くなって・・・」みたいなセリフを聞くことなく急に晩秋の気候に様変わりして、近年は春と秋の期間がどんどん短くなっているような気がします。まぁ、寒かろうが暑かろうが休日ニートな人間にはあまり関係ないのですがね。

 

RenderTexture

前回の記事でもRenderTextureを使ったギミックを作ったように、ここ最近はゲーム制作ではRenderTextureを利用する事が多いのですが、通常、カメラの映像をRenderTextureに映す場合に「オブジェクトだけを映して背景は透過させたい」といった用途で使うことはできません。

 

f:id:Karvan:20211019201514p:plain

カメラ側のClearFlags指定を「Depth Only」としても

 

f:id:Karvan:20211019201602p:plain

RenderTextureで映した画像は背景が黒塗りで表示されます。

 

なので、前回のギミックのようにRenderTextureの映像とメインカメラの映像の境目を分からなくさせたい場合にはメインカメラの映像の映像と同じ背景を用意する必要がありました。

 

クロマキーシャーダ

Unity関連で大手ブログの「凹みTips」さんがクロマキー機能を持ったシャーダを公開しています。

tips.hecomi.com

これは「クロマキーシャーダ」という名前の通りTexture内の任意の色相・彩度・明度の範囲を透過させて表示するシェーダです。
ということは、背景を一色で塗潰したカメラ映像をRenderTextureに映して、RenderTextureを使うMaterialにこのシェーダを指定すれば「オブジェクトだけを映して背景が透過した」RenderTextureの画像が作れることになります。「凹みTips」さん有難うございます。

 

f:id:Karvan:20211019202005p:plain

カメラ側の指定を「Solid Color」にして青色(0x0000FF)を指定

 

f:id:Karvan:20211019202021p:plain

映像を映すQuadのMaterialのシェーダに「ChromaKey/Standard/Transparent」を指定し、Textureに上のカメラ映像を映したRenderTextureを指定、最後に透過させるColorに青色(0x0000FF)を設定します。

 

f:id:Karvan:20211019202258p:plain

これでオブジェクトだけが映る映像が作れました。パチパチ

 

何か作る

背景が透過しているのでメインカメラ側のオブジェクトの上に置いても違和感なく合成することができます。

f:id:Karvan:20211019202503g:plain

 

この状態でRenderTexture側のカメラに何かしらエフェクトを掛けると面白い映像になります。

f:id:Karvan:20211019202531g:plain

 

試しに動く映像で重ねて見ても特に違和感はないです。

下の動画はどれがRenderTextureの映像なのか分かりやすいよう、Cube内だけ表示するようにマスキングしています。

f:id:Karvan:20211019202647g:plain

 

【小ネタ】RenderTextureを利用してループする世界を作る

f:id:Karvan:20211012213610p:plain

金欠体制

メトロイドの新作が面白そうだけどSwitchを買う余裕のない皆さんこんにちは。この前PCを新調したばかりなのにOculus Quest2も買ったし、携帯も買い替える予定だし、ルーターも買い換えたいしで端的にお金が足りません。ゼルダの新作が出る前には購入したいのですがゲーム制作で大金の援助を受けるとか、そんな幸運が降ってこない限りちょっと無理そうです。

 

ループする世界

ここ最近は講談社のゲーム企画コンテストに向けたプロトタイプ版を作成しているのですが、その作業中に思いついたギミックを作ってみました。

f:id:Karvan:20211012213734g:plain

 

ちょっと分かりづらいかも知れませんが、走る騎士がループして元の位置へ戻る直前に同じ騎士の姿が後方に見ることが出来ます。

f:id:Karvan:20211012213951p:plain

 

これは二体の騎士が動いているのではなく、同じ騎士が違う位置に見えているギミックとなっています。

このタネを説明すると、後方側(画面左側)に見える騎士が本物で、前方(画面右側)に見える騎士は後方側をカメラで映した映像の騎士です。

つまり画面右側の映像は実際の映像(MainCameraの映像)ではなく、後方側の映像がRenderTextureを利用した平面に写されているだけです。

 

f:id:Karvan:20211012214106p:plain

 

Sceneビューで見るとこんな感じ

f:id:Karvan:20211012214126p:plain

 

この状態でRenderTextureとの境目位置にあるゲートに騎士が接触したら、騎士を後ろのゲート位置へ移動させるとループする状態が出来上がります。

f:id:Karvan:20211012214223p:plain

 

ループするオブジェクトが一体だけだと分かりづらいので三体ぐらい並べてループさせると中々面白い映像になります。

f:id:Karvan:20211012214350g:plain

まぁ、このギミックがゲームの中で何に使えるかというと微妙ですが・・・

【アセット紹介】文字を3Dメッシュ化する Modular 3D Text

f:id:Karvan:20211005211036p:plain

副作用

ワクチン接種(2回目)の副作用で高熱と頭痛に悩まされている皆さんこんにちは。1回目は腕が痛くなっただけなんですがね、2回目でこんなに副作用が出るとは思いもしませんでした。これで3回目も受ける事になったら副作用はもっと激しくなるのでしょうか?反ワクチンではありませんが、ちょっと副作用が怖くなりました。

 

アセット紹介

そんな訳で体調がすこぶる不良なので今回は軽くアセット紹介

以前から気にはなっていたのですが、最近アセットストアで割引されているのを見つけたので購入したアセットです。

assetstore.unity.com

 

アセット名の通りにテキストを3Dメッシュ化するためのアセットで、指定した文字列の各文字を個別のオブジェクトとして生成することができます。

 

導入法

導入は簡単でHierarchy上で右クリックメニューから3D Object→Modular 3D Text→Textを選びます。

f:id:Karvan:20211005211646p:plain

 

シーン内に「Text(M3D)」オブジェクトが生成されます。Hierarchyを確認すると各文字がそれぞれ個別にオブジェクトとして生成されていることがわかります。

f:id:Karvan:20211005211821p:plain

 

f:id:Karvan:20211005211839p:plain

 

「Text(M3D)」には「3D Text」のコンポーネントがアタッチされており、このコンポーネントの設定を変更する事で生成する文字列やサイズ、色等々を変更します。

f:id:Karvan:20211005212043p:plain


設定はエディタ上でリアルタイムに更新されるので編集は非常に簡単です。フォントは約50種類用意されています。TTFファイルから新規に3Dフォントを作成することもできます。

f:id:Karvan:20211005212149g:plain

 

エフェクト/アニメーション

シーン内にTextを表示するだけならTextMeshProでも良いのですが、こちらのアセットの場合は各文字が個別にオブジェクト化しているので文字列に対してエフェクトやアニメーションをつけることができます。

 

プリセットとして簡単なエフェクト/アニメーションが用意されているので、「3D Text」のコンポーネントのModulesの設定に追加するだけでそれらのエフェクト/アニメーションを使うことができます。

f:id:Karvan:20211005212447p:plain

 

使用例はサンプルシーンで確認することができます。

f:id:Karvan:20211005212637g:plain

 

f:id:Karvan:20211005212709g:plain

 

f:id:Karvan:20211005212745g:plain

使いこなすことが出来れば色々と面白い演出が作れそうですね。

【Unity】小ネタ:複数マテリアルの一部をスクリプトで変更する

f:id:Karvan:20210928202541p:plain

息を吐くように愚痴を言う

朝夕がめっきり涼しくなって秋の気配が濃くなってきましたが昼間は暑かったりして未だにポロシャツを着ている皆さんこんにちは。季節的には着ていたら可笑しいそうです。後輩に指摘されました。余計なお世話です。
シルバーウィークも終わり、11月にならないと祝日が無いばかりか、3連休も年内はない事を知り、且つ、PMには「年内は稼働をあげて(=残業して)作業してください」と宣告されて、例の100日後に〇〇する47歳の如く、モチベーションがゼロ底辺を彷徨う状況となっています。ええ、残業しても残業代はもらえないし。

 

一応、集英社のゲーム企画応募の方はプロモーション動画も企画書も完成して応募する事ができたのですが、次に待っている講談社向けの企画について作業する情熱が中々燃え上がってきません。
心を燃やせ、と言われても早々燃えないです。きっとゴミだったら燃えないゴミの方に分別されると思います。

 

間違い探し

とか言いながらも締め切りは差し迫っているので、作業を進める為、プロモーション用にパズルゲームを作っている最中です。

 

f:id:Karvan:20210928202759g:plain

こんな感じの間違い探し(直し)ゲーム
左のジオラマと違うところをクリックして同じ状況に修正させるのですが、修正する「間違い」の中にはオーソドックスに「色違い」も存在します。

 

「色違い」だとmaterialのcolorを変更すれば良さそうですが、そうすると同じmaterialを使っている他のモデルにも影響が出るので、colorの変更は行わずmaterialそのものを変更する事になります。

 

textureを使用しているmaterialならtextureを変えれたmaterialを用意すれば良さそうですが、そうでなく下のように複数の色のmaterialで構成されているモデルの場合、狙った箇所だけmaterialを変更する必要が出てきます。

f:id:Karvan:20210928203020p:plain

当初は

gameObject.GetComponent<Renderer>().materials[1] = mat;

上のコードのように配列中のIndexを指定して、ORANGEのmaterialを別の色のmaterialに変更すれば良いと思ったがこれでは動作しませんでした。
調べた結果、以下のように配列ごと入れ替えると動作します。

Material[] tmp = gameObject.GetComponent<Renderer>().materials;
tmp[1] = mat;
gameObject.GetComponent<Renderer>().materials = tmp;

これで実行すると

f:id:Karvan:20210928203413g:plain

こんな感じ、上手い具合に狙った個所の色だけが変わるようになりました。

【進捗報告】unity1weekに参加せずに何を作っていたか

f:id:Karvan:20210914203659p:plain

ハッシュタグ

TwitterやらInstagram等でハッシュタグだらけの投稿を見ると自然とそのアカウントをブロックしてしまう皆さんこんにちは。アフィか地球市民的ジジババの腐臭が漂っているので見るに堪えません。

 

unity1week

前回の記事でも紹介しましたがunityroomの方でunity1week開催中で現在は(名目的な)開発期間が終わり評価期間に移行したので投稿作品を遊ぶことができます。

unityroom.com

今現在で200を超える作品が投稿されていますが評価期間中でも投稿は可能で、しかも評価期間は二週間あるで最終的は500近い作品数になると思われます。
昨今ではプロの作品かと思えるような完成度が高いものもあり、その作品の一部がアプリ化したり、switch等で販売されたりして注目度が上がっている当コンテスト、私も参加したかったのですが多忙すぎて手が回らず断念。今回は遊ぶ側に回りたいと思います。

 

何をしていたのか

以前から取り上げていますが集英社のゲーム企画コンテストが今月末の締め切りとなっています。

game-creators.camp

 

また、講談社のゲーム企画コンテストの方も来月末が締め切りなので、それらのデモ版作成に追われており他の事に手が出せない状況となっています。

creatorslab.kodansha.co.jp

 

去年から作り続けている脱出ゲームも開発がストップしており、いい加減そちらの方も仕上げていかないとエターナる(永遠の未完のまま終わる、という意味)心配でも出てきました。

f:id:Karvan:20210914012147g:plain

本当は11月にリリースする予定だったんですがね、到底間に合わない。

 

進捗を並べる

当面の目標は集英社向けのゲーム企画の方ですがこちらは何とかデモ版が完成しそうです。
デモ版と言いつつプレイアブルデモ(体験版)ではなく、動画撮影用のデモ版で実際に遊ぶことはできないんですが、とりあえず最終局面のボス戦までは作成しました。

 

f:id:Karvan:20210914011957g:plain

ボス登場シーンから

 

f:id:Karvan:20210914011851g:plain

攻撃をかわすシーン

 

f:id:Karvan:20210914011925g:plain

倒すところまで

 

これからの予定

そろそろ講談社向けの企画の方にも力を入れないといけません。
こちらはプレイアブルデモを作れそうですが、なんせ締め切りまで時間がないのでやっぱり動画撮影用のデモを作って手一杯になるかもしれません。

f:id:Karvan:20210914012038g:plain

企画書も書かないといけないしなぁ・・・・

【Unity】今更ながらBlend Treeを使う

f:id:Karvan:20210907210733p:plain

後だしジャンケン

辞めろ辞めろと言いながらいざ辞めるとなったら無責任だと文句意を言い、強いメッセージが必要と訴えるのに具体的な内容は口にしない後だしジャンケンが得意な皆さんこんにちは。各自思うところはあると思いますが、感染対策が焦点なのに「学術会議任命拒否問題がー」とか言ってる報道特集はどこを向いて報道しているんだろうと思う。

 

地上波デビュー

前回の記事でもお伝えしましたが、私が以前unityroomに投稿した作品「Supra animus quo」がテレビ朝日の「会心の1ゲー」という番組で取り上げて頂きました。

 

特に盛り上がり処の少ない作品だと思うのですが、MCの方に「面白い」「オシャレ」等々の言葉を掛けていただき感謝しかありません、ありがとうございます。

 

unity1week

この「Supra animus quo」はunity1weekの投稿作品ですが、今週からまたそのunity1weekが開催されています。
今回のお題は「ちゅう」だそうで少し難しいお題かなという気もしますが、最近ではこのunity1weekから「Supra animus quo」のようにテレビに取り上げられる作品が色々と出ているので、今回も数多くの作品が投稿されると思います。

unityroom.comまぁ、私は残念ながら参加できそうにないんですがね。。。

 

アニメーションの切り替え

例えば3DのSTGとかACT等で対面の敵と正面で対峙しつつ横に移動する、といった場面を作る場合、自機は敵と正面を向いたまま敵の周りを公転運動のように移動することになり、敵側も自機の方向を向かせるためにその場で回転させるような動作を行う必要があります。
とはいえ敵側を立ったまま(Idle状態のまま)回転させると違和感しかない絵となってしまいます。

f:id:Karvan:20210907211211g:plain



なので敵側はその場から移動しないにせよ「歩く」ようなアニメーションをさせたいのですが、通常通りアニメーションのステートマシンを利用して「立ち状態」→「歩き状態」にアニメーションを切り替えると、これまた動作が唐突過ぎて微妙な感じ

f:id:Karvan:20210907211255g:plain

そのため、より自然なアニメーションの切り替えを行うためにはステートマシンでなくBlend Treeを使って切り替えを行う事になります。

 

Blend Tree

BlendTreeはアニメーションステートマシーンの中の一つのステートとして作成します。
[Animator]タブのステートマシーン画面の中で右クリックし、メニューの中からCreate State → From New Blend Treeを選択します。

f:id:Karvan:20210907211432p:plain

作成されたBlendTreeをダブルクリックすると、

f:id:Karvan:20210907211457p:plain

BlendTreeの設定画面へ移動します。
今回の場合は「Idle」と「Run」の二つのアニメーションをBlendTreeで切り替えるので、BlendTreeを右クリックしAdd Motionを選択

f:id:Karvan:20210907211519p:plain

「Idle」と「Run」の二つのアニメーションクリップを追加、Inspector上には下図のようにパラメータやアニメーションクリップが表示されます。

f:id:Karvan:20210907211549p:plain

Inspectorからわかるようにここでは[Blend]という値を0~1に変更して0に近いほど「Idle」のアニメーションが、1に近いほど「Run」のアニメーションが強く反映されるようになります。

 

スクリプトを組む

[Blend]の値を指定した時間で0→1、1→0に変更するようスクリプトを組みます。
Easingを考慮するならDotweenのToやiTweenのValueToを使っても良いですが、今回は単純な(Linerな)変更でよいでUpdate関数内でSetFloatをコールして変更するようにしました。

    static readonly int BLEND_KEY = Animator.StringToHash("Blend");
    Animator Animator;
    
    public float BlendTime;    // Idle → Walkの変更時間
    public float IdleTime;     // Walk → Idleの変更時間
    
    private void BlendWalk(float deltaTime, bool isRev)
    {
        float nowBlend = Animator.GetFloat(BLEND_KEY);

        float modBlend = 0.0f;
        if (isRev)
        {
            modBlend = nowBlend - deltaTime / IdleTime;

            if (modBlend < 0.0f)
            {
                modBlend = 0.0f;
            }
        }
        else
        {
            modBlend = nowBlend + deltaTime / BlendTime;

            if (modBlend > 1.0f)
            {
                modBlend = 1.0f;
            }
        }

        Animator.SetFloat(BLEND_KEY, modBlend);
    }

 

ちなみにアニメーションステートマシーンの設定はこんな感じ、[Blend]の値が0.1以上になると最初の「Idle」のステートから「BlendTree」のステートへ、0.1以下になると「BlendTree」から「Idle」へ戻るようになります。

f:id:Karvan:20210907211755p:plain

これで実装は完了したので、実行すれば敵側が自機側の動き合わせて、Idle状態から徐々に歩き出すアニメーションとなり、逆も徐々に動きが止まる動作となります。

f:id:Karvan:20210907211848g:plain

ステートマシンを利用した時と比較するとかなり自然な動作になったと思います。

 

【Unity】立体スライドパズルできるかな(検証編)

f:id:Karvan:20210831202728p:plain

100日後に○○

例のワニ以降、SNSで「#100日後に○○」とタグが付いた投稿が増えていて安易だなぁと思いつつ「#100日後に退職する47歳」の投稿を楽しみにしている皆さんこんにちは。
IT業界の土方作業を経験した方なら誰しも身に覚えのある話ばかりで、私も興味深く拝見させてもらっています。現場には顔を見せない上役や営業が電話やメールやらでどんどん口を出して混乱している現場を更に混乱させる有様はこの業界のあるあるですね。

 

会心の1ゲー

テレビ朝日で毎週木曜深夜に放送されている「会心の1ゲー」という番組で、私が以前unityroomに投稿した「Supra animus quo」というゲームを遊んでいただけたらしく、その模様が今週分の放送回で放送されるそうです。

 

tver.jp

また、同じくunityroomに投稿した「The two met」も9月分の放送で紹介して頂けるそうで誠にありがたい限りです。
以前よりこの番組ではunityroomの投稿ゲームをいくつか取り上げており、私も小耳にはさんでは内心羨ましく思っていたのですが、まさか二つもピックアップしてもらえるとは夢にも思っていなかったので驚くばかりです。残念ながら私の住んでいる地域では放送されていないのでTVerでの配信待ちになるのですが、配信されたらPCの前で正座して視聴したいと思います。

 

立体スライドパズル

さて、前回はRenderTextureでcameraの映像を表示させた平面を立方体の形状で分割させて、3D空間が分割された(ように見える)画面を作ることまでできました。

後はこれをスライパズルの要領で動かせばパズルの完成だと思っていたのですが・・・

f:id:Karvan:20210824195318g:plain



結果としては思った通りにはいきませんでした。理由は大きく二つほどあって、一つは分割した映像を違う位置へ違う位置へ動かしてみると

f:id:Karvan:20210831203505p:plain

こんな感じになります。3D空間が分割されたというよりは側面に映った映像が分割しているようにしか見えない。


各立方体の初期状態では見えていない面に対しては何も描画しないようにしているのですが、このため立方体の「中に」オブジェクトがあるようには見えず、立方体の「側面に」映っている用しか見ない。

f:id:Karvan:20210831203544p:plain

もちろん位置を動かした時に両面すべて表示させることもできるのですが、そうした場合も問題があって、それがもう一つの問題「ステンシルバッファを利用してマスキングした部分が二つの立方体で重なった場合に描画順を制御できない」という問題。

 

f:id:Karvan:20210831203818g:plain

上の動画を見て一瞬、「ん?」と不思議に思う箇所があると思います。
それもそのはずホール部分が中央下に来た時、上の立方体部分の中に下の立方体の「通常では見えない部分」の映像が見えています。

f:id:Karvan:20210831204105p:plain

この部分

 

これはステンシルバッファに書き込む描画順が「下の立方体→上の立方体」ではなく「上の立方体→下の立方体」となっているため、ステンシルバッファに書き込まれる値が「下の立方体のステンシル値」で上書され、結果として下の映像が映し出されているのだと思います。

調べてみるとunityでは不透明分の描画順はZ方向に厳密にソートされているわけでなくRenderQueueの値も影響するらしいので、厳密に描画順を決定するならこのRenderQueueを変える必要があるらしい。

 

とはいえ、これは静止画でなくパズルとして各立方体の位置を動かす必要があるため、RenderQueueの値で調整するのは難しいと思います。

パズル内の場所によってステンシルバッファに書き込む値を決めて参照時に「Greater/Less」でレンダリングするという手も考えたのですが、そもそもシェーダのステンシル値を動的に変えられるのかも不明で、う~ん、どうしよう。。。と悩んでいる最中です。





 

◇プライバシーポリシー

●個人情報の利用目的

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

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

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

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

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

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

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

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

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

●免責事項

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

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

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

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

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

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