ねこバタ会議

スマホアプリ制作に関するブログです。

カテゴリ: Unity

このブログでも何回か書いていますが、女子高生が校門の前で銃を乱射するというゲームを作っています。
こう書くと非常に物騒な感じですね…レーティングとか色々大丈夫なのか心配になってきますね…(^_^;)

で、ゲームの骨格が結構出来てきたので、実機で動かしてみたところ、動作がカクカクして見るに耐えません…。
私の使用しているAndroidの端末が古いということもあるのですが、古い端末を使用されている方でも、それなりには遊べるようにしたいところです。

特に弾丸などの新しいオブジェクトを生成して表示する際に時間がかかっているようで、その動作がある度にフレームが飛んでしまいます。

今までまったく知らなかったのですが、Unityには色んな情報を見られる機能があるんですね。
以下のページを見て、どんな状態なのかを確認してみました。
Unity 5 Proとなっていますが、Unity 5ならフリー版でも問題なく使えます。

Unity 5 Proの新機能FrameDebuggerでグラフィックパフォーマンスを改善する

ゲームビューにあるStatsというボタンを押すと、色々な情報が見られます。
詳しくは私も知らないのですが、色々なオブジェクトをアクティブ化したり非アクティブ化したりすると数字が変わるので、それを参考にすれば良さそうです。
細かいことはいつか勉強しましょう。

Unity_stats

ただ、上記のStatsで見られるのは、当然Unityエディタ上での情報です。
参考にはなるのですが、重要なのは端末での動作ですね。
端末の方については、こちらのページで紹介されていたスクリプトを使用しました。

【Unity】メモリ使用量とか、FPSとか、色々表示するスクリプト:ほんにゃら重工

スクリプト
AllocationStats.cs

スクリプトを保存して、適当なゲームオブジェクトにアタッチするだけなので、とても簡単です。

 fps

フォントサイズとか調整していないので見づらいかもしれませんが、状態の把握が出来ればいいので私的にはオッケーです(阿武隈)。

上記の画像では30.1FPSと表示されていますが、調整前は9~26FPSあたりを行ったり来たりしていました。
不必要なオブジェクトを非アクティブ化したり、都度生成していたプレハブを最初に一括で生成して使いまわしたりしたところ、動作もかなり軽くなりました。

やはり情報を確認できるというのはいいですね。
多分情報可視化ツールはたくさんあると思いますし、自作もそれほど手間ではないと思うので、自分にあったものを見つけるなり作るなりしてください。

相変わらずレベルの低いブログですが、一歩ずつ進んでいきたいと思います。
ちなみに上記の女子高生銃乱射ゲームのタイトルは「ガンナーズハイ 学年ビリのギャルが40人倒して合格を目指す話」となりました。
なるべく早く完成させられるようにがんばります!

icon512

今日も大抵の人にとってはあまり役に立たないUnityのTIPSです。

Unityに限らず、Objective-CでもJavaでも意外と困ったのが色の指定方法です。
0.0~1.0とか0~255とかでRGB指定をすればいいのですが、そもそも色の配合要素を一々覚えるのは面倒です。

UnityではGUIで指定してPresetに保存したものを使いまわすこともできるので楽ちんなのですが、基本的にコードで操作したい私のようなアナログ人間にとっては使いづらい場面もあります。

color


というわけで、今日は「カラーネームで色を指定する」です。
カラーネームというのは、CSSやHTML等で使用される色名のことです。
color : #FF0000の代わりにcolor : redのような感じで使われます。
ブラウザによって表示される色が若干異なったり、色によっては表示されなかったりするので、個人的にはあまり使いませんでしたが、今は色名からRGB要素の指定を行うだけなので問題ありません。

参考ページ カラーネーム147色:TAG<index>

