Unity備忘録18頁目「ゲーム的な処理を作る1」

江上宿六です。

 

前回はシーン上にあるオブジェクトを探して代入し、違う所にアタッチされた

スクリプト内で処理を行うといった事をしてUIの書き換えをやってきましたが

こういうのはUnity独特なやり方という印象ですけど、実際はどうなんでしょうね。

 

では今回の作業ですがその前に、オブジェクトの高さを調整しましょう。

PlaneやCube、カメラやライトのYに5を加えます。 また、SphereGeneratorの

スクリプト内での生成する高さにも5加えます。 これでPlaneの初期高さが5になり

ゲームの初期状態が作る事が出来ました。 無計画だからこうなります。

f:id:y6yegami:20180721114038p:plain

ちゃんと高さが5になっていて、UIが正しく動作している事も確認できました。

 

さて、とりあえず次はスコアを部分に手を付けましょう。 スコアが加算される

タイミングはSphereが破棄される時にし、また、落ちた地点がPlaneから

遠いほどスコアが多く貰えるという風にしてみます。 固定でも良いですけど。

ではまずはGameDirectorスクリプトを編集します。

f:id:y6yegami:20180721160227p:plain

スコアを加算する関数を作りましたが、これはpublicで宣言しています。

こうする事で外部からこの関数を呼ぶことが出来るようになるわけです。

ではこれを呼び出す側のSphereControllerスクリプトを編集します。

f:id:y6yegami:20180721155250p:plain

GameObjectのgameDirectorとplaneを宣言し、Startでそれぞれ代入しました。

前回やった感じの処理ですね。 次に破棄する処理の所です。

f:id:y6yegami:20180721162205p:plain

まぁ、非常に横長になってしまってますが、transform.positionだったのは

Rigidbodyにするように変更しました。 それとどうやら書き方が古かったと

警告が出たので、参照のしかたも少し変えてみました。

 

そこはともかくとして、ベクトルを宣言してやたら長い代入式を書いています。

こうなってしまったのは、高さがスコアというかベクトルの長さに与える影響が

大きかったので、高さを排除するためにy座標を抜いたベクトルを参照して

新たに距離を測れるベクトルを作ろうとしたわけです。

 

そしてgameDirector.GetComponent<GameDirector>().AddScore~、とあります。

前回もやりましたが、gameDirectorにアタッチされているGameDirectorの

スクリプトにあるAddScoreを呼び出しているという感じです。 送っている

(int)vec.Magnitudeというのはベクトルの長さです、int型にキャストしています。

f:id:y6yegami:20180721164042p:plain

実行して色々と操作してみると、Sphereが破棄されるとスコアが加わり、

また、距離によってスコアが変わるのが確認出来ると思います。 やや数字が

小さいので、得られるスコアを2乗してみても良いかもしれないですね。

 

という感じで今回は終わりですが、どうせならAddScore関数をpublicにするより

gameScoreの方をpublicにすれば良いんじゃないかと思うかも知れませんし、

最初はそういう風に書こうとしていましたが、なんとなく直感でそれは駄目だと

思ったのでこんな感じになりました。

 

次回はSphereの接地数によってPlaneが落下していく処理をやりたいのですけど

その前に一つ対処したい問題がありまして、そっちを優先したいと思います。

Unity備忘録17頁目「UIの作成2」

江上宿六です。

 

前回UIのTextの説明をしてきました。 位置を変えたりサイズや色を変えたり

出来るようにはなったと思いますが、どうやって数字を取得したり、書き換えたり

するのかというのが問題ですね。 そこで使われるのが、やっぱりスクリプトです。

配置したTextも名前を分かり易いように変えておきましょう。

 

ではC#Scriptを追加し、GameDirectorと命名して記述していきましょう。

f:id:y6yegami:20180720184618p:plain

だいぶ長ったらしい事になりましたが、大した事はやっていません。

まず注意しなければいけないのは4行目、using UnityEngine.UIとあります。

