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

コード軽量込!30日で楽々記述できるUnityプログラムの書き方

おはよう。ブログのアクセス解析を見ていたら、
「Unity スクリプト 書き方」があがっていた。

自分もスクリプトの書き方に悩んだ人間なので、
自分がいかにして30日程度でサクサクできるようになったか、書いていく。

参考にしてほしい。

 

プログラミングは30日もあればサクサクできる

型名変数名

プログラミングは最初、何をすればいいか頭が真っ白になる。
30日もあれば大体サクサクできる。もちろん時間をかけるともっとサクサクできる。

スクリプトリファレンスやほかのサイト・動画を山荘しながら、
目的のプログラムを創り上げていくといいだろう……

問題はどこを探しても「自分の求めるプログラムがない」ときだ。
求めるプログラムがない場合、自作しなければならない。

自作のコツも含めて「初めてスクリプトに接する人」対象に書いていく。

 

一冊の本を購入し、プログラムを直接書き込まない!

まずはUnityに関する本を一冊購入する。
新規本でもいいし古本屋で手に入れてもいい。

たいていのUnity本は初めて手を出す人に合わせ、
必ず簡単なスクリプトの説明を載せている。

アマゾン:たのしい2Dゲームの作り方 Unityではじめるゲーム開発入門

楽天:たのしい2Dゲームの作り方 Unityではじめるゲーム開発入門

アマゾン:Unityの教科書 Unity 2023完全対応版

 

スクリプトは「ただ記述」しても覚えられない

スクリプトの書き方について、ただ読むだけではいけない

実際にC#スクリプトに記述すればいいんですね?

実際に書く作業は大切だけど、まず書くべき場所はコードでなくだ。
ペンとノートを用意し、紙にスクリプトの基本記述を書いていこう。

体にintやfloatなどスクリプトの基本作業を覚えこませるためだ。

実際にパソコンをにらめっこしている時間はもちろんだが、
むしろパソコンをオフにした時間こそ重要だ。

体に叩き込む作業として、毎日30分ほど時間をとって、
ひたすらUnityの教科書やたのしい2Dゲームの作り方に乗っている、
数々のスクリプトを「何も考えないで書き写して」いく。

その時点で意味は分からなくていい。頭の中が「??」でいい。
とにかく書き写して、体に英数字を叩き込んでいく。

その時点でも調べても「意味が分からない」プログラムがある場合、
そこで今すぐ解決しようと考えたら、一気にスランプの始まりだ。

なので、始めはわからなくていいから淡々と書いていく
このやり方で少しずつ「頭でなく体で」プログラミングに慣れていく。

 

大切な復習作業

アップデートスクリプト2

プログラミングの勉強はもう一つ、重要な作業がある。
復習だ。学んだ型番をしっかりと自分の言葉で言えるか?

即座に言えない場合、まだはっきりと自分の中に落とし込めていない。
時間をかけてスクリプト用語を教科書なしで、
自分の口からスラスラいえるようになれるよう、頑張ってほしい。

 

早く覚えておきたいキャッシュ化

const

スクリプトの勉強をしながら、同時に早く覚えておきたい処理がある。
キャッシュだ。キャッシュは上記二冊の教科書で記していない。

キャッシュと言っても現金でなく、関数を始める前に型番と変数を宣言する行為だ。

型番:int float string 自分で創った関数名やスクリプトの名前など

変数:型番に代入する「未知数x」のようなもの。

例: int korekara:
intが型番、korekaraが変数、変数は自分のわかりやすい名前で

キャッシュについてはこちらで詳しく書いている。
軽量化につながるので、早いうちに覚えておいた方がいい。

 

早く覚えたいインスペクターアタッチ

GetComponent軽量化1

上記画像にある右側の状態。スクリプトにて

[SerializeField] Animator anim;

などを入れた状態で、インスペクターから値を入れると、
スクリプトの記述を一部省略できる。

スクリプトは短い内容ほど、未来の自分にとって扱いやすいので、
ぜひ[SerializeField]をおさえておこう。

インスペクターアタッチは自分の作成したスクリプトも入れられる
別のスクリプト参照もできるわけだ。

後はもう一つ、スクリプトリファレンスを参照にしていくが、
はじめのうちは何を書いているか、さっぱりわからない

なので人様のやり方を参照したうえで、
「これはなんだろう」思ったときに使うといい。

 

注意:Updateの扱い(一度のみ発動させたい)

unity Updateでの注意事

UnityにおいてUpdate系は注意が必要だ。
Updateは何度もぐるぐる繰り返すからだ。

扉を開けたら音声を発動させるプログラムにて、
Update内でやると、繰り返しぐるぐる発動するため、音声がかき消されてしまう。

Update内で一度だけしか発動させたくない
それこそStart関数のように一度のみ発動させたい場合、
下記プログラムのようにしなければならぬ。

