ゲームプログラミング/Unity
- ※ ページ作った人が、これから「Unity勉強しよう」と思ってこのページ作ったあとにUntyをいじり始めてみたら、、なんだかコンパイルに凄い時間(30分以上)掛かってしまいました。なので、現状ではこのページの著作を放棄しています。パソコンのスペック(メモリ2GB)が足りないのかハードとの相性が悪いのか(2012年くらいに購入したPC)、他の原因なのか、原因は分かりません。
だから読者でもしUnityに詳しい人がいたら、どうぞ躊躇なく、上書きしてしまってください。そっちのほうが助かります。
セットアップの手順[編集]
- ※ wikiの都合上、画像が不足してますので(仮に画像投稿しても、バージョンアップで使えなくなることや、画像の著作権の問題が複雑なので)、外部の解説サイトの画像なども併用してください。
Unity は、Windows か mac OS で使わないと、挙動が不安定です。 たとえば実際に LInux の Fedora 33 でインストールしようとすると、 Unity Hub まではインストールできるのですが、Unity をインストールしようとする段階で、容量が余ってるのに容量不足などのエラーメッセージが出て、インストールに失敗します。(2021年1月24日 に Fedora33 でインストール失敗を確認。なお、UnityHub ダウンロード直後の UnityHub.AppImage の実行は、実行アインコンを右クリックし「アクセス権」のタブで、チェックボックス「プログラムとして実行可能」にチェックをいれれば、あとはアイコンのダブルクリックでUnityHubを起動できます。)
なので、本ページでは主に、Windows版のセットアップに関して述べます。
Windows版のUnityの使用には、まず、事前に .NET Framework の最新版と、ひとつ古いバージョンをインストールしておく必要がありそうである。
Windows版の Unity は、 .NET Framework の機能を間借りしているようである。(Unityインストール時に、勝手に .NET Framework の Windows Update が出たりするので。)
たとえば2020年4月現在の時点では、.NET Frameworkの最新版は ver 4.x 台だが、
Unityは ver 3.0 台を部分的に用いているようである。
インストール時に公式サイトでのアカウント作成が必要だが、
グーグルアカウントでもアカウント作成できるので、
グーグルアカウントでUnityアカウント作成するのがラクチンである。
unity のインストールや起動には、けっこう時間が掛かる。 ときどき、デスクトップを見に行こう。Unityのロゴ画面ウィンドウが表示中なら、 まだバックで作業中である。
入門プログラム Hello World[編集]
- ※ プロジェクト作成のあたりで、2Dか3Dかモバイルか、どんな用途のプロジェクトを聞かれる。とりあえず2Dか3Dを選ぶのが入門的である。
- 本ページの以降の解説では、2Dを選んだとして解説する。3Dやその他を選んだ場合とは、操作が多少、ちがっている可能性がある。
さて、インストールに成功して、プロジェクト画面が出るようになったら、
その中にあるProjectパネルにある項目「Assets」にマウスカーソルを合わせて左クリック。(メニューが表示されない。2023年7月25日に確認。)
表れるメニュー欄から「Create」→「C# Script」をマウスで選択。
※ つまり、まず「Create」にマウスをあわせてクリックすると、続いて表れるサブメニュー欄に「C# Script」があるので、マウスで選択すればいい。
すると、Assetsフォルダ内にC#コードのテンプレートが作成される。「NewBehaviourScript.cs」みたいな名前がついていると思うので、それがテンプレートである。
まだ、テンプレートに何の追記もしてないので、これに命令文を追記する。
Assetsをクリックした直後なら、
プロジェクトパネルの隣に、アセット内部の構成パネルがあるので、その選択フォルダ内のアイコン一覧に、 C#のアイコン画像でスクリプト新規ファイルが追加されているので、そのC#アイコンのあるファイルをクリック。
すると、Visual Studio などのエディターが立ち上がるので、そのスクリプトを編集すればいい。
- 編集前
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class NewBehaviourScript : MonoBehaviour
{
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{
}
}
編集後
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class HelloTest : MonoBehaviour // ここも必要に応じて変える
{
// Start is called before the first frame update
void Start()
{
Debug.Log("Hello World"); // ここに追加
}
// Update is called once per frame
void Update()
{
}
}
のように更新して保存する。
Visual Studio 側で実行しようがF5を押そうが、何も起きないか、まったく違う動作が起きるので、Visual Studio 側では保存より後のことはしなくていい。
class名はファイル名と同じ(ただし拡張子は抜き)でなければならない。
なので
public class NewBehaviourScript : MonoBehaviour
の 「NewBehaviourScript」 の部分をファイル名に変更する。
たとえばファイル名が「HelloTest.cs」なら、クラス名を「HelloTest」に変更しなければならない。そうしないとUnityがコードを認識せず、あとで再生ボタン を押しても全く「Hello World」が表示されない。
(なお、上記ファイルを編集・保存した時点では、まだ再生ボタンを押しても、hello World は表示されない。)
その後、unity側画面の左上にあるだろうHierarchy ウィンドウのほうで、これから目的として GameObject を作成するために、
Hierarchy パネル内で右クリックして
「Create」→「Create Empty」を選択。(Createを右クリックすると出てくるCreate Empty項目をクリック。)
- (※ なお、2023年現在、右クリックで出てくるメニュー一覧で、直接に「Create Empty」を選べる。)
そして、先ほど作成したC#ファイル(HelloTest.cs のような名前のファイル)のアイコンをマウスドラッグで(標準設定なら画面左側にあるだろう)GameObjectまでドラッグすると、
自動でインポートしてくれ、画面にウィンドウメッセージで Importing とか出てくるので待機。
このインポート作業をunity用語で「アタッチ」という。
さて、デバッグログはコンソール欄でしか見られない。
Unityのコンソールパネルの場所については、
画面左下のProject パネルのタブの真横の、コンソールのタブがあるので、
そのコンソールのタブをクリックして、コンソール欄を開けばいい。
もし無ければ、画面上部の「Window」メニューの「Panel」の先に「Console」があるので、それをクリックすればコンソールウィンドウが追加されるはずである。
画面上部の右側に再生ボタン があるので、ソレをクリックすると、
プログラムを実行する。
すると、コンソール画面に「Hello World」と出ているハズだろう。
なお、画面上部のゲーム画面のデモのほうには、いっしゅん色が変わるが、しかし Hello World はそこには表示されない。ゲーム画面ではなく(画面の左下側にある)コンソール画面を確認すること。
ゲーム画面に文字を表示したい場合[編集]
プレイヤーは作者のコンソール画面なんて見れないので、プレイヤーにも見えるように文字を表示するには、コンソール画面でない方法を使う。
とはいえ、作業は簡単である。
Hierarcy パネル内で右クリックし、「UI」→「Text」を選択。もしTextが無く「TextMeshPro」がある場合、それでもいい。初回の再生時にインポートの質問が出てくるが、許可してインポートすればいい。
これだけで画面に文字を表示できるようになっている。初期設定では「New Text」の文字を表示する。
再生ボタンを押せば、画面のどこかに表示されている(パソコン事情や個人設定などにより、表示位置が微妙に違う)。
(設定・バージョンによっては画面が暗くて見づらいかもしれないが、たぶん、画面のどこかに「New Text」とあるハズ)
このプレビュ-画面では文字が見切れてるかもしれないが(たとえば「w Text」みたいに冒頭「Ne」が画面外に出てしまったり等の可能性もある)、しかし、あとでビルドしたときには「New Text」全体がきちんと画面内に表示されているだろうから(2023年に最新 安定板で実験して確認済み)、現時点では気にしなくていい。
しかし、上記の再生ボタンの作業だけでは、まだビルドしてないので、実行ファイル(windowsなら .exeファイル)になっておらず、ゲームとして配布できない状態である。(再生ボタンは、単にプレビュー的な確認作業でしかない)
ビルドの方法[編集]
画面上部のメニュー欄から「File」→「Build Settings」を選択。
ボタン「Add Open Scenes」を押すと、そのUnity内で開いているsceneファイルを勝手に認識するので、
「Add Open Scenes」を押す。
画面下にボタン「Build and Run」があるので押す。
保存先の選択ウィンドウが開くので、とにかく画面下のほうにある決定ボタンを押す。(そのウィンドウ内で、右クリックで保存先のフォルダをつくることもできる。)
ともかく、成功すれば、ビルドが実行されていく。
すると、勝手にビルドが始まる。けっこう時間が掛かるので(5分くらい)、もし一見して反応が無いように見えるなら、
デスクトップ画面を見に行ったりして、ビルド中の表示欄が出てるか確かめよう。
待ち時間のあいだ、読書するなり、パソコンを使わない別の軽作業とか家事や、職場なら書類事務でもして時間を潰そう。
もし全画面モードで起動してしまった場合、
ウィンドウズの場合なら
Ctrl + Ald + Delete
でタスクマネージャが開くので、そのタスクマネージャを使って 自作unityアプリをいったん終了させよう。
さきほどの「Bulid and Run」実行によって、
新たにファイル
- New Unity Project.exe
- UnityCrashHandler32.exe
- UnityPlayer.dll
のようなファイルが、ビルド保存先(たとえばホームファイル内に(プロジェクト作成時に)自動作成された作成された「My Project」フォルダ内のサブフォルダ)に加わっているハズだ。
ビルド保存先を忘れてしまった場合、もう一度ビルドの設定の途中までの操作をしてみて(ビルド前に途中でキャンセルすればいい)、場所を確認すればいい。
バージョンによって、ハンドラが32ビットではなく64ビットなど、若干の変更はあるかもしれない。
この3つのファイルを丸ごとコピーして、1つのフォルダに入れたものを、ゲームファイルとして配布すればいい。 配布時には、 フォルダ名をゲーム名にしたり、「New Unity Project.exe」に相当する実行ファイルの名前をゲームのファイル名などに変更しよう。
- 全画面でないウィンドウモードでビルドする方法
ただし、上記のまま実行しても、全画面表示になってしまい、とても不便。
なので、ウィンドウ「Build Settings」の左下にあるボタン「Player Settings」をクリックして、
自動で開かれるウィンドウ「Project Settings」にある 項目「Resolution and Presentation」(右下のほうにある)に、 フルスクリーン化をしている「Fullscreen mode」に関するボックスがあるので、
このボックス内容を「Windowed」に変更する。
特に決定ボタンなどは無いので、設定が終わったら、右上の「x」ボタンでウィンドウ「Project Settings」を閉じる。
このあと、ビルドしなおすのを忘れないように。
キーボード入力[編集]
まず、
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class HelloTest : MonoBehaviour
{
// Start is called before the first frame update
void Start()
{
Debug.Log("Hello World");
}
// Update is called once per frame
void Update()
{
}
}
の void Update() 関数のほうのブロック内に、起動後の処理を書くので、キーボード入力の処理もこちら void Update() 関数のブロック内のほうに書く。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class HelloTest : MonoBehaviour
{
// Start is called before the first frame update
void Start()
{
Debug.Log("Hello World");
}
// Update is called once per frame
void Update()
{
if (Input.GetKey(KeyCode.RightArrow)) // この4行が追加
{ //
Debug.Log("migi"); //
} //
}
}
のように書けばいい。
Unity側の再生ボタンを押してテストしてみると、たしかにキーボードの右ボタンを押すたびに、コンソール欄にデバッグ文「migi」が表示される。(時刻が秒単位で併記されるので、押すたびに更新表示されてるのが分かる。)
ついでの確認作業として、上方向など他のボタンを押しても、コンソールの文字は更新されないことも確認しよう。
なお、キーコードについてはUnity公式マニュアル『KeyCode』 を参照せよ。
画像などを移動させたい場合[編集]
コンソールに何を表示したところでゲームにならないので(そもそもアプリにならない)、ゲームにするためには最低限、キーボードからの入力に応じてプレイ画面にある画像を移動させるなどの反応のためのプログラムを作る必要がある。
そうするためには、例えば、単に下記のように、文字列「New Text」の画面表示プログラムを作ったときのコードを加工して、
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class HelloTest : MonoBehaviour
{
// Start is called before the first frame update
void Start()
{
Debug.Log("Hello World");
}
// Update is called once per frame
void Update()
{
// 右方向に移動するための命令文
if (Input.GetKey(KeyCode.RightArrow))
{
//Debug.Log("migi");
gameObject.transform.Translate(0.5f, 0, 0);
}
// 左方向に移動するための命令文
if (Input.GetKey(KeyCode.LeftArrow))
{
//Debug.Log("hidari");
gameObject.transform.Translate(-0.5f, 0, 0);
}
}
}
- (このプログラムの内容は、キーボードの右矢印(→)を押すと画像「New Text」が右に移動して、左矢印(左)を押すと画像「New Text」が左に移動する。)
のように書けばいい。
「○○.transform.Translate(0.5f, 0, 0);」の○○のところはオブジェクト名で、もし初期設定のままならば「gameObject」という名称になっているだろう。
これを書いて保存しただけでは、まだ「New Text」は動かない。
さらに、このコードを、画面左上の hierarchy ウィンドウにあるText(TMP)にアタッチする必要がある。アタッチの方法は単に、ドラッグ&ドロップで完了し、つまり、アセットパネルにある上記のC#コードを、ドラッグ&ドロップでhierarchyウィンドウにあるText(TMP)の上まで持ってきて、そこで通常のドラッグ&ドロップ操作の終わりのようにマウスボタンを離せば済む。
Unity の void Update() 関数は、自動的にコンマ数秒ごとに呼び出されるので、画像更新などをしたい場合には、ここに処理を書いておけば、あとは自動でUnityが処理してくれる。いちいち画像更新の処理命令を追加する必要は無い。
余談だが、「○○.transform.Translate(0.5f, 0, 0);」の、
2項目のtransformは、テキストオブジェクトなどにあるtransform プロパティを意味し、
3項目のtranslateはそれに対する増分命令である。プラスなら増加、マイナスなら減少である。
※ 調査中[編集]
※ 読者にもし詳しい人いたら、書くの手伝って
変数の表示[編集]
ゲーム画面中に変数を文字表示できなければ、たとえばRPGならHPも表示できないので、ゲームになりません。
方法は・・・(※ 調査中)
変数の共有[編集]
RPGの場合、いろいろなモジュール間で、変数を共有する必要があります。たとえばRPGなら、変数 HP は、メニュー画面でもHP・MPの表示で使うし、マップ画面でもマップ移動中のダメージ床などでHPが減少するし、戦闘画面なら戦闘中にダメージを受けてHP現象したり又は回復アイテムでHP回復したりなど、・・・このように複数の別種類の画面でHPは共有されます。
しかし、C#の場合、標準C言語的な意味でのグローバル変数が規格上では存在しません。なので上記HPの例なら、グローバル変数でHPをつくるわけにはいきません。(なお、unityコミュニティでは「グローバル変数」と呼ばれているものも存在しているが、しかし標準C言語のそれとは意味が違う。)
どうすればいいかというと、方法は・・・(※ 調査中)