ゼロからはじめる Unity 基礎編 | Week 2 : うごく箱

Week 2 では、C#スクリプトを使って箱の動きを制御していきます。
(この記事は書きかけです)


2.1 C#スクリプトの準備

C#スクリプトでは、C#言語でプログラムを書くことで、Unity上に配置したオブジェクトを制御することができます。

たとえば…
  •  スペースキーを押すとプレイヤーがジャンプする
  • 1秒おきに敵がプレイヤーめがけて弾を撃ってくる
などは、C#スクリプトで実現できます。

スクリプトの準備

まずC#スクリプトを作成し、それを動かしたいオブジェクトへアタッチします。

C#スクリプトを作成する

Project ウィンドウの Create から C# Script を選びます。

次に、C#スクリプト名を入力します。
C#スクリプト名は、かならず半角英数のみでつけます。
たとえば、プレイヤの制御につかうスクリプトなら「PlayerController」といった具合です。

スクリプトをアタッチする

次に、制御したいオブジェクトへスクリプトをアタッチします。

アタッチするには、スクリプトを選択し、オブジェクトのInspector上へドラッグ&ドロップします。

作成したC#スクリプトをダブルクリックすると、Visual Studio が開き、プログラムを編集できるようになります。


2.2 プログラムを書くときの基本ルール

まずは、既存のプログラムを打ち込んでみましょう。

一般に、プログラム文のことを ソースコードコード と呼びます。
以下の説明でも、プログラムのことを「コード」と呼んでいきます。

スクリプトを作成して、半角英数で Circular という名前をつけます。
この Circular を適当なオブジェクトへアタッチしたあと、以下のように打ち込んでみてください。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Circular : MonoBehaviour
{
    public float radius = 2; // 回転半径
    public float speed = 3; // 回転速度

    void Start()
    {

    }

    void Update()
    {
        float t = speed * Time.time;
        float x = radius * Mathf.Cos(t);
        float y = radius * Mathf.Sin(t);
        transform.position = new Vector3(x, y, transform.position.z);
    }
}

C# でプログラムを打ち込むときのルールです。
  • 基本的に半角英数のみを使う
    (プログラム本文に全角文字や日本語を使うと面倒ごとが多いです)
  • アルファベットの大文字小文字は、別の文字として扱われる
    (Player と player は別の名前として認識されます)

Unity へ戻ってプレイボタンを押すと、アタッチしたオブジェクトがグルグルと回転しはじめるはずです。

Visual Studio で赤波線が表示されたり、Unity でプレイボタンを押したときにエラーが出た場合は、打ち間違いがあるはずです。
大文字と小文字 、カンマとピリオド、コロンとセミコロンなど、間違えていないかよく確認しましょう。

Console ウィンドウ

スクリプト内にミスがあると、エラーが出ることがあります。

スクリプトのエラーは、Unity の Consoleウィンドウ で確認できます。
表示するには、メニューの Window → General → Console を選択します。

ためしに、エラーを出してみましょう。
適当にめちゃくちゃな文字を打って、保存してみます。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class PlayerController : MonoBehaviour
{
    // Start is called before the first frame update
    void Start()
    {
        ncanckancjkasnckvunkancjaknczkxnjckasjnkva
    }

    // Update is called once per frame
    void Update()
    {
        
    }
}

Unityに戻ってみると、Console に赤くエラーが出ます。

この場合、表示されているように「; expected」というエラーとなります。
このエラーが言いたいことは、C#には命令の末尾に「;」を付ける規則があるので、それを守ってくださいね、というものです。



2.3 初期状態のC#スクリプトを読み解く

作成したC#スクリプトを開くと、最初からプログラムが書いてあるはずです。
この内容を、ざっと読み解いていきましょう。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class PlayerController : MonoBehaviour
{
    // Start is called before the first frame update
    void Start()
    {
        
    }

    // Update is called once per frame
    void Update()
    {
        
    }
}

コメント文

スラッシュ2個 // から行末までを コメント文注釈文 といいます。

// Start is called before the first frame update

// Update is called once per frame

コメント文は、メモ書きを残すためのものです。
プログラムの実行内容には影響しません。

Start関数・Update関数

以下の2つが Start関数 Update関数 とよばれるものです。

void Start()
{

}

void Update()
{

}

そもそも関数とは何なのでしょうか?
関数というのは、命令リストに名前をつけたまとまりのことです。

C# では、命令は関数の中にしか書けません。
ですから、プレイヤを動かしたり弾を撃ったりしたければ、それらの命令はすべて関数のなかに書いていくことになります。

Start関数の { } のなかに命令を書くと、最初に一回だけ命令が実行されます
Update関数の { } のなかに命令を書くと、1フレームごとに実行されます
たとえば、Unity が 60 FPSで動作しているとすれば、Update関数は1秒間に60回実行されます。

クラス

この部分は クラス といいます。

public class PlayerController : MonoBehaviour
{
    (略)
}
クラスは、C#スクリプトのひとまとまりを表すもの、と考えてください。
Unity側でスクリプトファイルの名前を変えた場合は、クラス名も変える必要があります。

using宣言

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
雰囲気でいえば、ファイルの先頭に using UnityEngine; と書くとスクリプトから Unity 上の機能が使えるようになる、といった感じです。使いたい機能が増えたときは、ここへ using 宣言を書き足すことがあります。


2.3 型と変数

本題の「箱を動かす」に入るまえに、型と変数について説明しておきます。

型とは

データやオブジェクトの種類のことです。