カラーネームと16進数が併記してあるサイトから適当にデータを引っ張ってきて、適当に作成したphpスクリプトで16進数を10進数に変換しました。
出力結果からC#スクリプトにして、完了です。
最初に変換した時に、なぜか若干色味が違う感じだったので、適当に暗めにするように処理した記憶があります。
なので、以下のスクリプトはカラーネームに正しく対応しているわけではありませんので、ご注意下さい。
あくまで簡易的に色名で指定できるようにしただけですね。
ちなみに適当なので143色くらいしかないと思います。

使い方としては
GetComponent<Image>().color = Colors.Crimson;
のような感じで指定します。
透過色の場合は、以下のようにColors.Alphaで色と透過率を指定します。
GetComponent<Image>().color = Colors.Alpha(Colors.Crimson, 0.3f);
もし色が気に食わない場合や自分好みの色がない場合は、数値を変えたり新しい色名を付け加えていけばいいんじゃないかなと思います。
Objective-CやJavaでも似たようなものを作ると楽になります。

なお、プログラミングの文法等は私は全然理解していないので、色々正しくない部分もあると思います。
くれぐれも参考程度でお願いいたします<(_ _)>

Colors.cs
using UnityEngine;
using System.Collections;

public class Colors : MonoBehaviour {

    public static Color rgb(int red, int green, int blue) {
        return new Color(red / 255f, green / 255f, blue / 255f);
    }

    // usage : Color color = Colors.Alpha(Colors.Red, 0.5f);
    public static Color Alpha(Color color, float alpha) {
        return new Color(color.r, color.g, color.b, alpha);
    }
	
