안녕하세요

프로그램 과정에서 막혔던 문제들에 대한 해결책 정리


페이지 목록

2024년 12월 27일 금요일

[유니티][Unity][chatGPT] Unity2D에서 MVC로 구현한 보스가 주인공 위치에 원형의 범위기술을 사용 후 Duration시간 뒤에 터지는 기술

 Unity 2D에서 MVC(Model-View-Controller) 패턴으로 보스가 주인공 위치를 기준으로 원형 범위 공격을 수행하는 시스템을 설계하는 코드이다. MVC 패턴은 코드의 분리를 통해 가독성과 유지보수성을 높이는 것을 목표로 한다.



MVC 구조

  1. Model:

    • 데이터 및 로직을 처리합니다.
    • 스킬 반경, 경고 시간, 데미지 값 등을 관리.
  2. View:

    • 사용자에게 보여지는 경고 UI와 스킬 효과를 처리합니다.
    • 경고 UI 생성, 스킬 효과 표시 등을 담당.
  3. Controller:

    • 사용자 입력이나 로직의 흐름을 관리합니다.
    • 보스의 행동을 제어하고 Model과 View를 연결.

1. SkillModel (Model)

스킬 데이터를 관리하고 범위 내 타겟을 감지하는 로직을 구현합니다.

csharp
using UnityEngine; public class BossSkillModel { public float Radius { get; private set; } public float Damage { get; private set; } public float WarningDuration { get; private set; } public BossSkillModel(float radius, float damage, float warningDuration) { Radius = radius; Damage = damage; WarningDuration = warningDuration; } // 범위 내 타겟 감지 public Collider2D[] GetTargets(Vector2 position, LayerMask targetLayer) { return Physics2D.OverlapCircleAll(position, Radius, targetLayer); } }

2. SkillView (View)

스킬의 시각적 요소를 관리합니다.

 - 경고 UI 프리팹에 임의로 그림판으로 작성한 원을 넣어 주고, 스킬 효과 프리팹은 아직 작성하지 않았다. (스킬 효과 프리팹은 주석 처리해도 동작한다)

csharp
using UnityEngine; public class BossSkillView : MonoBehaviour { public GameObject WarningPrefab; // 경고 UI 프리팹 public GameObject EffectPrefab; // 스킬 효과 프리팹 private GameObject warningInstance; // 경고 UI 표시 public void ShowWarning(Vector2 position, float radius) { warningInstance = Instantiate(WarningPrefab, position, Quaternion.identity); warningInstance.transform.localScale = new Vector3(radius * 2, radius * 2, 1); } // 경고 UI 제거 public void HideWarning() { if (warningInstance != null) { Destroy(warningInstance); } } // 스킬 효과 표시 public void ShowSkillEffect(Vector2 position, float radius) { GameObject effect = Instantiate(EffectPrefab, position, Quaternion.identity); effect.transform.localScale = new Vector3(radius * 2, radius * 2, 1); } }

3. BossController (Controller)

보스의 행동을 관리하고 Model과 View를 연결합니다.

 - BossSkillController가 아니라 BossController인 이유는 보스가 사용하는 스킬이기 때문이고, 작은 프로젝트의 경우 BossSkillController를 따로 구분 하지 않고 하나의 BossController에서 사용해도 감당 가능하기에 BossController를 사용한다. 

   감당이 안된다면 BossSkillController를 별도로 만들어 사용해도 된다.

csharp
using UnityEngine; public class BossController : MonoBehaviour { public Transform player; // 주인공 Transform public LayerMask targetLayer; // 타겟 레이어 public SkillView skillView; // 스킬 View private SkillModel skillModel; // 스킬 데이터 void Start() { // Model 초기화 skillModel = new SkillModel(radius: 5.0f, damage: 50.0f, warningDuration: 2.0f); } public void StartSkill() { if (player == null) { Debug.LogError("Player가 설정되지 않았습니다!"); return; } // 주인공 위치 저장 Vector2 targetPosition = player.position; // View를 통해 경고 UI 표시 skillView.ShowWarning(targetPosition, skillModel.Radius); // 일정 시간 후 스킬 발동
StartCoroutine(ActivateSkillAfterDelay(targetPosition, bossSkillModel.WarningDuration)); }

    IEnumerator ActivateSkillAfterDelay(Vector2 targetPosition, float delay)     {     yield return new WaitForSeconds(delay);      ActivateSkill(targetPosition);     } private void ActivateSkill(Vector2 targetPosition) { // View에서 경고 UI 제거 skillView.HideWarning(); // View에서 스킬 효과 표시 skillView.ShowSkillEffect(targetPosition, skillModel.Radius); // Model을 통해 범위 내 타겟 감지 Collider2D[] hitTargets = skillModel.GetTargets(targetPosition, targetLayer); foreach (var target in hitTargets) { target.GetComponent<Health>()?.TakeDamage(skillModel.Damage); } Debug.Log("스킬 발동 완료!"); } }

4. Health (Model)

주인공이나 다른 타겟이 데미지를 받을 수 있도록 체력을 관리합니다.

csharp
using UnityEngine; public class Health : MonoBehaviour { public float MaxHealth = 100f; private float currentHealth; void Start() { currentHealth = MaxHealth; } public void TakeDamage(float amount) { currentHealth -= amount; Debug.Log($"{gameObject.name} 남은 체력: {currentHealth}"); if (currentHealth <= 0) { Die(); } } private void Die() { Debug.Log($"{gameObject.name} 사망"); Destroy(gameObject); } }

5. Unity 설정

1) 보스 설정

  1. Boss GameObject에 **BossController**와 SkillView 스크립트를 추가.
  2. SkillView 설정:
    • WarningPrefabEffectPrefab을 연결.
  3. BossController 설정:
    • 주인공의 Transform을 Player 필드에 연결.
    • TargetLayer에 적합한 레이어 설정(예: "Player").

2) 주인공 설정

  1. 주인공 GameObject에 Health 스크립트 추가.
  2. Inspector에서 MaxHealth 값 설정.

3) 경고 및 공격 효과 프리팹

  • WarningPrefab: 원형 이미지 기반 UI.
  • EffectPrefab: 원형 스프라이트 또는 파티클 효과.

6. 테스트

  1. BossControllerStartSkill 메서드를 호출(키 입력으로 테스트 가능).
    csharp
    void Update() { if (Input.GetKeyDown(KeyCode.F)) { StartSkill(); } }
  2. 주인공 이동:
    • 스킬 발동 위치와 데미지 처리가 주인공의 위치에 맞게 동작하는지 확인.

결과

  • 보스는 주인공의 위치를 감지하여 원형 범위 경고를 표시하고, 일정 시간 후 해당 위치에서 스킬을 발동한다.
  • 범위 내에 있는 대상(주인공 포함)은 데미지를 받는다.

MVC 패턴 장점

  1. 코드 분리:

    • 데이터(Model), 시각적 요소(View), 로직(Control)이 독립적으로 관리되므로 유지보수성 향상.
  2. 확장성:

    • 새로운 스킬 View 또는 Model을 쉽게 추가 가능.
  3. 테스트 용이성:

    • 각 컴포넌트를 독립적으로 테스트 가능.

** 이 글은 chatGPT의 도움으로 작성되었습니다.

댓글 없음:

댓글 쓰기