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

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

進捗報告

喉痛い

出来るだけ起伏のない平坦な人生を選んできたつもりでしたが自然現象だけはこちらから選ぶことは出来ないので、ここ最近の急激な寒暖差に体がついていけずに風邪をひいて喉がとても痛いです。のど飴を舐め過ぎて舌も痛いし。

 

つまり全然本調子じゃないということで、本来ならDiscont@XR landscape design氏が紹介されていた窓シェーダーについて

 

styly.cc

 

実際に実装してみたアレやコレやを書くつもりでしたが、頭が働かないので今回は進捗報告のみです、ごめんなさい。

 

メニュー画面を作った

そんなこんなで先週から今日に掛けてはずっとタイトル&メニュー画面の作成に従事していました。
出来上がりとしてはこんな感じですが、どうでしょうか?

 

f:id:Karvan:20181211195710p:plain

 

サイバー系ゲームのあるあるで文字やら床やらがやたら発光しております。
「Run」ボタンをクリックするとさらに発光します。こんな感じで

 

f:id:Karvan:20181211195744g:plain

 

年内には完成したいなぁ・・・

 

ブログ開設一周年

早いものでこのブログを開設してから一年がたちました。パチパチ、おめでとう、おめでとう自分。

 

開設当初の予定では1年の間にアプリを2,3本リリースしてアプリの売り上げでウハウハな生活を営んでいるはずでしたが、実際のところはリリースできたのはたったの1本で、アプリの売り上げはほぼ0という惨憺たる結果となりました。

 

次の1年こそはアプリを2,3本リリースして、高級ホテルで両脇に売れないグラビアアイドルを抱えながら夜景を見つつワインを傾けるみたいな豪遊できるぐらいの収入を得たいと思います。ワイン苦手だけど。

 

 

 

 

【Unity】カメラワークによる演出を考える

ふと思い出す

12月に入ったのに気温が高くて全然冬になった気分にはなりませんが、確か昔、このぐらいの時期にひょんなことから足を骨折したことがあって、病院でギブスを巻き、なれない松葉杖をなんとか使いながら自宅に戻る途中で上司に本日は休みを取る旨の電話をしたら、「はぁ?おまえなぁ、有給ってのは病気したとか大怪我したとか、そういう時に使うものだぞ!」ってな感じで延々と説教された出来事を、バカリズムに似た芥川賞作家センセの「いい加減、国に与えてもらった休日に、みんなで一斉に休むとか止めればいいのに」といった高等遊民的なTweetを目にして思い出した今日この頃、私もいつの日か「ゴールデンウィーク?ww、みんな好きなときに好きなだけ休めばいいのにー(鼻ほじー)」みたいなことを言える立場になってみたいものです。

 

減衰・FoV・手振れ

そんな感じで私もナチュラルに上から目線で物を言えるような地位を確立すべくゲーム製作を頑張っている訳ですけれども、アレやコレや試行錯誤していく中で、つい最近では@yoship1639氏の書かれた記事が非常に有用で参考になりました。

 

qiita.com

ゲーム中のカメラワークについての手法に関する記事なんですが、記事の中で紹介されている「Lerp減衰・FoV変動・PerlinNoise手ブレ」を取り入れると、かなりダイナミックが表現が可能となります。

 

それぞれの手法については上記の記事で詳しく書かれているのですが、掻い摘んで説明すると

 

  • Lerp減衰:カメラとカメラの被写体の動きをピッタリ同時にするのではなく、カメラ側が少し遅れて被写体を追随するような動きをさせる手法。これにより被写体の動きが俊敏かつ大きく見える

 

  • FoV変動:カメラの画角(FieldOfView)を変化させて画面をダイナミックに変化させる手法。カメラのProjection(投影方法)がPerspective(透視投影)の場合は特に効果が大きい

 

  • PerlinNoise手ブレ:文字通り「手ブレ」を表現する。カメラを揺らすことで被写体が激しく動いているように見える。アクションゲームとかRPGなどではダメージを受けた時の表現にも使われる。

 

