이번에는 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 이 나타나도록 만들어보도록하겠다.