【Unity】アクティブと非アクティブ

 オブジェクトやコンポーネントにはアクティブな状態と非アクティブな状態がある。これは簡単に言うとゲームに登場しているか、舞台裏で控えているかの違い。Unityエディタ上でもチェックボックスで切り替えることができるので押して見るとわかりやすい。

 これはスクリプトから切り替えることができる。オブジェクトとコンポーネント(スクリプト)の切替方法は以下の通り。true【トゥルー】でアクティブ、false【フォルス】で非アクティブ。

//オブジェクトを非アクティブに
gameObject.SetActive(false); 

//コンポーネントを非アクティブに
GetComponent<コンポーネント名>().enabled = false; 

【Unity】マウスボタン・クリックの検出

 マウスのボタンが押されているかどうかはInput.GetMouseButton()【インプット.ゲットマウスボタン】で取得可能。型はbool。押されていればtrue【トゥルー】、押されていなければfalse【フォルス】。引数は0,1,2で指定可能で、それぞれ下図のようにマウスの左ボタン、右ボタン、ホイールの押し込みに対応している。

 boolを返すので下記のようにそのままif文の条件に入れて利用することが多い。尚、押している間はずっとtrueを返すので連続させたくない場合は工夫が必要である。

if (Input.GetMouseButton(0)){
            Debug.Log("クリックされちゃったぜ");
        }

【Unity】マウスポインタの座標

 スクリーン上でのマウスの座標はInput.mousePosition【インプット.マウスポジション】で取得可能。型はVector3。下記のように横縦もX,Yでそれぞれfloat型で取得可能。尚これは実行中のゲーム画面上でのピクセル値。

Input.mousePosition.x
Input.mousePosition.y

【Unity】Unityの取得がざっくりわかるはなし

 Unityで調べごとをしていると度々”取得”という言葉を見かけると思います。当記事群でもよく使っています。今回はその言葉の意味のイメージをまとめます。

 先にざっくり言ってしまうと次のようになります。
・取得は訊き出すこと

 意味がわからないと思いますので噛み砕いていきますが、オブジェクトとスクリプトの関係については「Unity入門前に知っておくといいはなし」をご一読いただければと思います。

 Unityで何かを作ろうとしたときオブジェクトやコンポーネントはいくつも登場させる必要があります。例えばキャラとアイテム。

 ”キャラがアイテムにふれたら体力を回復する”というプログラムを作りたいとしましょう。このときキャラは”自分がふれているものは何か?”を知る必要があります。

 こんなときアイテムに”あなたの名前は?”と尋ねて名前を教えてもらえれば解決しそうですね。ざっくり言ってしまうとこのように自分の持っていない情報を訊き出すのが取得です。さらにここからいつでも訊き出せる状態にすることも取得と呼んだりします。いつでも訊き出せる状態にするというのは予めオブジェクトを指定してニックネームを付けておくような処理です。
 ここではオブジェクトの名前を例に出しましたが、他にもオブジェクトがアクティブかどうか?オブジェクトの持つTransform【トランスフォーム】コンポーネントの位置座標のYはいくつか?オブジェクトに設定されているマテリアルの色のR値はいくつか?オブジェクトの持つ自作スクリプトの中で宣言されている変数の値はいくつか?などが取得できます。


 つまり何でも訊き出すことができます。

 いかがでしたか?あまり聴き慣れずイメージも湧きにくい言葉ではあると思います。取得にはオブジェクトとコンポーネント、そしてその中の変数などを適切に指定する必要があります。
 しかし裏を返せばこれらを適切に指定するだけでゲーム内のあらゆるパラメータを掌握しゲームに活用することができます。
 急に理解するのは無理ですが、参考にするスクリプトを読むときもただ真似するだけでなく、誰の何のパラメータを読み書きしているのかを少し意識していけるといいかもしれません。

友人との会話からゲームを作ったときのはなし

矢印キーで移動。
スペースキーで攻撃。
魚を倒すとスコア+5。ときどきアイテムを落とします。

川を流れていく子猫というキーワードから発想を広げて作りました。
こだわったポイントは以下の通り。
・シンプルなルール
・徐々に高くなる難易度
・終盤に向けての攻略性
・音声以外の素材の自作
身内向けに作ったのでボスが内輪ネタですが、気軽にアイデアを実現できるのがゲームづくりの楽しいところですね。

