Skip to content

keyone957/Slime_Adventure

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

43 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

슬라임의 모험

진행 기간: 2024. 05. ~ 2024. 06.

사용한 기술 스택: C#, Unity

개발 인원(역할): 개인

한 줄 설명: 2D 메트로베니아 + 캐주얼 미니게임

비고: 개인 프로젝트

게임 플레이 풀 영상


게임 플레이 풀영상

프로젝트 소개


  • 2D 메트로배니아 장르 게임과 캐주얼 미니게임을 섞은 게임 입니다.

주요 기능 구현


  1. 게임 시스템

    • 사운드 매니저
    • 플레이어 Stat, Input 매니저
    • 세이브/로드 기능
    • 씬 매니저
    • 게임 클리어·오버 로직
    • 던전 시스템
    • 보스 스테이지 시스템
    • 재화·보상 시스템
  2. 게임 플레이 관련

    • 몬스터 AI (FSM) 구현
    • 플레이어 카메라
    • 맵 오브젝트 인터렉터 (포탈, 보물상자, 보스 공격 총알)
    • NPC/상점 기능
    • 플레이어 분열 스킬·공격 구현
    • 플레이어 애니메이션
    • Scriptable Object 기반 전략 패턴 & 이벤트 채널 패턴을 이용한 스킬 구현

ScriptableObject 기반 전략 패턴으로 확장 가능한 스킬 시스템 구조 개선

스킬 실행 로직이 플레이어 입력 처리 컴포넌트에 직접 구현되어 있어 플레이어가 어떤 스킬을 사용할지와 스킬이 어떻게 동작하는지에 대한 책임이 분리되지 않아 OCP와 SRP 원칙이 지켜지지 않은 상태.

그로 인해 확장성이 떨어지고 유연한 스킬 구현이 어려웠음.

PlayerSkillSO.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public abstract class PlayerSkillSO : ScriptableObject
{
    public float coolDown;
    public abstract void DOSkill();
}

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

[CreateAssetMenu(fileName = "FireBallSkill", menuName = "SO/FireBallSkillSO")]
public class FireBallSO : PlayerSkillSO
{
   [SerializeField] private int damage;
    public override void DOSkill()
    {
        GameObject fireBallObj = 
        PoolManager.Instance.GetObject("Shooting",null,Quaternion.identity,null);
        fireBallObj.GetComponent<ShootingSkill>().InitValue(damage).Forget();
    }
}
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Cysharp.Threading.Tasks;

public class ShootingSkill : MonoBehaviour
{
  [SerializeField] private float shotSpeed;
  [SerializeField] private float shootingDuration;
  private Vector3 shootDirection;
  public int Damage { get; private set; }
  
  private void Update()
  {
    transform.Translate(shootDirection * shotSpeed * Time.deltaTime);
  }

  public async UniTaskVoid InitValue(int soDamage)
  {
    GameObject player = GameObject.FindWithTag("Player");
    transform.position = player.transform.position;
    
    if (player.transform.rotation.y == 0)
    {
      shootDirection = Vector3.right;
      transform.rotation=Quaternion.Euler(0,0,180);
    }
    else
    {
      shootDirection = Vector3.right;
    }
    Damage = soDamage;
    await UniTask.Delay(TimeSpan.FromSeconds(shootingDuration));
    PoolManager.Instance.ReturnObject("Shooting", gameObject);
  }
}
스킬 로직을 플레이어로부터 분리하기 위해 전략 패턴을 Scriptable Object 기반으로 적용함.
  • PlayerSkillSO.cs 추상 클래스를 정의하여 스킬 실행 인터페이스를 통일
  • 각 스킬을 개별 전략 객체로 구현
  • 플레이어 컴포넌트는 구체적인 스킬 타입을 알 필요 없이 DOSkill() 메서드만 호출하도록 함.
  • 또한 Scriptable Object를 사용함으로써 코드 수정 없이 SO만 갈아 끼우면 여러 스킬을 사용할 수 있음.
FullAttackSkillSO.cs+EventChannelListener.cs
using System;
using System.Collections;
using System.Collections.Generic;
using Unity.Mathematics;
using UnityEngine;
using Cysharp.Threading.Tasks;

[CreateAssetMenu(fileName = "FullAttack", menuName = "SO/FullAttackSkill")]
public class FullAttackSkillSO : PlayerSkillSO
{
    [SerializeField] private EventChannelSO fullAttackSO;
    public override void DOSkill()
    {
        GameObject fullAttackEffect=
        PoolManager.Instance.GetObject("FullAttack",null,quaternion.identity,GameObject.FindWithTag("Player").transform);
        fullAttackEffect.transform.localScale = new Vector3(0.125f, 0.125f, 0.125f);
        fullAttackEffect.transform.localPosition = Vector3.zero;
        
        fullAttackSO.RaiseEvent();
        DestroyEffect(fullAttackEffect).Forget();
    }

    private async UniTaskVoid DestroyEffect(GameObject effect)
    {
        await UniTask.Delay(TimeSpan.FromSeconds(2.0f));
        PoolManager.Instance.ReturnObject("FullAttack",effect);
        
    }
}
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;

public class EventChannelListener : MonoBehaviour
{
    
    [SerializeField] private EventChannelSO _eventChannel;
    [SerializeField] private UnityEvent _response;

    private void OnEnable()
    {
        if (_eventChannel!= null)
        {
            _eventChannel.OnEventRaised += OnEventRaised;
        }
    }

    private void OnDisable()
    {
        if (_eventChannel!= null)
        {
            _eventChannel.OnEventRaised -= OnEventRaised;
        }
    }

    public void OnEventRaised()
    {
        _response?.Invoke();
    }
}

스킬 중 전체 공격기는 SO기반 이벤트 버스 패턴을 적용하여 여러 시스템 간 결합도를 낮춤

  • FullAttackSkillSO는 스킬 사용시 직접적인 대상 제어 없이 이벤트만 발행
  • EventChannelSO를 이벤트 버스로 사용하여 로직간 직접 참조 제거
  • 각 몬스터 피격은 EventChannelListener를 통해 이벤트를 구독하고 독립적으로 반응

개발 내용 및 플레이 영상


[게임 플레이]

Player Attack
플레이어 공격, 피격, 피격 시 무적 판정 기능 구현
Skill Pattern
Scriptable Object 기반 전략 패턴, 이벤트 채널 패턴을 이용한 스킬 구현.
Player Attack
플레이어 분열 스킬을 사용하면 이동 속도 증가 및 공격력은 내려가지만 맵 내 일반 상태 일 때는 들어가지 못하는 공간에 들어갈 수 있다

[미니게임]

⇒ 일반 던전 맵 중간에 점프 맵, 코인 먹기의 미니게임을 클리어하여 보너스 보상을 얻을 수 있습니다

⇒ 마지막 보스에서는 날아오는 투사체들을 피하면서 보스를 물리쳐, 최종 보상을 얻을 수 있습니다.

[UI / UX]

  • 타이틀 씬 & 인게임 UI

⇒ 인게임에서 플레이어 상태, 스테이지, 등 필요한 UI를 배치하고 게임 도중에도 메뉴 창을 배치하였습니다.

=⇒ Scriptable Object를 이용하여 상점 기능을 구현하였습니다.

프로젝트 사용기술


⚒️ 클라이언트

  • Unity
  • C#

⚒️ 버전 관리 및 협업

  • Git
  • Notion

⚒️ 개발 환경

  • Visual Studio

About

2D 메트로베니아 + 캐주얼 미니 게임 - 슬라임의 모험

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages