[Unity2D] NPC 아웃라인 새기기

jaehyeonLee·2024년 9월 17일
0

이번에는 npc 상호작용을 만들기전 상호작용이 가능한 npc 를 구별하기 위해 npc 테두리에 아웃라인을 새길 예정이다. 원래는 직접 shader를 만들어 공부해보고 싶었지만 생각외로 나에게 너무 어려워서 shader 다루는 문제는 나중에 다루도록 하고 이번에는 asset에서 shader를 가져왔다.

https://assetstore.unity.com/packages/vfx/shaders/2d-sprite-outline-109669?locale=ko-KR

그다음으로
상호작용을 위한 material 을하나 만든다. 다운 받은 shader를 넣어주고 본인이 원하는 정도의 테두리를 만들어준다 .
Width 가 테두리의 굵기를 줄여주는 것으로 보였다. 나는 0.8정도로 하여 확인이 가능한 정도로 해주었다.

material 에 default material 또한 만들어 주었는데 이는 플레이어가 npc와 상호작용할 수 있는 거리를 벗어나게 되면 다시 원래대로 만들어주기 위함이다 .

그다음 npcsprite 부분이다.

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

public class NPCSprite : MonoBehaviour
{
    [SerializeField] Material normalState;
    [SerializeField] Material highLight;
    [SerializeField] SpriteRenderer spriteRenderer;

    private void Awake()
    {
        spriteRenderer = GetComponent<SpriteRenderer>();
    }

    public void FlipLeft()
    {
        spriteRenderer.flipX = true;
    }
    public void FlipRight()
    {
        spriteRenderer.flipX = false;
    }
    public void HightLight()
    {
        spriteRenderer.material = highLight;
    }
    public void MakeNormal()
    {
        spriteRenderer.material = normalState;
    }

}

normalState에 default material을 넣어주고 highLight 부분에 상호작용하였을때 나타내기 위한 테두리 material을 넣어준다.

using System.Collections;
using System.Collections.Generic;
using Unity.VisualScripting.Dependencies.Sqlite;
using UnityEngine;

public class NPCController : MonoBehaviour
{
    [SerializeField] NPCSprite sprite;
    [SerializeField] Animator animator;
    [SerializeField] int state;
   
    
    
    private float direction;
    private float movePower= 1.0f;
    private Rect moveBound;

    private float lastClickTime;
    private float doubleclickTime = 0.50f;
   

    private void Start()
    {
        animator = GetComponent<Animator>();
        sprite = GetComponent<NPCSprite>();
        sprite.MakeNormal();
        state = 0;
        moveBound = new Rect(transform.position.x - 5.0f, transform.position.y, 10.0f, 0);
        StartCoroutine(ChangeDirection());
    }
    private void FixedUpdate()
    {
        NPCMove();
    }
    public void NPCMove()
    {
      
        
        if(state==0)
        {
            animator.SetBool("isMove", false);
        }
        else
        {
            animator.SetBool("isMove", true);
            if(state==-1)
            {
                sprite.FlipLeft();
            }
            else if(state==1)
            {
                sprite.FlipRight();
            }
            direction = transform.position.x + state * movePower * Time.deltaTime;
            if (direction <= moveBound.xMin || direction >= moveBound.xMax)
            {
                state *= -1;
            }
            direction=Mathf.Clamp(direction, moveBound.xMin, moveBound.xMax);

            transform.position = new Vector2(direction, transform.position.y);
        }
    }
    IEnumerator ChangeDirection()
    {
        state = Random.Range(-1, 2);
        yield return new WaitForSeconds(5.0f);
        StartCoroutine(ChangeDirection());
    }

    public void OnMouseDown()
    {
        float currentTime =Time.time;
        if(currentTime-lastClickTime<=doubleclickTime)
        {
            ActiveNpc();
        }
        lastClickTime= currentTime;
    }

    public void OnTriggerEnter2D()
    {
        sprite.HightLight();
    }
    public void OnTriggerExit2D()
    {
        sprite.MakeNormal();
        Debug.Log("normal");

    }
    public void ActiveNpc()
    {
       
    }

}

원래는 mouse 가 오브젝트 위로 올라오면 테두리가 나타내도록 하고 싶었는데 지금 현재 게임에 카메라가 다중이라 그런지 mouseEnter가 안통하길래 일단은 Trigger를 이용하여 잘 작동 되는지 확인해보았다.

플레이어와 닿으면 테두리가 나오도록 잘작동이 된다.

지금은 shader를 asset에서 가져오긴 하였지만 이후에는 shader를 직접공부해서 outline 이 나타나도록 만들어보도록하겠다.

profile
이재현의 필기노트

0개의 댓글