この一文がないとUIが使えません、普通にエラーになります。

 

7行目、GameObjectを3つ宣言しています。 これらはUIのスコアのテキストと

フロアのテキストと、床のオブジェクトを取得するために宣言しています。

8行目はゲームスコアを宣言しており、スコアはこれを表示する事になります。

 

Start内ではそれぞれGameObject.Findという文が乱発されていますが、

これはシーン上にあるオブジェクトをオブジェクト名で探して取得し、

それらのオブジェクトを扱えたり値を参照出来るようにするものです。

それぞれScore、Floor、Planeのオブジェクトを取得しています。

 

そしてUpdateです。 scoreText.GetComponent<Text>().text = ~とあります。

記述自体は難解なんですけども、これは先ほどFindで見つかったスコアのTextに

その先のテキストを代入してやるというものです。

 

ToStringというのがありますが、これは数値を文字列に変換してくれるもので

こういう数値を文字列として出力するのには恐らく必要なものです。

 

19行と22行で記述が違いますが19行のは"D"とすることで整数として出力し、

22行の"F1"は少数点第一位まで出力するという風になっています。

 

これでscoreTextの方は"Score : "と文字列化したgameScoreを足したものを出力し

floorTextの方は"Floor : "と文字列化したplaneのy座標を足したものが出力される

という事になります。

f:id:y6yegami:20180720200112p:plain

これで実行するとこうです。 現状スコアの処理はありませんし、planeも

初期位置の0なので微妙な感じになっていますが、正しく表示されている

というのは分かってもらえるとは思います。

 

という事で続きは次回になります。 Sphereを弾き飛ばした時に得点を得たり

SphereとPlaneとの接触数が指定の数を上回った時にPlaneを下降させるという

ゲームっぽい処理をしたり、それによるUIの動作について書ければと思います。

 

Blender備忘録46頁目「Blenderでユニティちゃん」

江上宿六です。

 

なんとなくいじってたら楽しかったというか紆余曲折あったので、

何か記しておきたいなあと思っただけの回です。 だいたい受け売りですけどね。

 

まず公式からユニティちゃん3Dモデルデータをダウンロードします。

現在のバージョンは1.2.1のようです。 利用規約に同意してくださいね。

 

ダウンロードが完了したらUnityを開き、プロジェクトを作ったらメニューバーの

AssetsからImportPackage→CustomPackageを選択し、先ほどダウンロードした

ユニティちゃんのunitypackageファイルを選択します。

f:id:y6yegami:20180723180859p:plain

こんな感じでインポートされるものが表示されるので迷わずImportしましょう。

ファイル数が多いのでなかなか時間がかかると思いますが、待ちましょう。

完了したらUnity側での操作はおしまいです。 Blenderを起動しましょう。

Blenderのバージョンは2.79です。

 

メニューバーのファイルからインポート→FBX(.fbx)を選びファイルを選択する

画面になったら、先ほどのUnityのプロジェクトを作った所を探し、そこから

Assets→Unitychan→Modelsと進むと.fbxファイルが見つかります。 それを

開く前にこの画面の左下に注目しましょう、オプションがあります。

ここに少し手を加えます。

f:id:y6yegami:20180723184245p:plain

f:id:y6yegami:20180723184254p:plain

まず大事だと思うのはプライマリボーン軸をX軸にして、セカンダリボーン軸を

Y軸にする事です、受け売りです。 プリセットのまま行うとアーマチュア

変な風に読み込まれてしまうので、ここだけはちゃんと設定しましょう。

 

それとこれは自分の感覚ですけど、リーフボーンを無視と子を強制的に接続に

チェックを入れました。いくつかボーンが読み込まれなくなったり、勝手に

いじられたりするのですが、個人的には一見正しいような感じに見えたので。

f:id:y6yegami:20180723184459p:plainf:id:y6yegami:20180723184518p:plain

だいぶ後者の方がすっきりして見えますし、ウェイトに関してもそれほど問題は

