今回の内容は、初心者であるオジサンが、Unityをはじめるとどうなるか、東パソで紹介されたUnityで3択クイズほかを作れるかを検証する動画です。(4-002)
恐縮ですが、テレビ東京放送制作の「東京パソコンクラブ」のunityのパートについて考察するということをはじめました。非公式であります。
1. 「モノを動かす」第24回~第25回
まず今回の目標は、東パソの29話、Unityで3択クイズを作ってみる、です。簡単そうですが、ここまでにどんな苦労があったのでしょうか。
それで円を描くことに。まあ、画像を表示するということですね。
SpriteRenderer 画像は「Sprite」、表示する、は「Renderer」
新たなGameObjectの中にAdd Component、この画面の右下にある・・・まあ、検索で呼べます・・・・ここからSpriteRendererを加える
そして画像である円はUnityのものを使います。
第24回13分2秒で、Assets>Create>2D>Sprites>Circle
第24回13分35秒で、今できたCircleの画像をSpriteRendererのSpriteの項目にドラッグ&ドロップする操作をしていますが、これを「アタッチ」というんですね。
タッチは触る。アタッチ(Attach)はシールみたいに「付ける」という意味になりますね。なんかUnityのプログラミングでは頻繁に「アタッチ」「デタッチ」とかでてきますね。「デタッチ」は反対の意味で「剥がす」「はずす」「引き離す」ですね。
Circleの画像をSpriteRendererのSpriteの項目にアタッチすることでここでの情報連絡ができる。SpriteRendererで今、ここで操作しているのはこのCircleの画像です、というのをできる様にしました。ということなんですね。それで、他のSpriteRendererの項目を動かせばそれに準ずるし、何よりもSpriteRendererが仕事を開始して、画面にこの円の画像が表示されましたね。
第24回13分53秒で、ようやく第24回のテーマ「モノを動かす」ということで、自分たちでプログラミングして新たなComponentを作ってこの円を動かしてみましょう、というとことですね。
それで、自分たちでプログラミング・・・これはScriptですよ。このScriptは「一度作るとAdd Component」で呼び出せるようになる・・・ここはね、大事ですね。この動画でも後半に「Quiz」というオリジナルのスクリプトを作って、それをガンガン使いまわしますので、ここ、ポイントであると思って下さい。
第24回14分37秒
生高橋さんのセリフ、「このTranceformも使いまわしているじゃないですか」これに「確かに・・・」と乃木坂のみなさんの応答
まあUnityはこういう風なことになっているのだと、非常に応用力がある構成になっているんだな、ということがわかりますね。
ええ、表示はSpriteRenderer、この表示を動かすというのは、また別のComponentなんですね。ここでクイズになって、第24回20分19秒でやんちゃんがアイコンで覚えていて、その後、あやてぃーちゃんが口走ったんですね。「Rigidbody」と。そうですか。「Rigidbody」「Rigidbody 2D」・・・いやあ、私は初心者なので「はじめまして」ですけれど。
まあ、Add Componentで「Rigidbody 2D」を追加、すると図はこうなる
第24回21分44秒
それで、今からオリジナルのScript「Player」を作ります、ということで、
使えるようにするには「Player」の中で「public Rigidbody2D rigidbody;」と記入すると。これは「Player」での「Rigidbody2D」とアクセスできる準備なんですね。具体的には、この記入により、第24回22分10秒で、「Player」のコンポーネントの中で、Rigidbodyという欄が新たにできていることがわかります。
ただ、この段階ではまだアクセスの準備をしただけで、「none」空っぽであると表示されています。これがね「None(Rigidbody)」とね、Rigidbodyと表記が見えるので、なんかもうできたように見えるんですけれども、やっぱりNoneの表示があると、空っぽ、つまりアクセスがまだ準備不足であるという状態であると判断することが大事ですね。
準備を完成させるには、Player のRigidbody の項目にRigidbody2Dをアタッチ
第24回22分50秒
velocity 速度の様な意味。移動ベクトルと考えることもできる。
スクリプト「Player」の中で、
「rigidbody.velocity = new Vector2(5.0f,0.0f);」これを記入すると円が右に移動します。
第24回でのスクリプト(Player)

