유니티 주변 환경에 따라 오브젝트 색상 바꾸기

게임 속 오브젝트가 주변의 빛이나 환경 색상에 맞춰 자동으로 색이 변하는 것을 본 적 있나요? 마치 카멜레온처럼 자연스럽게 주변과 동화되는 효과는 게임의 시각적 몰입도를 크게 높여줍니다. 오늘은 유니티에서 이 기능을 간단하게 구현하는 방법을 소개합니다.

이 기능을 구현하는 핵심은 카메라를 이용해 주변 환경의 색상 정보를 읽어와 오브젝트의 재질에 적용하는 것입니다. 복잡한 셰이더 프로그래밍 없이도, 기본적인 스크립트만으로 충분히 멋진 효과를 만들 수 있습니다.


1. 주변 색상 추출 스크립트 만들기

먼저, 주변 환경의 평균 색상을 계산하는 스크립트를 작성해봅시다. ColorBlender.cs라는 이름으로 스크립트를 생성하고 아래 코드를 복사해 넣어주세요.

C#

using UnityEngine;

public class ColorBlender : MonoBehaviour
{
    // 주변을 렌더링할 카메라 (Inspector에서 설정)
    public Camera sceneCamera;

    // 색상을 적용할 오브젝트의 Material
    private Material objectMaterial;

    // 색상 업데이트 빈도 조절 (매 프레임/수동)
    public bool updateContinuously = true;

    // 색상 분석을 위한 텍스처 크기
    public int resolution = 32;

    void Start()
    {
        // 렌더러 컴포넌트가 있는지 확인하고 재질 가져오기
        Renderer renderer = GetComponent<Renderer>();
        if (renderer != null)
        {
            objectMaterial = renderer.material;
        }
        else
        {
            Debug.LogError("오브젝트에 Renderer 컴포넌트가 없습니다.");
            return;
        }

        // 카메라가 설정되지 않았다면 메인 카메라 사용
        if (sceneCamera == null)
        {
            sceneCamera = Camera.main;
        }

        // 초기 색상 설정
        UpdateObjectColor();
    }

    void Update()
    {
        // updateContinuously가 켜져 있으면 매 프레임 색상 업데이트
        if (updateContinuously)
        {
            UpdateObjectColor();
        }
    }

    public void UpdateObjectColor()
    {
        // 렌더 텍스처와 Texture2D 생성
        RenderTexture renderTexture = new RenderTexture(resolution, resolution, 24);
        sceneCamera.targetTexture = renderTexture;
        sceneCamera.Render();

        Texture2D texture = new Texture2D(resolution, resolution, TextureFormat.RGB24, false);
        RenderTexture.active = renderTexture;
        texture.ReadPixels(new Rect(0, 0, resolution, resolution), 0, 0);
        texture.Apply();

        // 텍스처의 모든 픽셀 색상 가져와 평균 색상 계산
        Color[] pixels = texture.GetPixels();
        Color averageColor = Vector4.zero;
        foreach (Color pixel in pixels)
        {
            averageColor += (Vector4)pixel;
        }
        averageColor /= pixels.Length;

        // 오브젝트의 재질 색상을 변경
        objectMaterial.color = averageColor;

        // 사용한 리소스 정리
        sceneCamera.targetTexture = null;
        RenderTexture.active = null;
        DestroyImmediate(renderTexture);
        DestroyImmediate(texture);
    }
}

이 스크립트는 **sceneCamera**를 통해 주변 환경을 낮은 해상도의 텍스처로 렌더링한 후, 그 텍스처의 모든 픽셀 색상을 모아 평균값을 계산합니다. 이렇게 얻은 평균 색상을 오브젝트의 Material에 적용하여 색상을 변경하는 방식입니다.


2. 유니티에서 설정하기

스크립트를 만들었다면 이제 유니티 에디터에서 간단하게 설정할 차례입니다.

  1. 스크립트 부착: 색상이 변하길 원하는 오브젝트(예: 큐브, 스피어 등)에 ColorBlender.cs 스크립트를 드래그하여 부착합니다.
  2. 카메라 연결: Inspector 창의 Color Blender 컴포넌트를 보면 Scene Camera 필드가 보일 겁니다. 여기에 씬의 **메인 카메라(Main Camera)**를 드래그하여 연결해 주세요.
  3. 성능 최적화: updateContinuously 옵션은 매 프레임 색상을 업데이트할지 결정합니다. 이 기능을 켜두면 실시간으로 색상이 변하지만, 성능에 약간의 부담을 줄 수 있습니다. 만약 색상 변화가 자주 필요하지 않다면 이 옵션을 끄고, 특정 이벤트(예: 플레이어가 새로운 공간으로 이동했을 때)에 UpdateObjectColor() 함수를 직접 호출하는 것이 효율적입니다. resolution 값을 낮추면 계산량이 줄어들어 성능이 향상됩니다.

결과 확인 및 활용

이제 게임을 실행하고 오브젝트를 주변 환경이 다양한 곳으로 옮겨보세요. 오브젝트가 주변 색상과 비슷하게 변하는 것을 확인할 수 있습니다.

이 기술은 단순히 오브젝트의 색상을 바꾸는 것 외에도 다양한 곳에 활용될 수 있습니다.

  • 카멜레온 효과: 캐릭터가 주변 환경에 맞춰 보호색을 띠게 만들 수 있습니다.
  • 환경 조명 효과: 오브젝트가 주변 조명의 색상에 반응하는 것처럼 보이게 할 수 있습니다.
  • 시각적 피드백: 플레이어가 특정 구역에 진입했을 때 오브젝트 색상을 바꿔주는 등 다양한 인터랙션에 활용할 수 있습니다.

이 스크립트를 응용하여 게임의 시각적 요소를 더욱 풍부하게 만들어 보세요! 혹시 코드를 수정하거나 기능을 확장하는 데 어려움이 있다면 언제든 알려주세요.

댓글 남기기