[Unity] 오브젝트 투명화 처리

muchan
muchan
∙∙조회 19
[Unity] 오브젝트 투명화 처리

개요

3D 쿼터뷰 게임에서 플레이어가 물체 뒤로 갔을 때 플레이어가 안보이는 현상이 발생한다

현재 만들고 있는 게임에도 똑같이 적용돼서 플레이어가 큰 물체 뒤로 갔을 때

그 물체가 투명화 되는 코드를 작성해봤다.

코드

csharp
using System.Collections.Generic;
using UnityEngine;

public class CameraOcclusionHandler : MonoBehaviour
{
    [SerializeField]
    private Transform player;

    [SerializeField]
    private LayerMask canopyLayer;

    [SerializeField]
    private Material originalMaterial;

    [SerializeField]
    private Material transparentMaterial;

    [SerializeField]
    private float sphereRadius = 0.5f;

    private Camera cam;
    private HashSet<Renderer> fadedObjects = new();

    private void Awake()
    {
        cam = Camera.main;
    }

    private void Update()
    {
        HashSet<Renderer> hitRenderers = new();

        Vector3 direction = cam.transform.position - player.position;
        float distance = direction.magnitude;

        RaycastHit[] hits = Physics.SphereCastAll(
            player.position,
            sphereRadius,
            direction.normalized,
            distance,
            canopyLayer
        );

        foreach (var hit in hits)
        {
            Renderer[] renderers = hit.collider.GetComponentsInChildren<Renderer>();

            foreach (var rend in renderers)
            {
                hitRenderers.Add(rend);

                if (!fadedObjects.Contains(rend))
                {
                    if (rend != null)
                        rend.material = transparentMaterial;
                    fadedObjects.Add(rend);
                }
            }
        }

        List<Renderer> toRestore = new();
        foreach (var rend in fadedObjects)
        {
            if (!hitRenderers.Contains(rend))
            {
                if (rend != null)
                    rend.material = originalMaterial;
                toRestore.Add(rend);
            }
        }
        foreach (var rend in toRestore)
            fadedObjects.Remove(rend);
    }

    private void OnDisable()
    {
        foreach (var rend in fadedObjects)
        {
            if (rend != null)
                rend.material = originalMaterial;
        }
        fadedObjects.Clear();
    }
}
  • 카메라와 플레이어 사이에 있는 오브젝트를 자동으로 투명하게 만든다
  • 플레이어 위치에서 카메라 방향으로 구형 레이캐스트를 쏴서, 사이에 있는 오브젝트를 감지
  • 특정 Layer에 해당하는 오브젝트면 투명화 된 Material로 교체
  • 범위를 벗어나면 다시 오리지널 Material로 교체

적용

위의 스크립트를 Main Camera에 붙이고 필드들을 다 연결해준다

나무 전체를 투명화시키는 것 보단 나무의 위치는 알려줘야할 것 같아서 제일 밑 나무 큐브는 투명화 하지 않았다

아직 나뭇잎 투명화는 어색하게 돼서 나중에 다시 손봐줘야 한다...