퍼온 자료

Unity 유니티 스크립트를 통한 color 컬러 변경

ITSkeleton 2020. 6. 18. 11:41
728x90
반응형

출처: http://blog.naver.com/PostView.nhn?blogId=ocy1011&logNo=220726159238

이번 시간에는 Color 설명과 함께 스크립트를 통해 Plane의 색깔을 바꿔봅시다.

Material를 만들어서 오브젝트에 적용하는 과정이 기억나시나요? Material를 만들어서 오브젝트의 MeshRenderer의 Material을 적용시켰었습니다. 우리는 스크립트를 통해 MeshRenderer -> Material로 접근해서 Color를 바꿔볼 것입니다.

Component에 접근하려면 어떻게 해야 된다고 했었죠? 네 바로 GetComponent<>().입니다.
ObjectMaker 스크립트에서 아래와 같이 작성해 줍시다.

using UnityEngine;
using System.Collections;

public class ObjectMaker : MonoBehaviour {
    public static ObjectMaker instance;
    public Transform plane;
    Vector3 planePos;

    void Awake()
    {
        instance = this;
    }
    
    void Start()
    {
        for(int i=0; i<8; i++)
        {
            Transform newPlane = Instantiate(plane);
            newPlane.GetComponent().material.color = Color.red;
            SpawnPlane(newPlane);
           
        }
    }

    public void SpawnPlane(Transform p)
    {
        p.position = planePos;
        Vector3 planeInterval = new Vector3(0, 0, 10);
        planePos += planeInterval;
    }
}

추가된 것은 newPlane.GetComponent<MeshRenderer>().material.color = Color.red; 한 줄입니다.  차근차근 살펴보시면 newPlane의 MeshRenderer Component로 접근해서 그것의 하위 목록에 해당하는 material로 접근하고 그다음 material의 color로 접근한 것입니다. 접근하는 과정이 짧진 않지만 마지막에 color로 끝나니깐 = 뒤에는 Color에 해당하는 것이 와야 합니다. 그래야 =이 성립하게 되는 것이죠. Color.red는 말 그대로 빨간색입니다.

실행하시면 아래 사진과 같은 결과를 얻게 됩니다.

Project 창을 보시면 Yellow Material의 색깔이 변하지 않았음에도 불구하고 Yellow Material를 가진 Plane들은 전부 빨간색으로 변했습니다. 이렇게 MeshRenderer->material->color로의 접근은 기존 Material의 성질은 유지하되, 색깔 변경에 있어서는 각자 독립되어 있는 상태로 만들어 버립니다.

위와 같이 Inspector에서 Plane 하나의 색깔을 변경하였습니다. 이때 다른 Plane의 색깔이 바뀌는 것도 아니고 Assets의 Material의 색깔이 바뀌는 것도 아닙니다. 

Assets 안의 Material 색깔을 바꾸려면 어떻게 해야 할까요? 그러기 위해서는 

public Material mat; void Start() { mat.color = Color.blue; }

Material 변수를 선언하고 유니티 상에서 

다음과 같이 설정하고 
mat.color = Color.blue;처럼 색깔을 바꿔주고 게임을 실행하면 아래와 같이 Material의 색깔이 바뀝니다.

그리고 게임 실행을 끝냈을 때도

Material의 색깔은 변해있는 상태입니다. 이러한 기능이 있다는 것만 알아두시고 그전의 내용으로 다시 돌아갑시다.

Color.으로 제공하는 색깔은 총 11개가 있습니다. 보여드리기 위해 UI와 간단한 코드를 작성하여 다음과 같은 결과를 얻었습니다. 

총 11가지 중에 gray와 grey는 색깔이 같은 회색이라 한 곳에 표현하였고 clear는 아무런 값도 없는 투명한 색깔입니다. 다만 Material을 투명하게 만들려면 특별한 조치를 취해줘야 합니다. 하지 않는다면 A 값을 무시한 RGB의 색을 구성하여 RGB가 각각 0인 black의 값을 갖게 됩니다.

위의 사진은 newPlane.GetComponent<MeshRenderer>().material.color = Color.clear;의 결과물입니다. 투명도를 조절하는 A 값이 0이지만 plane의 색깔은 투명하지 않고 검은색입니다.