	public static Color White = rgb(255,255,255);
	public static Color Whitesmoke = rgb(245,245,245);
	public static Color Gainsboro = rgb(220,220,220);
	public static Color Lightgrey = rgb(211,211,211);
	public static Color Silver = rgb(192,192,192);
	public static Color Darkgray = rgb(169,169,169);
	public static Color Gray = rgb(128,128,128);
	public static Color Dimgray = rgb(105,105,105);
	public static Color Black = rgb(0,0,0);
	public static Color Red = rgb(255,0,0);
	public static Color Orangered = rgb(255,69,0);
	public static Color Tomato = rgb(255,99,71);
	public static Color Coral = rgb(255,127,80);
	public static Color Salmon = rgb(250,128,114);
	public static Color Lightsalmon = rgb(255,160,122);
	public static Color Darksalmon = rgb(233,150,122);
	public static Color Peru = rgb(205,133,63);
	public static Color Saddlebrown = rgb(139,69,19);
	public static Color Sienna = rgb(160,82,45);
	public static Color Chocolate = rgb(210,105,30);
	public static Color Sandybrown = rgb(244,164,96);
	public static Color Darkred = rgb(139,0,0);
	public static Color Maroon = rgb(128,0,0);
	public static Color Brown = rgb(165,42,42);
	public static Color Firebrick = rgb(178,34,34);
	public static Color Crimson = rgb(188,6,12);
	public static Color Indianred = rgb(205,92,92);
	public static Color Lightcoral = rgb(240,128,128);
	public static Color Rosybrown = rgb(188,143,143);
	public static Color Palevioletred = rgb(219,112,147);
	public static Color Deeppink = rgb(255,20,147);
	public static Color Hotpink = rgb(255,105,180);
	public static Color Lightpink = rgb(255,182,193);
	public static Color Pink = rgb(255,192,203);
	public static Color Mistyrose = rgb(255,228,225);
	public static Color Linen = rgb(250,240,230);
	public static Color Seashell = rgb(255,245,238);
	public static Color Lavenderblush = rgb(255,240,245);
	public static Color Snow = rgb(255,250,250);
	public static Color Yellow = rgb(255,255,0);
	public static Color Gold = rgb(255,215,0);
	public static Color Orange = rgb(255,165,0);
	public static Color Darkorange = rgb(255,140,0);
	public static Color Goldenrod = rgb(218,165,32);
	public static Color Darkgoldenrod = rgb(184,134,11);
	public static Color Darkkhaki = rgb(189,183,107);
	public static Color Burlywood = rgb(222,184,135);
	public static Color Tan = rgb(210,180,140);
	public static Color Khaki = rgb(240,230,140);
	public static Color Peachpuff = rgb(255,218,185);
	public static Color Navajowhite = rgb(255,222,173);
	public static Color Palegoldenrod = rgb(238,232,170);
	public static Color Moccasin = rgb(255,228,181);
	public static Color Wheat = rgb(245,222,179);
	public static Color Bisque = rgb(255,228,196);
	public static Color Blanchedalmond = rgb(255,235,205);
	public static Color Papayawhip = rgb(255,239,213);
	public static Color Cornsilk = rgb(255,248,220);
	public static Color Lightyellow = rgb(255,255,224);
	public static Color Lightgoldenrodyellow = rgb(250,250,210);
	public static Color Lemonchiffon = rgb(255,250,205);
	public static Color Antiquewhite = rgb(250,235,215);
	public static Color Beige = rgb(245,245,220);
	public static Color Oldlace = rgb(253,245,230);
	public static Color Ivory = rgb(255,255,240);
	public static Color Floralwhite = rgb(255,250,240);
	public static Color Greenyellow = rgb(173,255,47);
	public static Color Yellowgreen = rgb(154,205,50);
	public static Color Olive = rgb(128,128,0);
	public static Color Darkolivegreen = rgb(85,107,47);
	public static Color Olivedrab = rgb(107,142,35);
	public static Color Chartreuse = rgb(127,255,0);
	public static Color Lawngreen = rgb(124,252,0);
	public static Color Lime = rgb(0,255,0);
	public static Color Limegreen = rgb(50,205,50);
	public static Color Forestgreen = rgb(34,139,34);
	public static Color Green = rgb(0,128,0);
	public static Color Darkgreen = rgb(0,100,0);
	public static Color Seagreen = rgb(46,139,87);
	public static Color Mediumseagreen = rgb(60,179,113);
	public static Color Darkseagreen = rgb(143,188,143);
	public static Color Lightgreen = rgb(144,238,144);
	public static Color Palegreen = rgb(152,251,152);
	public static Color Springgreen = rgb(0,255,127);
	public static Color Mediumspringgreen = rgb(0,250,154);
	public static Color Honeydew = rgb(240,255,240);
	public static Color Mintcream = rgb(245,255,250);
	public static Color Azure = rgb(240,255,255);
	public static Color Lightcyan = rgb(224,255,255);
	public static Color Aliceblue = rgb(240,248,255);
	public static Color Darkslategray = rgb(47,79,79);
	public static Color Darkslatenavy = rgb(47,47,79);
	public static Color Darkslatered = rgb(147,47,47);
	public static Color Steelblue = rgb(70,130,180);
	public static Color Mediumaquamarine = rgb(102,205,170);
	public static Color Aquamarine = rgb(127,255,212);
	public static Color Mediumturquoise = rgb(72,209,204);
	public static Color Turquoise = rgb(64,224,208);
	public static Color Lightseagreen = rgb(32,178,170);
	public static Color Darkcyan = rgb(0,139,139);
	public static Color Teal = rgb(0,128,128);
	public static Color Cadetblue = rgb(95,158,160);
	public static Color Darkturquoise = rgb(0,206,209);
	public static Color Aqua = rgb(0,255,255);
	public static Color Cyan = rgb(0,255,255);
	public static Color Lightblue = rgb(173,216,230);
	public static Color Powderblue = rgb(176,224,230);
	public static Color Paleturquoise = rgb(175,238,238);
	public static Color Skyblue = rgb(135,206,235);
	public static Color Lightskyblue = rgb(135,206,250);
	public static Color Deepskyblue = rgb(0,191,255);
	public static Color Dodgerblue = rgb(30,144,255);
	public static Color Ghostwhite = rgb(248,248,255);
	public static Color Lavender = rgb(230,230,250);
	public static Color Lightsteelblue = rgb(176,196,222);
	public static Color Slategray = rgb(112,128,144);
	public static Color Lightslategray = rgb(119,136,153);
	public static Color Indigo = rgb(75,0,130);
	public static Color Darkslateblue = rgb(72,61,139);
	public static Color Midnightblue = rgb(25,25,112);
	public static Color Navy = rgb(0,0,128);
	public static Color Darkblue = rgb(0,0,139);
	public static Color Slateblue = rgb(106,90,205);
	public static Color Mediumslateblue = rgb(123,104,238);
	public static Color Cornflowerblue = rgb(100,149,237);
	public static Color Royalblue = rgb(65,105,225);
	public static Color Mediumblue = rgb(0,0,205);
	public static Color Blue = rgb(0,0,255);
	public static Color Thistle = rgb(216,191,216);
	public static Color Plum = rgb(221,160,221);
	public static Color Orchid = rgb(218,112,214);
	public static Color Violet = rgb(238,130,238);
	public static Color Fuchsia = rgb(255,0,255);
	public static Color Magenta = rgb(255,0,255);
	public static Color Mediumpurple = rgb(147,112,219);
	public static Color Mediumorchid = rgb(186,85,211);
	public static Color Darkorchid = rgb(153,50,204);
	public static Color Blueviolet = rgb(138,43,226);
	public static Color Darkviolet = rgb(148,0,211);
	public static Color Purple = rgb(128,0,128);
	public static Color Darkmagenta = rgb(139,0,139);
	public static Color Mediumvioletred = rgb(199,21,133);
	public static Color Midnightblack = rgb(50,50,50);
	public static Color Midnightgray = rgb(75,75,75);
}

