몬스터가 플레이어를 체이싱 한 후 공격범위 안에 들어오면 공격하도록 수정

This commit is contained in:
Mingu Kim
2025-02-28 05:52:37 +09:00
parent 5e893a029f
commit 0bdfc0f544
7 changed files with 152 additions and 637 deletions

View File

@@ -4,28 +4,28 @@ namespace TON
{
public class Attack : MonoBehaviour
{
[SerializeField]
private MonsterBase _monsterBase;
public void SetMonsterBase(MonsterBase monsterBase)
{
_monsterBase = monsterBase;
}
private void OnTriggerEnter2D(Collider2D other)
{
if (other.CompareTag("Player"))
{
_monsterBase.IsAttacking = true;
_monsterBase.IsFinishAttack = false; // 공격 시작 시 FinishAttack 초기화
}
}
private void OnTriggerExit2D(Collider2D other)
{
if (other.CompareTag("Player"))
{
_monsterBase.IsAttacking = false;
_monsterBase.IsFinishAttack = true; // 공격 종료 상태로 설정
_monsterBase.IsFinishAttack = true;
}
}
}

View File

@@ -33,7 +33,7 @@ namespace TON
public bool IsDetect { get; set; } // 몬스터가 대상을 인식했는지 여부
public bool IsAttacking { get; set; } // 몬스터가 공격했는지 여부
public bool IsFinishAttack { get; set; } // 몬스터 공격 모션이 끝났는지 여부
public bool IsSkillAttackable => _skillPattern.IsAttackable;
public bool IsSkillAttackable;
public int Gold = 0;
public int Exp = 0;
@@ -51,7 +51,11 @@ namespace TON
InitializeMonsterData(); // 몬스터 데이터 로드 및 적용
_skillPattern = new Monster1SkillPattern(_monsterData, this);
if (_monsterData.monsterSkillID != 0)
{
_skillPattern = new MonsterSkillPattern(_monsterData, this);
IsSkillAttackable = _skillPattern.IsAttackable;
}
_direction = new Vector3(1, 0, 0); // 초기 이동 방향 (x 축 양의 방향)
@@ -62,7 +66,6 @@ namespace TON
// CharacterBase 참조 설정
_characterBase = GameObject.Find("TON.Player").GetComponentInChildren<CharacterBase>();
// HP 바 초기화
// HP 바 초기화
if (_hpBarImage != null)
{
@@ -70,8 +73,6 @@ namespace TON
hpMaxWidth = rectTransform.sizeDelta.x; // 초기 최대 너비 저장
_maxHP = _monsterData.hp;
currentHP = _maxHP;
Debug.Log($"Initial HP Bar Width: {hpMaxWidth}, Max HP: {_maxHP}");
}
}
@@ -162,12 +163,6 @@ namespace TON
// 변경된 크기 적용
rectTransform.sizeDelta = sizeDelta;
Debug.Log($"Current HP: {currentHP}, Max HP: {_maxHP}, Ratio: {hpRatio}, Bar Width: {sizeDelta.x}");
}
else
{
Debug.LogWarning("HP Bar Image is not assigned!");
}
}
@@ -185,7 +180,7 @@ namespace TON
_characterBase.ApplyDamage(damage);
Debug.Log($" 몬스터 공격! 최종 데미지: {damage}"); // 데미지 출력
// Debug.Log($" 몬스터 공격! 최종 데미지: {damage}"); // 데미지 출력
}
public void SetOppositionDirection()
@@ -201,8 +196,8 @@ namespace TON
public void Chasing()
{
var target = GameObject.FindGameObjectWithTag("Player");
UnityEngine.Vector2 direction = target.transform.position - transform.position; // 타겟과의 방향 계산
var target = GameObject.Find("TON.Player").GetComponentInChildren<CharacterBase>();
Vector2 direction = target.transform.position - transform.position; // 타겟과의 방향 계산
_spriteRenderer.flipX = target.transform.position.x < transform.position.x; // 타겟이 왼쪽에 있으면 스프라이트를 왼쪽으로, 오른쪽에 있으면 오른쪽으로 바라보도록 설정
transform.Translate(direction.normalized * moveSpeed * Time.deltaTime); // 타겟 방향으로 이동
@@ -222,5 +217,10 @@ namespace TON
RewardData();
Destroy(gameObject); // 몬스터 파괴
}
public SkillPattern GetSkillPattern()
{
return _skillPattern;
}
}
}

View File

