TIL - Out of Work 3일차

Amberjack·2024년 2월 14일
0

TIL

목록 보기
39/83
post-thumbnail
post-custom-banner

🛗 24.02.14 Out of Work 3일차

오늘은 팀 프로젝트 3일차. 팀원들과 다시 한번 Merge, 인터페이스 특강이 도중에 있었다.

👨‍💻 Codekata

https://velog.io/@amberjack/C으로-풀기-콜라츠-추측
오늘의 교훈은 문제에서 기본으로 적혀있는 데이터 타입도 의심해보자 이다..

👨‍🏫 인터페이스 특강!

https://velog.io/@amberjack/인터페이스-활용

인터페이스의 활용에 대한 특강을 들었다. 코드의 중복을 줄이고 의존성을 줄일 수 있다고 한다.

예를 들어 Player와 Monster가 있다고 가정을 해보자. 이 때, Player와 Monster 모두 서로를 공격하거나 피격될 수 있는 게임을 만든다고 할 때, Player와 Monster 2개의 클래스에 Attack와 TakeDamage에 대한 함수를 만들어줘야 할 것이다.

이를 인터페이스를 활용하여 Character에 Attack과 TakeDamage를 만들어주고, 이 Character를 Player와 Monster가 상속 받도록 하면 코드의 중복을 피할 수 있다.

또한, NPC라는 클래스를 만들어 NPC도 공격, 피격 처리가 필요할 때, 단순히 Character를 상속받도록 하면 해결된다.
이와 같이 확장성도 높여줄 수 있기 때문에 알아놓을 필요가 있다.

🖱️ 마우스 드래그로 카메라 움직이기

오늘은 우리 팀 프로젝트의 스테이지에서 마우스 우클릭을 누른 채로 카메라를 움직이는 것을 구현했다. 좌우로 긴 스테이지를 가진 프로젝트이기 때문에 플레이어의 원활한 플레이를 위해 필요하다고 생각하여 추가를 하게 되었다.

코드

public class DragCamera : MonoBehaviour
{
    Vector2 clickPoint;
    float dragSpeed = 30f;

    // 카메라 X 좌표의 최대값, 최소값.
    float limitMinX = -28f, limitMaxX = 24f;
    // 카메라의 가로 길이의 반
    float cameraHalfWidth;

    // Start is called before the first frame update
    void Start()
    {
    	// 카메라의 가로 길이의 반
        cameraHalfWidth = Camera.main.aspect * Camera.main.orthographicSize;
    }

    // 카메라의 처리는 보통 LateUpdate()에서 이루어진다.
    void LateUpdate()
    {
        // Input.GetMouseButtonDown(1) : 마우스 우클릭을 누르는 순간
        // 마우스 우클릭을 누르는 순간의 마우스 좌표값을 clickPoint 에 저장.
        if (Input.GetMouseButtonDown(1)) clickPoint = Input.mousePosition;
        
        // Input.GetMouseButton(1) : 마우스 우클릭을 누르는 동안
        if (Input.GetMouseButton(1))
        {
        	// LateUpdate가 갱신되기 전까지 마우스가 움직인 위치
            Vector3 position = Camera.main.ScreenToViewportPoint((Vector2)Input.mousePosition - clickPoint);
            // 카메라의 이동 속도
            Vector3 move = position * (Time.deltaTime * dragSpeed);

            float y = transform.position.y;

			// Translate()를 통해 GameObject를 원하는 방향으로 움직일 수 있다.
            // 이 경우, GameObject는 카메라가 된다.
            transform.Translate(move);
            
            // 카메라의 위치 변경하기.
            // Mathf.Clamp()를 통해 카메라의 X좌표의 최대값, 최소값을 지정함.
            transform.transform.position = new Vector3(
            	Mathf.Clamp(transform.position.x, limitMinX + cameraHalfWidth, limitMaxX - cameraHalfWidth), 
            	y, transform.position.z);
        }
    }
}

확인해보기

🛠️ OnSceneLoaded

GameObject를 DontDestroyOnLoad 처리를 할 경우, 씬을 로드해도 사라지지 않는다. 때문에 새 씬이 로드되어도 Start()가 실행되지 않는다. 따라서 Start()와 같이 씬이 로드될 때 처리를 해야할 경우, OnSceneLoaded를 사용하면 비슷한 효과를 얻을 수 있다.

private void OnEnable()
{
    SceneManager.sceneLoaded += OnSceneLoaded;
}

void OnDisable()
{
    SceneManager.sceneLoaded -= OnSceneLoaded;
}

void OnSceneLoaded(Scene scene, LoadSceneMode mode)
{
    if (PlayerPrefs.HasKey("StageCleared"))
    {
        stageCleared = PlayerPrefs.GetInt("StageCleared");
    }
    else stageCleared = 1;
}

위의 코드의 경우, PlayerPrefs에 저장되어 있는 StageCleared를 가져오기 위해 사용한 코드로, 씬이 로드될 때 OnSceneLoaded가 호출되어 stageCleared에 값을 할당해줄 수 있다.

🤔 GameObject 활성화 상태 확인하기

GameObject는 SetActive를 통해 활성화, 비활성화를 시켜줄 수 있다. 하지만 이미 활성화 혹은 비활성화 되어 있는 데 다시 한번 같은 작업을 진행할 필요가 없기 때문에, GameObject의 활성화 상태를 확인해줄 필요가 있다. 이 때 GameObject.activeSelf를 통해 확인할 수 있다.

public void OnClickUpBtn()
{
    if (stage >= 5)
        return;

    if (downButton.activeSelf == false) downButton.SetActive(true);

    stage++;
    stageTxt.text = stage.ToString();

    if (stage >= 5)
        upButton.SetActive(false);
}

위의 코드는 엘리베이터의 Up 버튼의 입력 처리를 위한 함수이다. 스테이지는 1 ~ 5층으로 나뉘어져 있으며, 1층에서는 Down 버튼이, 5층에서는 Up 버튼이 비활성화 시켜야 한다고 가정해보자.

이 때, 1층에서 2층으로 엘리베이터가 올라오면 비활성화되어 있던 Down 버튼이 다시 활성화가 되어야 한다. 이를 위한 처리로 Up 버튼이 클릭되었을 경우, downbutton.activeSelf == false라면 1층에서 2층으로 올라온 것으로 간주, downButton을 활성화 시켜준다.

이와 같이 activeSelf를 통해 현재 GameObject의 활성화 여부를 확인할 수 있다.

🛗 오늘의 회고

오늘은 다행히도 무난하게 흘러간 것 같다. 다시 한번 팀원들끼리 Merge를 했는데, 별 다른 문제 없이 Merge가 되었고, 내가 시험삼아 씬들을 병합하여 동작 여부를 확인해보았는데, 현재 구현한 기능들은 모두 동작하는 것 같아 정말 다행이다. 이제 BGM 추가와 Player Unit들의 엘리베이터 공격, 스테이지 승리 및 패배 구현, 인 게임 내 UI에 Unit 소환 재화 및 제한 시간을 구현하는 것만 하면 우리가 목표로 한 것은 모두 완성할 수 있을 것 같다.

post-custom-banner

0개의 댓글