C# 功能在错误的开关情况下触发
我正在尝试使用枚举实现一个“惰性状态机”,用于简单的敌方AI,但由于某些原因,逻辑无法按预期工作 我需要我的敌人不时停下来,让我处于空闲状态。但当空闲开关开火时,我的敌人不顾移动脚本的另一个状态条件继续移动 我的脚本逻辑有什么问题C# 功能在错误的开关情况下触发,c#,unity3d,C#,Unity3d,我正在尝试使用枚举实现一个“惰性状态机”,用于简单的敌方AI,但由于某些原因,逻辑无法按预期工作 我需要我的敌人不时停下来,让我处于空闲状态。但当空闲开关开火时,我的敌人不顾移动脚本的另一个状态条件继续移动 我的脚本逻辑有什么问题 void Update() { Debug.Log(state); onGround = Physics2D.Raycast(gameObject.transform.position, Vector2.down, groundLength, grou
void Update()
{
Debug.Log(state);
onGround = Physics2D.Raycast(gameObject.transform.position, Vector2.down, groundLength, groundLayer);
Debug.DrawRay(gameObject.transform.position, Vector2.down * 1f, Color.red);
isAnythingThere = Physics2D.Raycast(wallDetection.position, Vector2.right * speed, 0.3f, sideInfo);
RaycastHit2D groundInfo = Physics2D.Raycast(groundDetection.position, Vector2.down, distance);
RaycastHit2D isPlayerInSight = Physics2D.Raycast(wallDetection.position, Vector2.right * speed, 3f, playerLayer);
switch (state)
{
default:
case State.patrol:
if ((groundInfo.collider == false || isAnythingThere) && !isPlayerInSight)
{
if (movingRight == true)
{
Debug.Log("Поворот");
transform.eulerAngles = new Vector3(0, -180, 0);
movingRight = false;
speed = -speed;
}
else
{
transform.eulerAngles = new Vector3(0, 0, 0);
movingRight = true;
speed = -speed;
}
}
if (isPlayerInSight)
{
state = State.attack;
}
if (enemyIdleCheck == false)
{
StartCoroutine("IfEnemyWantsToIdle");
}
break;
case State.attack:
RaycastHit2D isPlayerThere = Physics2D.Raycast(wallDetection.position, Vector2.right * speed, 3f, playerLayer);
Debug.DrawRay(wallDetection.transform.position, Vector2.right * speed * 3f, Color.red);
if (isPlayerThere)
{
attackDirection = (playerPosition.position - transform.position).normalized;
}
else
{
if (!jumpCooldown)
{
state = State.patrol;
}
}
if (jumpCooldown == false)
{
jumpTimer = Time.time + jumpCooldownInSeconds;
}
break;
case State.idle:
if (isPlayerInSight)
{
state = State.attack;
}
if (!isInIdleState)
{
StartCoroutine("IdlingTime");
}
break;
}
}
IEnumerator IfEnemyWantsToIdle()
{
enemyIdleCheck = true;
Debug.Log("Checking for idle possibility");
yield return new WaitForSeconds(2);
if (Random.Range(0, 20) > 10)
{
state = State.idle;
}
enemyIdleCheck = false;
if (isPlayerInSight)
{
state = State.attack;
enemyIdleCheck = false;
yield break;
}
}
IEnumerator IdlingTime()
{
isInIdleState = true;
while (state == State.idle)
{
yield return new WaitForSeconds(Random.Range(2, 4));
isInIdleState = false;
state = State.patrol;
}
if (isPlayerInSight)
{
isInIdleState = false;
yield break;
}
}
private void FixedUpdate()
{
if (state == State.patrol)
{
if (!enemy.isTakingDamage)
{
rb.velocity = new Vector2(movingSpeed * speed, rb.velocity.y);
}
}
if (state == State.attack)
{
if (!enemy.isTakingDamage)
{
rb.velocity = new Vector2(attackDirection.x * attackSpeed, rb.velocity.y);
}
if ((Random.Range(0, 100) > 90) && !jumpCooldown && onGround)
{
Debug.Log("Прыжок сработал");
//rb.velocity = new Vector2(rb.velocity.x, rb.velocity.y * jumpForce);
rb.AddForce(Vector2.up * jumpForce, ForceMode2D.Impulse);
jumpCooldown = true;
Invoke("JumpCooldownTime", 1f);
}
}
}
目前,您只是没有添加进一步的力/速度。当您进入
idle
状态时,您应该确保rigiidbody2d
实际上已停止
IEnumerator IdlingTime()
{
isInIdleState = true;
// actually stop the movement
rb.velocity = Vector2.zero;
// you could even do
rb.isKinematic = true;
while (state == State.idle)
{
yield return new WaitForSeconds(Random.Range(2, 4));
isInIdleState = false;
rb.isKinematic = false;
state = State.patrol;
}
if (isPlayerInSight)
{
isInIdleState = false;
rb.isKinematic = false;
yield break;
}
}
或/并在
private void FixedUpdate()
{
switch(state)
{
case State.patrol:
if (!enemy.isTakingDamage)
{
rb.velocity = new Vector2(movingSpeed * speed, rb.velocity.y);
}
break;
case State.attack:
if (!enemy.isTakingDamage)
{
rb.velocity = new Vector2(attackDirection.x * attackSpeed, rb.velocity.y);
}
if ((Random.Range(0, 100) > 90) && !jumpCooldown && onGround)
{
Debug.Log("Прыжок сработал");
//rb.velocity = new Vector2(rb.velocity.x, rb.velocity.y * jumpForce);
rb.AddForce(Vector2.up * jumpForce, ForceMode2D.Impulse);
jumpCooldown = true;
Invoke("JumpCooldownTime", 1f);
}
break;
case State.idle
rb.velocity = Vector2.zero;
break;
}
}
非常感谢,我对玩家的移动感到困惑,但是敌人的移动速度是恒定的,不需要输入。我不知道可以在Update和FixeUpdate中使用相同的切换情况,这也非常有用。