【Unity】C#スクリプトでテクスチャの色を変更する #1

投稿者: | 2020-06-01

プレイ中にマウスでクリックした場所のテクスチャの色を変更してみます。

まずシーン上のPlaneオブジェクトのマテリアルに設定するテクスチャをスクリプトで新規作成して、白く塗りました。

[SerializeField] GameObject plane;
[SerializeField] Texture2D tex3; // 上から描画するテクスチャ
[SerializeField] GameObject cube;

MeshRenderer meshRenderer;
Mesh mesh;   
Texture2D tex; // Planeにつけるテクスチャ
Color[] c;

// ---
// Start()
tex = new Texture2D(256,256,TextureFormat.RGBA32, false);

for(int w = 0; w < tex.width; w++)
{
    for (int h = 0; h < tex.height; h++)
    {
        tex.SetPixel(w, h, Color.white);
    }
}
meshRenderer = plane.GetComponent();
mesh = plane.GetComponent().mesh;

// テクスチャをPlaneのマテリアルに設定
meshRenderer.material.SetTexture("_BaseColorMap", tex);

SetPixelに対応したテクスチャフォーマットにしないとエラーがでます。

そして、クリックしたときにマウスカーソルからレイを飛ばして、Planeオブジェクトとぶつかった場所のUV座標を取得し、上から描画するテクスチャのサイズの四角形の中の色を変更します。

// Update()
if (Input.GetMouseButton(0))
{

    Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);

    RaycastHit hit;
    if (Physics.Raycast(ray, out hit,Mathf.Infinity))
    {
        tex.SetPixels(Mathf.FloorToInt(hit.textureCoord.x * tex.width - tex3.width /2 ), Mathf.FloorToInt(hit.textureCoord.y * tex.height - tex3.height / 2), tex3.width, tex3.height, c);
        tex.Apply();
    }
}

SetPixelsで指定した四角形の中の色を変えられます。引数には基準の座標と縦横のサイズと色の配列を入れます。

RaycastHit.textureCoordでレイが当たった地点のUV座標が取れるので、それにテクスチャのサイズをかけると色を変える地点がわかります。

色を変える範囲のサイズは上から描画する小さなテクスチャのサイズにしますが、第1,2引数で指定する座標はこの四角形の角なので、これを中央にするために、小さなテクスチャのサイズの半分の長さを引いています。

色の配列はテクスチャから簡単に取れます。

// Start()
c = new Color[tex3.width * tex3.height];
c = tex3.GetPixels(0, 0, tex3.width, tex3.height);

この配列には、画像の左下からまず右へ行って、画像の次の行ではまた左から右へという順に取得した色が入っているようです。

for(int i = 0; i < tex3.width * tex3.height; i++)
{

    var a = Instantiate(cube, new Vector3(Mathf.FloorToInt(i % tex3.width), 0, Mathf.FloorToInt(i / tex3.width)), cube.transform.rotation);
    a.GetComponent().material.SetColor("_BaseColor", c[i]);

}

スクリプトでテクスチャの読み書きをするには、テクスチャを選択して、インスペクタでRead/Write Enabledにチェックを入れていないといけません。

チェックが入っているかどうかをスクリプトで確認するには、Texture2D.isReadableを使います。上のようにスクリプトで新規作成したテクスチャはデフォルトでtrueになっています。

これでプレイ中にテクスチャに色を塗ることができますが、冒頭のGIFのように星の画像の余白部分が下の色を塗りつぶしてしまったり、回転しても描画する星の向きが変わらなかったり、星のテクスチャがPlaneからはみ出るところでは描画できないなど課題が多いです。

コメントを残す

メールアドレスが公開されることはありません。