@@ -5,12 +5,13 @@ namespace TON
public class MonsterSkill : MonoBehaviour
{
public float speed = 5f;
public float damage = 1;
public float damage = 0f;
Vector2 direction;
Transform playerTransform; // 플레이어의 Transform을 저장할 변수
[SerializeField] private SpriteRenderer _spriteRenderer; // 스킬의 스프라이트 렌더러
private MonsterBase _monsterBase;
private CharacterBase _characterBase;
public Vector2 Direction
{
set { direction = value.normalized; }
@@ -20,11 +21,11 @@ namespace TON
{
_spriteRenderer = GetComponent<SpriteRenderer>();
GameObject player = GameObject.FindGameObjectWithTag("Player");
if (player != null)
_characterBase = GameObject.Find("TON.Player").GetComponentInChildren<CharacterBase>();
if (_characterBase != null)
{
playerTransform = player.transform;
playerTransform = _characterBase.transform;
}
else
{
@@ -42,10 +43,22 @@ namespace TON
private void OnTriggerEnter2D(Collider2D collision)
{
if (collision.CompareTag("Player") || collision.CompareTag("Ground"))
if (collision.CompareTag("Player"))
{
// 플레이어에게 직접 데미지 적용
_characterBase?.ApplyDamage(damage);
Destroy(gameObject);
}
else if (collision.CompareTag("Ground"))
{
// 지형에 부딪히면 스킬 오브젝트만 파괴
Destroy(gameObject);
}
}
public void SetSkillDamage(float skillDamage)
{
damage += skillDamage;
}
void SetDirection()

View File

@@ -14,65 +14,81 @@ namespace TON
}
public bool IsAttackable { get; set; }
public abstract bool IsSkillInCooldown();
public abstract void Attack(GameObject target);
public abstract void Update();
}
public class Monster1SkillPattern : SkillPattern
public class MonsterSkillPattern : SkillPattern
{
private float _skillCoolTime;
private float _lastSkillTime;
private MonsterSkillData _monsterSkillData;
private MonsterSkill _skill;
private Vector3 _skillOffset = new Vector3(0, -0.5f, 0);
private Vector3 _skillOffset = new Vector3(0, -0.5f, 0); // 스킬 생성 위치 조정값
public Monster1SkillPattern(MonsterData monsterData, MonsterBase monsterBase) : base(monsterData, monsterBase)
public MonsterSkillPattern(MonsterData monsterData, MonsterBase monsterBase) : base(monsterData, monsterBase)
{
_monsterSkillData = MonsterSkillDataManager.Singleton.GetMonsterSkillData(_monsterData.monsterSkillID);
_lastSkillTime = -_monsterSkillData.cooldown; // 시작시 스킬 사용 가능하도록
IsAttackable = true;
if (_monsterSkillData != null)
{
Debug.Log($"몬스터 {_monsterSkillData.skillName} 데이터 로드 완료");
// 프리팹을 연결한 코드
// Debug.Log($"몬스터 {_monsterSkillData.skillName} 데이터 로드 완료");
_skill = Resources.Load<MonsterSkill>($"MonsterSkillPrefabs/{_monsterSkillData.skillName}");
}
else
{
Debug.LogError($"몬스터 스킬 ID {_monsterSkillData.skillId}에 대한 데이터를 찾을 수 없습니다.");
}
_skillCoolTime = _monsterSkillData.cooldown;
}
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(_skill, spawnPosition, Quaternion.identity);
SkillAttack(_monsterSkillData.damage);
// 스킬 사용 후 쿨다운 시작
_lastSkillTime = Time.time;
IsAttackable = false;
// Debug.Log($"스킬 사용, 쿨다운 시작: {_monsterSkillData.cooldown}초");
}
public void SkillAttack(float skillDamage)
{
// 데미지 계산 (현재 임시 값)
DamageCalculator damageCalculator = new DamageCalculator();
float baseAttack = _monsterData.attackPower * skillDamage; // 기본 공격력 * 스킬 데미지
float equipmentAttack = 0; // 장비 공격력
float defense = PlayerDataManager.Singleton.player.defensivePower / (PlayerDataManager.Singleton.player.defensivePower + PlayerDataManager.Singleton.defensiveIntention); // 캐릭터 방어력
// 기본 데미지 계산 (치명타 없음)
float damage = damageCalculator.CalculateBaseDamage(baseAttack, equipmentAttack, defense);
_skill.SetSkillDamage(damage);
// Debug.Log($" 몬스터 스킬 공격! 최종 데미지: {damage}"); // 데미지 출력
}
public override void Update()
{
if (Time.realtimeSinceStartup - _skillCoolTime >= _monsterSkillData.cooldown)
// 스킬 쿨다운 체크
if (!IsAttackable && Time.time - _lastSkillTime >= _monsterSkillData.cooldown)
{
// TODO : 범위 체크
IsAttackable = true;
// Debug.Log("스킬 쿨다운 완료");
}
}
public override bool IsSkillInCooldown()
{
return !IsAttackable;
}
}
}