無いように思えます。 たかだか数ヶ月Blenderやっただけの自分が言っても

説得力はありませんけどもね。

 

それよりももっと目立つヤバい状況が立ちふさがっていると思います。

f:id:y6yegami:20180723185107p:plain

何処かの大仏の如き顔が横たわっていますが、ユニティちゃんの顔です。

体と頭、どっちがデカいのかというと、グリッドからして頭でしょうね。

それと遠く離れた所にまつげが転がっていますが、それもなんとかしましょう。

 

まずはこれらのオブジェクトをそれぞれ選択し、位置と回転を0にします。

するとオブジェクトらは一定の位置にまとまります。 ここで一旦放置します。

 

ここでアーマチュアを選択してプロパティシェルフからそれぞれ拡大縮小を

1.0に設定します。 これでなんとなく顔と合うサイズになりました。

体を顔の方に合わせたのには少し理由があるのですが、それについては後ほど。

f:id:y6yegami:20180723194706p:plain

ここから顔パーツのを90度回転させればピッタリとフィットするのですが、

その前にこの顔にはアーマチュアが設定されていないので、顔を全部選択したら

アーマチュアを選択し、Ctrl+Pメニューからアーマチュア変形を選択します。

出来たらX軸を基軸に90度回転させます。

f:id:y6yegami:20180723194842p:plain

ぴったり合わさりました。 アーマチュアを選択して拡大縮小で0.01倍にします。

f:id:y6yegami:20180723195506p:plain

多分これで良い感じのユニティちゃんが出来ました、まだ色はありませんが。

平面を並べてみると、だいたい身長は150cmくらいなんですね。

 

一旦アーマチュア側を拡大し、縮小したのは手間っぽいようには見えますが、

頭側のパーツが意外と多く、それぞれ0.01倍するのが更に手間だと思ったので

サイズを合わせ、アーマチュアに組み入れてから縮小するという風にしました。

 

若干長ったらしくなってきましたが続けます。

あとは色とかをなんとかすれば良いと思いますが、これは簡単です。

既にマテリアルやテクスチャもインポートされているので設定をするだけです。

 

ランプを設置するのも手間なので、マテリアルはシェーディングの所で

陰影無しにチェックを入れます。 別に普通にランプを設置しても良いです。

テクスチャの所の影響パネルの「カ」にチェックを入れてやります。

オブジェクトもマテリアルもそこそこ数はありますが、全部チェックを入れます。

f:id:y6yegami:20180723201822p:plainf:id:y6yegami:20180723202312p:plain

もう殆どユニティちゃんですけど、実に惜しいところがありますね。

チークの所はもちろん、眉毛やまつげもなんか正しくないように見えます。

f:id:y6yegami:20180723202830p:plain

眉毛の所は影響パネルのディフューズの「ア」にチェックを入れると解決します。

あとはチークですが、まず眉毛などと同様に影響の「ア」にチェックを入れます。

f:id:y6yegami:20180723203245p:plainf:id:y6yegami:20180723203505p:plain

引き続きマテリアルの所の透過にチェックを入れ、Z値透過でアルファを0にし、

オブジェクトの所の表示パネルの透過にチェックを入れます。

f:id:y6yegami:20180723203653p:plain

これで麗しいユニティちゃんの出来上がりです。

陰影無しを外して色んな描画をしてみても良いと思いますね。

 

そんな感じです。 あの読み込まなかったボーンも重力的な何かとかでは

大事だったのかもしれませんけど、個人的にはこうやったのが気に入ったので。

 

あとシェイプキーで表情を操作していたのが興味深かったですね。

標準テク本でも方法は書いてあったけど、効率的にはどうなのでしょう。

 

こうやってインポートして、見回したりテクスチャを見たり、ウェイトの

塗り方を見たりする事でその辺りの知識が増えて良かったです。

 

これで三角面が16000、匠の技には恐れ入りますな。

 

