2023. 7. 31. 22:40ㆍC# & Unity 공부
저번 시간에는 몬스터가 자유자재로 움직일 수 있도록 구현해줬다.
이번에는 플레이어가 가시나 몬스터에게 닿았을 때 나오는 이벤트를 구현해보겠다.
함정(가시) 추가
우선 가시를 추가해보자.
Tile Palette를 켜보자.
Sprites에서 가시를 찾아서 Tile Palette에 추가해주자.
그리고 아무데나 설정해 두자
이 가시를 설정하면 되는데,
가시를 지형과 같은 Tilemap에다가 두면 안된다.
왜냐하면 지형은, Platform이라는 Layer에 있는데 가시는 Platform이 아닌 적으로 간주해야 하기 때문이다.
그러면 타일맵을 하나 더 만들자.
Spikes라는 이름을 넣어주고 Add Component를 통하여
Tilemap Collider를 넣는 것을 깜박하지 말자!!
그 뒤에는 가시를 설치해주고 적이라는 것을 알기 위하여
Tag로 Enemy를 만들어 넣어주자. Layer도 Enemy를 추가해 넣어주자.
그리고 몬스터에게는 둘 다 Enemy를 넣어주자.
그리고 Player는 Player라는 태그와 레이어를 둘 다 쓸 것인데,
추가로 Player Damaged라는 레이어를 하나 더 사용할 것이다.
여기까지 따라왔으면 우선 몬스터부터 설정해보겠다.
몬스터의 Layer는 Enemy인데 가시도 똑같다.
우리는 같은 Layer끼리 부딪히지 않았으면 한다.
Layer 설정
Edit > Project Settings > Physics 2D에 가면 아래에
요런 것을 볼 수 있다.
Enemy와 Enemy끼리는 충돌하면 안되기 때문에
알맞는 칸을 해제시킨다.
그리고 실행시키면
부딪히지 않고 잘 지나가는 것을 볼 수 있는데,
만약 몬스터를 앞으로 보내고 싶으면
Z축을 바꿔주거나 Order in Layer을 바꿔주도록 하자.
그 다음은 Player 차례이다.
플레이어에게는 두 가지 레이어가 있었는데,
그 중 Player Damaged는 플레이어가 다친 상태를 의미한다.
그럴 때에는 무적 시간이 1,2초 정도 있기 때문에 데미지를 입지 않는다.
그래서 Player Damaged일 때는 Enemy와 만나는 것을 해제하면 된다.
이 칸들을 해제하면 OnCollisionEnter 함수를 써도 먹지 않는다.
몬스터와의 충돌 이벤트
우선 맞으면 효과가 발동하는 것을 구현하기 앞서 맞는 걸 확인해보겠다.
코드를 다음과 같이 짜서 넣어보자.
void OnCollisionEnter2D(Collision2D collision)
{
if(collision.gameObject.tag=="Enemy")
{
Debug.Log("플레이어가 맞았습니다!");
}
}
PlayerMove.cs에다가 Awake()나 FixedUpdate() 이런 곳 함수들
안에다가 적을 필요 없고 따로 적으면 된다.
그리고 실행하면
잘 실행되는 것을 확인할 수 있다.
무적 시간
이제 그럼 실제 기능을 구현해보자.
보통 기능이 담긴 함수는 따로 빼서 선언해주는 것이 좋다.
코드를 다음과 같이 작성해주자.
//충돌 이벤트
void OnCollisionEnter2D(Collision2D collision)
{
if(collision.gameObject.tag=="Enemy")
{
OnDamaged(collision.transform.position);
}
}
//무적 효과 함수
void OnDamaged(Vector2 targetPos)
{
//레이어 바꾸기
gameObject.layer = 9;
//색깔 바꾸기 (약간 투명하게)
spriteRenderer.color = new Color(1, 1, 1, 0.4f);
//튕겨져 나가기 (힘을 가해서)
int dirc = transform.position.x - targetPos.x > 0 ? 1 : -1;
//dirc 식으로 방향을 나타내서 왼쪽에서 부딪혔으면 음수이므로 -1.
//오른쪽에서 부딪혔으면 양수이므로 1이 된다.
rigid.AddForce(new Vector2(dirc, 1) * 7, ForceMode2D.Impulse);
//힘을 가한다.
}
바꾸고 실행하면
다음과 같이 투명해지면서 적들을 통과하고 다닐 수 있는 무적 효과처럼 된다.
하지만 무적 상태가 되고 다시 돌아오지는 않는다.
무적 시간 해제
우리는 무적 상태에서 다시 돌아오는 것을 구현해야 한다.
Layer를 다시 원래대로 돌려보내고 색깔도 원상태가 되며,
Invoke() 함수로 OnDamaged 함수가 실행되고 나서 몇 초후에 실행시켜주면 된다.
코드는 다음과 같다.
//무적 효과 함수
void OnDamaged(Vector2 targetPos)
{
//레이어 바꾸기
gameObject.layer = 9;
//색깔 바꾸기 (약간 투명하게)
spriteRenderer.color = new Color(1, 1, 1, 0.4f);
//튕겨져 나가기 (힘을 가해서)
int dirc = transform.position.x - targetPos.x > 0 ? 1 : -1;
//dirc 식으로 방향을 나타내서 왼쪽에서 부딪혔으면 음수이므로 -1.
//오른쪽에서 부딪혔으면 양수이므로 1이 된다.
rigid.AddForce(new Vector2(dirc, 1) * 7, ForceMode2D.Impulse);
//힘을 가한다.
Invoke("OffDamaged", 3);
//3초 후에 무적 풀기
}
//무적 풀기 함수
void OffDamaged()
{
//레이어 바꾸기
gameObject.layer = 8;
//색깔 바꾸기
spriteRenderer.color = new Color(1, 1, 1, 1);
}
}
실행하면 무적 상태에서 원상태로 복귀가 잘 될 것이다.
피격 애니메이션
맞는 모션을 좀 더 자연스럽게 해보자.
Jump 모션을 나타내는 Sprite 두 개를 합쳐서 애니메이션을 만들자.
애니메이션을 기호에 맞게 수정하자.
그리고 Animatior에 들어가 Any State와 Exit를 사용해 볼 것이다.
우선 Damaged를 가운데에다가 놓고 Any State와 Exit을 연결시키자.
그리고 Parameters에서 Trigger 변수 doDamaged를 만들어 보자.
참고로 doDamaged는 값이 없다.
Player_damaged에서 Exit으로 가는 것은 그대로 두어도 된다.
저 Has exit time은 애니메이션 시간과 똑같다.
그리고 애니메이션의 Loop Time을 꺼준다.
애니메이션이 돌지 않고 0.3초(설정값)만 실행시켜줄 것이기 때문이다.
그리고 스크립트에다가 트리거를 발동시키는 코드를 작성하자.
//애니메이션
anim.SetTrigger("doDamaged");
//트리거를 발동시킨다.
OnDamaged()함수 안에다가 넣어주면 된다.
참고로 AnyState는 현재 상태와 상관 없이 트리거 발동 조건이 만족되면
실행 후 복귀하게 된다.
실행시켜보면 잘 작동하는 것을 알 수 있다.
'C# & Unity 공부' 카테고리의 다른 글
Unity 2D RPG - 1. 도트 타일맵으로 쉽게 준비하기 (0) | 2023.08.08 |
---|---|
Unity 2D - 8. 스테이지를 넘나드는 게임 완성하기 (0) | 2023.08.05 |
Unity 2D - 6. 몬스터 Ai 구현하기 (0) | 2023.07.31 |
Unity 2D - 5. 타일맵으로 플랫폼 만들기 (0) | 2023.07.30 |
Unity 2D - 4. 플레이어 점프 구현하기 (0) | 2023.07.28 |