Unity 엔진 공부/project1

project1 개발일지 - 3 [몬스터 스탯 설계]

EJH 2025. 7. 14. 19:27
반응형

스탯 시스템 설계 및 몬스터 데이터 연동

목표

플레이어, NPC, 몬스터 등 다양한 오브젝트가 공유할 수 있는 스탯 시스템을 설계하고, 몬스터 데이터를 JSON 기반으로 관리 및 코드에 연동하는 것이 이번 작업의 핵심이다.

 

1. 스탯 상속 구조 설계

  • 플레이어, 몬스터, NPC 등 다양한 오브젝트가 공통적으로 가지는 전투/생존 관련 스탯을 공유하되, 객체마다 다른 스탯은 개별로 확장할 수 있게 하기 위함.
  •  

 BaseStat

(모든 체력 관련 오브젝트가 공통으로 가지는 스탯)

- id
- hp
- maxHp
- attackDamage
- armor
- speed
- attackSpeed
- attackRange

Player

- maxJumpCount
- jumpPower
- exp
- gold
- reviveCount
- hpRegen
- skillCooldowns

NPC

- detectRange

Monster

- detectRange
- rewardExp
- rewardGold

상속 관계도

BaseStat
├── StaticObject (e.g. wall)
└── DynamicObject
     ├── Player
     ├── NPC
     └── Monster

 

위와 같은 상속 관계도를 이용해 필요한 스탯을 추가하는 식으로 사용한다.


2. 몬스터 기획 및 데이터화

  • 몬스터 특성과 전투력을 미리 설계해두고, 이를 기반으로 전투 밸런스를 조율하며 구현할 수 있게 하려는 목적
  • 감지거리, 어그로 해제, 투사체 타입, 공격방식 등 구체적 스탯이 설계되어 AI 로직 구현 방향이 명확해짐
  • 기획자/디자이너와 공통 언어로 소통 가능

 

 


3. JSON 기반 외부 데이터 관리

  • 몬스터 수치 데이터를 코드에서 분리하여 유연하게 수정할 수 있도록 하기 위해 json 사용
{
  "stats": [
    {
      "monsterName": "mogi",
      "monsterId": 1,
      "detectRange": 60,
      "attackRange": 40,
      "aggroReleaseDistance": 90,
      "speed": 6,
      "maxHp": 24,
      "armor": 0,
      "attackDamage": 4,
      "attackSpeed": 0.4,
      "rewardExp": 50,
      "rewardGold": 10
    },
    {
      "monsterName": "gaori",
      "monsterId": 2,
      "detectRange": 40,
      "attackRange": 20,
      "aggroReleaseDistance": 60,
      "speed": 5,
      "maxHp": 40,
      "armor": 1,
      "attackDamage": 7,
      "attackSpeed": 0.3,
      "rewardExp": 50,
      "rewardGold": 10
    },
    {
      "monsterName": "dragon",
      "monsterId": 101,
      "detectRange": 20,
      "attackRange": 10,
      "aggroReleaseDistance": 30,
      "speed": 10,
      "maxHp": 100,
      "armor": 1,
      "attackDamage": 7,
      "attackSpeed": 0.3,
      "rewardExp": 50,
      "rewardGold": 10
    }
  ]
}

4. 스탯 시스템 코드 연동 (예: NPCStat.cs)

  • json 데이터를 가져와 동기화 한다.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class NPCStat : Stat
{

	[SerializeField] public int _monsterId;
	public int _rewardExp;
	public int _rewardGold;
	public float _detectRange;


	private void Start()
	{
		SetStat(_monsterId);
	}

	public void SetStat(int id)
	{
		Dictionary<int, Data.MonsterStat> dict = Managers.Data.MonsterStatDict;
		Data.MonsterStat stat = dict[id];

		_monsterId = stat.monsterId;
		_hp = stat.maxHp;
		_maxHp = stat.maxHp;
		_attackDamage = stat.attackDamage;
		_armor = stat.armor;
		_speed = stat.speed;
		_attackRange  = stat.attackRange;
		_attackSpeed = stat.attackSpeed;
		_detectRange = stat.detectRange;
		_rewardExp = stat.rewardExp;
		_rewardGold = stat.rewardGold;

	}

	public int MonsterId { get { return _monsterId; } set { _monsterId = value; } }
	public int RewardExp { get { return _rewardExp; } set { _rewardExp = value; } }
	public int RewardGold { get { return _rewardGold; } set { _rewardGold = value; } }
	public float DetectRange { get { return _detectRange; } set { _detectRange = value; } }



	//Todo 테스트용 나중에 삭제
	private void Update()
	{
		if(Input.GetKeyDown(KeyCode.P)) {
			_hp -= 5;
			if (_hp <= 0)
			{
				OnDead();
			}
		}

		
	}

	protected override void OnDead(Stat attacker = null)
	{
		base.OnDead(attacker);
		GetComponent<BaseNPC>().Die();
	}

		
}

json 파일과 스탯 동기화 확인완료

마무리

  • 다양한 객체가 공통 스탯을 상속 구조로 유연하게 사용할 수 있게 되었음
  • 몬스터 정보는 JSON으로 관리되어 게임 밸런스 수정이 쉬움
  • 코드에서는 ID 기반으로 스탯 자동 초기화
  • 향후 아이템/버프/디버프 연동 시에도 이 구조가 재사용 가능함
반응형