안녕하세요. 인텔리원스튜디오(IntelliOneStudio)입니다.
오늘은 ChatGPT를 활용하여 Unity 플랫포머 게임에서 적을 공격하는 기능을 추가해볼께요.
참고로 공격 처리는 총 3회에 걸쳐 게시될거에요.
제목 | 내용 |
[챗GPT게임개발21] ChatGPT를 활용하여 적 공격 처리 추가하기(1) | OnCollisionEnter2D를 활용한 충동 감지 기능 개발 |
[챗GPT게임개발22] ChatGPT를 활용하여 적 공격 처리 추가하기(2) | 애니메이션 이벤트로 콜라이더 위치 조정 |
[챗GPT게임개발23] ChatGPT를 활용하여 적 공격 처리 추가하기(3) | Physics2D.OverlapCircleAll을 이용한 충돌 감지 |
[오늘의 목표] 애니메이션 이벤트로 콜라이더 위치 조정 + OnCollisionEnter2D를 활용한 충동 감지 기능 개발 완료
1. 애니메이션 이벤트로 콜라이더 위치 조정
2. OnCollisionEnter2D 이벤트 활용
3. 실행 결과 살펴 보기
※ ChatGPT 답변 내용 중 제가 별도로 표시한 파란색 내용을 기준으로 읽으시면 좀 더 이해가 쉽게 될거예요.
애니메이션에서 콜라이더 위치 조정이 가능하지 않을까?
아래 글에서 충돌 이벤트를 활용하는데 실패를 했어요.
[챗GPT게임개발21] ChatGPT를 활용하여 적 공격 처리 추가하기(1)
그런데 궁금했어요.
애니메이션 수정을 통해서 콜라이더(Collider)의 위치 조정이 가능하지 않을까
콜라이더 위치 조정만 되면 적과 충돌이 가능해지고,
지난 시간이 만든 OnCollisionEnter2D 스크립트를 사용할 수 있어요.
챗GPT에게 물어봤어요.
[질문] 안녕 ChatGPT, 애니메이션 수정을 통해서는 콜라이더의 위치 조정이 가능하니?
[답변]
Unity에서 애니메이션 클립을 사용하여 콜라이더의 위치를 조정하는 것은 완전히 가능하고 때로는 바람직한 방법입니다. 애니메이션 클립 내에서 애니메이션 이벤트를 사용하여 특정 시점에서 콜라이더의 위치를 조정할 수 있습니다. 이 방법은 특히 시각적인 애니메이션과 물리적 상호작용이 밀접하게 연결되어 있을 때 유용합니다.
애니메이션 이벤트로 콜라이더 위치 조정하기
- 애니메이션 클립 열기: Unity 에디터에서 플레이어 캐릭터의 공격 애니메이션 클립을 엽니다.
- 애니메이션 이벤트 추가: 애니메이션 타임라인에 적절한 위치에 마우스 오른쪽 버튼을 클릭하고, "Add Event"를 선택합니다. 이 이벤트는 공격이 실제로 발동되는 순간에 위치해야 합니다.
- 이벤트 함수 지정: 이벤트에 함수를 지정합니다. 이 함수는 PlayerController 스크립트 내에 정의되어야 하며, 콜라이더의 위치를 업데이트하는 로직을 포함합니다.
스크립트에 콜라이더 위치 업데이트 함수 추가
public void UpdateColliderForAnimation() { float offsetDistance = 0.5f; // 적절한 오프셋 거리 설정 if (collider2d != null) { collider2d.offset = new Vector2(spriteRenderer.flipX ? -offsetDistance : offsetDistance, collider2d.offset.y); } }
애니메이션 이벤트 함수 연결
애니메이션 이벤트 윈도우에서 UpdateColliderForAnimation 함수를 선택합니다. 이렇게 설정하면, 애니메이션 클립이 해당 프레임에 도달했을 때 자동으로 콜라이더의 위치를 업데이트합니다.
추가적인 고려사항
- 애니메이션 이벤트의 정밀성: 애니메이션 이벤트는 매우 정확하게 특정 프레임에 함수를 호출할 수 있습니다. 이를 이용해 공격 애니메이션의 특정 동작에서 콜라이더의 위치를 조정해야 할 때 정확히 조정할 수 있습니다.
- 테스트와 조정: 애니메이션 이벤트를 사용한 후에는 반드시 게임을 실행하여 콜라이더의 위치가 올바르게 조정되는지 테스트해야 합니다. 필요에 따라 애니메이션 클립 내의 이벤트 위치를 조정하거나, 콜라이더 오프셋 값을 미세 조정할 수 있습니다.
이 방법을 사용하면 애니메이션과 게임 로직 간의 일관성을 유지하면서, 시각적인 부분과 물리적인 상호작용을 정확히 조율할 수 있습니다. 이는 플레이어의 직관적인 경험을 향상시키고, 게임의 전반적인 품질을 높이는 데 기여합니다.
애니메이션 이벤트 생성하기
챗GPT가 알려준대로 애니메이션 이벤트를 만들고 함수를 연결했어요.
물론 이벤트 함수도 PlayerController 스크립트에 추가했어요.
변경사항을 저장하고 실행모드에서 시험을 했어요.
플레이어 방향에 따라 콜라이더가 잘 이동했어요.
하지만 공격 애니메이션이 끝이나면 다시 콜라이더가 원래 자리로 돌아오지 않았어요.
애니메이션 종료 시 콜라이더는 원래 자리로 돌아와야해
콜라이더가 원래 자리로 돌아오는 방법을 물었어요.
[질문] 안녕 ChatGPT, 아래 콜라이더 업데이트를 실행하고 애니메이션 종료 시에는 원래 콜라이더 위치로 다시 돌아와야해. 원래 위치로 돌아오는 함수를 추가로 만들어줘
public void UpdateColliderForAnimation() { float offsetDistance = 0.5f; // 적절한 오프셋 거리 설정 if (collider2d != null) { collider2d.offset = new Vector2(spriteRenderer.flipX ? -offsetDistance : offsetDistance, collider2d.offset.y); } }
[답변]
공격 애니메이션이 끝날 때 콜라이더를 원래 위치로 복원하는 함수를 추가하는 것은 게임의 물리적 일관성을 유지하는 데 중요합니다. 여기에서는 UpdateColliderForAnimation 함수와 함께 콜라이더의 위치를 초기화하는 ResetColliderPosition 함수를 구현해 보겠습니다.
콜라이더 위치 초기화 함수
이 함수는 콜라이더의 offset을 초기 값으로 설정하는 역할을 합니다. 이 초기 값은 캐릭터의 디폴트 물리적 크기와 위치에 기반하여 정의되어야 합니다.
public void ResetColliderPosition() { if (collider2d != null) { // 여기에서는 collider2d.offset.y를 유지하고 x 값을 0으로 설정합니다. collider2d.offset = new Vector2(0, collider2d.offset.y); } }
애니메이션 클립에 이벤트 추가하기
- 애니메이션 클립 열기: Unity 에디터에서 공격 애니메이션 클립을 열고 애니메이션이 끝나는 지점을 찾습니다.
- 애니메이션 이벤트 추가: 애니메이션의 마지막 프레임에 마우스 오른쪽 버튼을 클릭하고 "Add Event"를 선택합니다.
- 이벤트 함수 지정: 이벤트에 ResetColliderPosition 함수를 지정합니다. 이렇게 하면 애니메이션이 끝날 때 자동으로 콜라이더의 위치를 초기화합니다.
사용 사례
- 공격 애니메이션 실행: 공격 애니메이션이 시작될 때 UpdateColliderForAnimation 함수를 호출하여 콜라이더의 위치를 조정합니다.
- 애니메이션 종료: 공격 애니메이션이 끝나는 시점에 ResetColliderPosition 함수를 호출하여 콜라이더를 원래 위치로 복원합니다.
이 방식은 플레이어 캐릭터의 물리적 상태가 애니메이션에 따라 동적으로 변화하면서도 게임의 물리적 일관성과 정확성을 유지할 수 있도록 합니다. 게임을 테스트할 때는 이러한 변화가 예상대로 작동하는지 확인해야 하며, 필요에 따라 offset 값의 조정이 필요할 수 있습니다.
UpdateColliderForAnimation를 추가한 프레임보다 한 프레임 뒤에 ResetColliderPosition함수를 호출하는 이벤트를 만들었어요.
변경사항을 저장하고 실행모드에서 시험을 했어요.
원하는 대로 콜라이더가 이동해요.
공격 준비를 완료했어요.
이제 공격 애니메이션이 동작할 때 플레이어의 콜라이더가 이동되요.
플레이어의 콜라이더가 적의 콜라이더와 부딪히면 되요.
그럼 아래 스크립트가 적에게 피해를 주고 적을 없애는 역할을 해요.
using Platformer.Core;
using Platformer.Mechanics;
using Platformer.Model;
using UnityEngine;
using static Platformer.Core.Simulation;
namespace Platformer.Gameplay
{
/// <summary>
/// Fired when a Player collides with an Enemy.
/// </summary>
/// <typeparam name="EnemyCollision"></typeparam>
public class PlayerEnemyCollision : Simulation.Event<PlayerEnemyCollision>
{
public EnemyController enemy;
public PlayerController player;
PlatformerModel model = Simulation.GetModel<PlatformerModel>();
public override void Execute()
{
Debug.Log("Collision detected between player and enemy.");
Debug.Log("Current Player Attack State: " + player.attackState); // player.attackState 값을 항상 출력
if (player.attackState == PlayerController.AttackState.Idle)
{
Debug.Log("Player is attacking. Handling attack collision.");
HandleAttackCollision();
}
else
{
Debug.Log("Handling regular collision based on player position.");
HandleRegularCollision();
}
}
void HandleAttackCollision()
{
var enemyHealth = enemy.GetComponent<Health>();
if (enemyHealth != null)
{
enemyHealth.Decrement();
Debug.Log("Enemy health decremented by player attack.");
if (!enemyHealth.IsAlive)
{
Debug.Log("Enemy has died from player attack.");
Schedule<EnemyDeath>().enemy = enemy;
// player.Bounce(2);
}
else
{
Debug.Log("Enemy hurt but still alive; player bounces higher.");
// player.Bounce(7);
}
}
else
{
Debug.Log("No Health component found on enemy during attack.");
Schedule<EnemyDeath>().enemy = enemy;
// player.Bounce(2);
}
}
void HandleRegularCollision()
{
var willHurtEnemy = player.Bounds.center.y >= enemy.Bounds.max.y;
if (willHurtEnemy)
{
Debug.Log("Player is positioned to hurt the enemy.");
var enemyHealth = enemy.GetComponent<Health>();
if (enemyHealth != null)
{
enemyHealth.Decrement();
Debug.Log("Enemy health decremented by player jump attack.");
if (!enemyHealth.IsAlive)
{
Debug.Log("Enemy has died from player jump attack.");
Schedule<EnemyDeath>().enemy = enemy;
player.Bounce(2);
}
else
{
Debug.Log("Enemy hurt by jump attack but still alive.");
player.Bounce(7);
}
}
else
{
Debug.Log("No Health component found on enemy for jump attack.");
Schedule<EnemyDeath>().enemy = enemy;
player.Bounce(2);
}
}
else
{
Debug.Log("Player will be hurt and possibly die due to collision.");
Schedule<PlayerDeath>();
}
}
}
}
이제 적을 공격해봐요.
플레이어를 적과 가까운 위치에 두고 공격을 해볼께요.
이번에는 오른쪽에서 적을 공격해볼께요.
모두 잘 되네요.
오늘은 ChatGPT를 활용하여 Unity 플랫포머 게임에서 적을 공격하는 기능을 만들기 위해
애니메이션 이벤트로 콜라이더 위치 조정하는 방법을 살펴봤어요.
다음 시간에는 Physics2D.OverlapCircleAll을 이용한 충돌 감지를 알아볼께요.
지금까지,
언제나 성장하는 인텔리원스튜디오(IntelliOneStudio)입니다.
감사합니다.
'디지털노마드' 카테고리의 다른 글
[챗GPT게임개발24] ChatGPT를 활용하여 적 캐릭터에 생명력(헬스) 추가 (74) | 2024.05.13 |
---|---|
[챗GPT게임개발23] ChatGPT를 활용하여 적 공격 처리 추가하기(3) (55) | 2024.05.12 |
[챗GPT게임개발21] ChatGPT를 활용하여 적 공격 처리 추가하기(1) (71) | 2024.05.11 |
[챗GPT게임개발20] ChatGPT를 활용하여 공격 애니메이션 추가하기 (68) | 2024.05.10 |
[챗GPT게임개발19] ChatGPT를 활용하여 가속 패드와 Jiggler 추가하기 (65) | 2024.05.09 |