rigidbody.velocity = new Vector2(5.0f,0.0f);
これの解説ですね。
rigidbodyの中のvelocity(速度)の関数に、新たにVector2(5.0f,0.0f)を入れましたという・・・Vector2(5.0f,0.0f)が一つの塊で、最初の5.0fがヨコのx座標、0.0fがタテのy座標
Vector2の「2」は2次元で2個という意味。Vector3ならZ軸もあって3次元という意味になります。
25回目の内容、左右矢印キーを押すと円を左右に動かし、一定の範囲でとどまる。Sample Scene(25) グラビティを0に
さて、最初にif文と!=とかの記号ですね。 !=はプチコン4のBASICでも取り上げていたんですが≠の意味ですね。あと等号は==と=を2つ並べる。単に=が1個の時は代入ですね。まあここは詳しい説明はすぐわかると思うので省略します。
それで第25回14分17秒、キーボードの入力の命令はGetkeyであるという紹介があったので、右へカーソルを動かすキーボードのボタンがありますよね。これは「Keycode.RightArrow」だそうです。ゆえに、「円を、右のキーを押すと右に動く」は
if(Input.Getkey(Keycode.RightArrow))
{
rigidbody.velocity = new Vector2(5.0f,0.0f);
}
まあ、このここの最後、セミコロンを忘れずにね。
まあ、こうなります。
If文の()内の状態がtrue(正しい)と以下の{}内を実行する。もし右矢印キーを押していないとifの隣の()内がfalse(正しくない)となり、以下の{}内は実行されなくなります。よって、右矢印キーを押したら、円の画像が右に動く、ということになります。
まあ、あと左の時は、LeftArrowで、x座標の5.0fを-5.0fに書き直せば左にもいけるよ、と。
第25回19分50秒ではこれに似たような図がありました。
あと、現在のX座標の位置はtransform.position.xで取得できるということです。
それで第25回22分36秒では
if(transform.position.x>9.6f) 自分の位置が9.6の座標より大きくなったら
transform.position=newVector2(9.6, transform.position.y)
自分の位置を9.6に戻す
という解説がされました。
まあ、これは円が画面の外に出ない様に移動範囲を右は9.6、左は-9.6に留めたい。-9.6については上記の逆パターンで、ということですね。
ええと、このタイミングでいうのもなんですが、補足です。
実はRigidbody2Dというコンポーネントはデフォルト、すなわち初期状態で重力、Gravity Scaleに1が入っていることがあります。

ここを0にすると本編の放送と同じ振る舞いをしてOKということになります。
ちなみにマイナスにすると浮かびます。
動画の22分4秒(完成)

今回のスクリプト(モノを動かす)
Unityの場合、スクリプトのリストだけを完成させても変数や画像の関連付けなどが必要になりますが、紹介しておきます。
第24回 Player

