본문 바로가기

Project/전투 시스템

[전투 시스템] Unity: 플레이어 컨트롤러 만들기

728x90

플레이어의 움직임과 점프 그리고 공격까지 만들어보겠습니다.

 

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
47
48
49
50
51
using UnityEngine;
using UnityEngine.UI;
 
public class PlayerController : CharacterStats
{
    public int jumpPower;
    public Transform attackTransform;
 
    Animator animator;
    Rigidbody2D rigid;
    SpriteRenderer sprite;
    Transform trans;
    public Image img;
 
    void Start()
    {
        animator = GetComponent<Animator>();
        rigid = GetComponent<Rigidbody2D>();
        sprite = GetComponent<SpriteRenderer>();
        trans = GetComponent<Transform>();
    }
 
    void Update()
    {
        if (Input.GetButton("Horizontal"))
        {
            Move();
        }
        else
        {
            animator.SetBool("isMove"false);
        }
 
        if (Input.GetButtonDown("Jump"&& !animator.GetBool("isJump"))
        {
            Jump();
        }
 
        if (rigid.velocity.y < 0)
        {
            Landing();
        }
 
        if (Input.GetMouseButtonDown(0))
        {
            if (Time.time >= nextAttackTime)
            {
                Attack();
            }
        }
    }

 

jumpPower - 점프 힘을 저장할 변수입니다.

attackTransform - 공격 범위를 저장할 변수입니다.

animator - 플레이어의 animator를 저장할 변수입니다.

rigid - 플레이어의 rigidbody2d를 저장할 변수입니다.

sprite - 플레이어의 spriterenderer를 저장할 변수입니다.

trans - 플레이어의 trasnform을 저장할 변수입니다.

img - 체력바 이미지를 저장할 변수입니다.

 

Start 함수를 통해서 변수들을 초기화해 줍니다. 그리고 Update 함수를 통해서 플레이어의 입력에 맞춰 함수들이 실행될 수 있도록 해줍니다.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
  void Move()
    {
        float hInput = Input.GetAxisRaw("Horizontal");
 
        animator.SetBool("isMove"true);
 
        if(hInput < 0)
        {
            Vector3 scale = transform.localScale;
            scale.x = -Mathf.Abs(scale.x);
            transform.localScale = scale;
        }
        else if (hInput > 0)
        {
            Vector3 scale = transform.localScale;
            scale.x = Mathf.Abs(scale.x);
            transform.localScale = scale;
        }
 
        trans.Translate(Vector2.right * hInput * moveSpeed * Time.deltaTime);
    }

 

플레이어의 움직임 애니메이션을 재생시켜주고, hInput에 따라서 플레이어가 뒤집어질 수 있게 해줍니다. 그리고 hInput과 moveSpeed에 맞게 플레이어를 이동시켜줍니다.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
     void Jump()
    {
        rigid.AddForce(Vector2.up * jumpPower, ForceMode2D.Impulse);
        animator.SetBool("isJump"true);
    }
 
    void Landing()
    {
        RaycastHit2D rayHit = Physics2D.Raycast(rigid.position, Vector2.down, 1f, LayerMask.GetMask("Ground"));
        Debug.DrawRay(rigid.position, Vector2.down, Color.red);
 
        if (rayHit.collider != null)
        {
            if (rayHit.distance <= 1f)
            {
                animator.SetBool("isJump"false);
            }
        }
    }

 

Jump 함수를 통해서 점프 애니메이션을 재생시켜주고, rigid에 jumpPower 만큼의 힘을 가해줍니다.

 

Landing 함수는 RaycastHit2D를 사용해서 "Ground" 레이어와의 충돌을 확인하고, "Ground" 레이어와 충돌했다면 착지한 것이므로 점프 애니메이션을 중지시켜줍니다.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
     void Attack()
    {
        animator.SetTrigger("onAttack");
 
        Collider2D[] enemies = Physics2D.OverlapCircleAll(attackTransform.position, attackRadius, LayerMask.GetMask("Enemy"));
 
        if (enemies != null)
        {
            foreach (Collider2D enemy in enemies)
            {
                enemy.GetComponent<EnemyController>().TakeDamage(attackPower);
            }
 
            nextAttackTime = Time.time + attackReload;
        }
    }
}

 

트리거를 통해서 공격 애니메이션을 재생시켜주고, 5행을 통해서 중심이 attackTransform이고, 반지름이 attackRadius인 원에 "Enemy" 레이어에 존재하고 있는 적 오브젝트를 enemies에 저장해줍니다.

 

그리고 enemies가 null이 아니라면 foreach 구문을 통해서 적 스크립트의 TakeDamage 함수를 실행시켜줍니다.

 

마지막으로 nextAttackTime을 초기화해줍니다.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
    public override void TakeDamage(int damage)
    {
        if(animator.GetBool("isDeath"))
            return;
 
        base.TakeDamage(damage);
        img.fillAmount = health / maxHealth;
   
        animator.SetTrigger("onHit");
    }
    public override void Die()
    {
        animator.SetBool("isDeath"true);
        this.enabled = false;
        GameManager.instance.GameOver(false);
    }

 

부모 스크립트에서 virtual로 선언하였던 함수 TakeDamage와 Die를 완성해줍니다. 6행의 base.TakeDamage(damage);는 부모 스크립트의 TakeDamage를 실행시켜주는 것입니다.

728x90