注:当ブログでは広告を利用しています。

スクリプト編:Unity2Dアクションゲーム制作裏話講座

おはよう。
現在Unity2Dでアクションゲームを作っている。

私は独学でUnityことゲーム制作を始めた。
Youtubeや本、ブログなどたくさんの人に助けてもらった

だからこそ私も記事という形で、
今のあなたに何らかの参考材料となればいいなと思い、記事を書いた。

結構長くなるので、いくつか分けて書きたい。

簡単な部分は省略したり、参考となる本や動画を載せたりする。
私が書くべき部分は参考あるいはイチから作ったものばかりだ。

くわえてスクリプトなど「なるべく減らす」形で書いていきたい

書く内容が多すぎるので、いくつかに分散化した。

まずは基本スクリプト編からだ。

 

スクリプトの基本とリファレンスの観方

Rigidbody2D.sharedMaterial

基本と言っても膨大にありすぎるので、私にとっての基本を書く。
またスクリプトリファレンスの見方を改めて記述していき、
「どうやって関数やスクリプトを記載していけばいいか」についても述べる。

はじめにスクリプトの基本だ。
スクリプトは作成しただけでは意味がない。

何かしらのゲームオブジェクト(ヒエラルキーに登録されているもの)に接続し、始めて効果を発揮する。

スクリプトを開くと、Start関数とUpdate関数に分かれている。
Start関数の前にまずは箱と箱名を決めてしまう。

private,publicの二つに分かれており、
privateは「そこでのみ、別のスクリプトからも使えない」状態。

publicはインスペクター上で設定できるうえ、別のスクリプトからでも呼び出せるモノだ。

[SerializeField] を使えば、private/publicどちらからでも直接インスペクター上で代入できる。

あなたに覚えてほしい項目が public staticだ。
public staticはシーン(scene)を変更しても継続される項目であり、
例えば主人公のHPや残り人数など、ステージを変えても維持する場合に使う。

public staticはGameManager.csにでも創っておくと、
ここから別のスクリプトにHPとか入れられる。

スクリプトを書くと、リファレンスの観方が大切になる。

リファレンスの観方についてはこちらでも語っているが、改めて一つ例をあげたい。

sharedMaterial;について他の部分では

var material = GetComponent<Rigidbody2D>().sharedMaterial;

書いてある。var(便利な箱)と書いてあるが、正確に知るなら検索しかない。
公式サイトには次のように書いてあった。

public PhysicsMaterial2D sharedMaterial ;

Rigidbody2D.sharedMaterial

参照:マテリアル(スクリプトレファレンス)

スクリプトにはvarでもいいが正確さなら、

PhysicsMaterial2D material = GetComponent<Rigidbody2D>().sharedMaterial; 

置いた方が、スクリプト及びあなたにとってもわかりやすい。

ついでにStart関数の前にRigidbody2Dの箱と名前を決めてしまい、
Start関数でGetComponentを行ったうえでmaterialの定義をしたほうが、
スクリプトも軽くで済むうえ、ほかの関数を使う際にも役立つ。

※キャッシュ化という。

例えばUpdate関数内でmaterialの定義を行ってしまうと、
Update関数以外では使えないというエラーが返ってくる

いちいちほかの関数にmaterialの定義をしなければならず、面倒くさい。
「特定の関数でしか使わない」ものを除き、最初に定義してしまったほうが楽だ。

//最初(//はコメントを示す)

private Rigidbody2D rb2d;
PhysicsMaterial2D material ;
// private Rigidbody2D rb2d = null; が初期状態

void Start(){
rb2d = GetComponent<Rigidbody2D>();
material = rb2d.sharedMaterial;
}

void Update(){
//省略
}

最後にスクリプトを入れた際、インスペクター上にRigidbody2Dの確認を行う。
でないとNullReferenceExceptionというエラーを起こす。

なお、別のスクリプトから参照する方法はこちらを見てほしい。

 

かなり大切なnull(空)判定

nullreferenceexception

Unityはnullにかき回される。例えば最初に置いた箱と箱の名前

private Rigidbody2D rb2d;は
private Rigidbody2D rb2d = null; を示している。

基本、最初のうちに等号(=)を入れていないものはすべて空(0)だ。
Start関数で入れるなどしないと、空のままだ。

空のままなのに、関数が入っているがごとく定義を書き込むと、
NullReferenceExceptionを起こしてしまう

私たちの脳みそは「そこにオブジェクトが入ってるやん」捉えるが、
ゲームプログラミングは違う。入っていないもんはない。

NullReferenceExceptionは私たちの脳が素晴らしいがゆえに起きるエラーだ。

NullReferenceExceptionエラーのうち
UnityEditor.Graphs.Graph.WakeUp()~が出てきたら、
いったんUnityを閉じて開けばいい(再起動すればいい)。

null対策として、Start関数にきちんと定義をするか、
if(何らかのオブジェクト ==null)何かしらの対策
if(何らかのオブジェクト !=null)何かしらの対策

!=は「~でない」を示す。「箱は空ではありませんよ」という意味だ。

null判定をどこで最も使うかと言ったらアイテムを出すときだ。

といっても空はなくしておきたいため、
ヒエラルキーに「空のオブジェクト」を作り、プレハブ化し、
インスペクター上に空オブジェクトを入れておけばいい。

 

プレハブ化とゲームオブジェクト

プレハブは便利な道具だ。
一つ作っておけばコピペするだけでいちいち設定せずとも使えるから。

プレハブの作り方はヒエラルキー似て作ったゲームオブジェクトを、
直接コンソール欄にもっていけばいいだけ。

敵キャラやアイテムを作成した時、まず一つをプレハブ化する。

コンソール欄で一つプレハブができたら、Ctrl+CとCtrl+Vでコピペし、
その場で新しいプレハブを創る(コピペ)。

後はspriterendererのイメージ画像と、
アニメーションを作っているならAnimatorのコントローラーを更新すればいい。

※コントローラー更新の手順は上記動画を参照。

プレハブ化において、一つ問題がある。

スクリプトにて「public GameObject ~」を入れたとき、
コンソール上では基本空(null)であり、コンソールから直接代入しようとしても、
目的のゲームオブジェクトがなく、入れられない

なんとオブジェクトを入れるとき「アセット」から参照すると、
簡単に入れられると分かった。

プレハブから取り入れる

「シーン」だとオブジェクトはないが、アセットだとある

アセットから目的のゲームオブジェクトを入れると、
使いまわすとき、いちいちインスペクター上から目的のオブジェクトを代入せずにすむ

加えてスクリプトで「重い」と言われるFind関数を使わずにすむ。

なおアイテムなどで「どうしてもオブジェクトを入れたくないが、空白は……」
思った場合、空のオブジェクトを一つ作成してプレハブにすればいい。

 

メソッド(関数)を使うコツ

関数(メソッド)

関数(メソッド)とは何だろう。

基本 void Start(){ほにゃらら}やUpdate()はもちろん、
void OnCollisionEnter(Collision collision)など当たり判定、
自作したvoid Jisaku(){ほにゃらら}、void Keisan(int damage){ほにゃらら}、
int Kakaku(){ほにゃらら returnうんたら}などを示す。

物理や数学ではいつの間にか「当たり前」に存在する関数について、改めて掘り下げてみよう。

関数とは「計算機あるいは電卓」にあたる。
関数でいろいろ計算をして、結果を出し、ゲームに反映させる。

何かを計算するための電卓と抑えておかないと、
何のためにメソッドを使うのか、わからなくなって混乱の元につながる。

メソッドは基本計算であり、計算次第で簡略にも複雑にもつながる。

関数を最小限に抑えるならUpdate()内にごちゃごちゃ書き込めばいいが、途中で混乱をきたす。

だからこそ目的にあった関数をどんどん作り、
UpdateやOnCollision関数などへの書き込みを減らし、
翌日あるいは数か月後の自分でもわかるように整えていく。

使い方として、

void Update(){
//ここに計算式うんたらかんたら
//例えばキャラを動かすなど
Kikaku(); //自作した関数
Life(2);
int answer;
answer = Plus(1 ,4):
}

void Kikaku(){
//うんたらかんたら計算式を入れる
}

void Life(int damage){ //上記よりdamageには2が入っている
int hpNokori -= damage;
}

int Plus(int a,int b){//上記よりa=1、b=4が入っている
int c += a + b;
return c;
}

int関数、bool関数などでは必ずreturnを入れる。

 

返り値returnの意味

unityにおけるreturn

returnは返り値と呼ばれており、最初私も意味わからなかった。
要は計算結果であり、この関数は「ここでおしまい」を示す。

returnの使い道例として、イベントや死亡などでキャラを動かしたくない場合を上げる。

一つbool(真偽値) sousaなどを入れるなどし、
sousaが偽(false)の時、ボタン操作を不能にさせるなら、

void Update(){
if(!sousa) return
//sousaがfalse(偽)の時、強引に作業を止めて切り上げる
//(!sousa)は(sousa == false)の略

//ここから下はsousa=true(真)なので歩くやジャンプなどのボタン設定ができる
} //Update()終わり

returnは計算結果かつ「この関数はここでおしまい、これ以降使わない」を示す。

先ほど載せたPlus(1 ,4):はint Plus(int a,int b)にて
c = 1+4 = 5となり、answerの中身は5として結果が返ってくる。

関数に放り込んでら、計算結果が返ってくる値=返り値と考えればいいのだろう。

 

目的の関数やスクリプトを組み立てる方法

プログラミングのメモ