となっています。

 

FoV変動を取りれよう

一般的なレースゲームではマシンにブースとが掛かったり急加速したりするときに、一瞬大きな引きの画になったりしますが、それはカメラの画角(FieldOfView以下、FoV)をあげている為です。

 

FoVを上げるとはカメラに写る範囲を広げる、という意味で、一般的に大きく引いた画を撮るときにこのFoV値を上げて画面に表示される範囲を広く取ります。

 

もちろん、カメラ自体を奥行き方向に移動させて画角を広く取るという手法もありますが、カメラの投影方法がPerspective(透視投影)の場合、このFoV値が大きくなると画面の端に行くほど歪みが大きな画像になり、被写体は引き伸ばされて映し出されます。

逆に中央に行くほど歪みは小さいものになるので、結果、奥行きが強調された画面になります。

 

通常時の画面

f:id:Karvan:20181204223558p:plain

 

カメラを奥行き方向に移動させて画角を広く取った場合(FoV値は変えない)

f:id:Karvan:20181204223630p:plain

 

FoV値を大きくして画角を広く取った場合(カメラの位置は移動しない)

f:id:Karvan:20181204223710p:plain

 

どちらも引いた画になりますが印象はずいぶん違ってきます。

 

実装してみた

FoV変動の実装は簡単でCamera.fieldOfViewの値をスクリプトで徐々に変えるだけです。今回はLerpを使って変化させてみます。

 

Camera.fieldOfView = Mathf.Lerp(Camera.fieldOfView, fov, Time.deltaTime * 2.0f);

 

第二引数のfovが最終的に変化させたいFoVの値です。
Lerpの第3引数にフレーム間の差分時間であるTime.deltaTimeを使い、目標値へ滑らかに変化するようにしています

 

上記の処理後に同じようにLerpを使って徐々に変化させながら元のFoV値へ戻します。
これで、一瞬大きく引いた画になったかと思うと、一気に元の画に戻る、という演出が行えます。

 

public class CameraController : MonoBehaviour 
{
    public float FoVTarget = 145;
    public float DefaultFoV;
    
    void Start () {
        m_Camera = GetComponentInChildren<Camera>();
        DefaultFoV = m_Camera.fieldOfView;
    }
    
    void LateUpdate()
    {
        ZoomControl();
    }

    /// <summary>
    /// ズーム処理
    /// </summary>
    void ZoomControl()
    {
        if (inZoom)
        {
            m_Camera.fieldOfView = Mathf.Lerp(m_Camera.fieldOfView, FoVTarget, Time.deltaTime * 2);
        }
        else
        {
            m_Camera.fieldOfView = Mathf.Lerp(m_Camera.fieldOfView, DefaultFoV, Time.deltaTime * 4);
        }
    }
    
    /// <summary>
    /// FoC変更
    /// </summary>
    void OnFoVChange()
    {
        StartCoroutine(DoZoomEffect(1.2f));
    }


    /// <summary>
    /// ズームエフェクト
    /// </summary>
    /// <returns></returns>
    IEnumerator DoZoomEffect(float duration)
    {
        inZoom = true;
        yield return new WaitForSeconds(duration);
        inZoom = false;
    }
}

  

で、ゲーム中の実際の動作はこんな感じになります。

 

 f:id:Karvan:20181204224653g:plain

 

実はFoVを元に戻すときに「PerlinNoise手ブレ」も動作しているのですが、サンプリングの関係なのか手ブレの効果については上のGIFでは良く分かりませんね。カメラが急にワープしたかのように見えるし。

 

「PerlinNoise手ブレ」については次回のブログで記事にしようと思います。

 

 

【Unity】複数のオブジェクトの色を一気に変える

三連休だった

