몬스터 스포너 테스트코드 구현
1. 몬스터 상태 Hit, Death 추가 2. 몬스터 스킬 정리
This commit is contained in:
@@ -5,7 +5,7 @@
|
||||
"damage": 50,
|
||||
"cooldown": 5,
|
||||
"range": 5,
|
||||
"prefabName": "IceBlastPrefab"
|
||||
"prefabName": "IceBlast"
|
||||
},
|
||||
{
|
||||
"skillId": 1,
|
||||
@@ -13,6 +13,6 @@
|
||||
"damage": 50,
|
||||
"cooldown": 5,
|
||||
"range": 5,
|
||||
"prefabName": "smallFirePrefab"
|
||||
"prefabName": "smallFire"
|
||||
}
|
||||
]
|
||||
@@ -32,7 +32,7 @@ Transform:
|
||||
serializedVersion: 2
|
||||
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
||||
m_LocalPosition: {x: 9.6, y: -6.82, z: 0}
|
||||
m_LocalScale: {x: 2, y: 2, z: 2}
|
||||
m_LocalScale: {x: 3, y: 3, z: 2}
|
||||
m_ConstrainProportionsScale: 0
|
||||
m_Children: []
|
||||
m_Father: {fileID: 0}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -2313,6 +2313,37 @@ PrefabInstance:
|
||||
m_AddedGameObjects: []
|
||||
m_AddedComponents: []
|
||||
m_SourcePrefab: {fileID: 100100000, guid: ab2e507b20e5dc844a1ea24b5619f656, type: 3}
|
||||
--- !u!1 &340342490
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
serializedVersion: 6
|
||||
m_Component:
|
||||
- component: {fileID: 340342491}
|
||||
m_Layer: 0
|
||||
m_Name: Monster1
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!4 &340342491
|
||||
Transform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 340342490}
|
||||
serializedVersion: 2
|
||||
m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
|
||||
m_LocalPosition: {x: 6.4799995, y: 2.25, z: -0.10636908}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_ConstrainProportionsScale: 0
|
||||
m_Children: []
|
||||
m_Father: {fileID: 1253934486}
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
--- !u!1 &391267027
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
@@ -58772,6 +58803,59 @@ MonoBehaviour:
|
||||
m_CameraActivatedEvent:
|
||||
m_PersistentCalls:
|
||||
m_Calls: []
|
||||
--- !u!1 &1253934484
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
serializedVersion: 6
|
||||
m_Component:
|
||||
- component: {fileID: 1253934486}
|
||||
- component: {fileID: 1253934485}
|
||||
m_Layer: 0
|
||||
m_Name: Spanwer
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!114 &1253934485
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 1253934484}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: 481676f31fc794c4b93848b442416f2c, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
_monsterLocations:
|
||||
- {fileID: 340342491}
|
||||
- {fileID: 1721288851}
|
||||
- {fileID: 1695686502}
|
||||
_monsterId: 01000000010000000100000004000000
|
||||
_spawnDistance: 10
|
||||
--- !u!4 &1253934486
|
||||
Transform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 1253934484}
|
||||
serializedVersion: 2
|
||||
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
||||
m_LocalPosition: {x: 15.07, y: -6.5, z: 1.0991049}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_ConstrainProportionsScale: 0
|
||||
m_Children:
|
||||
- {fileID: 340342491}
|
||||
- {fileID: 1721288851}
|
||||
- {fileID: 1695686502}
|
||||
m_Father: {fileID: 0}
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
--- !u!1 &1342711675
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
@@ -84036,7 +84120,7 @@ PrefabInstance:
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 3656570700648378249, guid: f92c93d0d7d455d40b84e993e40acfca, type: 3}
|
||||
propertyPath: m_IsActive
|
||||
value: 0
|
||||
value: 1
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 8528093570479225059, guid: f92c93d0d7d455d40b84e993e40acfca, type: 3}
|
||||
propertyPath: m_LocalPosition.x
|
||||
@@ -94630,6 +94714,68 @@ Rigidbody2D:
|
||||
m_SleepingMode: 1
|
||||
m_CollisionDetection: 0
|
||||
m_Constraints: 0
|
||||
--- !u!1 &1695686501
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
serializedVersion: 6
|
||||
m_Component:
|
||||
- component: {fileID: 1695686502}
|
||||
m_Layer: 0
|
||||
m_Name: Monster3
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!4 &1695686502
|
||||
Transform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 1695686501}
|
||||
serializedVersion: 2
|
||||
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
||||
m_LocalPosition: {x: 6.25, y: 2.26, z: 0}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_ConstrainProportionsScale: 0
|
||||
m_Children: []
|
||||
m_Father: {fileID: 1253934486}
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
--- !u!1 &1721288850
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
serializedVersion: 6
|
||||
m_Component:
|
||||
- component: {fileID: 1721288851}
|
||||
m_Layer: 0
|
||||
m_Name: Monster2
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!4 &1721288851
|
||||
Transform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 1721288850}
|
||||
serializedVersion: 2
|
||||
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
||||
m_LocalPosition: {x: 8.26, y: 3.17, z: 0}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_ConstrainProportionsScale: 0
|
||||
m_Children: []
|
||||
m_Father: {fileID: 1253934486}
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
--- !u!1 &1906030825
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
@@ -112802,3 +112948,4 @@ SceneRoots:
|
||||
- {fileID: 535565209}
|
||||
- {fileID: 1423029865}
|
||||
- {fileID: 1441848035}
|
||||
- {fileID: 1253934486}
|
||||
|
||||
@@ -1,82 +0,0 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace TON
|
||||
{
|
||||
public class AttackPattern
|
||||
{
|
||||
protected MonsterBase _monsterBase;
|
||||
|
||||
public AttackPattern(MonsterBase monsterBase)
|
||||
{
|
||||
_monsterBase = monsterBase;
|
||||
}
|
||||
|
||||
public virtual void Attack()
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
public class Monster1AttackPattern : AttackPattern
|
||||
{
|
||||
public Monster1AttackPattern(MonsterBase monsterBase) : base(monsterBase)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Attack()
|
||||
{
|
||||
|
||||
Skill1();
|
||||
|
||||
MeleeAttack();
|
||||
|
||||
}
|
||||
|
||||
private void Skill1()
|
||||
{
|
||||
_monsterBase.MonsterSkillLaunch();
|
||||
}
|
||||
|
||||
private void MeleeAttack()
|
||||
{
|
||||
_monsterBase.PlayerAttack();
|
||||
}
|
||||
}
|
||||
|
||||
public class Monster2AttackPattern : AttackPattern
|
||||
{
|
||||
|
||||
|
||||
public Monster2AttackPattern(MonsterBase monsterBase) : base(monsterBase)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public override void Attack()
|
||||
{
|
||||
|
||||
Skill1();
|
||||
|
||||
Skill2();
|
||||
|
||||
MeleeAttack();
|
||||
|
||||
}
|
||||
|
||||
private void Skill1()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
private void Skill2()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
private void MeleeAttack()
|
||||
{
|
||||
_monsterBase.PlayerAttack();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace TON
|
||||
{
|
||||
public partial class MonsterBase
|
||||
{
|
||||
private void OnGUI()
|
||||
{
|
||||
if (GUILayout.Button("Hit"))
|
||||
{
|
||||
ApplyDamage(1);
|
||||
}
|
||||
|
||||
if (GUILayout.Button("Dead"))
|
||||
{
|
||||
ApplyDamage(1000000000);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: be351d22396005d4bbcd8a3e72592f75
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,22 +1,13 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Numerics;
|
||||
using Assets.PixelFantasy.PixelMonsters.Common.Scripts;
|
||||
using Unity.VisualScripting;
|
||||
using TMPro;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
using DamageCalculator = TON.DamageCalculator;
|
||||
using Vector2 = UnityEngine.Vector2;
|
||||
using Vector3 = UnityEngine.Vector3;
|
||||
|
||||
namespace TON
|
||||
{
|
||||
public class MonsterBase : MonoBehaviour, IDamage
|
||||
public partial class MonsterBase : MonoBehaviour, IDamage
|
||||
{
|
||||
|
||||
[SerializeField]
|
||||
public int id; // 몬스터의 ID
|
||||
public float defencePower;
|
||||
@@ -30,14 +21,15 @@ namespace TON
|
||||
|
||||
StateMachine _stateMachine;
|
||||
|
||||
private AttackPattern _attackPattern;
|
||||
private SkillPattern _skillPattern;
|
||||
|
||||
// [SerializeField] private TextMeshProUGUI _textState;
|
||||
|
||||
private Vector3 _direction; // 몬스터의 이동 방향
|
||||
public bool IsDetect { get; set; } // 몬스터가 대상을 인식했는지 여부
|
||||
public bool IsAttacking { get; set; } // 몬스터가 공격했는지 여부
|
||||
public bool IsFisnishAttack { get; set; } // 몬스터 공격 모션이 끝났는지 여부
|
||||
public bool IsHit { get; set; } // 몬스터 공격 모션이 끝났는지 여부
|
||||
public bool IsDead { get; set; } // 몬스터 공격 모션이 끝났는지 여부
|
||||
public bool IsSkillAttackable => _skillPattern.IsAttackable;
|
||||
|
||||
[SerializeField] private GameObject _target; // 몬스터의 타겟
|
||||
|
||||
@@ -47,37 +39,23 @@ namespace TON
|
||||
private string currentAnimationState; // 현재 애니메이션 상태
|
||||
|
||||
// hp바
|
||||
[SerializeField] private Image _hpBarImage; // HP 바 이미지
|
||||
public GameObject _hpBarImage; // HP 바 이미지
|
||||
private float _maxHP;
|
||||
private float currentHP;
|
||||
|
||||
// 몬스터 스킬 프리팹
|
||||
public GameObject smallFirePrefab;
|
||||
public GameObject DragonBreathPrefab;
|
||||
public GameObject IceBlastPrefab;
|
||||
public GameObject PumpkinCrashPrefab;
|
||||
public GameObject TrollChargePrefab;
|
||||
public GameObject TrollCrashPrefab;
|
||||
public GameObject TrollThundePrefab;
|
||||
public GameObject WolfEnergyWavePrefab;
|
||||
public GameObject WolfPunchPrefab;
|
||||
public GameObject DragonShockWavePrefab;
|
||||
public GameObject FireImpactPrefab;
|
||||
private float hpMaxWidth;
|
||||
|
||||
// 첫 번째 프레임 전에 호출됩니다.
|
||||
private void Start()
|
||||
{ // 전략 패턴
|
||||
// TODO : 수정중
|
||||
// _attackPattern = new Monster1AttackPattern();
|
||||
// _attackPattern = new Monster2AttackPattern();
|
||||
|
||||
{
|
||||
_animator = GetComponent<Animator>(); // 애니메이터 컴포넌트 초기화
|
||||
|
||||
// _stateMachine = new StateMachine(new IdleState(), this, _textState);
|
||||
_stateMachine = new StateMachine(new IdleState(), this);
|
||||
|
||||
// 몬스터 데이터 로드 및 적용
|
||||
InitializeMonsterData();
|
||||
InitializeMonsterSkillData();
|
||||
|
||||
_skillPattern = new Monster1SkillPattern(_monsterData, this);
|
||||
|
||||
id = _monsterData.id;
|
||||
|
||||
@@ -86,6 +64,8 @@ namespace TON
|
||||
_spriteRenderer.flipX = !(_direction.x > 0); // 이동 방향에 따라 스프라이트 플립
|
||||
|
||||
_collider = GetComponent<Collider2D>(); // 콜라이더 컴포넌트 초기화
|
||||
|
||||
// hpMaxWidth = _hpBarImage.GetComponent<RectTransform>().sizeDelta.x;
|
||||
}
|
||||
|
||||
// TODO : 불러온 값 변수에 대응하게 수정
|
||||
@@ -95,9 +75,7 @@ namespace TON
|
||||
|
||||
if (_monsterData != null)
|
||||
{
|
||||
_maxHP = _monsterData.hp;
|
||||
currentHP = _maxHP;
|
||||
|
||||
currentHP = _monsterData.hp;
|
||||
defencePower = _monsterData.defencePower;
|
||||
|
||||
Debug.Log($"몬스터 {_monsterData.name} 데이터 로드 완료");
|
||||
@@ -108,29 +86,6 @@ namespace TON
|
||||
}
|
||||
}
|
||||
|
||||
// TODO : 불러온 값 변수에 대응하게 수정
|
||||
private void InitializeMonsterSkillData()
|
||||
{
|
||||
_monsterSkillData = MonsterSkillDataManager.Singleton.GetMonsterSkillData(_monsterData.monsterSkillID);
|
||||
if (_monsterData.monsterSkillIDTwo > -1)
|
||||
{
|
||||
_monsterSkillDataTwo = MonsterSkillDataManager.Singleton.GetMonsterSkillData(_monsterData.monsterSkillIDTwo);
|
||||
}
|
||||
|
||||
if (_monsterSkillData != null && _monsterSkillDataTwo != null)
|
||||
{
|
||||
|
||||
Debug.Log($"몬스터 {_monsterSkillData.skillName} 데이터 로드 완료");
|
||||
Debug.Log($"몬스터 {_monsterSkillDataTwo.skillName} 데이터 로드 완료");
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogError($"몬스터 스킬 ID {_monsterSkillData.skillId}에 대한 데이터를 찾을 수 없습니다.");
|
||||
Debug.LogError($"몬스터 스킬 ID {_monsterSkillDataTwo.skillId}에 대한 데이터를 찾을 수 없습니다.");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 애니메이션 상태를 변경하는 메서드
|
||||
public void ChangeAnimationState(string newState)
|
||||
{
|
||||
@@ -143,7 +98,7 @@ namespace TON
|
||||
private void Update()
|
||||
{
|
||||
_stateMachine.Update();
|
||||
|
||||
_skillPattern.Update();
|
||||
}
|
||||
|
||||
public void FinishAttack()
|
||||
@@ -163,13 +118,11 @@ namespace TON
|
||||
|
||||
if (prevHP > 0 && currentHP <= 0)
|
||||
{
|
||||
// 몬스터가 죽었을 때 처리 (죽는 애니메이션은 주석 처리됨)
|
||||
// Destroy(gameObject); // 몬스터 파괴
|
||||
DestroyMonster();
|
||||
_stateMachine.SetTransition(new DeathState());
|
||||
}
|
||||
else if (prevHP > 0 && currentHP > 0)
|
||||
{
|
||||
// 피격 애니메이션은 주석 처리됨 (필요시 활성화)
|
||||
_stateMachine.SetTransition(new HitState());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -178,9 +131,10 @@ namespace TON
|
||||
{
|
||||
if (_hpBarImage != null)
|
||||
{
|
||||
// 현재 체력 비율 계산 (0.0 ~ 1.0)
|
||||
float hpRatio = currentHP / _maxHP;
|
||||
_hpBarImage.fillAmount = hpRatio; // 이미지 크기를 체력 비율에 맞게 조절
|
||||
float minHPBarWidth = 5f; // 최소 HP 바 길이 (원하는 값으로 설정)
|
||||
float hpBarWidth = Mathf.Max(currentHP / _maxHP * hpMaxWidth, minHPBarWidth); // 최소 길이 적용
|
||||
|
||||
_hpBarImage.GetComponent<RectTransform>().sizeDelta = new Vector2(hpBarWidth, _hpBarImage.GetComponent<RectTransform>().sizeDelta.y);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -231,25 +185,12 @@ namespace TON
|
||||
|
||||
public void MonsterSkillLaunch()
|
||||
{
|
||||
|
||||
// _spriteRenderer.flipX = target.transform.position.x < transform.position.x;
|
||||
// newSkill.transform.position = transform.position + new Vector3(0, 1f, 0);
|
||||
// newSkill.GetComponent<MonsterSkill>().Direction = new Vector2(0, 1);
|
||||
var target = GameObject.FindGameObjectWithTag("Player");
|
||||
_spriteRenderer.flipX = target.transform.position.x < transform.position.x;
|
||||
|
||||
// TODO : 몬스터가 가지고 있는 스킬에 따라 분기되는 조건 추가
|
||||
// GameObject newSkill = Instantiate(smallFirePrefab);
|
||||
// GameObject newSkill = Instantiate(DragonBreathPrefab);
|
||||
GameObject newSkill = Instantiate(IceBlastPrefab);
|
||||
// GameObject newSkill = Instantiate(PumpkinCrashPrefab);
|
||||
// GameObject newSkill = Instantiate(TrollChargePrefab);
|
||||
// GameObject newSkill = Instantiate(TrollCrashPrefab);
|
||||
// GameObject newSkill = Instantiate(TrollThundePrefab);
|
||||
// GameObject newSkill = Instantiate(WolfEnergyWavePrefab);
|
||||
// GameObject newSkill = Instantiate(WolfPunchPrefab);
|
||||
// GameObject newSkill = Instantiate(DragonShockWavePrefab);
|
||||
// GameObject newSkill = Instantiate(FireImpactPrefab);
|
||||
|
||||
|
||||
newSkill.transform.position = transform.position + new Vector3(0, 1f, 0);
|
||||
newSkill.GetComponent<MonsterSkill>().Direction = new Vector2(0, 1);
|
||||
_skillPattern.Attack(target);
|
||||
}
|
||||
|
||||
public void DestroyMonster()
|
||||
|
||||
153
Gameton-06/Assets/Gameton/Scripts/Monster/MonsterSpawner.cs
Normal file
153
Gameton-06/Assets/Gameton/Scripts/Monster/MonsterSpawner.cs
Normal file
@@ -0,0 +1,153 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace TON
|
||||
{
|
||||
public class MonsterSpawner : MonoBehaviour
|
||||
{
|
||||
[SerializeField]
|
||||
private List<Transform> _monsterLocations = new List<Transform>();
|
||||
[SerializeField]
|
||||
private List<int> _monsterId = new List<int>();
|
||||
[SerializeField]
|
||||
private float _spawnDistance = 10f;
|
||||
|
||||
private CharacterBase _player;
|
||||
private List<MonsterBase> _spawnedMonsters = new List<MonsterBase>();
|
||||
private Dictionary<Transform, bool> _spawnPoints = new Dictionary<Transform, bool>();
|
||||
|
||||
private void Start()
|
||||
{
|
||||
InitializeSpawner();
|
||||
}
|
||||
|
||||
private void InitializeSpawner()
|
||||
{
|
||||
// 플레이어 찾기
|
||||
GameObject playerObj = GameObject.FindGameObjectWithTag("Player");
|
||||
if (playerObj != null)
|
||||
{
|
||||
_player = playerObj.GetComponent<CharacterBase>();
|
||||
Debug.Log("플레이어 찾음: " + playerObj.name);
|
||||
}
|
||||
|
||||
// 스폰 포인트 초기화
|
||||
foreach (var location in _monsterLocations)
|
||||
{
|
||||
if (location != null)
|
||||
{
|
||||
_spawnPoints[location] = false;
|
||||
Debug.Log($"스폰 포인트 초기화: {location.name}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void Update()
|
||||
{
|
||||
if (_player == null) return;
|
||||
|
||||
CheckSpawnConditions();
|
||||
}
|
||||
|
||||
private void CheckSpawnConditions()
|
||||
{
|
||||
for (int i = 0; i < _monsterLocations.Count; i++)
|
||||
{
|
||||
Transform spawnPoint = _monsterLocations[i];
|
||||
if (spawnPoint == null || _spawnPoints[spawnPoint]) continue;
|
||||
|
||||
float distance = Vector2.Distance(_player.transform.position, spawnPoint.position);
|
||||
if (distance <= _spawnDistance)
|
||||
{
|
||||
SpawnMonster(i);
|
||||
_spawnPoints[spawnPoint] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void SpawnMonster(int index)
|
||||
{
|
||||
if (index >= _monsterId.Count)
|
||||
{
|
||||
Debug.LogError($"유효하지 않은 인덱스: {index}");
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
int monsterId = _monsterId[index];
|
||||
|
||||
// MonsterDataManager에서 데이터 가져오기
|
||||
MonsterData monsterData = MonsterDataManager.Singleton.GetMonsterData(monsterId);
|
||||
if (monsterData == null)
|
||||
{
|
||||
Debug.LogError($"몬스터 ID {monsterId}에 대한 데이터를 찾을 수 없습니다.");
|
||||
return;
|
||||
}
|
||||
|
||||
// 몬스터 프리팹 경로 결정
|
||||
string prefabPath = GetMonsterPrefabPath(monsterData);
|
||||
|
||||
// 프리팹 로드
|
||||
MonsterBase monsterPrefab = Resources.Load<MonsterBase>(prefabPath);
|
||||
if (monsterPrefab == null)
|
||||
{
|
||||
Debug.LogError($"몬스터 프리팹을 찾을 수 없습니다: {prefabPath}");
|
||||
return;
|
||||
}
|
||||
|
||||
// 몬스터 생성
|
||||
Vector3 spawnPosition = _monsterLocations[index].position;
|
||||
MonsterBase newMonster = Instantiate(monsterPrefab, spawnPosition, Quaternion.identity);
|
||||
|
||||
// 몬스터 초기화
|
||||
newMonster.id = monsterId;
|
||||
_spawnedMonsters.Add(newMonster);
|
||||
|
||||
Debug.Log($"몬스터 생성 완료: ID {monsterId}, 위치 {spawnPosition}");
|
||||
}
|
||||
catch (System.Exception e)
|
||||
{
|
||||
Debug.LogError($"몬스터 생성 중 오류 발생: {e.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
private string GetMonsterPrefabPath(MonsterData monsterData)
|
||||
{
|
||||
// 몬스터 데이터에 따른 프리팹 경로 결정
|
||||
string basePath = "MonsterPrefabs/";
|
||||
|
||||
// 일반 몬스터인 경우
|
||||
if (monsterData.id == 6)
|
||||
{
|
||||
return basePath + "Nomal/BlackTroll";
|
||||
}
|
||||
|
||||
// 기타 몬스터들
|
||||
Dictionary<int, string> monsterNames = new Dictionary<int, string>
|
||||
{
|
||||
{ 1, "BlueDragon" },
|
||||
{ 2, "BrownWerewolf" },
|
||||
{ 3, "GreenDragon" },
|
||||
{ 4, "PurpleOgre" },
|
||||
{ 5, "RedWerewolf" }
|
||||
};
|
||||
|
||||
if (monsterNames.TryGetValue(monsterData.id, out string monsterName))
|
||||
{
|
||||
return basePath + monsterName;
|
||||
}
|
||||
|
||||
throw new System.Exception($"알 수 없는 몬스터 ID: {monsterData.id}");
|
||||
}
|
||||
|
||||
public void OnMonsterDestroyed(MonsterBase monster)
|
||||
{
|
||||
if (_spawnedMonsters.Contains(monster))
|
||||
{
|
||||
_spawnedMonsters.Remove(monster);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 481676f31fc794c4b93848b442416f2c
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
133
Gameton-06/Assets/Gameton/Scripts/Monster/SkillPattern.cs
Normal file
133
Gameton-06/Assets/Gameton/Scripts/Monster/SkillPattern.cs
Normal file
@@ -0,0 +1,133 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using Assets.PixelFantasy.PixelMonsters.Common.Scripts;
|
||||
using UnityEngine;
|
||||
|
||||
namespace TON
|
||||
{
|
||||
public abstract class SkillPattern
|
||||
{
|
||||
protected MonsterData _monsterData;
|
||||
protected MonsterBase _monsterBase;
|
||||
|
||||
protected SkillPattern(MonsterData monsterData, MonsterBase monsterBase)
|
||||
{
|
||||
_monsterData = monsterData;
|
||||
_monsterBase = monsterBase;
|
||||
}
|
||||
|
||||
public bool IsAttackable { get; set; }
|
||||
|
||||
public abstract void Attack(GameObject target);
|
||||
|
||||
|
||||
public abstract void Update();
|
||||
}
|
||||
|
||||
public class Monster1SkillPattern : SkillPattern
|
||||
{
|
||||
private float _skill1CoolTime;
|
||||
private float _skill2CoolTime;
|
||||
|
||||
private MonsterSkillData _monsterSkillData;
|
||||
private MonsterSkillData _monsterSkillDataTwo;
|
||||
|
||||
private MonsterSkill _skill1;
|
||||
private MonsterSkill _skill2;
|
||||
|
||||
private Vector3 _skillOffset = new Vector3(0, -0.5f, 0); // 스킬 생성 위치 조정값
|
||||
|
||||
public Monster1SkillPattern(MonsterData monsterData, MonsterBase monsterBase) : base(monsterData, monsterBase)
|
||||
{
|
||||
_monsterSkillData = MonsterSkillDataManager.Singleton.GetMonsterSkillData(_monsterData.monsterSkillID);
|
||||
if (_monsterData.monsterSkillIDTwo > -1)
|
||||
{
|
||||
_monsterSkillDataTwo = MonsterSkillDataManager.Singleton.GetMonsterSkillData(_monsterData.monsterSkillIDTwo);
|
||||
}
|
||||
|
||||
if (_monsterSkillData != null && _monsterSkillDataTwo != null)
|
||||
{
|
||||
|
||||
Debug.Log($"몬스터 {_monsterSkillData.skillName} 데이터 로드 완료");
|
||||
Debug.Log($"몬스터 {_monsterSkillDataTwo.skillName} 데이터 로드 완료");
|
||||
|
||||
// 프리팹을 연결한 코드
|
||||
_skill1 = Resources.Load<MonsterSkill>($"MonsterSkillPrefabs/{_monsterSkillData.skillName}");
|
||||
_skill2 = Resources.Load<MonsterSkill>($"MonsterSkillPrefabs/{_monsterSkillDataTwo.skillName}");
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogError($"몬스터 스킬 ID {_monsterSkillData.skillId}에 대한 데이터를 찾을 수 없습니다.");
|
||||
Debug.LogError($"몬스터 스킬 ID {_monsterSkillDataTwo.skillId}에 대한 데이터를 찾을 수 없습니다.");
|
||||
}
|
||||
|
||||
_skill1CoolTime = Time.realtimeSinceStartup;
|
||||
_skill2CoolTime = Time.realtimeSinceStartup;
|
||||
|
||||
}
|
||||
|
||||
public override void Attack(GameObject target)
|
||||
{
|
||||
if (target == null) return;
|
||||
|
||||
// 스킬 스프라이트 방향 플레이어 바라보게
|
||||
_monsterBase.GetComponent<SpriteRenderer>().flipX = target.transform.position.x < _monsterBase.transform.position.x;
|
||||
// 몬스터의 현재 위치에서 offset만큼 아래에 스킬 생성
|
||||
Vector3 spawnPosition = _monsterBase.transform.position - _skillOffset;
|
||||
|
||||
// 프리팹을 지정된 위치에 생성
|
||||
Object.Instantiate(_skill1, spawnPosition, Quaternion.identity);
|
||||
}
|
||||
|
||||
public override void Update()
|
||||
{
|
||||
if (Time.realtimeSinceStartup - _skill1CoolTime >= _monsterSkillData.cooldown)
|
||||
{
|
||||
// TODO : 범위 체크
|
||||
IsAttackable = true;
|
||||
}
|
||||
|
||||
if (Time.realtimeSinceStartup - _skill2CoolTime >= _monsterSkillDataTwo.cooldown)
|
||||
{
|
||||
// TODO : 범위 체크
|
||||
IsAttackable = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// public class Monster2AttackPattern : AttackPattern
|
||||
// {
|
||||
//
|
||||
//
|
||||
// public Monster2AttackPattern(MonsterBase monsterBase) : base(monsterBase)
|
||||
// {
|
||||
//
|
||||
// }
|
||||
//
|
||||
// public override void Attack()
|
||||
// {
|
||||
//
|
||||
// Skill1();
|
||||
//
|
||||
// Skill2();
|
||||
//
|
||||
// MeleeAttack();
|
||||
//
|
||||
// }
|
||||
//
|
||||
// private void Skill1()
|
||||
// {
|
||||
//
|
||||
// }
|
||||
//
|
||||
// private void Skill2()
|
||||
// {
|
||||
//
|
||||
// }
|
||||
//
|
||||
// private void MeleeAttack()
|
||||
// {
|
||||
// _monsterBase.PlayerAttack();
|
||||
// }
|
||||
// }
|
||||
}
|
||||
@@ -1,3 +1,4 @@
|
||||
using TMPro;
|
||||
using UnityEngine;
|
||||
|
||||
namespace TON
|
||||
@@ -8,6 +9,9 @@ namespace TON
|
||||
private IState _state;
|
||||
private MonsterBase _monsterBase;
|
||||
|
||||
private TextMeshProUGUI _textState;
|
||||
|
||||
// public StateMachine(IState state, MonsterBase monsterBase, TextMeshProUGUI textState)
|
||||
public StateMachine(IState state, MonsterBase monsterBase)
|
||||
{
|
||||
// 초기 상태 객체 생성
|
||||
@@ -15,6 +19,9 @@ namespace TON
|
||||
|
||||
_state = state;
|
||||
_state.Enter(_monsterBase);
|
||||
|
||||
// _textState = textState;
|
||||
// _textState.text = _state.ToString();
|
||||
}
|
||||
|
||||
public void Update()
|
||||
@@ -30,13 +37,13 @@ namespace TON
|
||||
}
|
||||
}
|
||||
|
||||
private void SetTransition(IState state)
|
||||
public void SetTransition(IState state)
|
||||
{
|
||||
// 다음음 상태로 전환
|
||||
_state = state;
|
||||
_state.Enter(_monsterBase);
|
||||
|
||||
Debug.Log($"State : {_state}");
|
||||
// _textState.text = _state.ToString();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -168,6 +175,11 @@ namespace TON
|
||||
if(_monsterBase.IsDetect== false)
|
||||
return new IdleState();
|
||||
|
||||
if (_monsterBase.IsSkillAttackable)
|
||||
{
|
||||
return new MonsterSkillState();
|
||||
}
|
||||
|
||||
// Attack으로 변경
|
||||
if (_monsterBase.IsAttacking)
|
||||
return new AttackState();
|
||||
@@ -178,8 +190,6 @@ namespace TON
|
||||
}
|
||||
}
|
||||
|
||||
// 몬스터 1의 어택(스킬 1개를 가진 중보스)
|
||||
// 몬스터 2의 어택(스킬 2개를 가진 보스)
|
||||
public class AttackState : IState
|
||||
{
|
||||
private const string AniAttack = "Attack"; // 공격 애니메이션
|
||||
@@ -188,7 +198,6 @@ namespace TON
|
||||
private float _lastAttackTime; // 마지막 공격 시간
|
||||
private float _attackAnimationDuration = 0.5f; // 공격 애니메이션 지속 시간
|
||||
private bool _isAttacking = false;
|
||||
private bool _completAttck;
|
||||
|
||||
public void Enter(MonsterBase monsterBase)
|
||||
{
|
||||
@@ -215,7 +224,6 @@ namespace TON
|
||||
if (_isAttacking && Time.time >= _lastAttackTime + _attackAnimationDuration)
|
||||
{
|
||||
_isAttacking = false;
|
||||
_completAttck = true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -238,11 +246,9 @@ namespace TON
|
||||
return this;
|
||||
}
|
||||
}
|
||||
// TODO : HIT, Death 상태 추가
|
||||
public class MonsterSkillState : IState
|
||||
{
|
||||
private const string AniAttack = "Attack"; // 공격 애니메이션
|
||||
private const string AniIdle = "Idle"; // 대기 애니메이션
|
||||
private MonsterBase _monsterBase;
|
||||
private float _skillAttackAnimationDuration = 0.5f; // 공격 애니메이션 지속 시간
|
||||
private float _skillAttackDelayTime = 2f; // 공격 딜레이 시간
|
||||
@@ -269,7 +275,6 @@ namespace TON
|
||||
if (_isSkillAttacking && Time.time >= _lastSkillAttackTime + _skillAttackAnimationDuration)
|
||||
{
|
||||
_isSkillAttacking = false;
|
||||
_monsterBase.ChangeAnimationState(AniIdle);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -288,6 +293,10 @@ namespace TON
|
||||
|
||||
public IState CheckTransition()
|
||||
{
|
||||
|
||||
if(_isSkillAttacking == false)
|
||||
return new IdleState();
|
||||
|
||||
return this;
|
||||
}
|
||||
}
|
||||
@@ -308,10 +317,7 @@ namespace TON
|
||||
|
||||
public void Update()
|
||||
{
|
||||
if (Time.time >= _hitStartTime + _hitDuration)
|
||||
{
|
||||
_monsterBase.IsHit = false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void Exit()
|
||||
@@ -320,12 +326,6 @@ namespace TON
|
||||
|
||||
public IState CheckTransition()
|
||||
{
|
||||
if (_monsterBase.IsHit)
|
||||
return new HitState();
|
||||
|
||||
if (_monsterBase.IsDead)
|
||||
return new DeathState();
|
||||
|
||||
if (Time.time >= _hitStartTime + _hitDuration)
|
||||
return new IdleState();
|
||||
|
||||
|
||||
Binary file not shown.
Reference in New Issue
Block a user