사생활 보호 설정
https://gamjia.tistory.com
Updated News
Mini Rooms
답글수 [0]
What Friends Say
한마디로 표현해봐~
1촌평 관리
수박게임 재개발일지 - 2
GamJia 2024. 8. 6. 23:04
수박게임 재개발일지 2편진짜 왜 저렇게 썼지
사실 일요일에 올렸어야 했는데
또 놀았다
재밌었으니 후회는 없다
사실 개발 안한건 아닌데
올리지만 않았을 뿐
정리해서 어제 올리려다가
몸이 너무 안 좋아서 못 올렸다
심지어 그거 때문에 오늘
출근 하자마자 집 감
(지금은 멀쩡함)
기존의 드래그 코드를 보면
월드 좌표에서 움직이던데
왜 그렇게 했나 모르겠다
심지어 left와 right라는
transform 까지 가져다쓰던데
왜 UI Canvas 상에서의 마우스
위치를 반영하지 않고 저렇게 했을까?
예전에 채린이가 줬던 피드백 중 하나가
설정 버튼을 눌러도 캡슐이 떨어진다
이거였다
그래서 게임 영역과 UI 영역을 구분하려고 했었고
그 내용을 넣었었지만 분리가 잘 안됐던걸로 기억한다
using UnityEngine; public class Claw : MonoBehaviour { private RectTransform rectTransform; private Canvas canvas; private bool isDragging = false; private Vector2 dragStartPos; private const float MinX = -300f; private const float MaxX = 300f; void Start() { rectTransform = GetComponent<RectTransform>(); canvas = GetComponentInParent<Canvas>(); } void Update() { Vector2 localPoint; if (Input.GetMouseButtonDown(0)) { if (RectTransformUtility.ScreenPointToLocalPointInRectangle(rectTransform, Input.mousePosition, null, out localPoint)) { dragStartPos = localPoint; if(dragStartPos.y<0) { isDragging = true; Debug.Log(dragStartPos); } } } if (isDragging) { if (Input.GetMouseButton(0)) { if (RectTransformUtility.ScreenPointToLocalPointInRectangle(rectTransform, Input.mousePosition, null, out localPoint)) { Vector3 newPosition = rectTransform.localPosition + (Vector3)(localPoint - dragStartPos); newPosition.x = Mathf.Clamp(newPosition.x, MinX, MaxX); rectTransform.localPosition = new Vector3(newPosition.x,762,0); } } else if (Input.GetMouseButtonUp(0)) { isDragging = false; } } } }
코드 리팩토링 전과 비교했을 때
달라진 점이 있다면
ScreenPointToLocalPointInRectangle
(캔버스 내에서의 마우스 위치)를 사용했다는 것이다
https://docs.unity3d.com/ScriptReference/RectTransformUtility.ScreenPointToLocalPointInRectangle.html
Unity - Scripting API: RectTransformUtility.ScreenPointToLocalPointInRectangle
The cam parameter should be the camera associated with the screen point. For a RectTransform in a Canvas set to Screen Space - Overlay mode, the cam parameter should be null. When ScreenPointToLocalPointInRectangle is used from within an event handler that
docs.unity3d.com
canvas RenderMode가(여기서는 overlay 캔버스를 사용했다)
world 좌표가 아니라서 camera는 null로 비워뒀다
마우스의 현재 위치를 RectTransform의 Local 좌표로
변환하고 새로운 위치를 계산하여 X 좌표를
-300부터 300 사이로 제한해주었다
(기존의 left, right)
그리고 만약에 마우스의 Y 좌표가
너무 높게 있으면 UI 영역을 침범하기에
Y 좌표를 확인하여 그 밑에 있을 때만
작동하게 해주었다
어 그리고 이거 지운줄 알았는데
안지웠었네? 좋아 이건 그대로 가져가야징
CapsuleID에 맞는 Prefab
객체들을 잘 연결해주고
랜덤 객체 생성은 기존 코드와 동일하게 갔다
만들어준 CapsuleStorage를 넣어주고
게임을 실행해보니 Start에서 Create가
잘 실행된걸 확인했다
전에도 설명했지만
랜덤 생성할 때 2개를 같이 하는 이유는
0번째 객체는 지금 떨어질 객체
1번째 객체는 다음 객체(설명 UI 반영)다
그 다음 Capsule Prefab의
Rigidbody Type을 Static으로 바꿔준다
Drop할 때 객체의 Type을
Dynamic으로 바꿔주기 위함이다
처음 Instatiate 했는데 Dynamic Type이면
생성하자마자 자기가 알아서 떨어져버린다
그리고 Shit...............
캡슐의 Animator와 Animation을 전부 분리했었다니...
일단 다 지워주겠다
캡슐이 새로 생성될 때
또는 Merge 됐을 때 재생되는
Animation, Appear다
이거는 작았다가 뿅!하고 커지는 애니메이션인데
여기에 내용을 하나 추가해주겠다
바로 Animation이 시작될 때
Collider를 끄다가 Animation이 끝날 때
Collider를 활성화 해주는 것이다
이렇게 하면 애니메이션이 재생되는 동안
Merge가 되는걸 방지해준다
using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; using MoreMountains.NiceVibrations; using UnityEngine.EventSystems; public class Claw : MonoBehaviour { ... [SerializeField] private List<GameObject> capsuleList; [SerializeField] private GameObject capsule; ... private void Create() { int currentIndex=2-capsuleList.Count; for(int i=0;i<currentIndex;i++) { capsuleList.Add(capsuleStorage.GetCapsule((CapsuleID)Random.Range(0, 5))); } if (capsule==null) { capsule = Instantiate(capsuleList[0], rectTransform); RectTransform capsuleRectTransform = capsule.GetComponent<RectTransform>(); capsuleRectTransform.localPosition = new Vector3(0, -180, 0); } } }
다시 코드로 돌아와서
방금 List에 넣어준 객체 중에서
0번째에 있는 객체를
Claw 기준 Y 좌표로 -180만큼 떨어진
위치에 캡슐들을 생성해주기로 했다
List에 맞게 객체가 잘 생성된걸 확인했다
전에 양 옆의 갈고리를
회전하는 계산식을 썼었는데
현재 생성된 객체의 크기를
확인해서 갈고리의 z축을 회전시켜보겠다
계산식은
(블루 width-현재 객체 width)/6으로 정했다
private void Create() { ... if (capsule==null) { ... float rotationValue = (180 - capsuleRectTransform.rect.width) / 6; left.transform.localRotation = Quaternion.Euler(0, 0, rotationValue); right.transform.localRotation = Quaternion.Euler(0, 0, -rotationValue); } }
해당 내용을 추가하고 실행했더니
갈고리가 아주 이쁘게 돌아간걸 확인했다
코드를 update에 다 때려넣은게
좀 보기 그래서 정리를 해주고
EndDrag에서 Rigidbody Type을
Dynamic으로 바꿔줬다
주말에는 Merge랑 Capsule
List update하는 방법 올려야지
다들 몸 조심 하세요