2023プログラミング:Unityのプログラミング1

いよいよ、Unityのプログラミングを進めていきます。

ゲームオブジェクトの配置
Sceneビューに以下のゲームオブジェクトを配置してください。

Plane: ゲームのベースになります。Inspectorで名称をFloorとし、PositionをX:0,Y:0,Z:0、RotationをX:0,Y:0,Z:0、ScaleをX:10,Y:10,Z:10とします。

Cube: ゲームのステージになります。Inspectorで名称をRoadとし、PositionをX:2,Y:0,Z:6、RotationをX:0,Y:90,Z:0、ScaleをX:15,Y:1,Z:3とします。

Cube: ゲームのキャラクターになります。Inspectorで名称をCharacterとし、PositionをX:2,Y:1,Z:0、RotationをX:0,Y:0,Z:0、ScaleをX:1,Y:1,Z:1とします。

それぞれに、異なるMaterial(色)を設定しておきます。

ゲームオブジェクトにコンポーネントをアタッチする
UnityのSceneビューに配置されているものは、全てゲームオブジェクトと呼びます。
ゲームオブジェクトにコンポーネントと呼ぶ部品を接続することで色々な機能が使えるようになります。
ゲームオブジェクトにコンポーネントやマテリアル、スクリプトを接続することをアタッチと呼びます。

Character ゲームオブジェクトにコンポーネントを追加します。
Character のInspectorで Add Componentを選択し、Rigidbodyを選択します。RigidbodyのウィンドウのConstraintsを開き、Freeze RotationのX,Y,Z全ての項目にチェックマークを記載します。この設定によりゲームオブジェクトは重力などの物理法則に従った動きをするようになります。Freeze Rotationの設定は、物理法則に従う際に回転方向への影響を防ぎ、不自然な動きを抑えるものです。

ゲームオブジェクトとカメラを親子関係にする
HierarchyウィンドウでMain Cameraを選択し、InspectorでPositionをX:0,Y:0,Z:-3、RotationをX:0,Y:0,Z:0、ScaleをX:1,Y:1,Z:1とします。

Main CameraをCharacter ゲームオブジェクトにドラッグアンドドロップします。この操作によって、Main CameraがCharacter ゲームオブジェクトに追随するようになります。

スクリプトの記述
スクリプト(Script)とは、簡易的なプログラミング言語のことです。Unityではゲームオブジェクトにスクリプトをアタッチすることで、様々なふるまいをゲームオブジェクトに実行させることができます。

ProjectウィンドウでFolderを追加し、名称をScriptsとします。Scriptsフォルダーを右クリックし、CreateメニューからC#Scriptを選択します。作成されたC#ScriptファイルにControllerという名称をつけます。

Controllerファイルをダブルクリックして展開すると、Visual Studioというプログラミング用のエディターというソフトウェアが開きます。

最初に開いた状態で、Visual Studioには以下のようにスクリプトが記述されています。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

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

    }

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

    }
}

以下の部分は各種機能の使用を宣言する部分です。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

以下の部分はクラスと呼ばれる処理の括りとなります。

public class Controller : MonoBehaviour
{

}

以下の部分は、それぞれメソッドと呼ばれ、スクリプト内での実行のタイミングが決まっています。

Startメソッド:ゲームオブジェクトが出現した時に実行する

void Start()
    {

    }

Updateメソッド:フレームごとに実行する

void Update()
    {

    }

ゲームのプログラミング
エディターに以下の記述を加えていきます。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Controller : MonoBehaviour
{
    private float speed = 3f;
    private float verticalInput = 0f;
    private Rigidbody CharacterRigidbody;

    void Start()
    {
        CharacterRigidbody = GetComponent<Rigidbody>();
    }

    void Update()
    {
        verticalInput = Input.GetAxis("Vertical");

        if (Input.GetKey("right"))
        {
            CharacterRigidbody.transform.Rotate(0, 10, 0);
        }
        else if (Input.GetKey("left"))
        {
            CharacterRigidbody.transform.Rotate(0, -10, 0);
        }
    }

    void FixedUpdate()
    {
         if (CharacterRigidbody.velocity.sqrMagnitude < 5f)
         {
            Vector3 CharacterForward = CharacterRigidbody.transform.forward;
            Vector3 moveVector = speed * (CharacterForward * verticalInput);
            moveVector.y = 0;
            CharacterRigidbody.AddForce(moveVector, ForceMode.Impulse);
         }
    }

}

 