ゲーム制作でよく使う型には、以下のようなものがあります。
  • int型 : 整数値
  • float型 : 実数値
  • bool型 : 真偽値 (true / false のこと)
  • string型 : 文字列データ
  • Vector3型 : 3次元ベクトルデータ
  • Quarternion型 : 回転データ

ちなみに、Vector3 や Quarternion は、複数の float型 が集まってできている、構造体とよばれるタイプの型です。
構造体型の新しいデータを作成するときは、 new 型名(入力データ) と書く決まりがあります。

変数とは

データを一時的にしまっておくものです。
変数は、データが入る「箱」として例えられることが多いです。

変数には、指定した種類のデータ(型)だけを格納できます
整数から小数など、C#が自動的に変換してくれる型もあります。
しかし、整数型の変数へ文字列データを入れようとすると、エラーになります。

変数の内容は、基本的にプログラムが終了すれば消えてしまいます
Unityであれば、プレイボタンがオフになると、すべて初期状態にもどります。

変数は基本的に自分で用意するものですが、あらかじめ C# や Unity が用意している変数もあります。

変数宣言(変数を用意する)

変数を作ってみましょう。

型名 変数名;
で作れます。

例1: プレイヤーのスコアを整数で管理したいとします。
そこで、int型の playerScore 変数を用意します。
int playerScore;

例2: 弾丸のスピードを実数で管理したいとします。
そこで、float型の bulletSpeed 変数を用意します。
float bulletSpeed;

例3: 爆弾が起爆したかどうかのフラグを作りたいとします。
そこで、bool型の isExploded 変数を用意します。
bool isExploded;

代入(だいにゅう)

変数へデータをしまってみましょう。

例: プレイヤのスコアを管理したいので、変数 playerScore を用意してみました。
int playerScore;

さて、プレイヤのスコアを 100 にしたいとします。
変数 score に 100 をしまうには、
playerScore = 100;
のように「=」記号を使います。
このような命令文を 代入 といいます。

さらに、スコアを 23 だけ増やしたいとします。
その場合は、
playerScore = playerScore + 23;
のように「playerScore に 23 を足した数値」を代入すればよいです。
最終的に playerScore は 123 になります。


2.5 スクリプトでオブジェクトを動かす

Transform について (前回の復習)

Inspector ウィンドウの Transform が位置・回転・拡大縮小をあらわすのでした。

実は、Transform 内の数値をスクリプトから操作できるようになっています。

transform変数

Unity は、あらかじめ transform という変数を用意してくれています。
この transform を使って、アタッチしたオブジェクトの Transform を操作できます。

変数のなかの変数・関数

実は transform 変数の中には、さらに変数や関数が入っています。
そのなかに、オブジェクトの位置座標が格納されている position という変数があります。

変数のなかへアクセスするときは「.」をつかいます。
transform のなかの position を使うには transform.position と書きます。

さらに、position 変数のなかには x, y, z という変数が入っています。
それぞれ、オブジェクトのX座標, Y座標, Z座標をあらわしています。

その1 : 指定位置へ箱を移動させる

変数 transform.position のデータを書き換えれば、オブジェクトの位置が変わります。
transform.position = new Vector3(1, 2, 3);

オブジェクトのワールド座標を直接指定するやりかたです。
x = 1, y = 2, z = 3 の位置に移動します。

関数 transform.Translate(x, y, z) を利用する方法もあります。
transform.Translate(1, 0, 0);
移動する量を指定します。
x = 1, y = 0, z = 0 方向へ進みます。

その2 : 箱を動かし続ける

Update関数は、毎フレーム繰り返し実行されるのでした。
これを利用して、1フレームごとに箱を動かし続けてみます。
void Update()
{
    transform.Translate(0, 1, 0);
}

やってみよう

3D空間上に、カプセルがあります。
ゲームを開始すると、(カメラから見て)斜め右上へ移動していきます。

このような動きをするスクリプトを書いてみよう。(制限時間 5分)

その3 : 速さを管理する


変数は、関数の内部か、クラスの直下でのみ宣言できます。

Start関数のなかに float型の moveSpeed という変数を用意してみます。
[コード]

最初から変数に値を入れておくこともできます。
[コード: float moveSpeed = 3;]

クラス直下に作った変数を、外部からアクセスしたり、インスペクタで編集したい場合は、public をつけます。
[コード: public float moveSpeed = 3;]

その4 : 2m先まで移動する

いまのところ、箱は無限の彼方まで移動しつづけてしまいます。
これは少し困るので、2メートル先まで移動したら、もう移動しないようにしてみます。

条件分岐 : if文
「もしこのときは、こうする」という、条件分岐のための文です。

比較演算子

論理演算子

その5 : あるキーを押したときだけ動かす

Input.GetKey(KeyCode.Space);
Keys.まで打つといろいろなキーの名前が出てきます。
いろいろなキーで試してみましょう。

やってみよう

3D空間上に箱があります。
左矢印キーを押すと、箱は左へ動きます。
右矢印キーを押すと、箱は右へ動きます。

このような動きをするスクリプトを書いてみよう。(制限時間 5分)
ヒント : 左矢印キーは KeyCode.LeftArrow、右矢印キーは KeyCode.RightArrow。

やってみよう

上の続きです。
箱を -5 ≦ x ≦ 5 の範囲内でしか移動できないようにしましょう。
(制限時間 5分)




Week 3 では、もっとゲームらしい動きを実装してみます。

次 : Week 3「物理演算と銃」

コメント