poi’s tech blog

3D多人数同時接続型球体アクション成人向けゲーム開発のためのアイデア、ナレッジ

Unityでカラースプレー的にテクスチャ切り替える

f:id:poipoipoip:20190324155234g:plain
ぷしゅぷしゅぷしゅー

以下備忘録


体色、口内、目、頬、紅潮などはそれぞれ独立したオブジェクト・テクスチャとして作成している。

f:id:poipoipoip:20190324154136p:plain
1つのメッシュオブジェクトに複数マテリアルがついてる

f:id:poipoipoip:20190324154353p:plain
特殊な目や頬なども色ごとに用意

Unityで色を変えるには、マテリアルを取得して設定されているテクスチャを変更したり、マテリアル自体を色ごとに用意して変更するなり色々やり方はあると思うけど今回は前者で試した。

変更したいマテリアルが設定されてるオブジェクトに適用するスクリプト

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

public class ChangeColor : MonoBehaviour {

    public Texture[] image_body;
    public Texture[] image_cheek;
    public Texture[] image_face;

    private int max;
    private int count;

    // Use this for initialization
    void Start () {
        max = image_body.Length;
        count = 0;
    }
    
    // Update is called once per frame
    void Update () {
        
    }

    public void Change()
    {
        Material[] materials = GetComponent<Renderer>().materials;
        for (int i = 0; i < materials.Length; i++)
        {
            Debug.Log(materials[i].name);
            if (materials[i].name == "body (Instance)")
            {
                materials[i].mainTexture = image_body[count];
            }
            else if (materials[i].name == "cheek (Instance)")
            {
                materials[i].mainTexture = image_cheek[count];
            }
            else if (materials[i].name == "face (Instance)")
            {
                materials[i].mainTexture = image_face[count];
            }

        }
        count++;
        if (max == count) count = 0;
    }
}

Material[] materials = GetComponent<Renderer>().materials;でオブジェクトに設定されているすべてのマテリアルが配列で取得できる。

目的のマテリアルを取得して適切にテクスチャを変更するために名前で文字列比較してる。

何故かmaterials[i].namematerials[i].toString()で取得した名前が素直にマテリアル名で取れずにマテリアル名 (Instance)となってしまうのでそのまま愚直に比較してるけどいい方法無いかな…

f:id:poipoipoip:20190324154958p:plain
public image_xx変数にテクスチャ設定してあげる

CanvasのButtonに適用するスクリプト

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

public class tests : MonoBehaviour {
    ChangeColor cc;

    // Use this for initialization
    void Start () {
        cc = FindObjectOfType<ChangeColor>();
    }
    
    // Update is called once per frame
    void Update () {
        
    }

    public void ChangeColor () {
        cc.Change();
    }
}

f:id:poipoipoip:20190324155149p:plain
押すたびにChangeColor()を呼ぶようにする。