Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/unity3d/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 功能在错误的开关情况下触发_C#_Unity3d - Fatal编程技术网

C# 功能在错误的开关情况下触发

C# 功能在错误的开关情况下触发,c#,unity3d,C#,Unity3d,我正在尝试使用枚举实现一个“惰性状态机”,用于简单的敌方AI,但由于某些原因,逻辑无法按预期工作 我需要我的敌人不时停下来,让我处于空闲状态。但当空闲开关开火时,我的敌人不顾移动脚本的另一个状态条件继续移动 我的脚本逻辑有什么问题 void Update() { Debug.Log(state); onGround = Physics2D.Raycast(gameObject.transform.position, Vector2.down, groundLength, grou

我正在尝试使用枚举实现一个“惰性状态机”,用于简单的敌方AI,但由于某些原因,逻辑无法按预期工作

我需要我的敌人不时停下来,让我处于空闲状态。但当空闲开关开火时,我的敌人不顾移动脚本的另一个状态条件继续移动

我的脚本逻辑有什么问题

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中使用相同的切换情况,这也非常有用。