お米 is ライス

C#やらUnityやらを勉強していて、これはメモっといたほうがええやろ、ということを書くつもりです

Unity4.6で実装されたuGUIを触ってみた【KMCアドベントカレンダー17日目】

この記事は、この記事はKMC Advent Calendar 2014の17日目の記事です。 昨日はporuporuさんの 知見、宣伝、はようせい! でした。

自己紹介

KMC2回生のid:spi8823といいます。
KMC的な活動としてはゲーム製作、DTM(Desk Top Music)(SoundCloudアカウント)をしております。
スピッツが好きです。

前置き

さて、何を書くか困ったものである。

自分は、人より優れている部分といえば、「スピッツについての知識」しかないのであるが、しかし、そんなものをKMCという「PCで何かをする」ということが目的の団体のブログで書いても詮無きことなのである。


そこで、自分がKMCでやっていることと言えば何か、というのを考えてみると、部室で寝るか、クッキーを食べるか、ゲームをするか、という具合で、まったくKMC部員としての体をなしていない。

しかしながら、かろうじてKMC的と言えるものとして、「Unityをいじること」と「DTMをぐだぐだすること」をしていたので、今日は前者の「Unityをいじること」についての記事を書くことにした。

そういえばNFでなんちゃら言うゲームを作ったのだった。

Unityとは?

こんな技術系の記事を読んでいるような技術系の人々にはもはや説明する必要もなさそうだが、
「Unity」とはゲームエンジンやら、開発環境やらが一緒になった、ええやつである。

なにが強いかというと、特に3D周りの機能が豊富なのである。

例えば、Mecanimというシステムを使って、3Dモデルのアニメーションを行ったり、ParticleSystemによって派手なエフェクトを出したり、という具合である。

ここでは、Ubuntuのなんちゃらは指していないのであしからず。

Unityでは開発用言語としてC#およびJavaScriptJavaScriptとは言っていない)を使うことができる。


数年前まで(あるいは今も)Windows及びC#でゲームを開発する、ということであれば、Microsoftが開発していた「XNA」というフレームワークが主流だったのであるが、自分がKMCに入り、C#を学び、いよいよゲーム作ろうか、という時分になってXNAを調べてみると、もうすぐ開発が終了される、ということを知った。

しかし、XBoxOneの発売が決まっており、何らかの形でMicrosoftから開発環境が提供されるはずだ、と思い、もう少し調べてみると、Unityというものと公式に提携する、という話を見て、「まぁ、これやっとくかぁ」と思ってUnityをいじるに至ったのである。


「OculusLift」や「Kinect」、「LeapMotion」などといったハードと連携して、バーチャルリアリティの世界でも活躍している。

uGUIについて

こんな風に、3Dの面では非常に便利なUnityなんですが、UIを作るときはあまり便利とは言えませんでした。

というのも、GUIを表示する方法というのが、Unity本体の機能だけではスクリプトをゴリゴリ書く、という方法しかなく、それもあまりなじみのない手法がとられていました。

したがって、開発者は泣く泣くそれを使うか、あるいは、金のある開発者ならばAssetStoreというUnityの素材を公開、販売しているところで販売されているもの(主にNGUIというAsset)を買うか、しかありませんでした。


そこで、Unity4では新しいGUIの開発方法が提供される、と言いながらUnity4がリリースされたわけですが、リリースされてもなかなかGUIの追加はされませんでした。

それから、そのままマイナーアップデートが続いていき、Unity4.5になっても追加はされませんでした。

そして、Unity5の事前予約が開始したころに、Unity4は新GUIを追加するという名目でリリースしたのだから新GUIは少なくともUnity4で出さないといけない、ということで今年の夏ごろにUnity4.6のベータ版が公開され、先月、正式にリリースされました。
それが、今回取り上げる「uGUI」です。

uGUIでは、スクリプトからだけでなく、ちゃんとグラフィカルにGUIを作ることができるようになりました。
というかGUIがちゃんとオブジェクトになった(旧GUIでは描画する関数と入力を受け取る関数が一緒になった変な関数を使っていました)。


ここからの本題では、NFで出したゲームを作るにあたってそのuGUI(主にベータ版)を触ってみた感想を書いていきたいと思います。

本題

こっからはちょっとUnityをいじってみたことのない人にはあんまりよくわからないことが書いてあるかもしれないです。

作ったもの

ホーム画面です。NF版では削る羽目になりました。
f:id:spi_8823:20141217173837p:plain
戦闘画面です。
f:id:spi_8823:20141217173838p:plain

エディット画面

f:id:spi_8823:20141217174603p:plain
こんな感じになってます。
そうです、こんな感じのが欲しかった!!
もうちょっとクローズアップしてみますと、
f:id:spi_8823:20141217180153p:plain
こうなっております。

ボタンの周りにある三角形のものがアンカーと言って、ボタンを配置する基準となる領域を決めます。
そして、ボタンの四隅にある青いチョボでその領域に対してボタンがどう配置されているかを決めます。
どういうことかというと、アンカーは親オブジェクトに対する自分の大きさの割合を使っていて、下の青いチョボではアンカーに対する相対的な座標を使っています。
こうすることによって、画面の大きさが変えられても、ある程度対応できるようになっている、というわけです。

そして、この機能を実装しているのが、従来のTransformを継承したRectTransformというコンポーネントです。

