TIL

2023/11/29 TIL

미역제자 2023. 11. 29. 20:28


어제에 이어서 오늘 개인과제 마무리를 하고자 한다.

 

오전에 과제 제출 전까지 시간이 남기에, NPC와의 대화 로직을 만들어보고자 한다.

 

과제에서 요청했던 부분은 NPC 근처로 가면 대화 상호작용 키가 열리게끔만 하면 되어서, 생각보다 난이도가 높아 보이진 않았다.

 

1. 먼저 NPC에 Collider 2D를 달아놓고 istrigger 버튼을 켜놓아서 근처에 가면 trigger가 발동되도록 했다.

2. 원하는 범위만큼 Collider 2D 범위를 늘렸다.

3. 범위에 들어갈 때는 대화 UI가 켜지고( Void OnTriggerEnter(Collider c)),  범위에서 벗어나면 대화 UI가 꺼지도록 Void OnTriggerExit(Collider c) 코드를 작성했다.

https://dnf-lover.tistory.com/entry/Unity-2D-%EB%9F%AC%EB%8B%9D-%EA%B2%8C%EC%9E%84-%EB%A7%8C%EB%93%A4%EA%B8%B0-6-Unity%EC%9D%98-%EC%B6%A9%EB%8F%8C-%EC%B2%98%EB%A6%ACCollision-Trigger

 

[Unity-2D 러닝 게임 만들기 6] Unity의 충돌 처리(Collision, Trigger)

Unity에선 여러 충돌 처리를 지원해준다. 그 중 가장 대표적인 두 가지는 Trigger와 Collision이다. 이 둘의 차이와 함께 충돌 처리를 해보도록 하자. 1. 충돌처리 조건 충돌이 일어나기 위해서는 충돌

dnf-lover.tistory.com

 

사실 지금 생각해보니 상호작용 키를 따로 배정해서 NPC 근처에서 상호작용 키를 누르면 NPC와 대화가 가능하도록 만들어 봤어도 좋았을 것 같다.


과제에 대한 해설 영상이 올라왔다. 

벡터에 대한 부분은 고등학교~얼마전까지 계속 듣던 내용이여서 넘어가고, 플레이어 이동 구현부분을 흥미롭게 들었다.

플레이어의 이동 구현을 Legacy 코드로 구현하는 법과  input을 이용한 방법 2가지를 알려주었다.

 

Legecy코드로 구현
- 먼저 입력을 받아와야 한다.
-> Input.GetAxis로 입력을 받을 수 있다.

void Update()
{
	float x = Input.GetAxis("Horizontal"); //수평을 의미. A, D를 입력
	float y = Input.GetAxis("Vertical"); //수직을 의미. W,S
	
	transform.position += new Vector3(x, y);
}

transform.position은 스크립트가 붙어있는 오브젝트의 좌표. 3차원 좌표를 말한다.


이 코드를 사용하면 이동이 구현된다. 하지만 캐릭터가 너무 빠르다

.
오른쪽 입력(D)-> 1을 반환
왼쪽 입력(A)-> -1을 반환
위 입력(W)-> 1을 반환
아래 입력(S)-> -1을 반환

void Update는 프레임마다의 이동을 의미한다. 지금 상태로는 프레임마다 1씩 움직인다고 보면 된다. 1초에 프레임 만큼 움직이게 되는 것이다. 따라서 Time.deltaTime을 곱해야한다.
->모든 컴퓨터에서 사양이 다르더라도 속도를 동일하게 만든다.

 

또, public float speed;란 변수를 만들어서 곱해서 속도를 늘릴 수 있다.


지금 상태는 가속도가 있다. 이유는 GetAxis가 바로 1을 반환하는게 아니라 0부터 서서히 증가하기 때문에 속도역시 0부터 점차 증가하는 방식이다.
-> GetAxisRaw는 바로 1을 반환한다. 따라서 입력과 동시에 캐릭터를 조종할 수 있다.


대각선으로 이동하면 속도가 빠르다. 벡터의 합이 1보다 커지기 때문이다.

-> 정규화를 함. (new Vector3(x,y)).nomalized 

-> 이러면 모든 방향의 벡터가 1로 정규화 되기 때문에 속도가 일정해진다.

마우스 입력받는 법도 만들어 보겠다.

void Update()
{
	float X = Input.GetAxis("Mouse X");
	float Y = Input.GetAxis("Mouse Y");
}

혹은

void Update()
{
	Vector3 mousePos = Input.mousePosition; //이건 벡터 값으로 반환
}

이렇게 입력 값을 받아 준 후

SpriteRenderer sprite;
void Start()
{
	sprite = GetComponenetInChildren<SpriteRenderer>();

	if(mousePos.x<Screen.width / 2) // 마우스가 화면 왼쪽에 있을 때
	{
		sprite.flipX = true;
	}
	else
	{
		sprite.flipX = false;
	}
}


=> 간략화 가능하다.

void Update(){
	transform.position
    		+= (new Vector3(Input.GetAxisRaw("Horizontal"), Input.GetAxisRaw("Vertical"))).nomalized * Time.deltaTime* speed;
	sprite.flipX = (Input.mousePosition.x <Screen.width /2)? true : false;
}


 + 추가로 활 움직임도  구현해 보았다.

public Transform bow;

void Update
{ // 마우스 위치 같은 스크린 상의 좌표는 오브젝트가 월드 좌표로 존재하기 때문에 월드 좌표로 바꿔주어야함.
 //Camera.man.ScreenToWorldPoint(Input.mousePosition); // 이것도 벡터 값을 반환함.
bow.LookAt(Camera.man.ScreenToWorldPoint(Input.mousePosition), Vector3.forward) ; //transform에는 LookAt(어디를 바라 볼 것인지)이 있다. 
//Vector3.forward: 기준점을 넣을 곳에 위치. 앞방향을 기준점으로 삼겠다는 뜻. -> 유니티에선 z축을 기준으로 회전함
}


하지만 이런 코드는 객체지향에 완벽하게 위배된다. 사용을 자제할 필요가 있다.

단순 테스트 용도로 빠르게 만들어야 할 경우 이런 절차지향적 방식도 사용할 수도 있다.

'TIL' 카테고리의 다른 글

2023/12/01 TIL  (0) 2023.12.01
2023/11/30 TIL  (1) 2023.11.30
2023/11/28 TIL  (0) 2023.11.28
2023/11/27 TIL (객체지향 / SOLID원칙)  (1) 2023.11.27
2023/11/24 TIL  (0) 2023.11.24