오늘의 학습키워드
"좌표"
✏️오늘 배운 내용
오늘은 강의 수강이 다 끝나서 수박게임을 기반으로 한 행성게임을 만들어보기로 했다.
먼저 행성과 바닥간의 선을 구현하기 위해
1.square 오브젝트의 scale 조절
2.UI Image로 구현
3.RayCast를 이용
두가지를 생각했었는데 행성의 크기를 종류에 따라 바꿀예정이였어서 행성의 scale 이 바뀌면
자식 오브젝트인 선도 scale이 바뀌었었다.
그리고 바닥의 좌표를 구하고 좌표 변환을 하여 그 거리 만큼의 선을 만들기란 지금 내 수준에서는 쉽지않았다.
RayCast를 이용해서 선을 만들수는 있었지만 GameScene에 보이게 하는 방법이 없는것같았다.
그래서 찾은 방법은
LineRenderer !!!
LineRenderer란?
두 개 이상의 지점 배열을 가져와 각각의 점 사이에 직선을 그리는 컴포넌트
위의 말대로 두개의 좌표만 있으면 그 두좌표의 거리의 선을 만들어주는 고마운 유니티의 기능이였다.
m_LineRenderer.SetPosition(0, 시작위치);
if(Physics.Raycast(시작위치,방향,RayCastHit,최대거리,레이어값))
{
m_LineRenderer.SetPosition(1, 종료위치);
}
찾아보니 이런식으로 쓰면 된다고 하길래 썼더니
선이 안나오고 Debug.Log를 써서 확인했더니 if문 안으로 처리가 안들어가는것이였다.
왜인지 확인을 했는데 지금 제작하는 환경은 2D였고
RaycastHit과 Physics를 2D로 바꿔보았다.
//좌표 개수 설정
m_LineRenderer.positionCount = 2;
// 첫번째 좌표 위치 설정
m_LineRenderer.SetPosition(0, transform.position);
//행성 밑으로 쏠 광선 설정
//밑으로 쏘는 광선이 Ground란 레이어와 충돌
RaycastHit2D hit = Physics2D.Raycast(transform.position, Vector2.down, Mathf.Infinity, LayerMask.GetMask("Ground"));
//닿은 오브젝트의 콜라이더가 null아 아니면 두번째 좌표 설정
if (hit.collider != null)
{
m_LineRenderer.SetPosition(1, hit.point);
}
하지만 아직도 안됐다.
왜지? 이러고 열심히 찾아보니까
행성과 바닥은 WorldSpace에 있었고
LineRenderer의 useWorldSpace에 체크가 안되어 있어서 제대로 작동이 안되고 있었다!
m_LineRenderer.useWorldSpace = true;
위의 코드를 넣어보니 정상적으로 작동!!!
결과 영상
y값을 움직여도 문제 없이 작동하는걸 볼수있었다!!!
그 다음으로는 행성을 마우스로 움직이게 하고 화면 밖으로 안나가게 하는것을 구현하기로 했다.
먼저 행성의 위치를 마우스 위치에 맞게 하기위해 강의에서 배운 코드를 쓰기로 하였다.
x축만 움직이게 하고 싶어서 마우스의 x축의 값만 넣어줬다.
Vector2 mousePosition = Camera.main.ScreenToWorldPoint(Input.mousePosition);
transform.position = new Vector2(mousePosition.x,trnasform.position.y);
그리고 행성을 화면 밖으로 안나가게 하도록 구현하기로 하였다.
강의에서는 직접 숫자를 넣어서 계산을 했는데 직접 숫자를 넣어서 하면 나중에 값을 수정할때 문제가 생길것같아
직접적인 값을 넣어서 계산하지않기로 했다.
화면 밖으로 안나가게 하는 방법을 생각해봤는데
Camera viewport 를 이용해서 구현하기로 했다.
월드에 있는 행성 오브젝트의 위치를 viewport로 변환해서 비교해서 값 수정후 다시 월드 위치로 변환해서 넣어줬다.
Vector3 pos = Camera.main.WorldToViewportPoint(transform.position);
if (pos.x < 0f) pos.x = 0f;
if (pos.x > 1f) pos.x = 1f;
transform.position = Camera.main.ViewportToWorldPoint(pos);
하지만 행성의 반이 화면으로 넘어가는 상황이 발생했다.
그래서 행성scale *0.5f의 값으로 계산을 했지만 전혀 해결이 되지않았다.
scale의 값이 아니라 실제 sprite의 크기로 계산해야하나 해서
Sprite.bounds.size.x 의 값으로 계산을 해도 좌표가 이상하게 나와서 해결이 되지않았다.
하지만 여기서 또하나의 방법인 Camera.main.ScreenToWorldPoint로 코드를 작성해서 해결이 되었다!
(튜터님 감사합니다)
Vector2 mousePosition = Camera.main.ScreenToWorldPoint(Input.mousePosition);
float objectWidth = m_Sprite.bounds.size.x * 0.5f;
float screenLeft = Camera.main.ScreenToWorldPoint(new Vector3(0, 0, 0)).x + objectWidth;
float screenRight = Camera.main.ScreenToWorldPoint(new Vector3(Screen.width, 0, 0)).x - objectWidth;
mousePosition.x = Mathf.Clamp(mousePosition.x, screenLeft, screenRight);
mousePosition.y = transform.position.y;
transform.position = mousePosition;
스크린의 좌표를 월드 좌표로 변환한뒤,
행성의 반지름으로 계산을 하고 값을 넣어주었다.
Mathf.Clamp(해당값,최소값,최대값)
Mathf.Clamp를 사용해 mousePositionX가 최소값과 최대값을 안넘기게 하고 구현 끝!!
결과 영상
정상적으로 움직이는것을 확인할수있었다!!!
💭오늘의 회고
LineRenderer를 이용해서 선을 만들어 보았지만 유니티의 기능에 너무 의존하는건 안좋기때문에 나중에는 기능을 안쓰고도 구현 할수있도록 실력을 늘리고싶다.
그리고 다음주 부터 C#을 공부하게 되는데 방해가 안되는 선에서 공부하고 남은 시간에 조금씩 행성게임을 완성해 나가고싶다. C#공부도 화이팅! 행성게임제작도 화이팅!
'TIL' 카테고리의 다른 글
🔥내일배움캠프 7일차 TIL (1) | 2025.01.31 |
---|---|
🔥내일배움캠프 6일차 TIL (0) | 2025.01.27 |
🔥내일배움캠프 4일차 TIL (0) | 2025.01.23 |
🔥내일배움캠프 3일차 TIL (2) | 2025.01.22 |
🔥내일배움캠프 2일차 TIL (0) | 2025.01.21 |