スパイダーマンになってNYの平和を守ったと思ったら、次は核戦争後の荒野を彷徨う事になってオンラインゲームなのに他のプレイヤーと滅多に出会わないという斬新な世界を旅する三連休を過ごしたのですが、あまりに休日ニートが過ぎたのか、車の定期点検にディーラに持ち込んだら担当者に「走行距離が全然伸びていないので、ほとんど新車同然ですね(ニヤニヤ)」みたいな感じで、褒められているんだか貶されているんだか分からない言葉を浴びたりしたので少しは外に出ようと誓った秋の夜。

 

一気に色が変わる

さて、製作中の「Dull Things No Life」ですが、ゲーム自体は典型的なエンドレスランゲームなので、迫ってくる障害物を右に左に上に下に避けて進んでいくだけ、という単純な内容となっています。

 

なので他の類似アプリと違いをだす為にアレコレと演出を考えているわけですが、最近思いついた演出が「周りの背景や障害物の色が一気に変わる」というやつ、シューティングゲームなどで偶に見かける演出です。

 

周りの背景の色を変える、とはスカイボックスやプレイヤー機を囲んでいる壁のMaterialをスクリプトで変えるだけなので特に問題ないのですが、悩んだのは「障害物の色を変える」こと。
つまり、大量に動いているオブジェクトの色を一気に変えないといけない

 

オブジェクトの色を変える

「Dull Things No Life」では障害物として動いているオブジェクトのMaterialは全て同じものを使用するように作っています。
これは性能対策としてBatch数を減らすためです。

 

ただ、Unityではオブジェクトに対して

GetComponent<Renderer>().material.color = 色;

を行うことでオブジェクトの色を変更する事が出来ますが、これを行うと内部処理でオブジェクト毎にMaterialが一つ追加されます。つまりBatch数が増えるという意味で、これでは性能対策をした意味がなくなります。

 

Materialのcolorを変更したいけどBatch数は増やしたくない。

 

そんなことで悩んでいたのですが、毎度お世話になっているテラシュールブログに解決方法が記載されていました。

 

tsubakit1.hateblo.jp

SharedMaterialを使う

テラシュールブログによればRendererのsharedMaterialで共通Materialにアクセスすることができるようです。


つまり、同一Materialを参照しているオブジェクト全てに対して変更内容を適用できるということで、共通Materialを変更するので内部処理で新たにMaterialを追加することもありません

 

使い方はmaterialと同じように

GetComponent<Renderer>().sharedMaterial.color = 色;
とするだけです。めっちゃ楽。

 

早速、取り込んでみたらこんな感じなりました。
(sharedMaterialの変更と同時に、スカイボックスと壁のMatrialを変更しています)

 

f:id:Karvan:20181127235051g:plain

 

まぁ、ソコソコ面白い演出になっているのではないでしょうか。

 

【Unity】Animator付きのGameObjectの非アクティブ化について

強炭酸ブームらしい

どちらかといえば微炭酸な人生を歩んできた人間なので気づかなかったのですが、巷では強炭酸がブームらしいです。バカリズム似の作家センセイがそんなTweetをしていて知りました。調べてみると昨今のハイボール人気から炭酸の需要が拡大し、強炭酸水のブームにつながったようです。なんでもウィルキンソンは前年比22・1%増の販売量だとか。

 

そういえば最近は居酒屋には必ずハイボールやサワーのメニューはあるし、乾杯の一杯目でもビールではなくハイボールを頼む人が多いですしね、あ、でもビールも炭酸か、なんだ、根っから炭酸好きじゃん日本人。

 

新しい発見

そんな感じで新しい発見に出会えたり出会えなかったりする日常を過ごしているわけですが、Unity関連で最近発見したことといえば、前回のブログで取り上げた性能対策を行っていたときに直面した問題だったりします。

 

www.karvan1230.com

