[Unity3D] 오브젝트 색상을 txt 파일에 저장된 색으로 바꾸기




오브젝트의 색 바꾸기


유니티에서 오브젝트 색을 바꾸는 방법은 2가지가 있다.

첫째는 수동으로 직접 하나하나 바꾸는 방법이다.

1. 색을 바꾸고 싶은 일반 오브젝트나 prefabs에서 Sprite Renderer의 Color의 색상자를 클릭한다.




2. 클릭하면 팔레트 같은 것이 나오는데 여기서 원하는 색을 찍어서 사용하면 된다.





3. 또는 색 선택창의 상단에 색을 바꾸는 방식을 바꿀 수 있는데 여기서 2번째에서 RGB를 바꾸거나 Hex Color를 바꿔주면 된다.






기본적인 방법이지만 바꿔야 할 오브젝트가 많다면 귀찮다. 또 오브젝트를 동적으로 불러오는 경우 default 색으로 지정이 되는데, 이런 경우도 위와 같은 방법으로는 바꿀 수 없다.


두번째 방법은 스크립트로 동적으로 색을 바꿔주는 방법이다.

일단 동적으로 오브젝트를 생성해서 색을 바꿔주는 방법은 아래와 같다.



string path = "Prefabs/obj/" + obj[i][0];
GameObject o = Resources.Load(path) as GameObject;
GameObject b = Instantiate(o, new Vector3(x, y), Quaternion.identity);
b.GetComponent<SpriteRenderer>().color = new Color(R / 255f, G / 255f, B / 255f);


Prefabs 폴더에 저장된 오브젝트를 Resources.Load로 불러와서 GameObject 타입으로 만든 후 (여기서 obj[i][0]은 불러온 오브젝트를 저장한 배열이므로 무시해도 괜찮다.) 이 오브젝트를 b라는 게임 오브젝트로 Instanticate() 로 동적으로 생성해 준다.
우리는 위에서 Sprite Renderer의 color를 수동으로 바꿔줬는데, 코드는 보다시피 위의 과정을 함축하고 있다. (R, G, B는 각 칸에 들어갔던 RGB 값의 수치) 여기서 R, G, B를 각각 255f 로 나눠주는데, 유니티에서 color는 입력한 값을 255f로 나눠준 것을 rgb로 보여주는 것이다. 따라서 코드로 지정할 때도 255f로 나눠줘야한다.





본인은 각 스테이지가 같은 색 계열의 오브젝트를 가지게 하고 싶었는데, 따라서 스테이지 별로 txt 파일에 rgb 값을 저장하고, 스테이지를 불러올 때 마다 해당 스테이지에 맞는 rgb를 int R, int G, int B에 넣고 색을 바꿔주었다.

1. mapColor.txt에 아래와 같은 형식으로 저장해준다.




2. 딱히 설명이 필요한 코드는 아니지만, 혹시 잘 모르겠다면 아래 설명을 확인해 보도록 하자.



using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.UI;
using System.Text.RegularExpressions;

public class sceneManager : MonoBehaviour
{
    public int[,] objColor = new int[5, 3];

    private void colorSave()
    {

        string ColorPath = "map/mapColor";
        TextAsset mapColor = Resources.Load(ColorPath) as TextAsset;

        string[] txt = Regex.Split(mapColor.text, @"\n");
        if (txt.Length < 1) return;
        for(int i = 0; i < txt.Length; i++)
        {
            string[] lineTxt = Regex.Split(txt[i], @",");
            for(int j = 0; j < lineTxt.Length; j++)
            {
                objColor[i + 1, j] = System.Convert.ToInt32(lineTxt[j]);
            }
        }
    }


    private void Start()
    {
        colorSave();
    }
}



  1. 각 index에 R, G, B를 저장할 objColor를 선언한다.
  2. map 폴더에 저장되어 있는 mapColor의 경로를 저장할 ColorPath string을 선언해준다.
  3. 엔터키, 즉 '\n'를 기준으로 잘라준 모든 라인을 저장해주는 txt 배열을 저장한다.
  4. txt의 길이가 1보다 작으면 (string이 없으면) return 해준다.
  5. txt를 돌면서 ','를 기준으로 잘라서 각 index에 int로 변환해서 저장해준다.

참고


  • @"\n"나 @","에서 @는 문자열에서 백슬래쉬를 쓸 때 "\\n"이런 식으로 쓰지 않고 그냥 "\n"이렇게만 써줘도 의도한대로 나오게끔 해주는 기호이다.
  • string -> int를 할 때 System의 Convert.ToInt32로 변환할 수 있다.

결과적으로 아래와 같은 코드가 나오는데, 여기서 다른건 중요하지 않고 find() 에서 sceneManager 클래스를 가져와서 int R, int G, int B를 stageLevel에 해당하는 index의 0, 1, 2로 지정해서 아까 얘기했던 color에 대입해주면 된다.



using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.Text.RegularExpressions;
using UnityEngine.UI;

public class Map_Editor : MonoBehaviour
{
    public void find()
    {
        sceneManager scenemanager = GameObject.Find("GameManager").GetComponent<sceneManager>();
        for(int i = 0; i < obj.Count - 1; i++)
        {
            int x = System.Convert.ToInt32(obj[i][1]);
            int y = System.Convert.ToInt32(obj[i][2]);

            int R = scenemanager.objColor[scenemanager.stageLevel, 0];
            int G = scenemanager.objColor[scenemanager.stageLevel, 1];
            int B = scenemanager.objColor[scenemanager.stageLevel, 2];

            string path = "Prefabs/obj/" + obj[i][0];

            if (obj[i][0].Contains("step"))
            {

                GameObject o = Resources.Load(path) as GameObject;
                GameObject b = Instantiate(o, new Vector3(x, y), Quaternion.identity);
                b.GetComponent<SpriteRenderer>().color = new Color(R / 255f, G / 255f, B / 255f);

                b.tag = obj[i][0];

                if (obj[i][0].Contains("up")) Up = true;
                else if (obj[i][0].Contains("down")) Down = true;
                else if (obj[i][0].Contains("left")) Left = true;
                else if (obj[i][0].Contains("right")) Right = true;

                stepCnt++;
            }

            else
            {
                GameObject o = Resources.Load(path) as GameObject;
                GameObject b = Instantiate(o, new Vector3(x, y), Quaternion.identity);

                if(obj[i][0] != "robot" && obj[i][0] != "player")
                {
                    b.GetComponent<SpriteRenderer>().color = new Color(R / 255f, G / 255f, B / 255f);
                }

                if (obj[i][0] == "robot")
                {
                    b.GetComponent<PlayerController>().enabled = false;
                    b.tag = obj[i][0];
                }
                else b.tag = obj[i][0];
            }
        }
    }
}


댓글