Unity Engine

Flast White, Shader

SB_J00N 2023. 4. 2. 23:13
public class FlashSprite : MonoBehaviour
{
    [SerializeField] private SpriteRenderer originalSprite;

    [SerializeField] private Material flashMaterial;

    [SerializeField] private float duration;

    [SerializeField] private int reapeatFlashNum = 1;

    private SpriteRenderer spriteRenderer;

    private Material originalMaterial;

    private Coroutine flashCoroutine;

    private void Start()
    {
        if (this.originalSprite != null)
        {
            this.spriteRenderer = this.originalSprite;
        }
        else
        {
            this.spriteRenderer = base.GetComponent<SpriteRenderer>();
        }
        this.originalMaterial = this.spriteRenderer.sharedMaterial;
    }

    private void OnDisable()
    {
        this.StopFlash();
    }
    public void Flash()
    {
        if (this.flashCoroutine != null)
        {
            base.StopCoroutine(this.flashCoroutine);
        }
        if (base.gameObject.activeSelf)
        {
            this.flashCoroutine = base.StartCoroutine(this.FlashRoutine());
        }
    }

    public void StopFlash()
    {
        if (this.flashCoroutine != null)
        {
            base.StopCoroutine(this.flashCoroutine);
            this.spriteRenderer.material = this.originalMaterial;
            this.flashCoroutine = null;
        }
    }

    private IEnumerator FlashRoutine()
    {
        if (this.spriteRenderer != null)
        {
            for (int i = 0; i < this.reapeatFlashNum; i = 1, i ++)
            {
                this.spriteRenderer.material = this.flashMaterial;
                yield return new WaitForSeconds(this.duration);
                this.spriteRenderer.material = this.originalMaterial;
                yield return new WaitForSeconds(this.duration);
            }
        }
        this.flashCoroutine = null;
        yield break;
    }


    
}

라이트한 게임에서 보통 유닛이 피격시 흰색으로 반짝하며 데미지를 입는 경우를 표현하기 위한 코드이다.

지금 연습겸 만들고 있는 게임이, Pixel Art를 기반으로 해서, 그냥 각 유닛들의 Sprite가 모두 흰색인것을 따로 만들면 되는거 아니야? 하고 단순히 생각했는데, 발생하는 문제가

1. Animation이 계속 재생중이라, 피격시 에니메이션이 부드럽게 이어지게 코드를 짜야함

2. 모든 유닛들에 대해 Sprite를 만들고, 코드를 따로 짜는등..

 

아무튼 여간 귀찮은 반복작업이 될 것같아서, 다른방법을 찾기위해 열심히 구글링과 유튜브를 검색한 결과

저렇게 흰색으로 반짝하는것을 "Flash White"라 한다. 처음 알았다.

그래서 찾다보니 결국 material을 교체하는 식의 구현이 괜찮을 것 같았고, 쉐이더 코드도 아래에서 얻을 수 있었다.https://www.reddit.com/r/Unity3D/comments/1vkirr/colorwhite_and_spriterenderer/ 

Shader "PaintWhite"
{
    Properties
    {
        _MainTex("Particle Texture (Alpha8)", 2D) = "white" { }
    }

        Category
    {
        Tags { "Queue" = "Transparent" "IgnoreProjector" = "True" "RenderType" = "Transparent" }
        Blend SrcAlpha One
        Cull Off Lighting Off ZWrite Off Fog { Color(0, 0, 0, 0) }

        BindChannels

        {
            Bind "Color", color
            Bind "Vertex", vertex
            Bind "TexCoord", texcoord

        }

        SubShader

        {
            Pass

            {
                SetTexture[_MainTex]

                {
                    combine primary, texture * primary

                }
            }
        }
    }
}

이에 따라 처음 보이는 코드가, material을 교체하는 방식으로 FlashWhite 효과를 낼 수 있는 것이다. 사용법은 인스펙터에

메테리얼과 스프라이트 등을 잘 등록해주고, 공격당함을 감지하는 Method에 이제 flashsprite.Flash()만 추가해준다면 아주 간단하게 구현할 수 있다.

 

이에 따라 쉐이더까지 공부해보려 했는데, 진짜 이부분부터는 약간 다른영역같아서 정말 기본중의 기본만 이해하고 포기했다. 왜냐면 전장의 안개(Fog of War)를 구현해보려고 Chatgpt와 열심히 얘기하면서 쉐이더를 이용해 구현을 해보려 했는데, 처참히 실패했다. 내가 쉐이더 스크립트를 제대로 이해못하니 참 쉽지않은 작업이였다. 

 

아무튼 FlashWhite는 끝!