前回のブログではBatch数を削減すために『使用しないUIはCanvasごと非アクティブにする』対策を行ったのですが、この非アクティブにする前後でUIのアニメーションが変わってしまう不具合を発見

 

非アクティブ状態にする前のUIアニメーション

f:id:Karvan:20181120235302g:plain

 

非アクティブ状態からアクティブ状態に戻した後のUIアニメーション

f:id:Karvan:20181120235353g:plain

 

見て分かるようにアクティブ状態に戻した後だと、右側の四角が半分切れた状態で表示され、途中で表示される白線も上に移動しています。

 

UIアニメーションはUnity標準のAnimationを使用しているのですが、アクティブ状態の切り替えでこんな影響がでるとは想定外でした。

 

原因?

まったく原因がわからないので、エディタウィンドウに表示される右の四角の設定を通常時とおかしくなった後で比較して確認。
すると、PivotのY位置が通常時は0.5になっているのに、おかしくなった後では0になっていることを発見、
つまりアクティブ状態の切り替えによってこの設定が0になるらしい、んー。

 

f:id:Karvan:20181120235502p:plain

 

次にAnimationエディターで右の四角の動作を確認。
AnimationではPivotのX位置についての設定はあるものの、Y位置について設定は特に行っていません。

 

f:id:Karvan:20181121000631p:plain

 

つまりAnimationではPivotのY位置は動かしていない。

 

f:id:Karvan:20181120235919p:plain

PivotのY位置が変わっているのにAnimationにはY位置の設定はない・・・

 

f:id:Karvan:20181120235938p:plain

だけどAnimationを動作させるとPivotのY位置が0になる・・・
それもアクティブ状態を切り替えた後にだけ・・・

 

f:id:Karvan:20181120235957p:plainわからん!!

 

当初はまったくお手上げでした。

 

たぶん、たぶん、きっと

で、改めてAnimationエディターで設定を確認。

 

f:id:Karvan:20181121000042p:plain

 

PivotのY位置について『DefaultValue』の記述があります。

『Default』ってことは初期位置(=0.5)だと思ったのですが、もしかするとアクティブ状態の切り替えによって『Default』値が変わっているのかもしれない・・・

 

そう思って、PivotのY位置について0.5となるように設定を追加すると・・・

 

f:id:Karvan:20181120235302g:plain

 

ちゃんと動いたー

こんな簡単なことで一日潰れたりする・・・

 

類似記事の紹介

ここら辺の話をよくよく調べてみると毎度お世話になっているテラシュールブログにて似たような記事がありました。

 

tsubakit1.hateblo.jp

つまり、Animatorを含むGameObjectの非アクティブ化はできるだけ避けたほうが良い、という事みたいです。

 

ん~、とは言ってもなぁ・・・

 

 

 

【Unity】使われないuGUIはCanvasごと非アクティブにした方が良い?

腰痛い

基本的に休日ニートな人間なので、休みの日は部屋に閉じこもることが多いのですが、先日は地元でADAM atのライブがあったので重たい腰を上げて参戦してきました。

 

www.jvcmusic.co.jp

ADAM atはピアノ・インストゥルメンタル・ユニットでCDショップなどではジャズ系に分類されることが多いのですが、ジャズスウィングの横ノリというよりはロックな縦ノリ曲が中心で、ライブではヘドバンするような曲も演奏されます。その所為かMCでは『ジャズなのにジャズ系のフェスに呼ばれない』とぼやいてました(笑)

 

実は、現在製作中の「Dull Things No Life」はADAM atの「共鳴ディストラクション」という曲を聴いた時のイメージがベースになっています。ゲーム画面のデザイン中はずっと聴いてたし。

 

なので、早々にチケット取りウキウキしながら参戦してきたのですが、結果腰が痛い。

なにせ前述のように激しい曲が中心で、ライブ中はほぼずっと飛び跳ねていたので、そりゃ腰を痛めるわ、って感じ。座っても立っても腰が痛い。

 

