사생활 보호 설정
https://gamjia.tistory.com
Updated News
Mini Rooms
답글수 [0]
What Friends Say
한마디로 표현해봐~
1촌평 관리
[Day 9] Save The Dog Tutorial 3
GamJia 2024. 11. 15. 22:51
오블완 챌린지 9일차
매주 금요일은 기타 레슨 날이라
기타 레슨을 받은 뒤 선생님께
칭찬 받아서 기분 좋은 GamJia 입니다
어제 강의에 이어서Save The Dog을 만들어 보겠습니다
Before & After
오늘은 특별하게 먼저
Before와 After를 비교해드리겠습니다
사실 어제, 오늘 유튜브 강의를 좀 봤는데
다 너무 어려운 방법으로 가는 것 같아서..
단순하면서 쉬운 방법으로
제가 (회사에서) 재구성 해보았습니다
using UnityEngine; public class LineManager : MonoBehaviour { [SerializeField] GameObject line; void Update() { if (Input.GetMouseButtonDown(0)) { Instantiate(line, Vector3.zero, Quaternion.identity, this.transform); } } }
일단 선들을 하나하나 분리하기 위해
Line Prefab 객체로 분리하고
그걸 LineManager가 만들어주는
역할로 바꾸어주도록 하겠습니다
그리고 배경 침범을 방지하기 위해
Background라는 새 Layer를
만들어주도록 하겠습니다
그리고 LineRenderer Component만 있는
Line 객체를 따로 생성해주겠습니다
여기서 가장 중요한건
Use World Space가 무조건 해제 되어야 합니다
using System.Collections.Generic; using UnityEngine; public class Line : MonoBehaviour { [SerializeField] private LayerMask backgroundLayer; // 백그라운드 레이어 설정 private LineRenderer lineRenderer; private EdgeCollider2D edgeCollider; private List<Vector2> linePoints = new List<Vector2>(); private bool isDrawing = false; // 초기값은 true로 설정하여 첫 그림은 허용 void Awake() { lineRenderer = GetComponent<LineRenderer>(); } void Update() { if (isDrawing) return; if (Input.GetMouseButton(0)) { Vector2 mousePos = Camera.main.ScreenToWorldPoint(Input.mousePosition); // Raycast로 마우스 위치가 backgroundLayer에 속하는지 확인 if (IsMouseOnBackground(mousePos)) { return; } if (linePoints.Count == 0 || Vector2.Distance(linePoints[^1], mousePos) > 0.1f) { linePoints.Add(mousePos); UpdateLineRenderer(); } } if (Input.GetMouseButtonUp(0)) { isDrawing = true; UpdateCollider(); } } private void UpdateLineRenderer() { lineRenderer.positionCount = linePoints.Count; for (int i = 0; i < linePoints.Count; i++) { lineRenderer.SetPosition(i, linePoints[i]); } } private void UpdateCollider() { if (!edgeCollider) { edgeCollider = gameObject.AddComponent<EdgeCollider2D>(); edgeCollider.edgeRadius = 0.05f; } List<Vector2> edgePoints = new List<Vector2>(); for (int i = 0; i < lineRenderer.positionCount; i++) { Vector3 pos = lineRenderer.GetPosition(i); edgePoints.Add(new Vector2(pos.x, pos.y)); // 2D 좌표로 변환 } edgeCollider.SetPoints(edgePoints); if (!gameObject.GetComponent<Rigidbody2D>()) { gameObject.AddComponent<Rigidbody2D>(); } } private bool IsMouseOnBackground(Vector2 mousePos) { RaycastHit2D hit = Physics2D.Raycast(mousePos, Vector2.zero, 0, backgroundLayer); return hit.collider != null; } }
보면 굉장히 복잡해보이지만
쉽게 설명 드리도록 하겠습니다
아까 만든 Background Layer를
연결해주고 Prefab으로 변환한 다음
Scene에 있던 기존 Line은 지워주겠습니다
Prefab 변환이 완료 됐다면
Line Manager에 할당해주겠습니다
어떤가요 원작 느낌이 조금 나나요?ㅎㅎ
이렇게 선을 그리고 거기에
물리 충돌 설정을 넣어주었습니다
이번에는 강아지를 한번 볼까요?
강아지의 표정은 크게 기본, 행복, 슬픈
표정으로 나뉘는데요 일단 Idle 표정
Animation을 위해 관련 Sprite들을 선택하고
Dog 객체에 드래그 해주겠습니다
방금 만든 Animation을 확인하는데
뭔가 눈을 감는거 같기는 한데..
좀 어색하지 않나요?
뭔가 끊기는 느낌도 들고...
그럴 때는 가장 마지막 Frame을
기준으로 이렇게 Frame을 복사해주세요
그러면 이전보다는 훨씬 자연스러워진답니다
어떤가요?? 아까보다는 자연스럽게
눈을 깜빡이고 있는 모습 같죠??
Loop Animation들은 이런식으로
해주면 대부분 훨씬 자연스러워진답니다
Happy와 Sad Animation도
Idle과 같은 방식으로 생성해줄게요
이 둘은 Loop Animation이 아니라
위와 같은 과정은 따로 안 거쳐도 됩니다
Windows / Animation / Animator를 활성화하면
다음과 같은 모습이 나오게 되는데요
방금 말한것처럼 Idle만 Loop Animation이기 때문에
나머지는 더블 클릭해서 관련 설정을
해제 해주도록 하겠습니다
Idle은 평소의 표정이고
Happy와 Sad는 특수한 경우에
짓게 되는 표정이라
그걸 bool값으로 관리해주도록 하겠습니다
isClear(게임을 클리어 한 경우) : Happy
isHit(벌에게 쏘인 경우) : Sad
제가 원할 때면 언제든 상태를 바꿀 수 있게
Make Transition을 설정해 오른쪽 이미지처럼
Happy와 Sad에 연결해주세요
방금 연결한 Transition을 클릭하면
이런식으로 Condition을 설정할 수 있게 됩니다
아까 설명처럼 isClear가 true일 때 Happy
isHit이 true일 때 Sad 표정을 짓게 설정해주세요
제가 Animator 자체에서
isHit을 true로 설정하고 확인해보니
condition에 맞게 멍멍이의
표정이 잘 바뀐걸 확인했습니다!
오늘은 여기까지 하고
GitHub에 Commit하는걸로
마무리 하겠습니다!
오늘 내용이 좀 어려웠는데
따라오는데 문제는 없으셨을지
조금 걱정 됩니다 하지만 어려운건
다 지나갔으니 안심하셔도 됩니다
감사합니다!!