ダークモード
C# 早見表
この教材で使う C#(シーシャープ)の書き方だけをまとめました。「あれ、どう書くんだっけ?」と思ったときに見てください。
スクリプトの形
csharp
using UnityEngine; // Unity の命令を使うための1行
using UnityEngine.InputSystem; // Input System を使うとき
public class PlayerController : MonoBehaviour // クラス名 = ファイル名
{
public float speed = 6f; // 変数
void Start() // 関数
{
}
void Update()
{
}
}using(ユージング)
ファイルの一番上に書いて、「この道具箱を使います」と知らせます。
| 書くもの | 使うとき |
|---|---|
using UnityEngine; | いつも(Unity の基本) |
using UnityEngine.InputSystem; | InputAction などの入力を使うとき |
using System.Collections; | コルーチン(IEnumerator)を使うとき |
using System.Collections.Generic; | List や Queue を使うとき |
using TMPro; | TextMeshProUGUI を使うとき |
using UnityEngine.UI; | Image などの UI を使うとき |
using UnityEngine.SceneManagement; | SceneManager でシーンを切りかえるとき |
class と MonoBehaviour
public class ○○ : MonoBehaviourと書くと、GameObject に付けられるスクリプトになります- ファイル名と ○○ は必ず同じ にします(
PlayerController.csならPlayerController) {と}で「ここからここまで」を囲みます。数が合わないとエラーになります
変数と型
csharp
int hp = 3; // 整数(小数なし)
float speed = 6.5f; // 小数。最後に f をつける
bool isDead = false; // true(はい)か false(いいえ)
string name = "BOSS"; // 文字。" " で囲む| 型 | 入るもの | 例 |
|---|---|---|
int | 整数 | 100、-3 |
float | 小数 | 0.5f、6f |
bool | true / false | true |
string | 文字 | "SCORE" |
Vector3 | x, y, z の3つの数 | new Vector3(1f, 2f, 0f) |
GameObject | GameObject(プレハブなど) | Inspector でつなぐ |
Transform | 位置・回転・大きさ | Inspector でつなぐ |
float の f を忘れない
float speed = 0.5; はエラーになります。C# では 0.5 は double という別の型だからです。小数には f をつけて 0.5f と書きましょう。6f のように整数につけてもかまいません。
int どうしの割り算
int どうしで割り算すると、小数点以下が切り捨てられます。1 / 2 は 0 になります。 小数で計算したいときは (float)hp / maxHp のように、片方を float にします(第17回の BossHPBar)。
public と [HideInInspector]
csharp
public float speed = 6f; // Inspector に出る。ほかのスクリプトからも使える
float timer; // Inspector に出ない。このスクリプトの中だけで使う
[HideInInspector] public int maxHp; // ほかのスクリプトから使えるが、Inspector には出さないTIP
Inspector で値を変えると、コードに書いた最初の値より Inspector の値が優先 されます。コードを書きかえても動きが変わらないときは、Inspector の数字を確認しましょう。
Unity が自動で呼ぶ関数
| 関数 | いつ呼ばれる | 使いみち |
|---|---|---|
Awake() | いちばん最初(Start より前) | instance = this; など、ほかより先に準備したいこと |
Start() | 最初の1回 | 準備(アクションを取る、変数の最初の値を決める) |
Update() | 毎フレーム(1秒に何十回も) | 移動、入力のチェック |
LateUpdate() | 毎フレーム、全部の Update が終わったあと | ほかのものが動いたあとに追いかける(オプション) |
OnTriggerEnter(Collider other) | Trigger の Collider に何かが入ったとき | 当たり判定。other がぶつかった相手 |
つづりに注意
update()(小文字)や OnTriggerEnter2D と書くと、Unity は呼んでくれません。エラーも出ないので気づきにくいです。
if と else
csharp
if (hp <= 0)
{
Die();
}
else
{
Debug.Log("まだ生きている");
}比較の記号
| 記号 | 意味 | 例 |
|---|---|---|
== | 等しい | cursor == 0 |
!= | 等しくない | enemy != null |
< / > | より小さい / より大きい | x < -12f |
<= / >= | 以下 / 以上 | hp <= 0 |
論理演算子
| 記号 | 意味 | 例 |
|---|---|---|
&& | かつ(両方とも) | attackAction.IsPressed() && timer <= 0f |
|| | または(どちらか) | other.CompareTag("Enemy") || other.CompareTag("EnemyBullet") |
! | ではない(反対) | if (!pierce) |
= と == はちがう
=は「入れる」(代入):hp = 3;は hp に 3 を入れる==は「等しいか調べる」(比較):if (hp == 3)は hp が 3 かどうか調べる
if (hp = 3) と書くとエラーになります。
計算の書き方
csharp
score += 100; // score = score + 100; と同じ
hp -= damage; // hp = hp - damage; と同じ
lives--; // lives = lives - 1; と同じ
cursor++; // cursor = cursor + 1; と同じくり返し
for(決まった回数)
csharp
// i が 0, 1, 2, 3, 4 のときの5回くり返す
for (int i = 0; i < 5; i++)
{
Instantiate(prefab, pos, Quaternion.identity);
}foreach(中身を1つずつ)
csharp
foreach (Transform option in options)
{
Fire(option.position);
}while(条件が正しいあいだ)
csharp
while (time < invincibleTime)
{
// ...
}while (true) はコルーチンの中だけ
while (true) は「ずっとくり返す」です。中に yield return がないと Unity が固まってしまいます。この教材では、コルーチンの中でだけ使います。
配列・List・Queue
csharp
// 配列: 数が決まっている
public GameObject[] enemyPrefabs;
GameObject first = enemyPrefabs[0]; // 0番目(1つ目)
int count = enemyPrefabs.Length; // 何個あるか
// List: あとから増やせる
public List<Transform> options = new List<Transform>();
options.Add(option.transform); // 増やす
int n = options.Count; // 何個あるか(配列は Length、List は Count)
options.Clear(); // 空にする
// Queue: 入れた順に取り出す(行列)
Queue<Vector3> history = new Queue<Vector3>();
history.Enqueue(target.position); // 後ろに並ぶ
Vector3 oldest = history.Dequeue(); // 先頭を取り出す番号は 0 から
配列や List の番号は 0 から 数えます。5個あるなら、番号は 0〜4 です。enemyPrefabs[5] はエラーになります。
関数・引数・戻り値
csharp
// 引数あり・戻り値なし(void)
public void TakeDamage(int damage)
{
hp -= damage;
}
// 引数なし・戻り値あり(bool を返す)
public bool UseShield()
{
if (shield.activeSelf)
{
shield.SetActive(false);
return true; // ここで終わって true を返す
}
return false;
}
// 呼び出す側
enemy.TakeDamage(1);
if (powerUp.UseShield()) { ... }voidは「何も返さない」という意味ですpublicをつけると、ほかのスクリプトやボタンから呼べますreturn;で関数の途中で終わることができます(if (isDead) return;)
enum と switch
csharp
// enum: 選択肢に名前をつける
public enum ShotType
{
Normal,
Double,
Laser
}
public ShotType shotType = ShotType.Normal;
// switch: 値で分ける
switch (index)
{
case 0:
Debug.Log("SPEED UP");
break; // ← break を忘れるとエラー
case 1:
Debug.Log("MISSILE");
break;
}public な enum の変数は、Inspector でプルダウンになります。
コルーチン
「待つ」ことができる関数です。
csharp
using System.Collections; // ← 必要
void Start()
{
StartCoroutine(SpawnLoop()); // コルーチンを動かす
}
IEnumerator SpawnLoop()
{
while (true)
{
yield return new WaitForSeconds(1.5f); // 1.5秒待つ
// 敵を出す
}
}| 書き方 | 意味 |
|---|---|
yield return new WaitForSeconds(1f); | 1秒待つ |
yield return null; | 1フレーム待つ |
yield break; | コルーチンを終わる |
StartCoroutine(○○()) | コルーチンを始める |
StopAllCoroutines() | このスクリプトのコルーチンを全部止める |
DANGER
SpawnLoop(); と直接呼んでも動きません。必ず StartCoroutine(SpawnLoop()); で動かします。
static
csharp
public class GameManager : MonoBehaviour
{
public static GameManager instance; // みんなで共有する1つだけの箱
void Awake()
{
instance = this; // 自分を入れておく
}
}
// ほかのスクリプトから
GameManager.instance.AddScore(100);static をつけた変数は、クラス名から直接使えます。「どこからでも呼べる係」を作るのに便利です。
よく使う Unity の命令
| 命令 | 意味 | 例 |
|---|---|---|
Instantiate(プレハブ, 位置, 回転) | プレハブから作って出す | Instantiate(bulletPrefab, muzzle.position, Quaternion.identity); |
Destroy(オブジェクト, 秒) | 消す(秒は省略できる) | Destroy(gameObject, 2f); |
GetComponent<型>() | 付いているコンポーネントを取る | other.GetComponent<Enemy>() |
CompareTag("タグ") | タグが同じか調べる | other.CompareTag("Player") |
SetActive(true/false) | 表示・非表示 | gameOverPanel.SetActive(true); |
transform.Translate(方向) | 今の位置から動かす | transform.Translate(Vector3.right * speed * Time.deltaTime); |
transform.position | 位置 | transform.position = new Vector3(-6f, 0f, 0f); |
Mathf.Clamp(値, 最小, 最大) | 範囲の中におさめる | Mathf.Clamp(pos.x, minX, maxX) |
Mathf.Min(a, b) | 小さいほう | Mathf.Min(speed + 1.5f, maxSpeed) |
Mathf.Sin(値) | 波のように -1〜1 をくり返す | Mathf.Sin(pos.x * frequency) * amplitude |
Mathf.Atan2(y, x) | 方向から角度を求める(ラジアン) | Mathf.Atan2(dir.y, dir.x) * Mathf.Rad2Deg |
Mathf.Lerp(a, b, t) | a と b の間の値(t が 0 なら a、1 なら b) | Mathf.Lerp(0f, 10f, 0.5f) は 5 |
Quaternion.Lerp(a, b, t) | 回転をなめらかに近づける | 第4回の機体の傾き |
Quaternion.Euler(x, y, z) | 角度から回転を作る | Quaternion.Euler(0f, 0f, 45f) |
Random.Range(最小, 最大) | ランダムな数 | Random.Range(-4f, 4f) |
Debug.Log("文字") | Console に表示する | Debug.Log("SPEED UP"); |
SceneManager.LoadScene("名前") | シーンを切りかえる | SceneManager.LoadScene("Game"); |
PlayerPrefs.SetInt("名前", 値) | 数を保存する | PlayerPrefs.SetInt("HighScore", score); |
PlayerPrefs.GetInt("名前", 初期値) | 保存した数を読む | PlayerPrefs.GetInt("HighScore", 0) |
InputSystem.actions.FindAction("名前") | 入力アクションを取る | InputSystem.actions.FindAction("Move") |
Random.Range の整数と小数
Random.Range(0, 3)のように 整数 で書くと、0, 1, 2 のどれか(3 は出ない)Random.Range(-4f, 4f)のように 小数 で書くと、-4〜4 のどれか
配列からランダムに選ぶ Random.Range(0, enemyPrefabs.Length) は、この「最後の数は出ない」性質を使っています。
初心者がつまずきやすいところ
| まちがい | 正しい書き方 |
|---|---|
float speed = 0.5; | float speed = 0.5f; |
if (hp = 0) | if (hp == 0) |
void update() | void Update()(大文字・小文字は区別される) |
文の終わりの ; がない | hp -= damage; |
" や ( の閉じ忘れ | Debug.Log("HELLO"); |
ファイル名 Player.cs、クラス名 PlayerController | 両方を同じ名前にする |
SpawnLoop(); | StartCoroutine(SpawnLoop()); |
全角のスペースや記号(; () | コードは 半角 で書く(日本語はコメントと " " の中だけ) |
コメント
// から行の終わりまでは「コメント」で、プログラムとしては無視されます。メモや説明を日本語で書いておきましょう。