내일배움캠프 - TIL/내일배움캠프 - TIL

내일배움캠프 1일차 TIL 빗물받는 르탄이, 게임 속 상호작용 분석 컨텐츠

rudals4469 2025. 4. 10. 20:33

 

낭비한 시간에 대한 후회는 더큰 시간 낭비이다.

 

 

오늘 배운 키워드 - 기초적인 애니메이션, 스크립트 구현, UI 박스 세팅

 

1. 애니메이션 만들기

 

 두 개의 이미지를 활용하여 걷는 것 같은 모션을 주는 기초적인 애니메이션을 만들었다.

 

르탄이1,2의 이미지를 활용하여 애니메이션을 만들어보자.

 

0초, 10초, 20초에 각 각 property를 추가 하여 이미지를 자연스럽게 움직이도록 설정한다.

 


 

 2. 스크립트 구현

 

  기본적으로 빗물받는 르탄이 게임을 만들기 위해선

  1.    좌우로 자동으로 움직이며 마우스 클릭 시 캐릭터가 반대 방향으로 가게 만든다.
  2.    하늘에서 1초 간격으로 1~3개의 랜덤한 위치와 크기로 물방울이 떨어지게 만든다.
  3.    캐릭터가 물방울과 충돌 시 점수를 얻으며 이 상황에 충돌 한 물방울은 사라지게 만든다.
  4.    30초 동안 게임이 진행되며 점수를 체크하고 타이머가 다 될 시 재도전 할 수 있는 버튼이 생성된다.

  정도의 기능을 가지고 있어야 한다.

 

먼저 캐릭터가 좌우로 자동으로 움직이는 기능부터 살펴 보면

 

 if(transform.position.x > 2.6f) // 오른쪽 벽에 붙이히면
 {
     dir = -0.05f;	// 방향 반대로
     renderer.flipX = true; // 캐릭터 좌우 반전
     
 }
 
 if( transform.position.x < -2.6f) // 왼쪽 벽에 붙이히면
 {
     dir = 0.05f;	// 방향 반대로	
     renderer.flipX = false;	// 캐릭터 좌우 반전
 }

 

 

위의 간단한 코드로 구현 되었으며, 마우스 클릭 시 캐릭의 반대 방향으로 가기 위해

 

if(Input.GetMouseButtonDown(0)) // 마우스 클릭 시
{
    dir *= -1;
    // 방향값 반대로 조정
    renderer.flipX = !renderer.flipX; 
    // 이미지 플립, true면 false, false면 true
}

 

 

위와 같은 코드를 구현했다. 

이로써 캐릭터의 움직임 구현은 끝났다.

 

 다음은 하늘에서 물방울이 생성되어 떨어지기 하기 위해 먼저 프리팹화 시킨 물방울 오브젝트에 RigidBody2D를 추가하여

중력의 영향을 받게 만들어 준다.

 

float x = Random.Range(-2.4f, 2.4f); // 좌우 범위
float y = Random.Range(3f, 5f); // 상하 범위
transform.position = new Vector3(x, y, 0); // 랜덤한 위치에 생성

int type = Random.Range(1, 5); // 갯수, 1~4 까지의 랜덤한 난수르 뽑아 낸다.
if(type == 1) // 랜덤한 난수에 따라 크기와 색깔이 다른 물방울 생성
{
    size = 0.8f;
    score = 1;
    renderer.color = new Color(100 / 255f, 100 / 255f, 1f, 1f);
}
...

transform.localScale = new Vector3(size, size, 0); // 랜덤한 난수에 따른 크기 변경

 

 

그 뒤 좌우, 상하, 갯수를 위해 Random 함수를 써서 난수를 생성한 뒤 if문을 통해 각 각 다른 물방울을 생성한다.

 

다음은 물방울의 충돌 판정이다. 물방울은 캐릭터나 바닥에 대였을 때 상호작용이 일어나야 한다.

충돌을 위해 각 각의 오브젝트에 모양에 맞는 Collider를 Comonent에 추가 한 뒤

 

private void OnCollisionEnter2D(Collision2D collision)
{
    if (collision.gameObject.CompareTag("Ground")) // 땅
    {
        Destroy(this.gameObject); // 오브젝트 삭제
    }
    if(collision.gameObject.CompareTag("Player")) // 캐릭터
    {
        GameManager.instance.AddScroe(score);
        Destroy(this.gameObject); 
    }
}

 

 

 

위와 같은 OnCollisionEnter2D라는 함수를 사용하여 충돌을 관리한다. 이 함수는 부가로 설명할 부분이 있다.