追記:

事故ってる所とか間違ってる所を修正しました。

 

追記21/11/27:

言及とかそういうのありましたね、初めてだったので少しアレで。

どうあれ自分が正しいと思う所で妥協するのが精神衛生上正しいです。

 

ここで一つ振り返って思うのはダイナミックボーンとして使われるボーンを

消してしまっているような気がするのはどうだったんだろうかなっていう問題。

揺れるボーンですよね、多分アレは。

Unity備忘録16頁目「UIの作成1」

江上宿六です。

 

UIと言っても場所や状況によって変わってくるのですが、ゲーム等の場合は

メニューやらコマンドの表示みたいな事や、スコアやライフの表示とかそういう

ものを指したりするものだと思います。 最近は後者をHUDとも言いますかね。

まぁ、そういうのを作っていく事になります。

 

Unityにはあらかじめこういうのを作るためのものが用意されています。

早速作っていきましょう。 ヒエラルキーのCreateからUI→Textと選択します。

f:id:y6yegami:20180720131208p:plain f:id:y6yegami:20180720131215p:plain

何か線が表示されたと思いますが、これは線ではなくキャンバスなんです。

画面を引いてみるといかに大きいかが分かります。 ヒエラルキーCanvas

このキャンバスで、その中にあるTextがUIとして表示されるTextです。

地味にシーンビューの角度が変わりました、今までのが変でしたね。

 

こういうサイズになると普通に拡大縮小してオブジェクトを確認するのも

大変です。 こういう時はヒエラルキーのオブジェクト名をダブルクリックすると

そのオブジェクトに注視してくれるので行き来が簡単になります。

とりあえずゲームビューを見てみましょう。

f:id:y6yegami:20180720132940p:plain

画面やや左下にNewTextという文字があります。 これが先ほどのTextです。

位置関係を見ると先ほどのキャンバスと連動している感じなのが分かります。

このTextの位置や文字を編集することでUIを作っていくというわけです。

では選択してインスペクターを見てみましょう。

f:id:y6yegami:20180720134118p:plain

色々と要素がありますが、左上の四角い所を見てみましょう。 これを

クリックするとアンカーを置く位置のプリセットが表示されます。

f:id:y6yegami:20180720134902p:plainf:id:y6yegami:20180720135327p:plain

アンカーというのは、今回で言えばTextが配置される原点の事でデフォルトでは

キャンバス中央になっていますが、上下左右それぞれ設定する事ができます。

使わなくても問題無いとは言え、使った方が便利だと思います。 今回は

右上に配置したいので右上の所を選択します。

 

すると画面上は変わってないのにインスペクターのPosX、PosYが変化しました。

どういう事かというと、これは単にアンカーからの位置を表しているからです。

f:id:y6yegami:20180720135735p:plain

(0,0,0)にするとこんな感じです。サイズ的に丁度見えない感じです。今回は

ゲームビューを見ながらPlaneの右上辺りに配置しました。

 

WidthとHeightはこのテキストの表示されるフィールドのサイズです。

テキストがこのサイズを超えてしまうと(設定次第では)表示されなくなるので

注意が必要です。 その他Rotation、Scaleとありますが、回転と拡縮です。

 

では次にその下の所を見てみましょう。

f:id:y6yegami:20180720140653p:plain

だいたい説明がなくても分かる感じではないでしょうか。

Textが表示する中身で、フォントやフォントサイズ、行間の幅も設定出来ます。

Paragraphの方は左揃えだとかそういうのを変えたり出来ます。

 

HorizontalOverflow、VerticalOverflowが先ほど言ったテキストがフィールドを

超えた時の処理ですかね。 Horizontalの方は横方向にを超えた時の処理で

Wrapで折り返し、Overflowで突き抜けます。 Verticalの方は縦方向ですね。

Truncateで表示がされなくなり、Overflowで突き抜けます。 BestFitにチェックを

