fsm을 이용해서 몹을 구현하고 있습니다. 그런데 그걸 적용하고 난뒤로부터 공격을 실행하는 함수의 호출이 딜레이가 됨니다.
아래는 해당 문제되는 코드입니다.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Windows;
public class KnightEnemy : enemy
{
public LayerMask whatIsTarget;
private Player targetEntity;
public Transform FindTargetPos;
public Vector2 FindTargeBoxSize = new Vector2();
public Transform AttackTargetPos;
public Vector2 AttacktTargeBoxSize;
private void OnDrawGizmos()
{
Gizmos.color = Color.blue;
Gizmos.DrawWireCube(FindTargetPos.position, FindTargeBoxSize);
Gizmos.color = Color.red;
Gizmos.DrawWireCube(AttackTargetPos.position, AttacktTargeBoxSize);
}
public float speed = 1f;
//public ParticleSystem hiteffect;
bool isStoped = false;
float m_facingDirection = -1f;
enum Enemystate
{
Idel,
Move,
Attack,
Damaged,
}
Enemystate m_State;
Animator animator;
Rigidbody2D rb;
public int Power = 20;
public float TimeBeAttack = 0.5f;
private float lastAttackTime = 0;
private bool hasTarget
{
get
{
if (!dead)
{
Collider2D[] colliders = Physics2D.OverlapBoxAll(FindTargetPos.position, FindTargeBoxSize, 0);
for (int i = 0; i < colliders.Length; i++)
{
Player player = colliders[i].GetComponent<Player>();
if (player != null)
{
if (!player.Isdeath)
{
targetEntity = player;
return true;
}
}
}
}
targetEntity = null;
return false;
}
}
private bool Attackdecttarget
{
get {
if (!dead)
{
Debug.DrawRay(transform.position, Vector2.right* m_facingDirection * speed, Color.yellow);
RaycastHit2D Rayhit = Physics2D.Raycast(transform.position, Vector2.right, m_facingDirection * speed, whatIsTarget);
if (Rayhit.transform != null)
{
if (Rayhit.transform.TryGetComponent(out Player player))
{
if (!player.Isdeath)
{
return true;
}
}
}
}
return false;
}
}
private void OnTriggerStay2D(Collider2D collision)
{
/*
//사망하지 않았으며,
// 최근 공격시점에서 timeBetAttack 이상 시간이 지났다면 공격가능
if (!dead&&Time.time >= lastAttackTime+TimeBeAttack)
{
Player AttackTarget = collision.GetComponent<Player>();
if(AttackTarget != null&&AttackTarget ==targetEntity)
{
AttackTarget.EnemyAttack(Power, AttackTarget.transform.position.x - transform.position.x);
}
}
*/
}
private void Start()
{
m_State = Enemystate.Idel;
}
private void Awake()
{
animator = GetComponent<Animator>();
rb = GetComponent<Rigidbody2D>();
}
public void setup(EnemyData enemyData)
{
//채력설정
startingHealth = enemyData.heath;
health = enemyData.heath;
speed = enemyData.speed;
startingGaege = enemyData.gaege;
gaege = enemyData.gaege;
}
public override void Die()
{
base.Die();
Collider[] Knightcolliders = GetComponents<Collider>();
for(int i = 0; i < Knightcolliders.Length; i++)
{
Knightcolliders[i].enabled = false;
}
isStoped = true;
//죽을시 특정 컴포넌트 끄기
//animator.SetTrigger("");
AudioManger.instance.PlaySfx(AudioManger.Sfx.EnemyDead);
}
public override void Damge(float damage, Vector2 hitPoint = new Vector2() , Vector2 hitNormal = new Vector2())
{
if (!dead)
{
//hiteffect.transform.position = hitPoint;
//hiteffect.transform.rotation = Quaternion.LookRotation(hitNormal);
//hiteffect.Play();
animator.SetTrigger("Hurt");
AudioManger.instance.PlaySfx(AudioManger.Sfx.EnemyHit);
}
base.Damge(damage, hitPoint, hitNormal);
}
// Start is called before the first frame update
protected override void OnEnable()
{
base.OnEnable();
}
// Update is called once per frame
public void FixedUpdate()
{
switch (m_State)
{
case Enemystate.Idel:
Idel();
break;
case Enemystate.Move:
Move();
break;
case Enemystate.Attack:
Attack();
break;
}
Debug.DrawRay(transform.position, Vector2.right * m_facingDirection * speed, Color.yellow);
}
void Idel()
{
if (hasTarget)
{
m_State = Enemystate.Move;
}
//Debug.Log("Idel"+hasTarget);
}
void Move()
{
var x = targetEntity.transform.position.x - transform.position.x;
rb.velocity = new Vector2(m_facingDirection * 2.5f,rb.velocity.y);
if (x > 0)
{
GetComponent<SpriteRenderer>().flipX = false;
m_facingDirection = 1;
}
else if (x < 0)
{
GetComponent<SpriteRenderer>().flipX = true;
m_facingDirection = -1;
}
//공격감지
if (Attackdecttarget)
{
rb.velocity = new Vector2(0, rb.velocity.y);
m_State = Enemystate.Attack;
}
Debug.Log("move");
if (!hasTarget)
{
rb.velocity = new Vector2(0, rb.velocity.y);
m_State = Enemystate.Idel;
}
}
protected virtual void Attack()
{
Debug.Log("Attack");
if (!Attackdecttarget)
{
m_State = Enemystate.Move;
}
}
}
본인 수준과 관계없이 원인 파악을 위해 한 고찰은 적어줘야 남들이 도와줄거 아님. 저도 코딩조무사 수준이지만 진짜 웬만한건 디버거 연결해서 f10갈기면 답이 어느정도 나옴. 디버깅은 습관임.
공격이 딜레이된다는 표현을 고려하면 이미 move 상태이고 공격범위안에 타겟이 있는데도 Attack이 호출 안된다는 의미인거 같은데 Attackdecttarget이 감지거리 안 일때 true를 리턴하는지 확인해보셈
아니면 Attackdecttarget도 정상적으로true를 반환해준다면 공격 감지할때 쓰는 레이의 길이가 OnTriggerStay2D의 범위보다 큰지도 체크해봐야할것 같음
친절해..
픽스드업데이트에 있는 상태 관리 부분을 업데이트로 옮겨보삼