Unity:マテリアルをランダムに変更したい

Unity

シーン上のオブジェクトに対してマテリアルをランダムで変更するC#スクリプトを紹介します。

作成イメージです。

プレハブを一定間隔で生成していきます。
生成したプレハブには、事前に準備した5つのマテリアル(Material)のどれかをランダムに設定します。

シーンの準備

シーンにPlaneCubeを1つずつ配置します。

Cubeは「落ちてくるCube」として後ほどプレハブ化します。

まずCubeにRigidbodyを追加しておきます。

一旦、実行確認して落ちてくることを確認します。(Materialで適当に色をつけていますが、この時点では色をつけなくて大丈夫です)

うまくいったので、プレハブ化しておきます。

プレハブ化したらシーン上のCubeは削除しておいてください。

Planeを選択して、InspectorウインドウのPosition項目を全て0にしておきます。
※作るタイミングによってPlaneの位置がまちまちのため

シーンの準備は以上です。

マテリアルの準備

Assetsに複数のマテリアルが準備できているならこの準備は不要です。

今回はプレハブから生成したCubeに、準備した5つのマテリアルからランダムに設定するようにします。

AssetsフォルダにMaterialsフォルダを作って、以下のように5種類のマテリアルを準備しました。

フォルダ名がMaterialsである必要はありません。マテリアル名や色は適当で構いません。
マテリアルが5種類あればOKです。

スクリプトの作成と設定

Plane上のランダムな位置にプレハブ化したCubeが落ちてくるようにします。

SetMaterialという名前でC#スクリプトを作成します。

SetMaterialをダブルクリックしてVisual Studioを起動し、以下のハイライト部分を入力してください。

SetMaterial

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

public class SetMaterial : MonoBehaviour
{
    // 生成するプレハブ格納用
    public GameObject PrefabCube;
    // マテリアル格納用(5つ)
    public Material[] ColorSet = new Material[5];

    // Start is called before the first frame update
    void Start()
    {
        
    }

    // Update is called once per frame
    void Update()
    {
        // 60フレームに1度処理を実行する
        if(Time.frameCount % 60 == 0)
        {
            // 生成するオブジェクトの位置
            Vector3 pos = new Vector3(0.0f, 10.0f, 0.0f);
            // マテリアル配列の添え字をランダムで設定(0~4)
            int ColorNo = Random.Range(0, 5);
            // プレハブを生成
            GameObject cube = Instantiate(PrefabCube, pos, Quaternion.identity);
            // 生成したプレハブのマテリアルを設定
            cube.GetComponent<MeshRenderer>().material = ColorSet[ColorNo];
        }    
    }
}

スクリプトアタッチ用に空のオブジェクトを作成します。

Hierarchyウインドウで、 + > Create Empty を選択し、名前をGameMainとしておきます。

SetMaterialをGameMainにドラッグ&ドロップしてアタッチします。

GameMainを選択し、InspectorウインドウのPrefab Cube項目にAssetsフォルダのCubeプレハブをドラッグ&ドロップします。

同じくInspectorウインドウのColor Set項目5つのMaterialを設定できるようになっています。

準備した5つのマテリアルを Element 0 ~ Element 4 にそれぞれ設定してください。(今回はランダムでこの5つのうちのどれかを選ぶので、順番は適当で構いません)

例)Prefab CubeColor Set項目全てを設定した状態

スクリプトと設定は以上となります。
実行確認してみてください。

カラフルなCubeが落ちてきたら成功です!

スクリプト解説

生成するプレハブとランダム設定するためのマテリアルは、Inspectorウインドウから設定できるようにpublic宣言しておきます。

// 生成するプレハブ格納用
public GameObject PrefabCube;
// マテリアル格納用(5つ)
public Material[] ColorSet = new Material[5];

ランダムで設定しやすくするため、Materialを配列宣言しているところがポイントです。

生成するプレハブの位置は固定にしてあります。Y軸を10.0fとして少し高い所からCubeを落とすようにします。

Vector3 pos = new Vector3(0.0f, 10.0f, 0.0f);

マテリアルをランダムで設定するため、Random.Range関数で変数ColorNoに0~4の数値のどれかを発生させておきます。

int ColorNo = Random.Range(0, 5); 

プレハブの生成だけであれば、Instantiate関数を使って、

Instantiate(PrefabCube, pos, Quaternion.identity); 

のみで可能ですが、生成したプレハブのマテリアルを変更したいので、GameObject型の変数cubeに戻り値を代入しています。

GameObject cube = Instantiate(PrefabCube, pos, Quaternion.identity);

戻り値cubeを利用して生成したプレハブのマテリアルを変更します。
具体的にはMeshRendererコンポーネントのMaterial項目に配列ColorSetを代入することになります。

cube.GetComponent<MeshRenderer>().material = ColorSet[ColorNo];

これらのスクリプト全体を60フレームに1回の割合で実行するようにTime.frameCountを使って制御しています。60の部分の数値は適当に変えてみてください。

// 60フレームに1度処理を実行する
if(Time.frameCount % 60 == 0)
{
    // 生成するオブジェクトの位置
    Vector3 pos = new Vector3(0.0f, 10.0f, 0.0f);
    // マテリアル配列の添え字をランダムで設定(0~4)
    int ColorNo = Random.Range(0, 5);
    // プレハブを生成
    GameObject cube = Instantiate(PrefabCube, pos, Quaternion.identity);
    // 生成したプレハブのマテリアルを設定
    cube.GetComponent<MeshRenderer>().material = ColorSet[ColorNo];
}

以上、Unity:マテリアルをランダムに変更したいでした。

コメント

タイトルとURLをコピーしました