본문 바로가기

Unity 기초 기능 #2 - 마우스 위치, 태그, PlayerPrefs, FSM, Time

@코야딩구2025. 6. 13. 16:57

1. 마우스 위치를 스크린 좌표로 변환하기

 - Input.mousePosition을 이용하여 마우스 위치를 가져오고, Camera.main.ScreenToWorldPoint()을 통해 마우스 위치를 월드 좌표로 변경할 수 있다.

 - 예시 코드:

// 말 그대로 화면 좌표에서 월드 좌표로 변환
Vector2 mousepos = Camera.main.ScreenToWorldPoint(Input.mousePosition);
transform.position = mousepos;

2. Invoke()와 InvokeRepeatin() 함수

 - 두 함수 모두 일정 시간 후 함수를 자동으로 실행하는 함수

 - 차이점:

  Invoke() InvokeRepeating()
호출 횟수 한 번만 실행됨 주기적으로 반복 실행
사용 목적 일 정 시간 후 한 번 실행 일정 시간 후부터 일정 간격으로 반복 시행
기본 형태 Invoke("함수이름", 딜레이); InvokeRepeating("함수이름", 시작지연, 반복 간격);
종료 방법 자동으로 종료 CancelInvoke("함수이름")으로 수동 중단 필요

 - CancelInvoke()는 모든 인보크 멈춤, 오브젝트 파괴를 통해 멈출 수도 있음

 - IsInvoking()으로 작동 중인 인보크 체크 가능, IsInvoking("함수이름")은 해당 함수의 인보크가 작동 중인지 체크

3. Instantiate()함수

 - 게임 중 프리팹을 복제하여 새로운 오브젝트를 동적으로 생성할 때 사용한다.

 - 예제 코드:

// 프리팹용 변수 선언, inspector에서 설정해줘야 함
public GameObject square; 

void MakeSquare()
{
    Instantiate(square); // 동적 생성
}

4. 게임 오브젝트 Tag와 Layer 기능

  4-1. Tag

   - Tag는 특정 오브젝트를 식별하거나 그룹으로 분류할 때 사용한다.

   - 사용 예시:

// 충돌하였을때
private void OnCollisionEnter2D(Collision2D collision)
{
    if (collision.gameObject.CompareTag("Player")) // 충돌한 오브젝트의 태그가 "Player"인가
    {
        GameManager.instance.GameOver();
    }
}

  4-2. Layer

   - 오브젝트의 렌더링, 충돌 검사, 카메라 처리 등을 세부적으로 제어할 때 사용한다

   - 사용 예시: Rain의 Layer를 Water로 설정하고, 충돌에서 Water Layer를 충돌에서 제외하였다.

5. PlayerPrefs란?

 - 게임 내 값을 로컬에 저장하여, 앱을 껐다 켜도 데이터가 유지되게 하는 기능.

 - 사용법:

// 오타 안나도록 키 따로 저장하기
string bestScoreKey = "bestScore";
// 최고점수 갱신
float bestScore = time;
if (PlayerPrefs.HasKey(bestScoreKey)) // 키가 있다면 최대 점수 갱신
{
    bestScore = Mathf.Max(PlayerPrefs.GetFloat(bestScoreKey), bestScore);
}
PlayerPrefs.SetFloat(bestScoreKey, bestScore); // 키에 값 저장

 

6. Animator Controller와 유한 상태 기계(FSM)

 - Animaotr Controller를 이용해 애니메이션 상태 전이를 구성하여, FSM를 구현할 수 있다.

 - 예시: Idle상태에서 Die상태로의 전이 조건을 파라미터로 설정하고, 스크립트에서 해당 변수 값을 변경하여 전이를 제어

public void GameOver()
{
	// 게임 오버가 되면 애니메이션 상태가 Die가 되게 하기
    balloonAnim.SetBool("isDie", true); // Animator 변수 설정
}

7. 게임 오브젝트 삭제

 - Destroy(gameObject)를 사용하여 오브젝트를 제거할 수 있다.

 - 예시:

void Update()
{
    // 이 게임 오브젝트의 y값이 -6.1이하라면
    if(transform.position.y <= -6.1f)
    {
        Destroy(gameObject); // 이 게임 오브젝트 삭제
        //Destroy(gameObject, 2.0f); // 2초 뒤 삭제
        
	    //Destroy(this); // 틀린 방법
        // this는 사용 불가, 여기서 this는 현재 스크립트 컴포넌트를 가리킴
        // 따라서 이 게임 오브젝트를 삭제하기 위해선
        // this가 아닌 gameObject를 써야함
    }
}

8. Time.deltaTime과 Time.timeScale

 - 충돌 시점에 Time.timeScale을 0으로 설정했지만, 그 직후 실행된 Update()에서 Time.deltaTime 값은  0이 아니었다.

 - 시간이 멈췄다면 당연히 Time.deltaTime도 당연히 0일 것이라 생각했지만, 실제로는 그렇지 않았다. 왜일까?

 - Time.deltaTime은 전 프레임부터 현재 프레임까지의 시간 경과를 의미하며, 해당 프레임 시작 시점에 이미 계산된 값이기 때문이다.

 - 반면, 충돌 판정은 Update()보다 먼저 실행되기 때문에, 그 안에서 Time.timeScale을 0으로 설정해도 이미 계산된 Time.deltaTime에는 영향을 주지 않는다.

 - 따라서 Update()에서는 여전히 0아닌 Time.deltaTime이 적용된다. 

 - 단, 이 다음 프레임부터는 Time.timeScale = 0이 적용되어, Time.deltaTime도 0이 된다.

 - 문제가 된 코드:

// 프레임마다 호출
void Update()
{
	// 이 Update()함수 호출 전에 충돌을 먼저 감지해 GameOver()함수가 호출되어
    // Time.timeScale이 0.0f이 되었지만 이 일련의 과정들은 같은 프레임에 실행됐으므로
    // 이 시간 누적에서 Time.deltaTime 값은 0이 아니다.
    time += Time.deltaTime; 
}

// 풍선이 네모에 닿았을때 호출되는 함수
public void GameOver()
{
    Time.timeScale = 0.0f; // 시간 정지
}

9. 게임 구현

 - 아래는 앞서 설명한 기능으로 구현한 게임입니다.

 

Unity 기초 프로젝트 #2 - 풍선을 지켜라

1. 풍선을 지켜라 게임 소개 - 모바일 기반으로 제작된 게임이며, 풍선을 최대한 오래 보호하여 높은 점수를 획득하는 것이 목표입니다. - 하늘에서는 다양한 크기와 중력 값을 가진 네모 오브젝

gyro-code-game.tistory.com

목차