23.03.26. (일) - Ruby 2D Unity 튜토리얼

김도익·2023년 3월 26일
0

Unity

목록 보기
14/23
post-custom-banner

전체 타일에서 내가 원하는 부분만 collider 적용하는 법 - 세계 상호 작용 - 움직임 차단

Tile을 갖고 있는 gameObject에 Tilemap Collider 2D 컴포넌트룰 추가합니다.

모든 타일에 녹색 Collider 사각형이 추가된다. 여기서 물이 있는 부분만 Collider하도록 만들겠다면?

Project창에서 Tile폴더로 이동한다. -> 물이 아닌 모든 타일을 선택한다.(shift 누른 상태에서 목록의 마지막 타일을 클릭하면 모두 선택 가능) -> Inspector에서 CollierType 속성을 Sprite(현재 상태) -> None으로 변경한다.

그런데 여기서 물 타일들이 별도로 Collider를 갖고 있다. 이러면 물리 시스템 계산도 무거워지고, 게임속도가 느려지고, 내가 예상하지 못한 버그가 발생할 확률이 높아진다. 그래서 최적화가 필요하다.

최적화 하는 방법

  1. Tile을 갖고 있는 gameObject에 Composite Collider2D 컴포넌트를 추가해준다.

  2. Composite Collider2D가 제대로 작동하기 위해선 Rigidbody2D가 필요하니, 자동으로 추가된다.

  3. Tilemap Collider 2D 구성 요소에서 Use By Composite 확인란을 활성화합니다.

  4. Rigidbody 2D 구성 요소에서 Rigidbody Body Type 속성을 Static으로 설정합니다.
    Static으로 설정하면 세상이 움직이지 않습니다. 또한 Rigidbody가 움직일 수 없을을 알고 있기 때문에 Physics System이 계산을 최적화하는 데 도움이 됩니다.

속성을 사용하는 이유 - 세계 상호 작용 - 수집품

모든 것을 공개하면 버그가 발생할 수 있다.
특히 어디에서나 액세스하고 변경할 수 없도록 하고 싶은 항목의 경우 더욱 그렇다.
예를 들어 currentHealth를 공개하고 싶지 않는데, 다른 스크립트에 참조하고 싶다고 해서 public으로 열어 놓으면 누군가, 혹은 자기 자신이 실수로 값을 변경하면 예상하지 못한 버그를 발생 시킨다.

따라서 다른 스크립트의 변경을 방지하고, currentHealth의 값을 읽기만 가능하도록 만들고 싶다면 '속성'을 사용하면 된다.


세계 상호 작용 - 손상 구역 및 적

Ruby가 DamageZone에 가만히 들어가 있을 때 지정된 시간 초마다 지속된 damage를 받도록 구현하도록 구현하겠다.

  1. DamageZone 오브젝트에 Box Collider 2D에 IsTrigger를 체크한다.

  2. DamageZone 오브젝트에 Rigidbody 2D 컴포넌트를 추가하고, Sleeping Mode를 Never Sleep모드로 바꿔준다.

  3. Ruby가 일정 시간마다 데미지를 받도록 코드를 작성해준다.
    나는 Ruby가 DamageZone에 가만히 있을 때, 2초마다 -1씩 damage를 받도록 구현하겠다.

  • DamageZone Script

  • RubyPlayerMove


Sprite Render에 크기를 넓힐 때 sprite크기만 커져 흉해 보지이 않고, 같은 Sprite가 여러개 그려지도록 만드는 방법

  • Prfabs로 들어가지 말고, Sprite로 들어갑시다.

이렇게 적용하지 않으면?

CollisionEnter 와 TriggerEnter 차이


이해 안되는 점

  1. MovePosition을 Unity API를 읽어 확인했으나 이해가 되지 않음.

해결책 : 아~ 이렇게도 쓰는구나~

Mathf.Approximately(0.0f, 0.0f)