2. 「3択クイズ」第26回、まるをつけるまで
はい、ここから後半、第26回から第29回の「オリジナル3択クイズ」の作成となります。
ええと、まるとバツの画像はAssetsフォルダの中で直接作っちゃいました。ここで何か操作すると、ええと、ここでAssetsフォルダの中身を表示していますので、もうありますよね。まるとバツの画像が。
次に背景の色を決めますね。
MainCameraからBackground
GameobjectとしてCanvasを作成 マウスでクリックしてUI>Canvas
第26回15分59秒
Canvasを使う時は、これ絶対「UI Scale Mode」とあやてぃーちゃんが言ってました。まあ、これは項目の方なんですが、その、Canvasを作った時に登場するCanvas Scalerというコンポーネント、その中の「UI Scale Mode」、この項目の中、この中から「Scale With Screen Size」に変更する、という話ですね。デフォルトの「Constant Pixel Size」のままだと都合が悪いと。UIはユーザーインターフェイスで、まず今回のクイズは「画面いっぱいに使う」ということで、いろんなUIでも同じ「画面いっぱいに使う」という仕様にしたいのなら「Scale With Screen Size」にしておくと、UIごとに違いが起きない、ということですね。
参考サイト https://docs.unity3d.com/ja/2022.3/Manual/script-CanvasScaler.html
第26回16分27秒
CanvasにカーソルをあわせてUI>Text、つまりCanvas の下にテキストを作ります。
僕の環境でしたら、Text(TMP)つまり、TextMeshProでしたね。テキストメッシュプロ
2019年ころからUnityで標準になったそうです。
参考サイト https://yurinchi2525.com/20230110textvstextmeshpro/
まあ、テキスト効果でグレードアップしたもので、従来のテキストとは拡大しても滲まないなどの細かい違いがあるようですが、まあ普通に使えるみたいです。で、この後ね、テキストメッシュプロであったために、日本語で苦労するんですが、まあそれはこの時点で漢字を使用していなかったので全然気づかなかったんですね。
まずは問題文の作成。
次にボタンの設置とその中に表示する選択肢の文章の作成です。
第26回17分32秒
「Button」とその子要素に「Text」を設置することで、ボタン上の文字が設定できる。
この様にすると、Buttonの表示位置を移動すると、その上のTextもズレることなく追従して表示位置を移動できるようになる。
親子関係を考慮して、Canvasの下にButton、その下にTextのオブジェクトを作成します。
大きさとか文字の太さとかの好みの設定は、Font Sizeとか、まあ、わかりやすく表示しているので、これは見ればわかると思います。
Buttonにカーソルを合わせて
Duplicate(複製)をすると、楽に3つのボタンが作成できます。
次の目標は「正解すると、まるが出る。」です。
そのための準備として「とりあえずボタンを押すと、まるが出る様にする。」をまず目指します。
第26回18分27秒のところ。これ、Imageで、オブジェクトのImageの中にコンポーネントのImageがある、名前がダブっていると慣れるまで大変ですよね。これ、この後、オブジェクトの方は、「MaruImage」と「BatuImage」というわかりやすい名前にしました。コンポーネントの方、これは名前は変更できませんね。それで、ImageコンポーネントのSorce Imageの項目に、まるい画像をアタッチする。まあ、登録して、Unityに、「この画像だよ」と登録する感じですね。
第26回18分35秒のところ。ここは第26回のポイントのところでしょうね。ええと、「このままではマルが表示され続けるので・・・・」
オブジェクトそのものを有効にするかどうかのところ、この、Inspectorのすぐ下、ここは今カーソルにあるオブジェクトの管理や情報を示しているところで、その下が、その支配下にあるコンポーネントの集団、まあ、こっちでなくて、Inspectorのすぐ下の今カーソルにあるオブジェクトの管理や情報を示しているところ、ここのチェックボタンをはずすことで、わざわざオブジェクトを無効にすることで、画像を見えなくする、という方法ですね。そしてクイズに正解すれば有効にしてマルを表示する、ということです。
なので、最初は無効にして、マルの表示を消す。
第26回19分9秒のところ。ここも面白いところですね。今まで、スクリプトというプログラミングをしてコンポーネントを作っていたのですが、その作る場所に関係する話です。親子関係みたいな。
今回はCanvasに並行して別のGameObjectを作り、その中の子でQuizというスクリプトを作るとCanvasの中でいつでも呼び出せる様になる。まあ、Canvasの中で作ってしまうと、親子の関係上、子がたくさんいますからその子であるボタンにそれぞれ判定を別個に作る必要がでてくる。それよりも、Canvasと対等な立場のGameObjectを別に作り、親を通してその子であるボタンへの判定は共通していくので1個で済むようになる、ということです。

新しいスクリプトのQuizの中身。

ここで行いたいのは、Maru()という関数、これをvoid、ええと空っぽという意味ですが、Returnが要らない、戻り値が無いという意味の方が強いです。関数の宣言ではあります。その数値でなくて、画像やメッセージを表示するだけ、アクションを起こすだけの関数であるので、そこにさらに計算とかをして結果を持ってくる、ということはしない、ということなんですね。
なんか説明が下手ですね。
関数と変数ってもうなんか、ごっちゃになりそうですけれど
まあ、ここでね。さらにBASICの話をするのもなんですが、BASICだと、DIMとかで変数の宣言をしますね。この動画シリーズでは関数の宣言は、あんまりやってこなかったんで苦しいところもあるんですが、DEFとかでね関数の宣言を使うこともありますね。まあ、このイメージで大体あっているんですけれども、
とりあえず、変数はね、みなさんざっくりとはわかると思うので、関数を少し深く話しますね。
普通に関数って言ったらこれもそうじゃないですか Y=X+1
これは関数なんですね。