중간에 있는 CompareTag("..."); 라는 부분인데 이 부분은 

 

 

Rtan이라는 오브젝트의 tag는 Player이다.

 

 

위와 같이 오브젝트를 구분할 수 있는 태그를 통해 판정한다는 의미이다.

즉, 물방울이라는 오브젝트는 Player라는 태그를 가진 오브젝트와 부딪혔을 때 무언가 일어난다는 의미이다.

위의 코드를 보자면 물방울을 삭제 시키고 AddScore라는 함수를 실행시킨다고 볼 수 있다.

 

마지막으로 점수를 계산하고 게임 시간이 끝날 시 게임을 재시작할 수 있는 버튼만 구현하면 모든 구현이 끝나게 된다.

위의 구현을 편하게 하기 위해선 GameManager를 통해 기능을 묶어 구현한다. 

먼저 점수를 더하는 함수는

 

 public void AddScroe(int score)
 {
     totalScroe += score;
     totalScroeTxt.text = totalScroe.ToString(); //형변환 ( int -> string )
 }

 

 

AddScore() 함수를 만들었다. 근데 여기서 의문점이 하나 든다.

위의 함수가 있는 Script는 GameManger.cs 이고

실제로 이 함수를 사용한 부분은 물방울의 기능을 구현한 Rain.cs의 Script로 서로 다른 스크립트에서 참조를 하고 있다.

이를 사용하기 위해 먼저 GameManger.cs를 싱글톤 패턴으로 만들어 주었다.

 

public static GameManager instance;

 private void Awake()
 {
     instance = this;
 }

 

 

더 많은 문법이 있겠지만 이 게임에서는 이 이상으로 필요하지 않으므로 이 정도만 구현하였다. 위의 명시로 인해 다른 스크립트에서도 Gamemanager 내의 함수를 참조 할 수 있도록 만든 것이다. 물론 사용하기 위해 AddScore 함수를 public으로 사용하였다.

 

다음은 시간이다. 시간을 구현하는 건 아주 쉽기 때문에 짧게 설명하고 넘어가겠다.

 

 float totalTime = 30f;
 private void Awake()
 {
     Time.timeScale = 1.0f;
 }
 
  void Update()
 {
     if(totalTime > 0f)
     {
         totalTime -= Time.deltaTime;
     }
     else
     {
         totalTime = 0f;
         Time.timeScale = 0f; // 시간을 멈추게 하는 효과
         EndPanel.SetActive(true);
     }
     TimeTxt.text = totalTime.ToString("N2");  //형변환 ( float -> string ), N# = 소수점 제어
 }

 

 

위의 코드를 해석 해보자면 totalTime을 선언하여 원하는 게임 시작을 변수에 넣어준다. 그 뒤 0보다 크다면 totalTime을 Time.deltaTime을 빼준다. Time.deltaTime은 각 프레임을 렌더링하는데 걸리는 시간을 계산하는 Unity 함수이다. 즉 일정하게

시간을 뺄 때 사용된다고 보면 된다.

0 이하라면 totalTime을 0으로 초기화 하고 timeScale을 0f으로 해주어 시간을 멈추게 해준다. 그 뒤 게임을 재시작 할 수 있는

버튼을 true로 바꾸어 UI창에 나타날 수 있도록 한다. 

마지막으로 설명할 부분은 ToString의 활용 부분인데 ToString은 int, float와 같은 형식을 string 형식으로 바꿔준다.

여기서 괄호 안에 "N2"와 같은 쓰임은 소수점 2째 자리 까지 표현한다는 의미가 된다고 한다.

 

이로써 기능에 대한 구현은 완료가 되었다.


 

3. UI 박스 세팅

 

 마지막으로 UI만 만져주면 게임은 완성된다.

이 게임에서 UI는 크게 

  1.  점수를 보여주는 UI
  2.  시간을 보여주는 UI
  3.  재시작을 보여주는 UI

총 3개의 UI를 사용한다.

UI는 Hierarchy 창의 Canvas 안에 생성하여

 

 

와 같이 점수 라벨, 점수, 타임 라벨, 타임, 재시작버튼을 만들어 각 각 할당 해주어 사용하였다.

여기서 EndPanel만 Button UI를 사용하였는데 이는 버튼을 눌렀을 시 어떠한 변화가 일어나게 해주기 위해서이다.

 

 

EndPanel의 Inspector 창을 내려보면 Button Component에 On Click()을 찾아 볼 수 있다. 이것이 버튼을 클릭 하였을 때 이벤트를 설정 할 수 있는 곳이다.

 

