유니티 로그라이크 12

유니티 로그라이크 12

Summary 유니티 로그라이크 게임 개발에 대한 내용으로, 적 처치 로직, 넉백 구현, 리지드바디 및 콜라이더 비활성화, 애니메이션에서 스크립트 추가, 카테고리 이름 헤더 추가 등의 주제를 다루고 있습니다. 또한, 레벨업 시스템과 무기 데미지 증가에 대한 코드 수정 방법도 설명하고 있습니다.


🎥 동영상 보기

🔥 WaitForFixedUpdate : 다음 FixedUdate가 될때까지 기다려준다

🔥 넉백을 구현해볼까요

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
WaitForFixedUpdate wait;

void Awake()
{
    ... (생략) ...
    wait = new WaitForFixedUpdate(); //하나의 FixedUdate를 기다리는것이기때문에 매개변수는 따로 X
}

//물리적인 추적을 할거기 때문에 일반 Update() 함수를 쓰지않고 FixedUpdate를 사용할것임
void FixedUpdate()
{
    **//GetCurrentAnimatorStateInfo(애니메이션레이어).애니메이션이름
    if(!isLive || anim.GetCurrentAnimatorStateInfo(0).IsName("Hit"))**
        return; //플레이어가 죽어있으면 바로 코드를 종료시켜버리는 필터코드

		... (생략) ...
}

void OnTriggerEnter2D(Collider2D collision) 
{
    ... (생략) ...

		**StartCoroutine(KnockBack());**		

    if (health > 0)
    {
        // ... 살아있음
        **anim.SetTrigger("Hit");**
    }
    else
    {
        // ... 죽음
        Dead();
    }
}

//넉백을 구현해봅시다
**IEnumerator KnockBack()
{
    yield return wait; // 하나의 물리 프레임을 딜레이해줄것이다
    Vector3 playerPos = GameManager.instance.player.transform.position;
    Vector3 dirVec = transform.position - playerPos; //현재위치 - 플레이어 위치
    //노멀라이즈를 해줘야 순수하게 방향값만 가진 값이 된다
    //리지드바디도 2D기 떄문에 ForceMode도 2D가 된다
    rigid.AddForce(dirVec.normalized * 3, ForceMode2D.Impulse);
}**

🔥 사망 리액션을 제작해볼까요

리지드바디는 비활성화할때 simulated를 불러와야하고

콜라이더는 enabled입니다

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
void OnTriggerEnter2D(Collider2D collision) 
    {
        ..........
        else
        {
**            // ... 죽음
            // PoolManager에서 재활용해야하기 때문에 다시 true로 변경해야한다
            isLive = false;
            coll.enabled = false; //콜라이더 비활성화해라
            rigid.simulated = false; //리지드바디도 비활성화해라 리지드바디는 simulated로 꺼야한다
            spriter.sortingOrder = 1; //죽고나서 게임오브젝트 레이어를 하나 낮춘다
            anim.SetBool("Dead", true); //죽음상태 애니메이션
            Dead();**
        }
    }

OnEnable에서 Pooling할때 죽은 오브젝트에서 실행했던 bool 작업을 다시 원래대로 되돌려버립시다

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
void OnEnable()
{
    //게임매니저에 이미 플레이어가 저장되어있기떄문에 타겟을 저장할 수 있음
    //target의 Type은 Rigidbody2D라 플레이어 내부에 Rigidbody2D를 불러와야한다
    target = GameManager.instance.player.GetComponent<Rigidbody2D>();
    isLive = true;
    coll.enabled = true;
    rigid.simulated = true;;
    spriter.sortingOrder = 2;
    anim.SetBool("Dead", false);
    health = maxHealth; //objectPooling이 일어났을때 피를 원래대로 되돌리기 위해서 maxHealth를 넣어줌
}

🔥 애니메이션에서 이벤트를 추가하여 스크립트를 추가해봅시다 Image

Image

애니메이션이 포함되어있는 Prefab으로 이동하면 그 프리팹 내부에 컴포넌트에 저장된 스크립트속에있는 함수를 불러올 수 있습니다

이제 특정 초 뒤에 이벤트가 발생되며 몬스터는 사망하게됩니다