uGUIでボタンを設置しても反応しないこと、ありますよね。
最初は反応していたのに、色々と手を加えたら反応しなくなることがしばしばあり、非常に困りました。
Googleで調べてみたらハルシオンシステムさんのブログに原因が書いてありました。
uGUIはボタンとかコライダーがなくても押せるのはいいのですが、ボタンの親にImageとかついてるとそいつが邪魔して押せないみたいです・・・。
【Unity】uGUIスクロールでボタンを作ったんだよ・・:ハルシオンシステムの気ままBlog

ということで、ImageやらTextやらのオブジェクトが邪魔をするようです。
実際に見てみると、確かにそうなっています。

button

Imageがボタンの子要素となっていればいいのですが、ハルシオンシステムさんのブログにある通り親要素のImageが邪魔をすることもあります。
構成を変更してしまえばいいのですが、そういうわけにはいかない場合もありますよね。

そういう場合は、ImageなどのオブジェクトにCanvas Groupコンポーネントを追加して、Blocks Raycastsのチェックを外すと、そのオブジェクトの下に配置されているボタンをタップすることができるようになります。

button2

Interactableも大抵の場合はチェックを外してよさそうですね。
ボタンやスライダー等以外はデフォルトでブロック無効にしてほしいと思ってしまいますが…(^_^;)

相変わらずスキルレベルの低いところであれやこれや悩んでますが、私と同じような初心者の方には助けになる場合もあるかもしれないので、今後もメモ代わりに書いていこうと思います。

Unityを使っていると、Objective-CやJavaなどで作成するよりも簡単にできることが多い反面、今まで簡単に出来ていたことを実現するのが以外に手間だったりして、戸惑うことがあります。
特にUI関連はまったくもっていけていないと個人的には思います。

ということで、今回のテーマは「スクロールした時のみスクロールバーを表示する」です。

確かAndroidでもiOSでもスクロールした時のみスクロールバーを表示するのは簡単に出来たはずなのですが、Unityの場合は、これが一筋縄では行きません(私にとっては)。