例えば私が「キャラと地面が降れているか」を知りたい場合、
Youtubeやグーグルさんなどを使い

  • Unity2d 地面 当たり判定
  • Unity2d 地面 キャラ

こういった言葉を使って、まずは調べる。
すでに他人がやり方を知っているのだから、まずは他人に頼る

ここまではあなたもやっているだろう。

他人に頼っても(=検索しても)出てこない「細かい悩み」が出てきた場合、
紙とペンを使って「自分が何をしたいのか」分解していく。

例えば角の部分では大地とキャラが接しているのに動かない。
まずやるべきことは紙とペンに書いて問題点を認識する。

頭は基本混乱をきたし、何をするかわけわからなくなるからだ。

次にDebug.LogやDebug.Drawlineなどを使い、ギズモをオンにする。
ギズモをオンにしておかないと、Debug.Drawlineが働かないためだ。

//私がよく使うDebug
Debug.Log("Hello"); 
//""の中に文字を入れて、関数が働いているかどうかを確認するときに使う

Debug.Log(Sore);
//bool(ここではSore)が働いているかどうかで使う

Debug.DrawLine(Vector3.zero, new Vector3(5, 0, 0), Color.red);
//当たり判定、大地との接触判定などでよく使う

他のデバッグについてはこちらに乗っているので、参照してほしい。

参照:UnityのDebugの種類(公式)

パソコンから離れて、紙とペンにて色々書き込んでいく。
例えば私の場合「大地と床の設置判定を線でなく長方形にすればいいのでは?」
メモを取って気づいたら、すぐさまパソコンに戻って調べたり、数値を入れたりする。

Debug及び紙とペンを使うと、だんだん自分が何をしたいのか。
そのためにどんなプログラムや材料が必要なのかが見えてくる

またスクリプトを組んで困ったうえで解決した出来事があれば、載せていく。

お願い

めがびちゃんからお知らせ♪

お知らせ

megabe-0へ訪問した"本当"の理由

まさか記事の書き形一つでこうなるとは…

お願い1

Writer軽い自己紹介

ティラノスクリプトや小説家になろう、ピクシブ他で物語を書きながら、 「私が気になった事件」の裏側を作家の視点で書いているおっさん。

プロフィール画像は自画像でなく、Megabe-0ブログのマスコット、めがびちゃん。

 

雷が苦手で、光を見ると頭が固まる(元から固い)。 月初めは墓参りと神社参拝を行い、賽銭箱へ1万円を入れた際、とても気持ちがすっきりした。

 

■ 簡単な自分史 ■

0歳:釧路のある病院で生まれる。暇さえあれば母乳を吸って、ご飯を4膳食べても体重が落ちるほど、母のダイエットにものすごく貢献したらしい

 

3歳:行方不明になり、全裸で海を泳ごうとしたところ、いとこのお姉さんに発見され、この世へ留まる

 

8歳:自分のお金でおもちゃのカードを初めて買い、経済を知る。なぜか父親に怒られ、家出するがすぐに見つかる。

 

12歳:学校で給食委員長になる。委員長として初めて全校生徒の前にて演説する際、原稿用紙を忘れてアドリブで笑いを誘いながらも何とかやり過ごし、多くの生徒に名前と顔を覚えてもらう。また、運動会の騎馬戦では変なアドリブを行い、多くの笑いを誘った。

 

18歳:初めて好きな人ができたけれど、告白が恥ずかしくてついにできず、別れたことを今でも根に持っている(妻となる人にははっきり言えてよかった)

 

21歳:大学在学中、アルバイトを始める。人手不足かつとても忙しい日々を過ごしながら「どうせなら自分から楽しいことをしていきたいなあ⇒起業って選択肢があるのか」働き方の選択肢を見つける

 

27歳:自分で作った会社がうまくいかず、一度たたんで都落ち。実家でとことん自分を責める日が続く。「何をやっても駄目だな、お前は」など。自分を責めても自殺ができず、体中から毒素があふれ出て苦しい日々を送る。寝るのも怖かった日々。

 

28歳:「このままじゃいけない」決心を決め、小学校からの勉強をやり直す。高校の勉強で躓きながらも、学び直すうちに「自分は何もわかっていなかったんだなあ」大切な教えに気づかされる。 加えて、小説やイラストなど「今までの自分が手を出さなかった分野」に手を伸ばしてみた。

 

29歳:「定義」と「自己肯定」こそが生き方を決めると気づかされ、不安な日々が起きても、心が強くなったと感じる。でも子供の誘惑にはめっぽう弱くなる。

 

35歳:人生初の交通事故(物損)に出会う。冬道の運転で車を上下に大回転(スピンではない)を体型氏、何とか命を取り留め、なぜ生きているのかわからない状態に陥る。

自分の生き方はすべて自分が握っている。わずかな瞬間にしか現れない「自分の真実」を表に引きずり出し、ピンチからチャンスを生み出す発想や視点をブログやメルマガ他で提供中。