🔥 제작한 변수들을 알아보기쉽게 헤더를 추가해볼까요

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
//정적변수 static을 미리 설정해두면 즉시 클래스에서 부를 수 있다는 편리함이 있다
    public static GameManager instance;
    **[Header("# Game Control")]**
    //게임시간과 최대게임시간을 담당할 변수
    public float gameTime; //실제 게임타임
    public float maxGameTime = 2 * 10f; //최대 게임타임 (숫자는 '초')
    **[Header("# Player Info")]**
    //플레이어의 레벨 시스템을 저장하기 위한 변수
    public int level;
    public int kill;
    public int exp;
    public int[] nextExp = {3, 5, 10, 100, 150, 210, 280 , 360, 450, 600};
    **[Header("# Game Object")]**
    public PoolManager pool;
    public Player player;

Image

🔥 레벨업을 해볼까요

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
//GameManager.cs

[Header("# Player Info")]
//플레이어의 레벨 시스템을 저장하기 위한 변수
public int level;
public int kill;
public int exp;
public int[] nextExp = {3, 5, 10, 100, 150, 210, 280 , 360, 450, 600};

public void GetEXP()
{
    exp++;

    if(exp == nextExp[level]) //해당 레벨업에 필요한 경험치와 현재 경험치가 같다면
    {
        level++; //레벨업
        exp = 0; //경험치는 다시0부터
    }
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
//Enemy.cs

void OnTriggerEnter2D(Collider2D collision) 
{

    if (health > 0)
    {
        // ... 살아있음
        anim.SetTrigger("Hit");
    }
    else
    {
        // ... 죽음
        // PoolManager에서 재활용해야하기 때문에 다시 true로 변경해야한다
        isLive = false;
        coll.enabled = false;
        rigid.simulated = false;
        spriter.sortingOrder = 1;
        anim.SetBool("Dead", true);
        **GameManager.instance.kill++;
        GameManager.instance.GetEXP();**
    }
}

레벨에 따라 무기의 갯수와 데미지가 증가하도록 코드를 수정해 보았습니다

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
예의바른대학생
1개월 (수정됨)
다음 강의에 들어갈 지는 모르겠지만
레벨에 따라 무기의 갯수와 데미지가 증가하도록 코드를 수정해 보았습니다

<Weapon.cs 파일>

맨위에 여러 변수 선언하는 (ex. public float speed;) 아래에
public int weaponlevel; 
추가 

void Update() 
if (input.GetButtonDown("Jump"))
    LevelUp(3,2);
  앞에 // 를 각각 입력하여 주석처리 (임시비활성화)

if (weaponlevel != GameManager.instance.level)
      {
            weaponlevel = GameManager.instance.level;
            LevelUp(3, 2);
      }
주인공의 레벨과 무기레벨이 같지 않을  무기레벨을 주인공레벨과 같게 만들어주고
"Jump"키를 눌러서 레벨업하던걸 자동으로 로드하게 했습니다.
그리고 아래에 레벨업 코드를 다음과 같이 수정해줍니다
public void LevelUp(float damage, int count)
  {
      this.damage += damage;
      this.count += count;

      if (id == 0)
            Batch();
  }
이러면 주인공의 레벨이    마다 데미지는 3 추가되고 무기의 수는 2개가 추가됩니다

주인공이 너무 쎄다 싶으시면 맥스게임타임을 늘려주시고, 몬스터 체력을 맥스게임타임에 따라 조금씩 증가시키는 스크립트도 추가하신다면,,,,,

게임 하나 뚝딱!

💬 댓글

GitHub 계정으로 로그인하여 댓글을 남겨보세요. GitHub 로그인

🔧 댓글 시스템 설정이 필요합니다

GitHub Discussions 기반 댓글 시스템을 활성화하려면:

  1. Giscus 설정 페이지에서 설정 생성
  2. GISCUS_SETUP_GUIDE.md 파일의 안내를 따라 설정 완료
  3. Repository의 Discussions 기능 활성화

Repository 관리자만 설정할 수 있습니다. 설정이 완료되면 모든 방문자가 댓글을 남길 수 있습니다.