본문 바로가기
개발/Unity

유니티 - 오브젝트를 선택된 상태로 만들기 : (3) Shader Outline

by 피로물든딸기 2022. 4. 29.
반응형

깃허브 데스크탑으로 프로젝트 관리하기 강의 오픈!! (인프런 바로가기)

 

Unity 전체 링크

 

오브젝트를 선택된 상태로 만들기 : (1) bool
오브젝트를 선택된 상태로 만들기 : (2) 이미지로 만들기
오브젝트를 선택된 상태로 만들기 : (3) Shader Outline
오브젝트를 선택된 상태로 만들기 : (4) 오브젝트를 하나만 선택하기


링크의 경우, 오브젝트를 선택된 상태로 만들기 위해 이미지를 이용해 outline을 직접 만들었다.

 

이번에는 오브젝트를 선택된 상태로 만들기 위해 Shader를 이용해보자.

먼저 Shader 자체는 Outline Shader로 검색해서 적당한 shader를 구한다.

Shader "Draw/OutlineShader" {
	Properties {
		_OutlineColor ("Outline Color", Color) = (1,0,0,1)
		_Outline ("Outline width", Range (0, 1)) = .1
	}
 
CGINCLUDE
#include "UnityCG.cginc"
 
struct appdata {
	float4 vertex : POSITION;
	float3 normal : NORMAL;
};
 
struct v2f {
	float4 pos : POSITION;
	float4 color : COLOR;
};
 
uniform float _Outline;
uniform float4 _OutlineColor;
 
v2f vert(appdata v) {
	v2f o;

	v.vertex *= ( 1 + _Outline);

	o.pos = UnityObjectToClipPos(v.vertex);
 
	o.color = _OutlineColor;
	return o;
}
ENDCG
 
	SubShader {
		Tags { "DisableBatching" = "True" }
		Pass {
			Name "OUTLINE"
			Tags {"LightMode" = "Always" }
			Cull Front
			ZWrite On
			ColorMask RGB
			Blend SrcAlpha OneMinusSrcAlpha
 
			CGPROGRAM
			#pragma vertex vert
			#pragma fragment frag
			half4 frag(v2f i) :COLOR { return i.color; }
			ENDCG
		}
	}
 
	Fallback "Diffuse"
}

 

Properties에서 Outline의 색을 조절할 수 있다. 

아래의 경우는 빨강색(Red)이 된다.

	Properties {
		_OutlineColor ("Outline Color", Color) = (1,0,0,1)
		_Outline ("Outline width", Range (0, 1)) = .1
	}

Shader를 불러와 Material에 할당한다. 

    Material outline;
    
    void Start()
    {
        outline = new Material(Shader.Find("Draw/OutlineShader"));
    }

 

Shader를 Find 할 때는 파일 이름이 아닌 Shader 옆에 정의된 이름을 사용한다.


OnMouseDown에서 오브젝트의 Material에 Outline을 추가하고, 

OnMouseUp에서 Outline을 다시 제거한다.

 

오브젝트의 Renderer를 받을 변수와 여러 개의 Material을 담을 수 있도록 List를 선언한다.

    Renderer renderers;
    List<Material> materialList = new List<Material>();

 

유니티에 제공되는 큐브의 경우는 Material이 하나지만, 실제 오브젝트는 여러 개일 수 있다.

따라서 List로 처리한다.

 

마우스로 처음 클릭한 경우, materialList를 비워주고, 오브젝트의 Renderer에서 모든 material을 들고온다.

그리고 List에 추가로 outline을 넣은 후, renderer에 다시 넣어준다.

    void OnMouseDown()
    {
        renderers = this.GetComponent<Renderer>();

        materialList.Clear();
        materialList.AddRange(renderers.sharedMaterials);
        materialList.Add(outline);

        renderers.materials = materialList.ToArray();
    }

 

마우스 클릭을 종료하면 materialList에 현재 오브젝트의 모든 material을 다시 받아온다.

OnMouseDown에 의해 outline이 포함되어 있으므로, 이것을 제거한 후, 다시 오브젝트에 반영한다.

    void OnMouseUp()
    {
        Renderer renderer = this.GetComponent<Renderer>();

        materialList.Clear();
        materialList.AddRange(renderer.sharedMaterials);       
        materialList.Remove(outline);

        renderer.materials = materialList.ToArray();  
    }

 

마우스를 클릭하면 아래와 같이 마지막 Element에 outline shader가 적용된 material이 추가된다.

 

아래와 같이 Material이 여러 개인 오브젝트도 정상적으로 Outline이 추가되고 사라지는 것을 알 수 있다.

 

최종 코드는 아래와 같다.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class SelectedOutline : MonoBehaviour
{
    Material outline;

    Renderer renderers;
    List<Material> materialList = new List<Material>();

    private void OnMouseDown()
    {
        renderers = this.GetComponent<Renderer>();

        materialList.Clear();
        materialList.AddRange(renderers.sharedMaterials);
        materialList.Add(outline);

        renderers.materials = materialList.ToArray();
    }

    private void OnMouseUp()
    {
        Renderer renderer = this.GetComponent<Renderer>();

        materialList.Clear();
        materialList.AddRange(renderer.sharedMaterials);       
        materialList.Remove(outline);

        renderer.materials = materialList.ToArray();  
    }

    void Start()
    {
        outline = new Material(Shader.Find("Draw/OutlineShader"));
    }
}

 

Unity Plus:

 

Easy 2D, 3D, VR, & AR software for cross-platform development of games and mobile apps. - Unity Store

Have a 2D, 3D, VR, or AR project that needs cross-platform functionality? We can help. Take a look at the easy-to-use Unity Plus real-time dev platform!

store.unity.com

 

Unity Pro:

 

Unity Pro

The complete solutions for professionals to create and operate.

unity.com

 

Unity 프리미엄 학습:

 

Unity Learn

Advance your Unity skills with live sessions and over 750 hours of on-demand learning content designed for creators at every skill level.

unity.com

반응형

댓글