しかし、この機能があるがゆえに、RectTransformでは座標関係の変数がかなりややこしいことになっていて、スクリプトからもGUIを動かしたい人間としてはここはちょっと改善してほしいなぁ、という感じですね。
このへんについて、詳しい解説サイトがなかったので自分でいろいろいじってみて推測したことを前にブログで書いたので、気になる人はそちらも参照してみてください。

Unityの新しいGUI機能(uGUI)で実装されたRect Transformの仕様メモ - なんかのあれ


Unityは日本語のリファレンスが壊滅的に少なくて非常に辛いです。

イベント管理

GUIではGUIはすべて関数で扱っていた(表面的にはオブジェクトですらない)ので、クリックのイベントや、テキスト編集のイベントなどもすべて関数の返り値として知ることができるだけでした。
つまり、例えばボタンのGUIであれば、

void OnGUI()
{
    bool clicked = GUI.Button(rect, "button");
}

としないと、クリックされたことを知ることができませんでした。
テキストボックスに至っては、現在入力されている文字列すらも保持してくれていないので、

private string text;
void OnGUI()
{
    text = GUI.TextBox(rect, text);
}

という具合に、いちいちめんどくさいことをしないといけませんでした。

しかし、uGUIでUI要素がGameObjectになってくれたので、普通にテキストを保持したり、クリックされた時に特定の関数を呼び出すことが自然にできるようになりました。
で、イベント関数を指定するときのUIが結構賢くて、
f:id:spi_8823:20141217183925p:plain
こうなってます。

左下でシーン上のGameObjectを指定すると、右上のプルダウンからそのGameObjectが持っているコンポーネントと、そのコンポーネントが持っている関数の一覧を見て、そこから登録したい関数を選ぶことができるようになっています。
そして、右下のテキストボックスから、イベント関数に渡したい引数を指定することができるようになっています。
GUIから比較すると見違えるような進化ですね(はじめっからこうしろっていう説もある)。

これらのイベント機能をどうやって実装しているかというと、Canvas(すべてのUI要素の親)とは別に、EventSystemというGameObjectおよびクラスがあり、そいつが入力を見てうんぬんかんぬん、ということをしているようです。
このへんで詰まったところというのが、スクリプトからUI要素のフォーカスを変えようとすると、このEventSystemから変えないといけない、とかがあったと思います。

アニメーション

uGUIでは、UIにアニメーションをさせることも可能になりました。
Unityでアニメーションと言えば、そう!だいぶ前に3DのアニメーションをさせることができるMecanimというものがあると紹介しました。
uGUIのアニメーションにもこのMecanimを使います。
すごい!実際すごい!

例えば、ボタンの場合、
インスペクターはこんな感じになってます。
f:id:spi_8823:20141217192431p:plain
この画面のすぐ下の先ほどのイベント関数を指定するUIが配置されてあります。

いま、Transitionという項目がAnimationとなっていて
その下にNormalTrigger、HighlightedTrigger、etc…というのがあります。
そして、その下にAutoGenerateAnimationというボタンがあって、そいつを押すと保存ダイアログが出てきて、~~.controllerを保存させられます。
それを保存すると、今度はButton(Script)コンポーネントの下にAnimatorコンポーネントが追加されます。
f:id:spi_8823:20141217193236p:plain
このAnimatorなどの詳しいことについては、別途、それを解説しているサイトなどを参照してください。
この状態(Animatorが追加されたGameObjectをヒエラルキービュー上で選択した状態)でメニューバーからWindow→Animationと選ぶと、次のような画面が出てきます。
f:id:spi_8823:20141217193729p:plain
この画面はMecanimを使ったことのある人ならばおなじみの画面ですね!

この画面で、AddCurveと書かれたボタンを押すと、アニメーションをしたい変数を選ぶことができます。
左上のNormal、Highlighted…などで、例えばHighlightedならば、ボタンがハイライトされたときに実行するアニメーションを設定することができます。
そして左から右に時間軸が伸びているっポイ領域で、この時間ではこの値、その時間ではその値、という風に指定し、その間をどのように変化するのか(直線的に変化するのか、Sin関数のように変化するのか、など)を指定することができます。
このあたりも、3Dでアニメーションをするのと基本的に同じなので、気になる方は別途、詳しいサイトを参照してみてください。
ホーム画面では、この機能を使って、ボタンにカーソルを合わせるとボタンの説明が"ニュッ"と出るのを実装してみました。

Gyazo - b3aa6d2d058c65575a615726af3ccb6d.gif


原理的には別にuGUIのほうに実装されていなくても、Mecanimを使えばできたことなんですが、四つの状態について、数クリックの操作でアニメーションを作ることができるのは本当に便利だと思います。
夢が広がりんぐって感じです。

そろそろ終わり

というわけで、Unityでゲームを作った時に使ってみたuGUIの感想とかをグダグダと書いてみました。
Unityを使っているけど、まだuGUIは使ったことはない、という人や、Unityは使ったことがない、という人がuGUIに興味を持ったり、uGUIを使ってみたけどあんまりよくわからなかった、という人に役立ったりしたらうれしい限りでありんす。

明日のKMC Advent Calendar 2014id:hideyaさんの担当で、テーマは「八ツ橋シューティングについて 前編」です。偶然ですが、今日紹介したUnityを使って作った八ツ橋シューティングについての解説記事となっております。ぜひ読んでください。