ここのサイトでは、関数と戻り値の有無、引数(変数)の有無で整理できています。
ざっくりというと、このY=X+1の例では足し算をする処理をしている、+(プラス)、「処理方法」と考えちゃっていいんです。関数は数学では「xの値が決まるとyの値が1つに決まる関係」と定義されています。関係。関係がメイン。数値ではない。だから戻り値が無い、というのもある。戻り値がある、というモノもあるのですが、
まあ、このサイトにある分岐の図から、今回の話にかかわるvoidの部分を抜き出すと・・・

voidと関数を宣言すれば、それは戻り値が無い関数である。うーんとね。この動画で、こんなところで止まっちゃうと進まなくなるので、
変数は?この単体ですね。そのXなり、Yなり、Aなり、Bなり、そのなんか値が一つ入れられるハコみたいな感じですね。ここで変数は値が変化するデータという言い方もあるんですが、大体変数1個に数値1個なんですが、この後GameObject型という、もう配列と考えた方がいいくらいデータの塊のものも変数っていうんですよ。まあ、これは後で話します。
すなわち、voidは関数の宣言、うん、voidの後に続く名前は関数であると。関数は処理と考えることもできる、ということから、処理の宣言ですね。
この最初から書かれているvoid Start()も開始時に{}の中の命令を無条件で行う処理ですね。(でもこれはあらかじめ処理内容が用意されている関数だな)
これをpublicで作ります(publicというのは普通には公共ですが、おおやけ、つまり「みんな使える」「みんな知っている」に近いですね。いろんな場所で使えるようにする、ということで)public void Maru()となる訳です。この{}の部分の命令を呼ばれたら処理します。
どうやって呼ばれるかというと、後でButtonのコンポーネントを別に作るので、クリックすると呼ばれて実行、ということになります。
Maru()とは別に、全部小文字のmaruという変数。ややこしいですね、関数ではなくて変数を作るんです。
第26回20分18秒では、見えていない。ええと後で、今から話す変数が追加されるんですけれども、全部小文字のmaruという変数。public GameObject maru;が必要になりますね。これは、ちょっと第29回の話に一旦とびますが、第29回12分8秒、本当に急ですけど、ここで変数の話をしています。そう。変数と関数。ごっちゃにならないでくださいね。今度は変数の話です。
int型は整数、うん。float型は小数も扱える、となっていますが、まあ、要は実数ですね。そして文字はこのさらに後で話になるんですがstring。うん、ここまではBASICとそんなに変わらない。で、画像などがGameObject型と言っているんですね。この、全部小文字のmaruという変数。public GameObject maru;でGameObject型で宣言しています。
これね、ややこしい
これね、型の説明なんですよ
GameObject | GameObject (ゲームオブジェクト) は、Unity のシーンで使用される基本的なエンティティです。全ての GameObject は、名前、シーン内における位置と角度のトランスフォーム、そしてコンポーネントのリストを持っています。 |
なんか、配列みたいに変数を沢山持っていて、GameObjectに関するデータをまるごと抱えている。
でもこれはVisual Scriptingちょっとまた違うやつの説明ということですが、そんなに違っていないと思います。
ちなみにintは
Integer | integer (整数型) は、小数位を持たない数値です。 例えば 3 や 200 です。 |
第26回20分53秒では、見えてますね。7行目に「public GameObject maru;」