...
using UnityEngine.SceneManagement;
public void Retry()
  {
      SceneManager.LoadScene("MainScene");
  }

 

 

위와 같이 Retry 함수를 만들어 SceneManger.LoadScene을 통해 메인씬을 다시 불러 와 재시작을 할 수 있도록 만든 뒤,

Onclick에 Retry 함수를 할 당 해 주었다.

한 가지 더 봐야 할 것은 SceneManager를 사용하기 위해선 using UnityEngine.SceneManagement; 와 같이 엔진을 추가해주어야 한다.

 


4. 후기 및 느낀점

 

 아주 오랜만에 유니티를 만져보는 것 같다. 어려운 코드는 아니었지만 구현하다 보니 싱글톤 패턴, 인보크 사용법, 프리팹 생성, 충돌 판정 등 기억이 안나는 파트가 꽤나 많았던 것 같다. 다시 보니 쉬워보이는데 생각이 안나는 걸 보니 더욱 열심히 해야 될 것 같다는 생각이 나는 파트였다.

 


 

[게임 속 상호작용 분석 컨텐츠]

 

팀원들과 게임을 하나 선정하고 그 게임 캐릭터에 대한 시스템의 구조를 분석하고 과정을 설명하는 팀 프로젝트를 진행하였다.

 

  1. 선택한 게임의 이름은 무엇인가요?
    • 오버워치
  2. 선택한 게임의 장르는 무엇인가요?
    • FPS
  3. 선택한 게임의 어떤 시스템에 집중하셨나요?
    • 영웅 아나의 좌클릭 기본공격
  4. 해당 시스템이 동작하는 구조의 시작부터 과정을 최대한 자세하게 분석, 나열해봅시다.
    • 캐릭터가 공격할 수 있는 상태인지?
      • 사망 시 공격 불가 상태
      • 탄환 전부 소진 시 공격 불가
      • 재장전 중에 공격 불가
      • CC기에 걸린 상태일 때 공격 불가
      • 스킬, 평타 딜레이 상태일 때 공격 불가
      • 스킬 사용 중 일 경우 기본 공격 불가
    • 충돌 오브젝트 구분
      • 오브젝트
        • 벽이나 구조물에 충돌시 총알 자국 생성 후 종료
      • 유닛
        • 아군 충돌 시 회복
          • 체력이 가득 찬 아군은 관통
        • 아군 소환 유닛
          • 애쉬 궁극기 B.o.B은 아군 판정으로 회복
          • 나머지 소환 유닛들은 관통
        • 적군 충돌 시 데미지
      • 허공
        • 공격 판정 x
    • 유닛 충돌 시
      • 헤드샷 특전이 활성화 되어있다면
        • 적군 피격 부위 추가
          • 헤드샷 - 평소 데미지의 두 배
          • 헤드샷이 아닌 경우 - 평소 데미지
      • 적군 쉴드(노란 체력)에 충돌한 경우
        • -5의 피해 감소한 데미지
      • 이외의 경우 적군 충돌 시 데미지
      • 체력이 감소한 아군 충돌 시 회복
    • 공격력 버프를 가진 상태에서 버프량 만큼 데미지, 회복량 추가
      • ex) 메르시 공버프, 아나 나노 강화제
      • ex) 바티스트 궁극기 증폭 매트릭스 통과 시
      •  
  5. 직접 분석해본 내용 중 가장 핵심이 되는 구성 요소는 무엇이라 생각하나요?
    • 충돌 오브젝트 및 유닛의 구분
    • 충돌 판정

오늘 첫 날이라 이런 저런 이슈가 있었지만 좋은 팀원들과 소통하여 유익한 시간을 보냈다.

 그저 게임의 한 요소에서 이렇게 많은 상호작용이 나온다는 것에 다시 한 번 놀랐다. 지금 보니 회의 때 찾지 못한 보다 더 많은 상호작용이 있을 것 같기도 하다. 고작 게임 캐릭터가 총 하나를 쏘는데 이렇게 많은 요소들이 있다니.

 

또한 다른 조들의 분석도 볼 수 있었는데 다들 재미있는 주제들이 많았다. 롤, 배틀 그라운드, 뱀서라이크 류 게임, 메탈슬러그 등 여러가지 게임의 분석을 보면서 흥미로운 시간을 보냈던 것 같다.

 

오늘 첫 날이라 떨리기도 설레기도 하였는데 다들 열심히 하는 분위기라 좋은 결과 나올 거 같은 기분이 들어 한결 편안해진 기분이다. 열심히 해서 다들 좋은 결과있길 바래본다.