부동소수는 ==을 사용할 수 없다.
컴퓨터는 부동소수를 명확하게 판별하는 것을 어려워하기 때문이다. 그래서 위에 함수를 사용해서 부동소수끼리 근사값이라면 true를 반환하고 아니라면 false를 반환한다.

  • 당연히 변수로 매번 변환되는 부동소수 값을 받고 판별하는 용도로 사용해도 된다.
    Mathf.Approximately(move.x, 0.0f) 같은 느낌으로

Normalize()

Vector 함수에서 사용하는 메소드로 길이를 1로 만들어주는 역할을 한다.

사용하는 이유는 길이는 중요하지 않고 방향만 중요할 때, 방향을 저장하는 백터를 정규화 해주기 위해 사용합니다.

  • 예를 들어 (0,-2) 와 같은 Vector2는 길이가 2 이고 아래쪽을 가리킵니다. Vector 를 정규화하면 (0,-1) 과 같아지므로 여전히 아래쪽을 가리키지만 길이는 1 입니다.

위치를 저장하는 벡터를 정규화 하면 안 됩니다. x 및 y가 변경될 때 위치가 변경되기 때문입니다!

magnitude

Vector 함수에서 사용하는 메소드로 길이를 반환합니다.(읽기 전용)

벡터의 길이는 (x * x + y * y)의 제곱근입니다.

일부 벡터의 크기만 비교해야 하는 경우, sqrMagnitude를 사용하여 벡터의 제곱 크기를 비교할 수 있습니다(제곱 크기 계산이 더 빠름).

SetFloat

Animator 함수에서 사용하는 메소드로 애니메이터에 실수 값을 전송하여 트랜지션에 영향을 줍니다.

스크립트에서 SetFloat를 사용하여 전환을 활성화하기 위해 애니메이터에 실수 값을 전송할 수 있습니다. 애니메이터에서 특정 애니메이션의 전환 방식에 영향을 주는 값을 정의합니다. 이는 다양한 상황에서 유용하며, 특히 버튼 압력에 따라 캐릭터가 걷거나 뛰어야 하는 이동 애니메이션과 같은 애니메이션 사이클에서 유용합니다.

Quaternion

회전을 표현하는 수학적 방법이다.
Quaternion.identity는 회전이 없다는 것을 의미한다.

Rigidbody2D 와 Awake()함수에 관계

공부가 더 필요한 부분이다.

충돌했을 때(Collision, Trigger) 다른 오브젝트에 컴포넌트 참조하는 방법

시네머신

Window -> Package Manager -> Unity Registry -> Cinemachine -> Install

시네머신을 사용하면 복잡한 3D 카메라 설정을 생성할 수 있으므로 여러 카메라 간에 이동 및 컷이 가능하다.

Follow에 루비 오브젝트를 넣는다면 카메라가 루비 중심으로 이동하게 된다.

카메라가 맵 외부에 아무것도 표시하지 않도록 하려면 Cinemachine Confiner를 사용하여 일부 경계를 정의한다.

하지만, 새로 추가된 구성 요소는 경고를 표시하므로 경계로 사용할 Collider 2D를 제공해야 한다 . Confiner 는 Composite Collider 2D 또는 Polygon Collider 2D를 사용할 수 있다 .

Hierarchy 창에 빈 오브젝트를 생성한다.
그리고 Polygon Collider 2D 컴포넌트를 추가한다.

Edit Collider를 통해 오각형이 물 안쪽 맵 전체를 감싸도록 만들어준다.

vcam1 로 돌아가 해당 GameObject를 CinemachineConfiner 의 Bounding Shape 2D 속성 에 할당한다.

모든 레이어의 항목을 제거한다.

Particle - 파티클

Texture Sheet Animation을 체크한다.

Mode를 Sprites로 처리한다.

  1. Mode 옆 + 키를 눌러서 2가지 창을 만들고 연기나는 스프라이트를 넣는다.

  2. Start Frame을 Random Between Two Constants를 누른다.
    그리고 범위를 0, 2로 둔다. 그러면 0과 1 사이에서 실행된다.
    2를 입력하면 1.9998로 값이 알아서 변경된다.

  3. Frame over Time을 누르고, 빨간 선 가장 높은 쪽에 마우스 오른쪽 키를 누른다음 Delete Key를 누른다.