それで、この場合の全部小文字のmaruというのはGameObjectの管理部分にかかわる変数ですので、これにSetActiveという命令をつけた次の命令文
maru.SetActive(true) これは、引数Maru()にセットしたImageのGameObjectを有効にする、ということで、
ちょっと、戻る。Imageには、マルの画像をアタッチしていましたね。
それでfalseになって消していた。
さあ、ここから新しい作業となるのですが、先程のScript(Quiz)を完成させると、そのコンポーネントでMaru()関数の引数の欄が現れます。
そこで、GameObject内でScript(Quiz)のMaru関数にImageをアタッチして情報伝達させます。
さっき、空のオブジェクトの中にScript(Quiz)を作る、といいましたが、このあたり、変なところにScriptを作るとMaruの項目が表示されませんねえ。
そして、第26回21分15秒、ここでOn Clickですね。
ここは、僕の方はQuizのスクリプトが入ったGameObject、これ、GameObjectという名前のままにしていたんですね。なんかそのわかりやすいかな、と思って。それで、第26回21分15秒のRuntimeの下のところ、Quizって見えているんですが、はじめ、Scriptの方をいれていたんですよ。これ混乱しました。このButtonのコンポーネントのOn Click()の項目にはGameObjectをもってこないといけない。GameObjectごと「マウスでクリックしたら動かすオブジェクト」をもってこないといけない。コンポーネントではおかしい。
ここまでで第26回終了ということです。
ちなみに本編ではこの状態でクイズを行っていましたが、
第26回21分17秒で「正解のボタンにOn Clickで設定する」と佐藤璃果ちゃんのナレーションが入りますね。だから、誤答のボタンにはOn Clickの設定をしなければ、マルは表示されませんので、これで普通に3択クイズはできますね。
3. 「3択クイズ」第27回、ばつをつける、「次へ」のボタンを設定するまで
27回目の内容、バツバーション追加
26回の内容から、全てのボタンでマルが表示される様にOn Clickを一旦設定してですね、それから前回の内容のスクリプトQuizでの Maru()の関数とmaruの変数ですね、これのバツバージョンを追加、すなわちBatu()の関数とbatuの変数を追加します。
第27回9分28秒のホワイトボードにはこう書いてますね
1 Quizに関数を作る
void Maru()みたいなやつ public void Batu()
{
・・・
}
2 batuの変数を用意する public GameObject batu;
3 batuのactiveをtrueにする batu.Setactive(true);
4 BatuImageを作る ここからUnity Editor
5 まちがえのButtonのOn Click に
Batu(オブジェクトの方)を登録
もちろん正しいボタンは前回のままMaruにしておく
6 QuizのBatuの変数に
BatuImageを入れる(アタッチ)
第27回11分43秒、生高橋さんが、次に「バツでもマルでも答えたら「次へ」のボタンが出てくるようにしたい」と言いますね。それで、ここら辺は繰り返しですね。他のボタンと同じ様にオブジェクトのCanvasの下で、UI>Buttonを作成して、まあ僕は名前を「Button(NEXT)」にしました。
それで、文字を「次へ」と
ぎゃー!
に・・・日本語が出ない・・・困った。
Text(TMP)つまり、TextMeshPro(テキストメッシュプロ)でしたね。2019年ころからUnityで標準になったそうです。
それで、日本語対応にしなければならない。どうせセッティングするなら、なじみ深い「けいふぉんと」でも使えるかな?と考えたんですが、ええ・・・・余談ですが、ゆっくり動画でなじみの「けいふぉんと」・・・あれアニメの「けいおん!」から来ていたんですね。まあ、本当に余談ですが、あんまり知らないで使っていました・・・
でもね、できるんですよ。サイトで情報を探しました。
[Unity] Text Mesh Proで日本語を表示する方法

まあ、サイトの方で扱っていたフォントは「Noto Sans Japanese」でしたけど、まあそれは好みで大丈夫ですね。たぶん。
Asstesフォルダの下、>TextMesh Pro>Fonts Fontsというフォルダが他のフォルダと同じ様に置いていますので、ここに「けいふぉんと」をコピーしておいて、
Unityの方が日本語になっていますが、
編集>プロジェクト設定>Text Mesh Pro>設定 というのがあるので、ここで「けいふぉんと」を設定します。でもこれだけでは不十分で、
このサイトの情報に従います。
[Unity] Text Mesh Proで日本語を表示する方法