【Unity】オブジェクトの取得

 前提が必須ではないが「【Unity】Unityの取得がざっくりわかるはなし」も合わせて読んでおくことを推奨する。

 オブジェクトの取得にはいくつか手段があるが大きく分けると2つ。
①事前に手動で登録
②スクリプトで自動取得

 それぞれ場面に応じて使い分けが必要だが、特に事情がなければ①の方がとっつきやすい。

①事前に手動で登録

 方法は主に以下2パターン。宣言のときに一言つけるだけでInspector【インスペクター】ウィンドウにドラッグ&ドロップ用の枠が作られる。取得したオブジェクトで何をするかで最適な記述は変わってくる。よくわからないうちはpublicでよい。

//スクリプトで取得したオブジェクトのコンポーネントや値をいじりたいとき
public GameObject kaeru;

//スクリプトから変更を加えないとき
[SerializeField] GameObject kawaz;

②スクリプトで自動取得

 方法はいくつかあるが扱いやすいのは以下サンプル。シーン中のアクティブなオブジェクトをオブジェクト名で検索する。処理負荷が大きいため毎フレーム実行することのないように工夫が必要。Start【スタート】関数で最初に取得して使うのが一般的。

//オブジェクト名で検索
GameObject kaeru = GameObject.Find ("KaeruSan");

【Unity】コンポーネントの取得

 GetComponent【ゲットコンポーネント】関数を使う。

オブジェクト.GetComponent<コンポーネント名>()

 以下は具体的なサンプル。TextオブジェクトにText【テキスト】コンポーネントと自作のスクリプトを追加してある。自作のスクリプトからTextコンポーネントのtextプロパティを書き換えるサンプルプログラム。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;  //UIを使うのでこれを追加

public class kazoeru : MonoBehaviour{
    void Start(){
        gameObject.GetComponent<Text>().text = "otameshi";
    }
}

 尚、GetComponentは探し出すような処理であるため、Update【アップデート】関数の中など繰り返し頻繁に利用したい場合は負荷軽減のためにスクリプト内で別途宣言した変数に代入して利用するのが一般的である。以下にそのサンプルを示す。

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

public class kazoeru : MonoBehaviour{

    Text kerokero;  //Text型変数kerokeroの宣言

    void Start(){
        //↓変数kerokeroにコンポーネント代入
        kerokero = gameObject.GetComponent<Text>();  
    }

    void Update(){
        //keorkeroのtextプロパティに文字列代入
        kerokero.text = "otameshi";  
    }
}

【Unity】スクリプトの全体レイアウトのはなし

 Unityでスクリプトを書く際のセオリーをまとめました。厳密なルールはほとんどありませんが、NGを覚えるよりBestを覚えるほうが得策です。
 まずスクリプトを作成すると下記のようなソースコードが自動的に書かれた状態になります。スクリプトの作り方を知りたい方は「【Unity】スクリプトの作成と追加」を参考にしてください。

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

public class otameshi : MonoBehaviour{
    void Start(){
    }

    void Update(){
    }
}

 otameshiの部分はスクリプトのファイル名で作られているはずです。その中のStart【スタート】関数とUpdate【アップデート】関数はよく使うので書いてくれている部分です。使わなければ書かなくても構いません。逆に必要であれば他の使える関数を使うこともできます。自分で関数を作ることもできます。それを踏まえて全体のレイアウトを図にまとめました。

using なんたら
 あまり書き換えることはありません。名前空間などと呼んだりしますが共通の言葉をまとめた辞書のようなものだと思っておいてください。

クラス宣言
 あまり書き換えることはありません。クラス名とファイル名は同じにするルールです。基本的に自動生成されたままで構いませんが、ファイルを複製などした場合はご注意ください。

変数宣言など
 そのクラスで使う変数の宣言などを書きます。Update関数内で宣言すると毎フレームリセットされてしまうので、ゲーム中保持したい変数などはこのエリアで書きます。

Start関数
 最初に一度だけ実行されます。これから使うオブジェクトやコンポーネントの設定などを書いたりします。ゲームの開始時というと少し語弊があるのですがいずれ他の記事にまとめられたらと思います。