Shape에 들어가서 Angle에 크기를 조절한다. Angle은 퍼지는 각도를 조절할 수 있다. 5로 했기 때문에 파티클이 덜 퍼지고, 직선처럼 보이게 생성된다.

Radius
반지름으로 각이 작을수록 반지름에 각도도 줄어든다.
여기서 필요한건 0.00001을 했을 때이다.

반지름이 1이면 아래 보이는 것처럼 넓이가 크다.

Start Lifetime

파티클이 생성되는 길이를 조절할 수 있다.
숫자가 작으면 작을 수록 길이는 짧아진다.

Start Size에서 크기를 조절한다.

Start Speed

Color over Life

파티클이 아래 처럼 연한 연기처럼 보여지도록 만들어줄 수 있다.

Size over Lifetime

Simulation Space

파티클을 이동 시키고 싶다면 World로 바꾸면 된다.
Local -> World

Local일 때

World일 때

Canvas

Rect Transform

Canvas Scaler

체력 바 만들기

  1. Health라는 Image를 만든다.

  2. 왼쪽 상단에 맞춘다.

  3. 체력바 이미지를 넣는다.

  4. Health 오브젝트 자식으로 Image를 만들고 Ruby 사진을 넣는다.

  5. Health 오브젝트 자식으로 Image를 만들고 체력바 크기 만큼 Image를 맞춘다.

  6. 앵커를 아래 사진터럼 Image 양 끝으로 맞춘다.

  7. 게이지 만들 때 피벗을 움직여야한다.

피벗으로 바뀌어야 피벗이 움직인다.

  1. Mask 오브젝트에 자식으로 Image를 만든다.

  2. UIHelathBar Image를 넣는다.

  3. 아래 사진처럼 위치를 맞춘다.

  4. 체력바 위치는 잘 맞게 되고 아제 남은 흰색만 처리하면 된다.

  1. 흰색 이미지를 가리기 위해 Mask 오브젝트에 Mask 컴포넌트를 추가한다.

그리고 Show Mask Gaphic을 Off한다.

체력바 스크립트


Mask를 할당해준다.

게임 화면

루비는 로봇과 부딪히면 체력이 깎이는 UI를 확인할 수 있다.

NPC 만들기!

Raycasting

NPC 대화상자 만들기

오브젝트에 자식으로 Canvas를 만든다.

Canvas에 Render모드를 World Space로 바꾼다.

Canvas 크기를 조절한다.

Canvas에 자식으로 Image를 만든다.

Image를 넣고, Alt + Shift 키 눌러서 위치 맞춘다.

Canvas 위에 아무 것도 렌더링되지 않도록 하려면 Hierarchy 에서 Canvas를 선택 하고 Inspector에서 Order in Layer를 높은 값(예: 10 )으로 설정한다.

Text 설정



대화 할 때만 대화창이 보이도록 만들기!

Ruby가 Jambi와 대화할 때 대화 상자를 표시 해야 한다.

이를 위해 캔버스를 비활성화하여 숨긴다.

  1. Hierarchy에서 Canvas를 선택 하고 Inspector 에서 Inspector 상단의 체크박스를 선택 취소합니다 .
  1. 그런 다음 NonPlayerCharacter 라는 새 C# 스크립트를 만들어 Jambi에 추가한다.

  2. RubyPlayerMove 스크립트에 Displaylog()함수를 사용한다.

  3. Jmabi 오브젝트에 Canvas를 할당한다.

  4. 게임 화면

애니메이터 이름 해시값으로 설정

애니메이터 파라미터는 string으로 되어 있고, 우리도 string으로 파라미터를 불러야한다. 그래서 실수할 여지가 크기 때문에 다음과 같이 만들어서 사용하면 된다.

  • Scripts 파일에 새폴더를 만든다. '
    PlayerAnimationID라는 파일을 만든다.

  • 아래 사진 처럼 작업하면 된다.

profile
고급 개발자가 되고 싶어요!
post-custom-banner

0개의 댓글