스크립트를 통해 다양하게 색깔을 바꾸고 싶은데 Color.로 제공하는 11가지 색깔만 사용할 수 있을까요? 그렇지 않습니다.

우리가 새로운 Color를 만들어서 사용하면 됩니다. 방식은 새로운 Vector3을 만드는 것처럼 new Color()를 사용하면 됩니다.

newPlane.GetComponent<MeshRenderer>().material.color = new Color(0, 0, 0);

이렇게 말이죠. (A 값까지 입력하려면 new Color(0, 0, 0, 0)로 할 수 있습니다)

이 사진을 다시 한 번 봐주세요. 하얀색인 white의 RGB 값은 (1, 1, 1)로 되어있습니다. 하지만 아래의 사진을 보시면 하얀색의 RGB 값은  (255, 255, 255)입니다. 이게 어떻게 된 일일까요?

복잡하게 생각하지 마시고 이렇게 생각하시면 됩니다. 팔레트와 유사한 Color 창의 값을 255f로 나눈 값을 스크립트에서 Color 값으로 생각한다. 제가 설명을 잘 못하겠는데 

위의 사진처럼 RGB 값이 (150, 150, 150)이라면 

newPlane.GetComponent<MeshRenderer>().material.color = new Color(150/255f, 150/255f, 150/255f);

로 같은 색깔을 구현할 수 있습니다. 

만약 RGB 값이 (50, 100, 150)이라면

newPlane.GetComponent<MeshRenderer>().material.color = new Color(50/255f, 100/255f, 150/255f);

이렇게 표현하는 것입니다. 이제 이해가 되실 것이라고 생각합니다.

그렇다면 newPlane을 생성할 때 i에 따라 색깔이 다르게 만들어 줍시다.

using UnityEngine;
using System.Collections;

public class ObjectMaker : MonoBehaviour {
    public static ObjectMaker instance;
    public Transform plane;
    Vector3 planePos;

    void Awake()
    {
        instance = this;
    }
    
    void Start()
    {
        for(int i=0; i<8; i++)
        {
            Transform newPlane = Instantiate(plane);
            newPlane.GetComponent().material.color = new Color(i/7f, i / 7f, i / 7f);
            SpawnPlane(newPlane);
        }
    }

    public void SpawnPlane(Transform p)
    {
        p.position = planePos;
        Vector3 planeInterval = new Vector3(0, 0, 10);
        planePos += planeInterval;
    }
}

newPlane.GetComponent<MeshRenderer>().material.color = new Color(i/7f, i / 7f, i / 7f);
이것 하나만 추가해주시면 됩니다. Color의 값은 1이 최대이므로 i가 0에서 7까지 증가하는 for 구문에서 이렇게 코드를 작성하면 

다음과 같이 각기 다른 색깔로 만들 수 있습니다.

만약에 
newPlane.GetComponent<MeshRenderer>().material.color = new Color(0, i / 7f, i / 7f);
으로 바꾼다면 

다음과 같은 결과를 얻을 수도 있습니다.

이번 강의는 이것으로 마치겠습니다. 감사합니다.

[출처] [유니티 강의]스크립트를 통한 Color 변경|작성자 차돌

 

 

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

출처: https://guesty.tistory.com/entry/%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8%EB%A1%9C-material-%EB%B3%80%EA%B2%BD%ED%95%98%EA%B8%B0

동적으로 GameObject의 재질을 변경해야 할 경우.

material이 하나일 때나 0번째 material만 수정할 때.

// source material
Material mt = Resources.Load("something", typeof(Material)) as Material;
// resource 폴더에서 불러온 재질을 복사
renderer.material = mt;

material 여러개일때나 전체 material을 수정할 때.

view sourceprint?
// source material
Material mt = Resources.Load("something", typeof(Material)) as Material;
// 모든 재질을 임시로 복사
Material[] mts = renderer.materials;
// 원하는 인덱스의 재질을 불러온 재질로 복사
mts[1] = mt;
// 임시로 복사해뒀던 재질로 변경
renderer.materials = mts;


Resources.Load()의 경로는 Assets/Resources 안에 있는 것들만 접근이 가능하다.

Resources 폴더가 없으면 만들어 줘야함.



출처: https://202psj.tistory.com/1285?category=640054 [알레폰드의 IT 이모저모]

728x90
반응형