まぁ、ライブが楽しかったからいいけど

 

性能対策に頭が痛い

そんな感じで痛めた体を庇いながらもゲーム製作は進んでいくのですが、前々回の記事で報告したメニューウィンドウを実際のゲームSceneに取り込んでみたら、実機での動作がまたモッタリするような感じに何度目だ。

 

スマホ向けゲームを作るうえでは避けて通れない性能対策に頭を痛めながらStatisticsを確認すると、確かにBatch数が常時130オーバーな状態になっている。んー、これはいかん。

 

f:id:Karvan:20181113211319p:plain

 

メニューウィンドウを追加する前だとBatch数は100を切っていたので、これは明らかに追加したメニューウィンドウの所為だと分かります。


まぁ確かに、実行前のゲーム画面はこんな感じでゴチャゴチャしているし、起動後はマスクによって非表示状態になっているだけなので、いくら見えないとはいってもBatch数は軽減されないのかもしれない。

 

f:id:Karvan:20181113211421p:plain

(テキスト部分は分かりやすいように文字を入れています)

 

uGUIに関する性能対策

uGUI周りの性能対策について広く知られているのは

  • SpriteをAtras化する
  • 動くUIと動かないUIでCanvasを分ける

等があります。詳しくは下記リンクを参照してください

 

siguma-sig.hatenablog.com

「Dull Things No Life」でも同様の対策を行っていて、Canvasも通常(動かない)UI、メニュー系UI、メッセージ系UI、トランジッション系UIで別々のCanvasに分けています。

Canvasが増える分、SetPassが増える=Batch数が増える、ことは覚悟していたのですがここまで増えるとは予想外でした。

 

とはいえ、今更同じCanvasに纏めるのは馬鹿らしいし、違うところで負荷が増えることになるので対策にはならない。
なので試しに、マスクによって非表示状態になっている時はCanvasごと非アクティブにしてみようと思ったわけです。

 

で、結果として・・・

f:id:Karvan:20181113211833p:plain

おお、見事にBatch数が減っている!

 

んー・・・使われないGUIはCanvasごと非アクティブにしたほうが性能的にはいいのかな?

 

 

 

 

 

 

 

・・・とか思ったのですが、ここでまた別の問題が発生、はぁー、頭痛い・・・詳細は次回の記事で

 

 

【Unity】パーティクルを使って動くオブジェクトの軌跡を描く

11月

11月にもなると気温もぐっと低くなり、年末も差し迫ってきた感じがして、私の周りでも忘年会をどこで開こうか、みたいな話がチラホラ聞えて来ます。忘年会に限らず年末年始は飲み会の多いシーズンなので出費と胃腸の心配をされる方も多いかと思いますが、私の場合は全くその心配がないので安心です。別に私が金持ちだから健康優良児だからというのではなく、単に誘われないからなんですけどね。「辛れー、昨日一時間しか寝てないから辛れーわー、オールで飲んでたから辛れー」は私の中で一度声に出して読みたい日本語の第五位くらいにいます。

 

いきなり進捗報告

とはいえ今週末は体調があまり優れなかったので寝ている時間も多かったのですが、それでも製作を細々と続けてやっと演出部分がここまで出来ました。

 

f:id:Karvan:20181106223626p:plain

 

演出を強化したい

ゲームでは良くある演出の一つに「キャラクターが移動した軌跡を表示する」ってのがあります。
車の土煙とか、ミサイルの噴煙とか、その物体が高速で移動していますよ!みたいなことを上手く表現する手法です。

 

ご多分にもれず「Dull Things No Life」でもプレイヤーの主機となるバイクに噴煙みたいなパーティクルをつけて、バイクが高速で動いているように見せようと努力しています。

 

f:id:Karvan:20181106223759g:plain

 

こんな感じで

 