Window > TextMeshPro > Font Asset Createrで開きます。
以下の設定をします。
・Source Font File:フォルダに追加したフォントデータ
・Sampling Point Size:Auto Sizing
・Packing Method:Fast
・Atlas Resolution:8192,8192
・Character Set:Custom Characters
・Custom Character List:日本語データから
japanese_full.txtのデータをコピペ
この「日本語データからjapanese_full.txtのデータをコピペ」。これは上記サイト([Unity] Text Mesh Proで日本語を表示する方法)の中からリンクで移動したサイトの先にあるデータをコピー&ペーストして行います。
あと、このサイトの下の方に、フリーズとか処理落ちが発生するのだったら、データに余裕をもたせるPadding の値を8にした方がいい、というコメントがありましてね、僕もそうしていますね。これもね、この変換の処理時間長かったですね。Atlas Resolution:512,512なら早かったのですが文字がぼやけてダメ。サイトで紹介されている通りAtlas Resolution:8192,8192なら、けっこう・・・ううんと、ここに、2054389.85ms、つまり、約34分かかりましたね。
これで、みごとにきれいな日本語「次へ」になりました!ああ、よかった。
第27回12分30秒
次へのボタンを出すには
弓木ちゃんが答えた「nextButton.Setactive(true);」これを
Maru()、Batu()にそれぞれ追加
動画の53分32秒

Quiz(スクリプト)には
上の方に public GameObject nextButton; の変数宣言
下の方に public void Next() { } の関数宣言
次へボタン追加のところ。この場合Imageでなくて、ボタン表示するから、「次へボタン」のオブジェクトをアタッチ
この状態では、ボタンを表示しただけの状態なので、
別のシーンに飛ばす、ということで2問目に行くと。
1問目はもちろん保存して、Save Scene AS….
第27回16分44秒
これ、僕の前回の動画とは別の所から「Save Scene AS…」をだしてますね
2問目として別の名前で保存
ここで
1問目を 3taku(27_1).unity
2問目を 3taku(27_2).unity
としました。
そして、シーンを飛ばす処理(全3ステップ)
(ステップ1)第27回17分30秒での、Quiz(スクリプト)の参照、これ、「using ディレクティブ」っていうんですね。それの、別のシーンに飛ぶというプログラム
using UnityEngine.SceneManagement;
これを上部に追加
(ステップ2)次へボタンの関数 Next(){}には
SceneManager.LoadScene(“ファイル名”)
僕の場合は
SceneManager.LoadScene(“3taku(27_2)”) ←拡張子unityはいらない
(ステップ3)
FileのSaveの下の方にある「Build Settings」これを選択し、利用するシーンを
登録する。
あと問題作り。他の問題の背景とか文章とか。しかし3問目は・・・
これは全部2問目に飛んでいるんですね。
4. 「3択クイズ」第29回、完成
これで27回目は終了して、次は28回目の内容なんですが、別のゲーム、どうぶつタワーの回でありまして、ええ、飛ばします!
そして29回目になります。本編は3択問題のプログラム中級編ということで、27回目の続きになります。これまでの仕様で、3問作ると、全部2問目に飛んでしまうんですね。これはプログラミングで作ったオリジナルのスクリプトのコンポーネントQuizが他のシーンでも使えるからなので、ファイル名が固定になると不都合が起きている、ということです。
僕もね、最初、これがよく理解できていなくて2問目で3問目に飛ぶようにしてたら、今度全部3問目に飛ぶようになるんですよ。全部のシーンで共通しているから。
それで、中級編として、まずファイル名を文字の型、string、
string型のファイル名を保存する変数を設定して、
それを引数としてならば別々のファイル名に設定できるのでうまくできる、ということなんですね。
第29回16分8秒
11行目に public string ScnenName; ScnenNameという文字型の変数を作成
24行目 SceneManager.LoadScene(“3taku(27_2)”)
これを
24行目 SceneManager.LoadScene(“ScnenName”) に変更
ScnenNameが引数として聞いているので、好みの問題のファイル名の文字列を入力する。拡張子はいらない。
完成!
実行結果
動画の1時間7分55秒

動画の1時間8分1秒

動画の1時間9分21秒

今回のスクリプト(3択クイズ)
Unityの場合、スクリプトのリストだけを完成させても変数や画像の関連付けなどが必要になりますが、紹介しておきます。
第29回 Quiz

コメント