入れるとピッタリ収まるようになりますが、好ましい方法とは思えませんね。

 

その他、色とかマテリアルをセットする事も出来ます。 見ての通りです。

f:id:y6yegami:20180720142832p:plain

まぁ、今回はこのように画面上部にフロアとスコアを用意しました。

スコアはともかくフロアなんですが、SphereがPlaneに一定個数乗っている時に

Planeが下降していき、一定の高さまで落ちたらゲームオーバーになると言う

ルールをなんとなく思いついたので、その為の数値を表示する所です。

が、少し別の表示方法を思いついたので次回以降唐突に変わると思います。

 

今回はここまでです。 なんかあまり必要無いかもしれない所まで説明したので

長くなってしまいました。 回跨ぎは想定内です。

Unity備忘録19頁目「ゲーム的な処理を作る2」

江上宿六です。

 

前回言った対処したい問題というのは、なんとなく分かると思うんですけど、

これ二度タッチが出来るんです。 これやるととんでもない速度で飛んでいくので

ゲームとしては放置しておけません。 なのでそこをなんとかします。

f:id:y6yegami:20180722171606p:plain

フラグを宣言しました。 publicにはしません。

f:id:y6yegami:20180722171612p:plain

こちらはpublicな関数で、フラグを立てるSetFlagとフラグの状態を判定する

CheckFlagを宣言しています。

f:id:y6yegami:20180722171617p:plain

Update内です。 フラグが立っている場合はTime.deltaTimeを使って時間計測。

フラグが立って1秒が経過したらフラグを消してます。 Sphere側はこんな感じで

良いと思います。 続けてCube側のスクリプトを編集します。

f:id:y6yegami:20180722173353p:plain

OnCollisionEnter内。 Sphereと衝突した時、この当たったSphereのフラグを

CheckFlagで取得し、フラグが立っていない時に限り衝突時の処理を行い、

SetFlagでフラグを立てています。 これでとりあえず二度タッチを防げます。

 

では次に床に乗っているSphereの数を取得し、数によってPlaneを下げるという

処理をやりたいと思います。 思いついた処理はPlane用にスクリプトを用意し

OnCollisionStayで数を計算するものでしたが、これは上手く行きませんでした。

 

理由としてはこのOnCollisionStay等の呼ばれるタイミングが不定期というか

Update関数の呼び出しとの流れが今一つ噛み合ってない感じなのです。

なので別の方法を考えてやってみました。 とりあえずGameDirectorの

スクリプトを編集していきます。

f:id:y6yegami:20180722195727p:plain

f:id:y6yegami:20180722195731p:plain

Planeに乗っている数をカウントする変数countと、カウントを増減させる

publicな関数2つです。 これを何処で使うのかというと、SphereControllerです。

f:id:y6yegami:20180722201934p:plain

Sphereが接触したらカウントを増やし、離れたらを減らすようにしました。

こうする事で乗っている数を取得する事は出来るハズです。

f:id:y6yegami:20180722201327p:plain

GameDirectorスクリプトの方にカウントを取得出来る関数を作りました。

この値を参照してPlaneを下げる処理を行いましょう。 Plane用のスクリプト

追加して記述していきましょう。

f:id:y6yegami:20180722202944p:plain

もはやこういう関数の使い方も慣れたと思います。 GameDirectorを取得する

GameObjectを宣言しStartでFind、GetComponentでpublicな関数を呼びます。

このカウントが5以上ならPlaneのyを-0.01f移動させるようにしました。

アタッチして実行してみましょう。

f:id:y6yegami:20180722203253p:plain

5個以上乗っかった時から徐々に下がっていってるのが分かると思います。

乗ってる数が増えたら下がるスピードを上げたりするのも良いでしょう。

 

さて、これで想定していた処理は殆ど行えたと思います。 あとは床の高さが

0になった時にゲームオーバーという風にしてやれば、完成と言えますかね。

 

という所で今回は終わりです。

次回はシーンの移動あたりをやります。