Short Cake
8PM - Animal Crossing Wild World

사생활 보호 설정

https://gamjia.tistory.com

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하는 방법 올려야지

 

다들 몸 조심 하세요