ScrollbarにFade Durationという項目はあるものの、これはどうやらスクロールバー自体をクリックしてドラッグした場合などに色を変化させる時間を設定するためのもののようです(詳しくは分かりませんが)。

scrollbar

ではどうすればいいのかというと、これまたいくつか方法があるようです。
例えば以下のページにあるように、ScrollRectを継承した独自クラスを作成するのも、その一つです。

uGUI スクロールしてないときはバーをフェードアウト:Qiita

ただ、私の環境だと上記ページに掲載されているスクリプトは上手く動かなかったのと、エラーを見ても意味がわからなかったので断念しました。

ということで、ものすごく簡易的な方法をご紹介します。
それはScrollRectのOnValueChangedでスクロールバーを表示させるというものです。

scrollbar2

例えばですが、以下のようなメソッドを用意して表示させます。

    public void EnableScrollBar() {
        if (scrollBarEnabled == false) {
            scrollBarEnabled = true;
            scrollBar.SetActive(true);
            Invoker.InvokeDelayed(DisableScrollBar, 1.0f);
        }
    }

    void DisableScrollBar() {
        scrollBar.SetActive(false);
        scrollBarEnabled = false;
    }

表示した後は一定時間後に非表示に切り替えます。
ここではゲームがポーズ中の前提なので、前回の記事でご紹介したInvoker.csを使用しています。

実際に動いているところは以下の動画をご参照下さい。



本来はフェードアウトのアニメーションを実行すればいいかもしれませんが、面倒だったので入れていません。 例により、もっといい実装の方法があるかもしれませんので、あくまで参考程度でお考えいただければ幸いです。 

ご無沙汰しております。

久しぶりの更新となりますが、今後しばらくはUnityでの制作のメモを書いていくことにしたいと思います。

さて、Unityでポーズを実現するために一番手軽なのは、Time.timeScale = 0;として再生速度を停止してしまうことです。
ただ、停止中はアニメーションも止まってしまいます。

アニメーション用のメソッドを自前で用意してUpdate()内で実行すればアニメーションすることもできるかもしれませんが、Time.deltaTimeなどが使用できなくなる気がするので面倒くさそうです。

Time.timeScaleを使うのではなく自前でポーズ用の処理を作る方法もありますが、これもかなり面倒です。
なので、timeScaleを使った上でアニメーションさせる方法を紹介します。

まず、普通にアニメーションを行う場合は以下のページが参考になると思います。

 【Unity】時間を止めてもアニメーションさせる:Unity/cocos2d-x開発メモ

AnimatorのUpdate Modeを「Unscaled Time」にするだけなので、とても簡単ですね。
私はAnimatorを全く理解していないので、行き着くまでにものすごく時間がかかってしまいました。

ただ、当たり前の話ですが、この方法だとAnimationとして登録していないものは処理ができません。
いちいちAnimationを登録するのも結構かったるいものですし、遅延して処理を行いたい場合もあると思います。
その際に役に立つのが以下のページで紹介されているスクリプトです。

Unscaled time invoke? | Unity Community

ページ中にも記載されていますが、
Invoker.InvokeDelayed(実行したいメソッド, 経過秒数);
と指定することによって、Time.timeScale=0;になっていても遅延処理を実行することができます。
とても便利ですね。ありがたいことです。

というわけで、若干分かりづらいのですが、実際に使ってみたところを動画にしました。
メニューが表示されている時はゲームがポーズしていますが、メニュー開閉時などにアニメーションしているのがお分かりになるかと思います。



他にも同様の処理を実現出来る方法や、もっとスマートな方法もあるかもしれませんので、そこは調べていただければいいかと思います。

追記)以下の記事でDOTweenによるポーズ中のアニメーション実行について書きました。
コーディングでアニメーションしたい場合は、以下の方法が楽だと思います

 【Unity】DOTweenでポーズ中のアニメーションを実行する。

↑このページのトップヘ