本投稿は2024年9月時点の内容になります。アップデートにより変更となる場合があります。また環境によって違いがあると思いますのであくまで参考として、ご了承ください。
様々な書籍、ブログや動画を参考にさせていただきました。多すぎて一つ一つは紹介できませんが感謝です。
初心者の自分がUnity ソフトウエアでゲームを作ってみました。とりあえずシンプルなものということでモグラたたきに挑戦です。ゲーム作ってみるかという感じになったときに、いいタイミングで某ゲームのイベントシナリオ内ミニゲームにモグラたたきが実装されていたのでUIとかエフェクトとか、諸々の仕様をぱくって参考にして作ってみましたよ。様々なHowToの中の選択肢のひとつとして、同じ初心者さんの参考になればよいです。
\ チェック /
目次
用語を解説しつつスクリプトにチャレンジしていきます
今回は結構きついです。書いてる本人の頭の中もケイオスでした。なので必要なところだけチェックして読み飛ばしてもらってOK Death!
本記事のポイント
- ゲームオブジェクトとコンポーネント超概要解説、ついでにゲームオブジェクトの名前変更
- スクリプトの作成
- クラス、MonoBehaviourの超概要解説
- スクリプトをコンポーネントとしてのアタッチ(紐づけ)して、実行します
- デバッグログの出し方がわかる
- trasformの罠問題を考える
ゲームオブジェクトとコンポーネント
ゲームオブジェクトって何だろう?
まず前回シーンに配置したユニティちゃんを選択して、インスペクターを見てみましょう。
\ 前回をチェック /
ゲームオブジェクトとコンポーネントの関係をみてみる
- ユニティちゃん(ゲームオブジェクト)を選択
- インスペクターを見ると「Transform」、「SpriteRenderer」という項目が確認できると思います。シーンに配置された物体(ゲームオブジェクト)はこれらの部品(コンポーネント)が集まって出来ています。
- 選択しているついでに、ゲームオブジェクトの名前を変更してみましょう。インスペクターの一番上の欄が名前なので、これを変更します。名前の変更はインスペクター以外、ヒエラルキーでもできます。
ゲームオブジェクトとコンポーネント
ゲームオブジェクトとコンポーネント概要
- GameObject (ゲームオブジェクト) はキャラクター、小道具、背景などを表す Unity の基礎となるオブジェクトです。今回のユニティちゃんのスプライトもゲームオブジェクトです。シーンはこのようなゲームオブジェクトの集まりで構成されます。
- ゲームオブジェクト自体に機能はほとんどありません。コンテナ(箱)のようなもの、もしくは自動車のフレームみたいなものをイメージするといいかもしれません。そこにコンポーネントという部品が付くことで様々な性能、機能が付きます。
- ゲームオブジェクトには必ず空間中の情報を付与するTransformコンポーネントが付きます。
スクリプトを作成してみよう
スクリプトを作成してみましょう。
スクリプトを作成してみよう
- まずはスクリプトを整理するためにプロジェクトに「Scripts」フォルダーを作成しました。
- プロジェクトで 右クリック>作成>C#スクリプト をクリック
- 今回は「Test」名前で作成しました。
- スクリプトをダブルクリックするとVisualStudioが開きます。コーディングして保存するとUnity エディターでコンパイルしてくれます。
コンパイルとは
- Unity プロジェクトではC# プログラミング言語をサポートしているので、基本スクリプトはC#で書いていきます。コンパイルとは人間ベースの言語で書かれたもの(今回はC#という文法で書かれたもの)をコンピューターが理解できる形に翻訳することをイメージしてもらうと良いかもしれません。
クラス継承とMonoBehaviourについて
作成したスクリプトの中身を見てみます。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Test : MonoBehaviour
{
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{
}
}
Unity プロジェクトでスクリプトを作成すると、必ず「:MonoBehaviour」と付きます。
これはMonoBehaviourというクラスを継承した派生クラスだよという意味です。クラスとはオブジェクト指向プログラミングにおいて、オブジェクトの設計図に相当するものです。
初学だと何のことかよくわからないですよね。マケイヌもそうです。なので、ここからは、初心者のマケイヌならではのイメージで書いていきます。
クラスて何(初心者解説)
クラスとは(初心者的イメージ解説)
- ロールプレイングゲームをプレイする方はよくジョブ/クラスてよく聞くと思いますが、そのクラスに近い感じでイメージしています。
- 特定のパラメータやスキル(プログラミングだとフィールドとかメソッド)を持ったキャラクターテンプレート(設計図のニュアンスを入れるならキャラクターシートて感じかな?)のイメージ
- 名前やHP、MPといったステータスがあり魔法が使える魔導士テンプレートがクラス。
- 魔導士を元にさらにスキルなどを加えた白魔導士、黒魔導士などのテンプレートが派生クラス。
- 魔導士テンプレートに具体的な名前、数値を入れた実態のあるプレイヤー(クラス:魔導士)がオブジェクト/インスタンス
なんとなくイメージ持てましたか?もっとしっかり知りたい方はオブジェクト指向について書かれた書籍やブログで学習しましょう。ちなみにマケイヌは学習したくありません!
MonoBehaviourて何(初心者解説)
以上を踏まえたうえでMonoBehaviourの解説です。
Monobevavior概要
- MonobevaviorはUnity スクリプトの基本クラス。デフォルトですべてのUnity スクリプトがここから派生します。
- スクリプトをコンポーネント(ゲームオブジェクトに機能を持たせる部品)とするためのフレームワークを提供してくれる。
- Start、Updateや衝突判定など数多くの便利なイベントへのフックを提供してくれる。
はじめのうちは基本的にMonobevaviorを使っていく方向で良いでしょう。
スクリプトを書く、ついでにデバッグログを出してみる
スクリプトを書いてみます
具体的にスクリプトを書いてみます。
ついでにデバッグログの出し方も解説します。プログラミングをしていると必ずうまくいかなくなります。その時に変数が正しい値になっているかとか、関数が実行されているかとか、調べる定番の方法がログを出すことです。簡単なので覚えましょう。
ユニティちゃんを左右反転させるコードを書いていきます。
public class Test : MonoBehaviour
{
// Start is called before the first frame update
void Start()
{
//Vector3型のtransform.localScaleの値をscaleに代入
Vector3 scale = this.transform.localScale;
//scaleのx方向を-1
scale.x = -1.0f;
//厳密には元の倍率を生かすべきなので
//scale.x=-scale.x;の方がより好ましい
//scaleの値をtransform.localScaleに代入
//これで反転します
this.transform.localScale=scale;
//transform.localScale.xの値をログに出力します
Debug.Log("xの倍率は:"+ this.transform.localScale.x);
}
// Update is called once per frame
void Update()
{
}
}
スクリプト解説
- 7行目:scaleにゲームオブジェクトのlocalScaleを代入
- 9行目:scaleのx軸成分に-1を代入(x軸に沿って反対方向に向ける)
- 14行目:ゲームオブジェクトのlocalScaleにscaleを再代入
- 18行目:コンソールにログを出すにはDebug.Logを書きます
スクリプトをコンポーネントとしてアタッチしてみる
スクリプトをゲームオブジェクトにアタッチして実行しよう
- スクリプトを保存したらUnity エディターに戻って、ユニティちゃんを選択し、プロジェクトの「Test」スクリプトをインスペクターにドラッグアンドドロップしアタッチします。(インスペクターの「コンポーネントを追加」からも可能です)
- 再生ボタンをクリックします。
- ゲームが再生されてユニティちゃんが反転しました。
- コンソールタグをクリックするとちゃんとログが出ているのが確認できます。必ず最後に停止ボタンをクリックしてゲーム再生を終わらせましょう。
うまく反転できましたね。
transformの罠問題
trasform.position.x問題
今回はうまくいきましたが
実は「transform」には初心者がハマりがちな罠があります。先ほどのコードで一足飛びに次のように書いたらどうでしょう?
this.transform.localScale.x=-1.0f;
一見間違ってなさそうですが、「transform.localScale.x」は変数ではないから変更できないと怒られてしまいます。どうやらプロパティを通じて、構造体のメンバーにアクセスすると出るエラーのようです。これ「trasform.position.x」とかもやりがちです。
どうしてうまくいかないのか
- Vector3が参照型のクラスではなく値型の構造体(struct)だから
- 「trasform.position」とか「trasform.localScale」がVector3型のプロパティなのに、その中のフィールド変数にアクセスしてるから
はい、よくわからないですよね。
構造体と値型
構造体とは関連あるものをまとめたクラス似たものです。ただしクラスは参照型で、構造体は値型としてふるまいます。
値型はメモリーに値そのものを格納します。代入などしたときは値のコピーを渡すイメージです。(参照型は格納された住所を渡すイメージ)。値型なんていうと難しそうですがintとかで実は結構普通に使ってます。
int x;
x=1;
foo(x);
Debug.log("x:"+x);
void foo(int y){
y=y*10;
}
fooを通過したxの値は?
- xは1です。fooにはx のコピーが渡されているのでfooの外にあるx本体は変化しません。
- もしもintが参照型だったら?xは10です。fooには参照が渡されるので参照元のxも変化します
なんとなくイメージできましたか?
プロパティとは
次にプロパティです。プロパティとはクラス内で限定公開されている変数に外からアクセスして取り出したり、書き込んだりする仕組みみたいなイメージです。
public class foo
{
// 隠蔽(privateに)された変数
private int bar;
//アクセスして取り出したり、書き込んだりする仕組み
public int Bar
{
//取り出す
get { return bar; }
//書き込む
set { bar = value; }
}
}
上記ではint 型ですが、「transform.position」や「trasform.localScale」は構造体のVector3型を取得したり書き込んだりします。このとき上記したように構造体は値型なので取得する側はコピーを渡されます。
transform.position.xはコピーの中身?
もう一度問題のコードを見てみます
this.transform.localScale.x=-1.0f;
とか「transform.position.x=」とかすると、プロパティとしてVector3のコピーを渡しただけだから、その中身のxに代入しても意味ないよ、とエラーになるのかなと思われます。
もっと厄介なtransform.position.Set
ちなみにもっと厄介なのが、Vector3にx、y、zの成分を渡すSet(x,y,z)メソッドです。それを使って
this.transform.position.Set(-1.0f,0,0,);
などとしたらコンパイルはされるのに何も起きないとなってハマります。
おそらくこれも同じ理由で、それ渡したコピーの値変えてるだけだけど、プロパティ的にVector3型できちんと代入しないと意味ないけど?まあでもこの人この値変えただけのコピーどこかで使うつもりかも?とりあえずコンパイル通しとくかて感じでなのかなと思います。
さてざっくりとした理解で長々と書いてきましたが結局どうすればいいのか?
transformの罠問題はどうすればいいのか
答えはシンプルにVector3型をしっかり代入するです。
transformの罠問題
- transform.positionやtransform.localScaleにはVector3型をしっかり代入
今回参考にした動画です。
まとめ
あいまいな理解の解説にお付き合いいただいた方ありがとうございました。あくまで初心者がイメージ優先で書いたので、至らない部分が多々あると思います。ご容赦ください。
まとめ
- ゲームオブジェクトはコンポーネントの集まりである。
- スクリプト作成はプロジェクトで右クリック、アタッチはインスペクターにドラッグアンドドロップ。(インスペクターの「コンポーネントを追加」でもできる)
- 初心者は基本MonoBehaviourを継承してOK。
- Debug.Log()でコンソールにログが出せる。
- transform.positionやtransform.localScaleにはVector3型を代入する。
- もっと詳しく知りたかったらオブジェクト指向やC#の書籍などで学習しよう
\ Unityのスクリプトを書くのに役立ちます /
もっと早く教えてほしかった!Unity C#入門
MARU
おすすめ記事
Unity ソフトウエアでゲーム制作#1モグラたたき編(28.ゲームに効果音…
Unity ソフトウエアでゲーム制作#1モグラたたき編(27.エフェクト2パ…
Unity ソフトウエアでゲーム制作#1モグラたたき編(26.エフェクトその1)
Unity ソフトウエアでゲーム制作#1モグラたたき編(25.プレハブバリア…
Unity ソフトウエアでゲーム制作#1モグラたたき編(24.Buttonで…
Unity ソフトウエアでゲーム制作#1モグラたたき編(23.シンプルなアニ…