Unityに関連する記事です

学習内容


 ここではマテリアルの色の変更方法をスクリプトから行う方法を学びます。

 Unity ではゲームオブジェクトのインスペクターからマテリアルをドラッグアンドドロップすることでマテリアルの変更が可能です。

 マテリアルの変更についてはスクリプトからも制御できるようになっていますので、今回はその手順を学習します。


スクリプトを作成する


 Projects内のAsset → Scripts をダブルクリックして開き
その中で右クリックをしてメニューを出し Create → C# Script を選択します。名前はMaterialTestにします。


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

/// <summary>
/// マテリアルの色のテスト用クラス
/// </summary>
public class MaterialTest : MonoBehaviour
{    
    [Header("マテリアル(色)の設定用")]
    public Material material;

    [Range(0,2), Header("変更する色の設定値")]        // Range属性。引数で値の(最大値, 最小値)を制限できる。2つ以上の属性を記載する場合には半角カンマで区切る
    public int colorNumber;

    [Header("Planeかどうかの判定用 trueならPlane")]
    public bool isPlaneFlag;

     void Start()
    {
        // このクラスがアタッチされているオブジェクトがPlaneかどうか判定し、分岐させる
        if (isPlaneFlag) {  // この分岐条件は、isPlaneFlag == true と同じ意味

            // Planeならこちらのメソッドを実行
            // 引数としてcolorNumberというint型の数値を渡している
            ChangeMatColor(colorNumber);
        } else {

            // Planeではない(Cube)なら、こちらのメソッドを実行
            // 引数としてColor.blueという、Color型の色情報を渡している
            SetMatColor(Color.blue);
        }
    }

    void Update()
    {
        // ボタンを押す度にMaterialの色を変更する
        if (Input.GetKeyDown(KeyCode.F)) {

            // このクラスの持つメソッドを呼び出し実行する
            // 引数としてcolorNumberというint型の数値を渡す
            ChangeMatColor(colorNumber);
        }
    }    
        
  /// <summary>
    /// マテリアルの色の初期設定処理
    /// </summary>
    /// <param name="argumentColor"></param>
    private void SetMatColor(Color argumentColor) {

        // 引数として渡されたargumentColorを使い色を変更(初期設定)する
        // 設定にはMaterial型の変数materialの持つcolorプロパティにアクセスする
        material.color = argumentColor;

        // 色の番号を設定する
        colorNumber = 1;
    }

    /// <summary>
    /// マテリアルの色を変える処理
    /// public修飾子なので、他のクラスからでもこのメソッドを実行できる
    /// </summary>
    /// <param name="argumentColorNumber"></param>
    public void ChangeMatColor(int argumentColorNumber) {

        // 引数として渡されたargumentColorNumberに入ってる番号を使い、分岐により色を設定する
        // ここでもmaterial.colorにアクセスすることで色を変更する
        // switch文はいずれかのcaseに入ると終了する( = breakで抜けている)
        switch (argumentColorNumber) {
            case 0:
                material.color = Color.blue;
                break;
            case 1:
                material.color = Color.green;
                break;
            case 2:
                material.color = Color.red;
                break;
        }

        // 色の番号を1ずつ加算する = 次回以降、別の分岐に入るようにする
        colorNumber++;

        // 色の設定値は2までなので、3以上の数値になったら0に戻す処理を入れておく
        if(colorNumber >= 3) {
            colorNumber = 0;
        }
        Debug.Log(colorNumber);
    }
}

 スクリプトを作成したらセーブします。


スクリプトの処理を読み解く


 今回のスクリプトには、複数の自作したメソッドがあるため、呼び出し命令を受けて動く処理を実装しています。

 まず Start メソッドにおいて、実行するメソッドが2つに分岐します。


    void Start()
    {
        // このクラスがアタッチされているオブジェクトがPlaneかどうか判定し、分岐させる
        if (isPlaneFlag) {  // この分岐条件は、isPlaneFlag == true と同じ意味

            // Planeならこちらのメソッドを実行
            // 引数としてcolorNumberというint型の数値を渡している
            ChangeMatColor(colorNumber);
        } else {

            // Planeではない(Cube)なら、こちらのメソッドを実行
            // 引数としてColor.blueという、Color型の色情報を渡している
            SetMatColor(Color.blue);
        }
    }

 isPlaneFlag 変数の値を評価し、true の場合には ChangeMatColor メソッドを実行します。引数には colorNumber 変数の値を指定します。

 isPlaneFlag 変数が false の場合には SetMatColor メソッドを実行します。引数には Color.blue の値を指定しています。

 このように、Unity が用意している Start メソッドや Update メソッド以外の、自分で作成したメソッドは、
実行する命令があってはじめて処理が実行されます。そのため、スクリプトの何行目に書かれているかは関係しません。

 仮に Start メソッドよりも上段に SetMatColor メソッドが記述されていたとしても、このメソッドは自動的には動きません。

 まずはこの部分をしっかりと理解していきましょう。



 ChangeMatColor メソッド内には switch 構文による分岐が用意されています。
