2 분 소요

이벤트 구현하기

이번 포스팅에서 다뤄볼 내용은 이벤트입니다.

그중에서 오늘은 플레이어가 몬스터에 맞았을 때의 이벤트를 구현해보려고합니다.

보통 일반적으로 플레이어가 몬스터에게 피격당하면 뒤로 밀려나고 잠깐 무적이 되는데, 이 작업을 해보도록 하겠습니다.

그전에, 저번 포스팅 내용중에, MonsterController.cs 에서 에러가 발생하는 부분이 있었을겁니다.

스프라이트 렌더러를 초기화해주는 과정에서, renderer이라는 변수명을 사용했었는데, renderer이라는 키워드가 존재했던 모양입니다.

따라서 renderer 라는 변수명을 다른 변수명으로 바꿔주면 해결되는 문제였습니다. 저는 renderer -> spriteRenderer 로 변경했습니다.

Layer설정

지금은 몬스터와 피격되어도 아무런 반응이 없습니다.

먼저 레이어와 태그들을 만들어줍니다.

  • 몬스터의 레이어 : Monster
  • 플레이어의 레이어 : Player
  • 플레이어가 피격됐을 때의 레이어 : PlayerDamaged

우선 3개를 만들어줍니다.

image

그리고 플레이어, 몬스터에게 각각 Player, Monster 레이어,태그를 붙여줍니다.

또한가지 생각해보면, 보통 몬스터끼리는 충돌이 없도록하는것이 일반적이죠.

이것을 위해서는

  • Edit - ProjectSettings… - Physics2D 맨 아래

image

레이어들간에 충돌 설정을 할 수 있는 부분이 있습니다.

Monsert/Monster 부분을 체크 해제합니다.

플레이어가 몬스터와 피격되었을 때, 잠깐동안 무적상태를 만들어주지않으면 계속해서 충돌이 일어나 난이도가 많이 어려워지겠죠.

그렇기 때문에 PlayerDamaged/Monster 부분도 체크를 해제합니다.

몬스터와 충돌 이벤트 구현

플레이어가 피격됐을 때의 애니메이션을 추가해줍니다.

Player_Damaged 라는 이름의 애니메이션을 추가해주었고, 피격은 어느상태에서나 일어날 수 있기때문에 다음과 같이 설정했습니다.

파라미터는 Trigger로 만들었고 이름은 Damaged입니다.

image

image

image

PlayerControl.cs

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class PlayerControl : MonoBehaviour
{
    Rigidbody2D rigid;
    SpriteRenderer spriteRenderer;
    Animator anim;

    public float maxSpeed;
    public float jumpPower;

    private void Awake()
    {
        rigid = GetComponent<Rigidbody2D>();
        spriteRenderer = GetComponent<SpriteRenderer>();
        anim = GetComponent<Animator>();
    }
    // Start is called before the first frame update
    void Start()
    {

    }

    void Update()
    {
        //키보드 뗏을때 속도감소(멈춤)
        if (Input.GetButtonUp("Horizontal"))
        {
            //normalized : 단위벡터화
            rigid.velocity = new Vector2(0.5f * rigid.velocity.normalized.x, rigid.velocity.y);

        }

        //플레이어 방향 전환
        if (Input.GetButtonDown("Horizontal"))
            spriteRenderer.flipX = Input.GetAxisRaw("Horizontal") == -1;

        //Walking Animation 설정
        if (Mathf.Abs(rigid.velocity.x) < 0.3f)
            anim.SetBool("isWalking", false);
        else
            anim.SetBool("isWalking", true);

        //점프(1단점프만 가능)
        if (Input.GetButtonDown("Jump") && !anim.GetBool("isJumping"))
        {
            rigid.AddForce(Vector2.up * jumpPower, ForceMode2D.Impulse);
            anim.SetBool("isJumping", true);        
        }
    }

    void FixedUpdate()
    {
        //키보드 방향키 입력으로 움직임
        float h = Input.GetAxisRaw("Horizontal");

        rigid.AddForce(Vector2.right * h, ForceMode2D.Impulse);

        if (rigid.velocity.x > maxSpeed) //오른쪽 속도
            rigid.velocity = new Vector2(maxSpeed, rigid.velocity.y);
        else if (rigid.velocity.x < maxSpeed * (-1))  //왼쪽 속도
            rigid.velocity = new Vector2(maxSpeed * (-1), rigid.velocity.y);

        //착지(캐릭터가 떨어지고있을 때)
        if (rigid.velocity.y < 0)
        {
            Debug.DrawRay(rigid.position, Vector3.down, new Color(1, 0, 0));
            RaycastHit2D rayHit = Physics2D.Raycast(rigid.position, Vector3.down, 1, LayerMask.GetMask("Floor"));
            if (rayHit.collider != null)
            {
                if (rayHit.distance <= 0.45f)
                    anim.SetBool("isJumping", false);
            }
        }
    }

    // 충돌 이벤트
    void OnCollisionEnter2D(Collision2D collision)
    {
        if(collision.gameObject.tag == "Monster")
        {
            OnDamaged(collision.transform.position);
        }
    }

    // 피격됐을 때 호출되는 함수 [무적만들기] (피격된 대상의 위치를 받음)
    void OnDamaged(Vector2 targetPos)
    {
        // PlayerDamaged 레이어로 변경
        gameObject.layer = 8;

        // 반투명도 설정(맞았다는것을 표현)
        spriteRenderer.color = new Color(1, 1, 1, 0.4f);

        //맞았을 때 팅겨남
        int dirc = transform.position.x - targetPos.x > 0 ? 1 : -1;
        rigid.AddForce(new Vector2(dirc, 1) * 7, ForceMode2D.Impulse);

        //피격 애니메이션
        anim.SetTrigger("Damaged");

        //무적풀림
        Invoke("OffDamaged", 2);
    }

    // 무적판정 풀기
    void OffDamaged()
    {
        gameObject.layer = 7;
        spriteRenderer.color = new Color(1, 1, 1, 1.0f);

    }
}

  • OncollisionEnter2D 함수는 플레이어와 충돌했을 때 호출되는 함수로, 만약 몬스터와 부딪혔다면 OnDamaged 함수를 호출

  • OnDamaged 함수는 부딪힌 대상의 위치정보를 받아, 플레이어가 피격대상의 반대편으로 튕겨져 나가도록 연출했음

  • 피격됐을 때 플레이어는 PlayerDamaged 레이어로 바뀌며, 몬스터와 충돌이 일어나지않음(무적) 2초뒤에 OffDamaged를 호출해 무적풀림

image

댓글남기기