private bool dooropen ;//初期値はfalse

void Update(){
if(dooropen){
dooropen = false; //即座にfalseへ変えて、繰り返し処理を防ぐ。
//ここに何かしらの処理
} 
}//Update

何かしらの処理でdooropenがtrueになり(下記のtrigger/collision参照)、
trueの時のみUpdateが働く場合、何度も繰り返し発動する。

一度のみしたい場合、boolを上手く使って発動を抑えなければならない。

 

注意2:Triggerとcollision「スクリプト」での大きな違い

triggerとcollisionの違い

ゲーム作成にて当たり判定を生み出すTriggerとCollisionは抑えておこう。

トリガーは上記画像で赤線引いた箇所にあるチェックボックスに、
チェックマークをつければいい。

違いとしてtriggerはすり抜けられるが、collisionはぶつかる(すり抜け不可)

void OnCollisionEnter2D(Collision2D col){
ItemManager iteM = col.gameObject.GetComponent<ItemManager>();
dooropen = true;
}
//接触で起動

void OnTriggerEnter2D(Collider2D tri){
ItemManager iteM = tri.gameObject.GetComponent<ItemManager>();
}
//すり抜けで起動、しかしCollisionEnterも同時に起動

スクリプト記述にて注意すべき箇所がある。

collisionは「物理接触」のみ反応するが、
triggerは「すり抜け」だけでなく「物理接触」も起動する。

triggerだと2度起動するわけだ。

入室/退室などドア系プログラムを働かせるとき、
Triggerでなくcollisionにしておかないと二度起動するため、
本来働かせたいプログラムが働かない場合がある。

例えばドアを開けるときに音声プログラムを入れたとする。
音声プログラムを入れた後、部屋(シーン移動)に入る仕組みだ。

トリガーだと二度働くので音声が途中で切られ、いきなりドアを開ける。
コリジョンだと一度しか働かないので、音声が終わるまで働く。

 

絶対すべきDebug.Log();

GetComponent軽量化2

Unityはエラーとの闘いだ。
基本エラーについてはネットで調べると、大まかな予想がつく。

私を悩ませるエラー代表はNullReferenceExceptionだ。
特に参照している、値を入れているはずなのに、nullエラーが出ると絶望だ。

また一度解決したのに、しばらくたって色々スクリプトをいじった際、
なぜかエラーが出ると絶望に陥る。

なぜnullエラーが起きるのか、スクリプトを分析しなければわからない。
そこでnullエラーの糸口になる指標がDebug.Log();だ。

Debug.Log(“date”);と言った文字列を入れるか、
Debug.Log(vec);など変数を入れるかで、

エラーの出たところに一つずつ入れて検証していく。

nullエラーの代表原因として

  • 時間差(変数のおく順番が原因)
  • スクリプト付きゲームオブジェクトを非表示(機能なし)にしたまま再生
  • 大文字小文字の間違い(大文字と小文字は違う)、スペルミスなど
  • あなたの思い込み(自分はすでに値を入れていると勘違い)

とても厄介な原因が「あなたの思い込み」による間違いだ。
思い込みを解消するためにDebug.Log(“eror”);を使って検証していくわけだ。

 

目的のプログラムを作るために必要な思考

さてプログラミングの勉強も30日を超えると、少しずつ分かってくる。

わかってきてからが本番だ。
いかにして自分のしたいことをプログラムに変換させるか。

プログラミングを行う際、次の前提を頭に叩き込まねばならぬ。

私たち人間は機械よりもよほど高精度な条件分岐を心がけている。

機械は「言われたこと」しかやらないばかりか、
「書いてないがやってくれるだろう」は通じない

私たちの脳はプログラムに比べて、かなり高精度な条件分岐を立てている。
例えばジャンプ一つをとっても、私たちは飛ぶ動作をすれば上に上がる。

しかしプログラミングは

  1. 飛ぶ対象が床と接しているか
  2. 床と接していないとき、飛べないようにしているか
  3. 飛ぶ最大値を越えたら、きちんと重力に沿って落ちれるか

最低三つの条件を考えながらプログラミングしなければならぬ。

上記動画で飛ぶときのやり方を載せている。

私阿智人間は高度な条件分岐を楽々こなしている。
言い換えるなら条件分岐すら何も考えないままやっている

ゲームプログラミングの難しさは人間の当たり前にある。
私たちにとっての当たり前をいかに言語化・筋道立てて説明していくか。

当たり前を一つずつ言葉で説明できるほど、高度なプログラムも仕掛けられる。

当たり前の難しさを知ったところで今から一つ、
一緒にプログラムをみていきたい。

 

シナリオロールなしで文字表示

先ほど私のツイートを載せた。スタッフロール作成だ。
文字が出て、新しい文字が出る。私は2日費やした。

スタッフロール作成プログラムはこちら。
名前は「EndingMnager.cs」だ。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using TMPro;