プログラムの解説

変数の宣言
変数の型を決めて、変数名を宣言します。
変数の「値」を設定しておくこともできます。

private float speed = 3f;
private float verticalInput = 0f;
private Rigidbody CharacterRigidbody;

GetComponentメソッド
<>内に取得したいコンポーネント名を記載して使用します。

CharacterRigidbody = GetComponent<取得したいコンポーネント名>();

Updateメソッド
Vertical(上下)、right(右)、left(左)それぞれのキーに対応する動きを設定しています。

Verticalキーの上向きボタンを押下すると0.01fの小さい値が入力され、押下し続けると最大で1.0fの値が入力されます。下向きボタンを押下すると、-0.01fの小さい値が入力され、押下し続けると最小で-1.0fの値が入力されます。押されていない時は0.0fの値が入力されます。

verticalInput = Input.GetAxis("Vertical");

if文(条件分岐)
プログラミングは通常は最初の1行から終わりの1行まで順番に処理されます。しかし、それでは複雑な処理をコンピューターに実行させることができません。複雑な処理をさせるための方法のひとつとして条件分岐という考え方が存在します。

単純な処理:
公園に行く。

複雑な処理:
晴れたら公園に行く。
そうでなければ、家で読書する。

上の例のように、条件によって行動(=処理)が変化する(=分岐する)ことを条件分岐といいます。上の複雑な処理の例は以下のように条件分岐命令の書式で記述することができます。

if( 晴れ ){ 公園に行く; }else{ 家で読書する; }

コードであらわす場合は以下のように記述します。

if( 条件式 ){ 条件式が真の場合に実行する内容; }else{ 条件式が真ではない場合に実行する内容; }

プログラミングでは、真であることをtrueと記述します。また真ではない場合は偽とあらわしfalseと記述します。

if〜else文

if文の条件を満たさなかった場合の処理を明示する場合は、以下のように記述することができます。

if( 条件式 ){ 条件がtrueの場合に実行される内容; }else{ 条件がfalseの場合に実行される内容; }

条件式
真偽を判定するために使用できる条件式を以下に記載します。

< 左辺が右辺より小さい

i<100

> 左辺が右辺より大きい

i>100

<= 左辺が右辺以下

i<=100

>= 左辺が右辺以上

i>=100

>== 左辺が右辺に等しい

i>==100

!= 左辺が右辺に等しくない

i>!=100

&& かつ (「かつ」はandとも表現する)

i>0 && i<100

|| または (「または」はorとも表現する)

i<0 || i>100

Unityのスクリプトでは、右ボタンが押下されたら10度回転、そうでない場合は、-10度回転するようにif文で記述しています。

if (Input.GetKey("right"))
{
    CharacterRigidbody.transform.Rotate(0, 10, 0);
}
else if (Input.GetKey("left"))
{
    CharacterRigidbody.transform.Rotate(0, -10, 0);
}

追加の処理(ジャンプボタンの追加)
以下のif文を追加してみましょう。

if (Input.GetKey("a"))
{
    CharacterRigidbody.position += Vector3.up * 0.05f;
}

FixedUpdateメソッド
キャラクターの移動処理を記述します。

if (CharacterRigidbody.velocity.sqrMagnitude < 5f)
{
   Vector3 CharacterForward = CharacterRigidbody.transform.forward;
   Vector3 moveVector = speed * (CharacterForward * verticalInput);
   moveVector.y = 0;
   CharacterRigidbody.AddForce(moveVector, ForceMode.Impulse);
}

AddForceメソッド
Rigidbodyコンポーネントがアタッチされているゲームオブジェクトに力を加えて動かす。

Rigidbody型の変数.AddForce(力の強さ,力のかけ方)

力のかけ方:
ForceMode.Force 重さあり、継続的に力を加える
ForceMode.Impulse 重さあり、瞬間的に力を加える
ForceMode.Acceleration 重さ無視、加速度を設定
ForceMode.VerocityChange 重さ無視、速度を設定

Visual Studioでスクリプトが記述できたら保存して、Unityの操作画面に戻り、トップバーのゲーム実行ボタンを押して動作確認してみる。