こちらもしっかりと読み解けるように復習をしておいてください。
 
 
    /// <summary>
    /// マテリアルの色を変える処理
    /// public修飾子なので、他のクラスからでもこのメソッドを実行できる
    /// </summary>
    /// <param name="argumentColorNumber"></param>
    public void ChangeMatColor(int argumentColorNumber) {

        // 引数として渡されたargumentColorNumberに入ってる番号を使い、分岐により色を設定する
        // ここでもmaterial.colorにアクセスすることで色を変更する
        // switch文はいずれかのcaseに入ると終了する( = breakで抜けている)
        switch (argumentColorNumber) {
            case 0:
                material.color = Color.blue;
                break;
            case 1:
                material.color = Color.green;
                break;
            case 2:
                material.color = Color.red;
                break;
        }

        // 色の番号を1ずつ加算する = 次回以降、別の分岐に入るようにする
        colorNumber++;

        // 色の設定値は2までなので、3以上の数値になったら0に戻す処理を入れておく
        if(colorNumber >= 3) {
            colorNumber = 0;
        }
        Debug.Log(colorNumber);
    }


スクリプトをアタッチして設定を行う


 完成したら、このクラスをCubeオブジェクトとPlaneオブジェクトに、それぞれアタッチします

 ヒエラルキーで各オブジェクトを選択し、インスペクターでクラスがアタッチされているかを確認します。
Planeの方では MaterilaTest クラス内の isPlaneFlag チェックをいれてtrueの状態にしておきます。

 その後、色の情報を変更するためにCubuオブジェクトとPlaneオブジェクトの両方に
MaterialTestのインスペクターからMaterialの部分にPlaneのマテリアルをアサインします。

 両方のオブジェクトにMaterialTest をアタッチするのは、それぞれのオブジェクトで色の変更を確認するためです。
またここでは isPlaneFlag というBool型を利用することでオブジェクトに種別を与えています。

変数の役割
 isPlaneFlag = false(チェックなし) => ゲーム中ではCubeオブジェクトであるとMaterialTestに認識させる
 isPlaneFlag = true(チェックあり)   => ゲーム中ではPlaneオブジェクトであるとMaterialTestに認識させる

 このようにフラグには条件が整ったことを判断させる以外に、事前に種別の判断をさせる場合にも利用ができます。


ゲームを実行して確認する


 ではそのまま実行して、色を変更するキーを実行して、色が変っていくかどうか、確認してみましょう。
どちらも青色になり、キー入力をするたびに、同じ色に変っていくはずです。

その後、PlaneオブジェクトのMaterialTest クラスをインスペクターにて確認し、colorNumber を1か2に変更します。
この変数によって色の変更を管理していますので、CubeとPlaneとで ゲーム開始時の 変数の値が異なると、ゲーム開始時の色も変化します。
ではゲームを実行して確認してみましょう。それぞれのオブジェクトの色が異なる状態で始まり、その後も異なる色で変化していきます。


スクリプトのリファクタリングを行う


 見た目の処理の内容はそのままで、内部の処理を見直して改善することをリファクタリングといいます。
バグやエラーの修正とは異なり、正常に処理が動作する状態で、スクリプトの内容を精査し、よりよい記述に書き換えることを言います。

 そのため、リファクタリング後に、エラーが出てしまったり、いままで正常に動いていた処理が変わってしまうようなことは避けなければなりません。

 今回は1つの例として、下記の ChangeMatColor メソッドの処理を一部変更します。
リファクタリングであるので、ゲームを実行した場合には、以前と同じように問題なく動きます。


    /// <summary>
    /// マテリアルの色を変える処理
    /// public修飾子なので、他のクラスからでもこのメソッドを実行できる
    /// </summary>
    /// <param name="argumentColorNumber"></param>
    public void ChangeMatColor(int argumentColorNumber) {

        // 引数として渡されたargumentColorNumberに入ってる番号を使い、分岐により色を設定する
        // ここでもmaterial.colorにアクセスすることで色を変更する
        // switch文はいずれかのcaseに入ると終了する( = breakで抜けている)
        switch (argumentColorNumber) {
            case 0:
                material.color = Color.blue;
                break;
            case 1:
                material.color = Color.green;
                break;
            case 2:
                material.color = Color.red;
                break;
        }

        // 色の番号を1ずつ加算する = 次回以降、別の分岐に入るようにする
        colorNumber++;


////*  ここから修正します  *////


        // 色の設定値は2までなので、3以上の数値になったら0に戻す処理を入れておく
        //if(colorNumber >= 3) {
            //colorNumber = 0;
        //}


        // % 演算子を利用し、上記の if 文と同じ処理を実装する
        colorNumber = colorNumber % 3 == 0 ? 0 : colorNumber;


////*  ここから修正します  *////


        Debug.Log(colorNumber);
    }
}

 スクリプトを修正したらセーブし、ゲームを実行してください。
いままでと同様に制御が行えていれば、リファクタリングは成功です。
 

コメントをかく


「http://」を含む投稿は禁止されています。

利用規約をご確認のうえご記入下さい

Menu



技術/知識(実装例)

2Dおはじきゲーム(発展編)

2D強制横スクロールアクション(発展編)

3Dダイビングアクション(発展編)

2Dタップシューティング(拡張編)

レースゲーム(抜粋)

2D放置ゲーム(発展編)

3Dレールガンシューティング(応用編)

3D脱出ゲーム(抜粋)

2Dリアルタイムストラテジー

2Dトップビューアドベンチャー(宴アセット使用)

3Dタップアクション(NavMeshAgent 使用)

2Dトップビューアクション(カエルの為に〜、ボコスカウォーズ風)

VideoPlayer イベント連動の実装例

VideoPlayer リスト内からムービー再生の実装例(発展)

AR 画像付きオブジェクト生成の実装例

AR リスト内から生成の実装例(発展)

private



このサイト内の作品はユニティちゃんライセンス条項の元に提供されています。

管理人/副管理人のみ編集できます