public class EndingManager : MonoBehaviour
{

[SerializeField][TextArea(5, 7)] string[] textArea;
[SerializeField] string textAreaEnd;
[SerializeField] TMP_Text endText;
private bool rollOn,rollOn1,roll3;
private float times ;
private int i;
private IEnumerator hyouji ;
private WaitForSeconds wfs5 = new WaitForSeconds(5f),
wfs10 = new WaitForSeconds(10f), wfs1 = new WaitForSeconds(1f);
private Coroutine hyoujis;
private const string Credits = "Credit";

private void Start() {
hyouji = Hyouji();
endText.enabled = false;
Invoke(Credits , 3);
}

void Credit(){
endText.enabled = true;
hyoujis = StartCoroutine(hyouji);
}

IEnumerator Hyouji(){
for (i = 0; i < textArea.Length; i++)
{
endText.SetText(textArea[i]);
yield return wfs5 ;
}
endText.enabled = false;
yield return wfs1 ;
endText.enabled = true;
endText.SetText(textAreaEnd);
//ここで終わり
}

}

さて、あなたは私が「何をやっているか」説明できるだろうか

コピペなら簡単にできる。

※コピペする場合、UIからtextmeshproを入れる必要がある。
参照までにtextmeshproに関する動画を載せる

上記プログラムを簡単に説明すると、

[SerializeField][TextArea(5, 7)] string[] textArea;
[SerializeField] string textAreaEnd;
[SerializeField] TMP_Text endText;

private bool rollOn,rollOn1,roll3;
private float times ;
private int i;
private IEnumerator hyouji ;
private WaitForSeconds wfs5 = new WaitForSeconds(5f),
wfs10 = new WaitForSeconds(10f), wfs1 = new WaitForSeconds(1f);
private Coroutine hyoujis;
private const string Credits = "Credit";

まずは型番と変数、場合によって代入し、キャッシュ化させている。

private void Start() {
hyouji = Hyouji();
endText.enabled = false;
Invoke(Credits , 3);
}

Start関数は初回のみ一度起動だ。
ここでコルーチン系のキャッシュ、そして文字の非表示を行っている。
その後3秒後に関数Creditを発動させる。

void Credit(){
endText.enabled = true;
hyoujis = StartCoroutine(hyouji);
}

3秒後に飛んだ関数で文字を表示に変える。
その後コルーチン関数を使って、秒数つき処理を行う。

IEnumerator Hyouji(){ 
for (i = 0; i < textArea.Length; i++) { 
endText.SetText(textArea[i]); 
yield return wfs5 ; } 
endText.enabled = false; 
yield return wfs1 ; 
endText.enabled = true; 
endText.SetText(textAreaEnd); 
//ここで終わり 
}

配列処理を使って、要素の分だけ繰り返し廻す。
回すとき、5秒だけ処理を止める(5秒だけ待つ)。

ループを終えたら次の処理を発動。
一度文字を非表示に、次に別の文字を出す。

とまあ、一部はしょって私が作ったプログラムを言語化した。

あなたは理解できているだろうか。
できているなら、あなたもC#と接して半年くらいたっていると考えている。

私の話が完全に分かるためには、
Invoke関数、IEnumerator、for配列などの意味や役割を、
しっかりと抑えていなければならぬ。

Unityスクリプトには「本には載っていないプログラム」が、
ネットには普通に乗っているからこそ、

「次々と新しい用語を覚えるの、大変だ」気持ちになってしまう。

本当に必要なプログラムはグーグル検索した際、
人様の情報経由で自然と接するから、あれもこれも先取りしなくていい。

言葉で説明するだけでも、かなり紙面をさいた。
一つずつ自分の言葉で何をしているか、きちんと言葉で表していこう。

自分の作業を一つずつ言語化できれば、
自作で「こういうの創りたい」ができるようになる。

 

どうしても思い通りに動かないプログラム対策

Unityプログラミングゲーム用

プログラミングをやってて最もストレスをためるときは、
微調整段階で「思った通りにプログラムが働かない」場合だ。

働かない場合、いったんパソコンから離れて、紙とペンを取り出し、

  1. 自分が目指したい展開
  2. 今まで自分がしてきたプログラム

二つを紙に書いていくしかない。

書いているうちに「これは」思ったら即座に書き込む。
書き込んだ後、すぐでもいいし時間を置いてでもいいので、
再びプログラミングに戻って試行錯誤してみよう。

ひらめきがおりてくるまでパソコンから離れ、今までしてきた流れを整理しなさいだ。

一緒に頑張っていこう。

お願い

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

お知らせ

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

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

お願い1

Writer軽い自己紹介

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

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

 

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

 

■ 簡単な自分史 ■

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

 

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

 

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

 

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

 

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

 

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

 

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

 

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

 

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

 

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

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