Update関数
 起動中常にずっとやる処理を書きます。毎フレームですので設定が60fpsなら1秒間に60回処理することになります。リアルタイムな変化を作る部分ですので一番書き込む部分と言っても過言ではありません。

その他の関数
 自作した関数は勿論、最初から書かれていなくてもいくつか使える関数があります。便利なものでいうとAwake【アウェイク】関数、OnEnable【オンイネイブル】関数、FixedUpdate【フィックスドアップデート】関数、LateUpdate【レイトアップデート】関数などがあります。習得してしまえばより詳細にタイミングをコントロールできますが、最初から覚える必要は全くありません。

 少し長くなってしまいましたが、実際に書きながら少しずつ実感の湧いてくるものになります。一度に覚えようとせず実践しながら都度この記事の図を確認しに来ていただければと思います。

【Unity】スクリプトから大きさを変更する

  「【Unity】スクリプトから位置座標を変更する」とほぼ同じだがscale【スケール】ではなくlocalScale【ローカルスケール】を使う点に注意。
 手順は大きく以下3つ。
①仮の変数に今の座標取得
②仮の変数の値を変更
③オブジェクトの座標に仮の変数を代入

 代入という言葉がわからない場合は「【C#】代入のはなし」を参照。またVector3【ベクタースリー】という言葉がわからない場合は「【Unity】Vector3がざっくりわかるはなし」を参照。さらにTransform【トランスフォーム】コンポーネントについては「【Unity】位置、回転、大きさを変える」も参照しておくことを推奨。

Vector3 kero = new Vector3(1, 1, 1);  //①仮の変数宣言&初期化
kero.x = 2;                           //②変数keroのx座標を2に書き換え
gameObject.transform.localScale = kero; //③位置座標に変数keroを代入

 本来スクリプトからコンポーネントの変数にアクセスするときは同じオブジェクトであってもコンポーネントの指定や取得をしておく必要があるが、Transformは基本的にどのオブジェクトにも標準搭載なので省略できる。

 よくある落とし穴のポイントとして以下のように直接localScale【ローカルスケール】の座標を変更したくなるが、これはできない仕様。Vector3で代入できるので仮のVector3型変数を作っている。

//エラーになるパターン
gameObject.transform.localScale.x = 1;

 また、勘のいい方ならscaleを使うと思ってしまうが、localScaleを利用する。これはオブジェクトを子オブジェクトとして設定した際親オブジェクトに連動してサイズが変わるため、全体から見たサイズ情報とオブジェクト自身が持つサイズ情報を区別するためにあると思われる。

【Unity】スクリプトから回転・姿勢を変更する

 「【Unity】スクリプトから位置座標を変更する」とほぼ同じだがrotation【ローテーション】ではなくeulerAngles【オイラーアングルズ】を使うことに注意。
 手順は大きく以下3つ。
①仮の変数に今の座標取得
②仮の変数の値を変更
③オブジェクトの座標に仮の変数を代入

 代入という言葉がわからない場合は「【C#】代入のはなし」を参照。またVector3【ベクタースリー】という言葉がわからない場合は「【Unity】Vector3がざっくりわかるはなし」を参照。さらにTransform【トランスフォーム】コンポーネントについては「【Unity】位置、回転、大きさを変える」も参照しておくことを推奨。

Vector3 kero = new Vector3();  //①仮の変数宣言&初期化
kero.x = 1;                           //②変数keroのx座標を1に書き換え
gameObject.transform.eulerAngles = kero; //③位置座標に変数keroを代入

 本来スクリプトからコンポーネントの変数にアクセスするときは同じオブジェクトであってもコンポーネントの指定や取得をしておく必要があるが、Transformは基本的にどのオブジェクトにも標準搭載なので省略できる。

 よくある落とし穴のポイントとして以下のように直接eulerAnglesの座標を変更したくなるが、これはできない仕様。Vector3で代入できるので仮のVector3型変数を作っている。

//エラーになるパターン
gameObject.transform.eulerAngles.x = 1;

 また、勘のいい方はrotationで動かせるかと思ってしまうがこれもエラー。transform.rotationはVector3ではなくQuaternion【クオータニオン】という型で保存されている。普段私達が使っているオイラー角で代入するためにはeulerAnglesを指定すればよい。