だが、なんか物足りない。噴煙がカメラ方向に伸びているだけで、ちょっと地味。
なので週末はバイクの左右の移動によってそれっぽい軌跡を表示する演出部分を作っていました。

 

出来上がりの図(二度目)

f:id:Karvan:20181106223626p:plain

 

赤い軌跡の部分はTrailRendererで表示しているのですが、タイヤ横の青い軌跡はParticleSystemで表現しています。

 

上の図でも分かるようにTrailRendererだと一つの線として軌跡が表示されますが、ParticleSystemを使うと段階的に軌跡が表示されるのでちょっとカッコイイ、こちらのほうが高速に動いて見える感じがします。

 

軌跡を表示する

参考にしたのは、毎度お世話になっているテラシュールブログさんです

tsubakit1.hateblo.jp

リンク先ではCubeを使用していますが、今回は四角形のSpriteです。
これをParticleSystemを使ってタイヤの横から放出されるようにします。

 

まず基本部分の設定

f:id:Karvan:20181106224100p:plain

 

Simulation SpaceにWorldを指定してWorld座標でパーティクルを生成します。

この指定により放出したParticleが親オブジェクト(今回の場合はバイク)にくっついて移動することがなくなります。


またPrewarmフラグをONにしておくとループの途中から再生されたかのように一気にパーティクルが発生します。

 

次にEmissionの項目

f:id:Karvan:20181106224154p:plain

 

ここでRate over TimeでなくRate over Distanceに値を設定することがポイントです。


Distanceということは、時間ではなくParticleSystemの親オブジェクトが動いた距離によってパーティクルが発生します。
つまり、軌跡に沿ってパーティクルが生成される、ということになります。

 

併せてサイズの指定で、Size Over Lifetimeで最大値から一気に縮むように設定。残影っぽく見えるように。

 

最後にRendererのModeにBillboardを指定します。

f:id:Karvan:20181106224317p:plain

 

これによりカメラが移動してもパーティクルが正面を向くように表示され、形がゆがむ事はありません。

 

これらを設定して実際に動作させると、こんな感じに

 

f:id:Karvan:20181106224343g:plain

 

GIFの解像度が悪いですが、実際は綺麗に表示されます。

 

11月中には仕上げたい

でも無理っぽい。もっと効率的に動ける能力がほしいですね。頭の中の仕様をぱっと実装できるような才能が、それも努力無しに。
「あれ?俺またなんかやっちゃいました?」は私の中で一度声に出して読みたい日本語の第二位くらいにいます。

 

 

あ、ちなみに第一位は「アレクサ、大さじ4杯は何カップ?」です。

その前に目分量で0.3カップを測る能力を身につける必要がありますが。

 

たまには進捗報告をしよう

寒暖差が激しい

晩秋の候にもなると朝夕の寒暖差が激しくて体調を崩す方も多いと聞きますが、私もご多分に漏れず、風邪を引いたようで鼻づまりがひどい状況となっています。前回の記事でも書いたのですが、どうもここ最近は巡り合わせ悪いターンに差し掛かっているようで、思うように事が運ばずテンションが上がらない、ここ最近で面白かった事といえば、台湾事故で発生当初は『大変だー、心配です。・・・車両は日本製だけど』とウキウキでTweetしたいたのに、事故原因が人為的ミスだと明らかになるにつれてピタリと話題に触れなくなった平野啓一郎ぐらいで、これといった楽しい話もありません。あー、鼻水が辛い

 

UI周りの進捗

そんなわけで、今回は「Dull Things No Life」のメニュー周りができたのでその動画を載せて、後はゆっくり寝ます。あー、本当に鼻水辛い。

 

f:id:Karvan:20181030234447g:plain

 

あ、メニューができただけで、実際にScene遷移処理はこれから作成します。

 

 

◇プライバシーポリシー

●個人情報の利用目的

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

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

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

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

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

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

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

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

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

●免責事項

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

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

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

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

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

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