Unity初学者の気を付けるべき点
この記事は、UEC Advent Calendar 2021 - Adventar 9日目の記事です。
前日の記事は、Mr.Mountainさんの「身の上話とメンタルヘルス」についてでした。
選択肢を多く持っておく事は安心にもつながりますからね。人生山あり谷ありです。山だけに。
こんにちは、こう(昼飯)です。AdbentClenderにはこう(アマテラス氏)で登録しておりましたが直しました、こう(昼飯)です(以下ブログ主)。
プロフィールはtwitterに書いてありますのでこちらを参照
https://twitter.com/hirumeshikuuya
ブログ主は先日創立記念日だったのにもかかわらず数学演習と物理学概論の試験だったのですが、見事に爆死しましたね。3桁÷3桁の分数の5/2乗を計算しろってどういうことだよ。
はじめに
私のアドベントカレンダーではUnity初学者にありがちな勘違いやジレンマについて話させていただこうと思います。理由は書くネタが無かったからです。
わざわざこの話題を選んだということはブログ主はUnityについての造詣が深いのでは、と読んでる方はお考えになるかもしれません。しかし、なんとこのブログ主、まだUnityをインストールしてから1年もたっておりません。本格的にUnityを始めたのはたったの一ヶ月前です。
そのため、このブログは初心者の為にUnityを学習するにあたって気を付けるべき点を解説する、というよりは今僕がリアルタイムで困っている事をつらつらと書き連ねていく、という形式となっておりますがご了承ください。
前置きが長いのもよろしくないので早速本題に入っていきます。短いので最後までお付き合いください。
Unityとは
Unityとは、Unity Technologiesが開発・販売している、IDEを内蔵するゲームエンジンです。要するにUnityを使えば比較的簡単にゲームが作れます。ニッチなインディーゲームから白猫プロジェクトやポケモンGOなどの超有名タイトルまで、幅広いゲームでUnityが使われています。ブログ主がはまっているAmongUsもUnityで作られています。
以下Unityの概要とAmongUsの布教↓
Unityダウンロードページ
Unityについての分かりやすい説明
AmongUs公式ホームページ
さて、そんなUnityをブログ主が最近勉強しているわけなのですが、何かを習得しようとするとそれを妨げるような落とし穴が初学者の学習を妨害してくる事実は古今東西変わりません。
そんな訳で、Unity初学者がつまずきやすい点や抱え込みやすいジレンマについて、初学者目線から、解説していこうかなーと思います。
では早速本題に。
Unity初学者が躓きやすい点や陥りやすいジレンマ6選
1.Unityってプログラミングでゲームを作る物じゃないの?
Unity初心者が最も抱え込みやすい勘違いと言っても過言ではないでしょう。ゲームを作るというと、どうしてもプログラミングで作るというイメージがぬぐい切れません。実は5割方それで合っているのですが、事情はもう少し複雑です。それにはまず実際のUnityの画面を見ると分かりやすいでしょう。
こちらがUnityを始めて開いた時に現われる画面です。
Unityの画面は主に、
- ヒエラルキーウィンドウ:ゲーム上に出てくる登場人物やキャラクターなどが一覧で出てくる場所。
- ゲームシーン:実際のゲーム上でどうなっているかを見ることができる場所。
- インスペクターウィンドウ:ゲームに出てくるキャラクター等の、現在の座標、貼り付けられている写真、物理的な挙動など、キャラクターについての情報が載っている場所。
- プロジェクトウィンドウ、及びコンソールウィンドウ:ゲームの素材等が置いてある場所。コンソールウィンドウはコードの間違っている部分を教えてくれる等の場所。
と、ざっくりこんな感じになっています。
これが、ゲームの開発が進むと、下図のようになります。
さて、先ほどの④のプロジェクトウィンドウに注目して欲しいのですが、このプロジェクトウィンドウには、Twitterのハッシュタグのようなものが沢山ならんでいると思います。これが何なのかというと、C#Script、つまりゲームのプログラミングの部分です。
このC#Scriptを書くことで、ゲーム上のキャラクターを動かしたりすることが出来ます。
しかし、先ほども述べましたように、Unityではプログラミングの部分を書くだけではゲームは完成しません。Unityでゲームを作るにあたって大事な要素として、プログラミング部分の他にもう一つ、インスペクターウィンドウに載っているコンポーネントという物があります。
これはGameObjectやPrefab(ゲーム上に出てくるキャラクターや敵)に背負わされている情報のような物なのですが、例えば、上のアヌビスのような形をしたキャラクターの例では、Transform,Box Collider,Rigidbodyのようなコンポーネントがインスペクターウィンドウに並んでいます。(図参照)
各コンポーネントの実際の機能としては、
- Transform:GameObjectやPrefabのx,y,z座標、回転、拡大縮小等の情報を担う物。
- Colider:オブジェクトの当たり判定に関する物。
- Rigidbody:オブジェクトに物理的な挙動を加える物。例えば上のRigidbodyの「Use Gravity」の欄にチェックを付けると、オブジェクトが重力を受けたような挙動を受ける。
という仕様になっています。
これらコンポーネントがゲームにとってどれほど大事かは説明するまでもないでしょう。
また先ほど説明したC#Script(プログラミング部分)もオブジェクトのコンポーネントの一つとして扱われます。
ではUnityでScriptとコンポーネントが実際にどのように使われているかどうかについて、自機の操作を用いて説明します。
まず、このゲームのヒエラルキーウィンドウ(先ほどの①)上にjetというGameObjectがありますが、これが自機です。このGameObjectにはTransform(座標や向きを決める)とC#Script(プログラミング部分)のコンポーネントがアタッチされています。Transformには現在の自機の座標の情報が入っています。
次にプログラミングでTransformの値を操作していきます。下図自機のC#Script。
色々ごちゃごや書いてますが大事な部分はここの部分です。拡大個所では、Transformのコンポーネントの値を取得して、それを実際に操作しています。
ここで書かれている"transform.position.x"が、自機のx座標の値です。ここでは、自機が画面内ならカーソルキーを押すと自機の座標(transformの値)が押したカーソルキーの方向に増えたり減ったりします。時機の座標が変われば当然実際の自機もゲーム上で動きます。こうして、
自機が動きました。キモチィィィィィィィィィィィィィ!!!!!!!!!!!!!
この、
- GameObjectやPrefab(ゲーム上のキャラクター)がある。
- キャラクターに、コンポーネントがアタッチされている。
- コンポネントのある値や項目を、プログラミング上で取得・操作する。
- キャラクターが動く
という基本的なステップが分かっていないと、基本的に何をやっていいのか分かりません。Unity初学者はどうしても色々調べてプログラミング側でなんでもやってしまおうとしてしまいがちですが、そのプログラミングも、コンポーネントの値や項目を前提として組まれているので、コンポーネントを使いこなせないと、基本的にゲームを作る事は出来ません。本を読んでも、この本がいったい何をやろうとしているのか、今自分が書いているコードは一体どういう関係で実際のゲームとつながって来るのか、全く分からなくなってしまいます。
Unityをこれから学ぼうと思っている人は、是非上の4ステップを頭に入れてから、学習に臨んでください。
追伸:Unityには沢山コンポーネントがあるのですが、その中で3D,2Dオブジェクトでは基本的に限られたコンポネントしか使いません。これまで「ColliderとRigidbodyしか使えなくて、Unityのほとんどの機能を活用出来てないんだろうな」と思っていたのですが、そうでもなかった(他のコンポーネントはTextやSlider等、UIや特別なオブジェクトにそれぞれ限定して付随するコンポーネントなので)。後、インスペクターウィンドウのコンポーネント選択からNew ScriptでC#Scriptを開いてコードを書いても全く動かないんだけどあれはどういう仕様なんだろう。
2.ゲームを作るのに適しているのは本当にUnityなのか?
これはUnityを始めるにあたって多くの人が抱える疑問でしょう。ゲームをこれから作ろうと思っても、Unityが便利かつ余りにも有名なので、なんとなくでUnityを始める方がほとんどだと思われます。
ブログ主がこの疑問をもったのはちょっとだけUnityの勝手が分かったころでした。先程のスクリプトとコンポーネントの関係が分かった辺りで、ブログ主はこう思い始めたわけです。
「あれ、もしかしてUnityって汎用性あんま高くない?」
Unityはコンポーネントという、オブジェクトの操作が簡単に分かりやすく行える機能が付いているのはいいのですが、それならUnityで行っている事を一からプログラミングで出来た方が将来役に立つ?等と考えてしまう訳です。
Unityを始めるくらいですから、ブログ主には技術職やITへのあこがれが少なからずある訳です。そんな中、Unityの動作原理を理解しないまま使っている事実、ひいてはUnityがプログラミング能力があまり無い人向けの子供だましですらある可能性に、ブログ主は後ろめたさとやるせなさを感じていた訳です。
そんな僕のジレンマは、
「一流の大工は、自分で工具を作れる訳ではない」
「一流の料理人は、自分で調理器具を作らない」
という気付きであっさり解決します。
ようはUnityを使いこなせればいいのです。
今ブログ主はPUN2(Photon Unity Networking 2、ようするにUnityでオンラインゲームを作れる奴)の勉強をしています。それを使えば簡単にUnityでOnlineゲームを実装することが出来るのですが、それを使いこなせたとしてもネットワークの知識や技術が身につく訳ではありません。逆に言えば、ネットワークの知識が無くてもオンラインゲームを作ることが出来るのです。
これからゲームに限らず様々な方面で便利なエンジンが出てくる・若しくは既にあると思うので、それを十分に使いこなせるようになるのが一番建設的では?とブログ主は結論づけました。まずUnityも出来ね―奴が一からゲーム作れる訳ねーだろ
3. サンプルプロジェクトを一通りなぞらないまま始めると大抵躓く
中途半端にプログラミングの知識があったりすると、こうなるのではないのでしょうか。
ブログ主は弾幕シューティングゲームを作りたくてUnityを触り始めたわけですが、それまでは東方弾幕風という、東方っぽいシューティングゲームが簡単に作れる奴で遊んでました。
そのため、「angleの値をだんだんに変えて行って弾幕を~」というように、なんとなくシューティングゲームを作る事へのイメージが出来上がっていました。ブログ主はUnityをダウンロードして何となく基本機能を勉強して、自機が動くプロジェクトを引っ張ってきて、「さぁ!球を自機から発射させるぞ!」と意気込んだのですが、当時のブログ主では全く実現できませんでした。
「球を撃つためには、球のGameObject(ホントはPrefab)をスクリプトの方で指定して、条件分岐で球を自機に持ってくればいいなー」などと考えていたのですが、全くやり方が分かりません。(とは言いつつも大体方向性は合ってる。)
おまけに個々に必要な段階(Prefabの指定、球のコンポーネントの取得方法)等を個別に調べてちぐはぐに実装する始末。その時は人に聞きながらなんとか実装したのですが、もう一回出来るかと聞かれていたら絶対に出来ないと答えていたでしょう。(その時参考にした記事の一つがこれ)
当時の心情をブログ主のツイートが物語っています。
俺はどっちかっていうとUnityやりたいっていうよりやりたいことの為にUnity始めたからとりあえず色々無視して突き進んだけど、そりゃ行き詰る訳だな。
— こう(null) (@hirumeshikuuya) 2021年7月16日
この時質問しに行った人から、「まずは出来上がってるプロジェクトをそのまま写して学べ」と言われたので、言われたとおりにプロジェクトのサンプルを何個かそのまま写しました。すると自分の疑問点がそのまま実装されている部分を次々に見つけ、様々な問題が解決しました。
これからUnityを始めようという人は片意地はらずに、是非お手本のプロジェクトを一から勉強してみてくださいね。
4.スクリプトの分からない部分が、「Unity独特の物」なのか「C#の文法」なのか区別がつかない
先ほどUnityではコンポーネントが重要という話をしましたが、当然スクリプトの重要性も無視できません。そんなスクリプトの、実際に打つコードの勉強をするにあたって、ぶち当たる問題がこれです。
「お前は初めて見るけどUnityの住人なの?それとも俺の知らないC#の機能なの?」
UnityではC#の最初に書くusing(ラテフで言うパッケージみたいな物だと思っているけどどうなんだろ)の項目に、UnityEngineと書く必要が一般的にはあり、これを書くことによってUnity独特の機能が使えます。
つまり、Unityのスクリプトは、C#の元々の文法にUnityの機能が加わって出来ているのです。
そんな中スクリプトで初め見る単語に出会うと、それがUnity特有の物なのか、それともC#由来のものなのか分からなくなります。
使っているのがUnityEngineだけならリファレンスに載っているかいないかで判断すればまだ楽なのですが、何かのアセットをインポートして使っていると、悲惨です。
先ほど述べた通り、ブログ主は今PUN2(Unityでオンラインゲームを作れるアセット)の勉強をしているのですが、その中で新しい関数や機能が出てくると、何が何だか訳が分からなくなります。
Photon公式ホームページ
ブログ主が今参考にしているサイト
僕が学んだ「まずはサンプルプロジェクトより始めよ」の精神に則って、このサイトのプロジェクトを1から写している最中なのですが、その中に出てくるスクリプトが、まぁ悲惨です。
このスクリプトの上部に注目すると、usingにPhoton.PunとUnityEngineと書かれているのが分かります。
これは要するに「このスクリプト内ではUnity由来の物とPhotnPUN由来の物を使うよー」と言っているわけです。
例えば、スクリプトの森の中にブログ主が迷い込んだとします。そこでブログ主は、そこに住む森の住人に出会いました。もちろん今まであった事もありません。ブログ主は彼に名前を尋ねました。
「やぁブログ主の名前はこう(昼飯)。君に名前は?」
ところが森の住人は言葉を発せなかったのです。彼は、恥ずかしそうに僕に名札を見せてきました。
「そうか、君は『Init』って言うんだね!」
さぁ名前も分かった事だし、これから仲よくなろう!となった所で、
お前誰やねん
ブログ主はプログラミングについては条件分岐や繰り返し処理くらいしか分からないプログラミング弱者ですし、Unityについても初心者です。そんな中PhotonPUNという未知の領域を探索中に、急にIsit君に出会っても、「お前誰?」となってしまいます。
これの対策としては、事前にC#についての知識をちゃんと持っておくことで回避できるのですが、電通大に来ると同時にUnity始めたブログ主にとっては、あまり現実的ではないです。これから頑張って勉強していきます。。
5.NullReferenceException
さぁ初学者が出会いやすい落とし穴やジレンマもいよいよ最後です。今までの4っつに比べたらやや具体的な事例です。
”NullRefernceException” Unityを触ったことがある人は、この文字列を見たらほぼ間違いなく苦笑いをするでしょう。Unityでスクリプトを書くにあたって、初学者は様々な様々なエラーに出会います。
例えば、各行の最後に「;」を忘れているとか、
宣言されていない変数を使っているだとか、
等のエラーがありがちなエラーです。
これらのエラーは、スクリプトの変更内容を反映した時点でエラーとして出てくれます。また、(16,48)のように、何行目の何文字目に間違っている箇所があるのかも教えてくれます。さらに、例えば上の例だと" ; expected" 「ここに『;』が入るんじゃない?」等と、平易な英語でエラーの具体的な内容を教えてくれます。
さて、ここで、次のスクリプトを見てみましょう。ボスのHPを表示するSliderにくっついているスクリプトです。
ゲームシーン上のHPバー(Slider)
インスペクターウィンドウにて、HPCSがSliderのコンポーネントとしてアタッチされている様子
HPCS
ここで、16行目の"anubis_head"と書かれている部分のuを抜いて、"anbis_head"としてしまいましょう。スペルミスを起こしているため、コンソールウィンドウにエラーとして出るはずです。ところが、コンソール画面にはエラーは一つも出てきていません。
あれ?と思ってゲームを実行すると、
NullReferenceException
しかも、エラー表示をよく見てください。このコンソール画面によると、スクリプトのエラー箇所は、17行目と24行目にあるそうです。しかし、思い出してください。ブログ主は「16行目の」anubis_headのuを抜いた、つまり間違っている箇所は16行目にあるという事になります。
それなのに17行目と24行目にあると表示される。これは初学者にとっては大問題です。
また、このエラーはGameObject型の変数"Anubis"に値が何も入っていないことが原因なのですが、このエラーには"Anubis"という文字が入っていません。ただ、「NullReferenceException」と表示されるだけです。つまり、具体的にどのようなミスなのかが示されていない訳で、これは初学者にとって、非常に不親切です。
NullReferenceExpectionとは、直訳すると「空っぽ参照例外」となり、つまり参照先のスペルがミスっていると空っぽ判定を受けてゲームが動かなくなるのですが、このエラーは今まで見てきた通り、超不親切です。
一般的なエラーでは、
- エラーがスクリプト反映時にすぐに出る。
- 間違った箇所を指定してくれる
- どのように間違えたのか教えてくれる。
といった仕様になっているのですが、NullRefereceExceptionでは、
- エラーが最初は表示されないのに、実行時にポンッと出てくる。
- 間違った箇所が初学者では探しにくい。
- NullReferenceExpectionとしか言ってくれない。
と言った仕様となっており、超が付く不親切です。
Unity初学者には、スペルミスや写し間違いが付き物です。そんな中、数多のエラーを乗り越えて、「やっとゲームを実行できる!」となった時に実行後急に
"NullReferenceException"
という訳の分からんエラーが出てきたら、はっきり言って心おれます(笑)
ブログ主のこのツイートが、NullReferenceExceptionです。絶賛心折れてますね。
動かした瞬間にエラーが605個出たんだけど、ひどすぎ。
— こう(null) (@hirumeshikuuya) 2021年11月4日
Unityでこれが出てきたら、大体はスペルミスなので、頑張って探してみてくださいね~。
終わりに
さて、今まで初学者がUnityで躓きやすい5つの事(というよりブログ主が躓いた5つの事)を見てきた訳なのですが、何がともあれUnityは素晴らしいゲームエンジンです。
ところで、このUnity、先ほど紹介した通り、AmongUsという神ゲーにも使われているのですが、皆さんアモアスはやったことありますか?
人狼ゲームとアクションゲームを合わせたような画期的なゲームなのですが、あまりゲームをやらないブログ主が珍しくはまったゲームです。月に何回か深夜にやっているのですが、まじで奥が深くて神ゲーです。プレイしたことが無い人でも、一度くらいは動画を見たことがある人もいるのではないでしょうか?これを一度もやったことないというのは、人生を半分くらい損してます。
つまり結論、皆アモアスをやりましょう!
以上で2021/12/09のUECAdventClenderの記事を終わりにしたいと思います。
今日が終わる7分前に記事書き終えるって何?
12/10はユーキさんの記事です。是非ご覧ください。