Как я могу выполнить строку кода один раз в void Update? - PullRequest
0 голосов
/ 22 марта 2020

Я сейчас играю в Unity. Мне нужен плеер, чтобы можно было запускать WallRun, а для лучшего впечатления камера должна наклоняться на 12,5 градусов. Это код, который я использую:

void Update()
{
    if (Physics.Raycast(transform.position, transform.right, out hitR, 1))
    {
        if (hitR.transform.tag == "Wall")
        {
            isWallR = true;
            isWallL = false;
            jumpCount += 1;
            rb.useGravity = false;
            StartCoroutine(afterRun());
            playerCamera.transform.Rotate(new Vector​3(0.0f, 0.0f, -12.5f));

        }
    }
    if (Physics.Raycast(transform.position, -transform.right, out hitL, 1))
    {
        if (hitL.transform.tag == "Wall")
        {
            isWallR = false;
            isWallL = true;
            jumpCount += 1;
            rb.useGravity = false;
            StartCoroutine(afterRun());
            playerCamera.transform.Rotate(new Vector​3(0.0f, 0.0f, -12.5f));
        }
    }
}

Он внутри void Update(). Я знаю, что обновление вызывается один раз за кадр, что заставляет камеру переворачиваться несколько раз, но как я могу вызвать его один раз, чтобы камера наклоняла только нужные градусы?

Ответы [ 2 ]

0 голосов
/ 22 марта 2020

Попробуйте использовать что-то вроде этого скрипта, который я сделал:

using UnityEngine;

public class Test : MonoBehaviour
{
    bool start = true;

    private void Update()
    {
        if(start)
        {
            // Do your code

            start = false; // So we don't call the method again
        }
    }
}

0 голосов
/ 22 марта 2020

Вы можете использовать простой флаг bool, чтобы остановить выполнение Update (или, по крайней мере, немедленно вернуться), пока не завершится Coroutines sh.

Также я бы использовал перечисление для отличия между сторонами и реализовать код только один раз в зависимости от стороны.

Кстати, вместо == вместо этого используйте CompareTag, который является более безопасным и предотвращает сбои при опечатках.

private enum Side
{
    Left,
    Right
}

private bool IsAfterRun;


private void Update()
{
    if(IsAfterRun) return;

    if (Physics.Raycast(transform.position, transform.right, out hitR, 1))
    {
        if (hitR.transform.CompareTag("Wall")) 
        {
            StartCoroutine(afterRun());
        }
    }
    // Additionally use else here
    // so this second Raycast is only done if the first one fails
    else if (Physics.Raycast(transform.position, -transform.right, out hitL, 1))
    {
        if (hitL.transform.CompareTag("Wall"))
        {
            StartCoroutine(afterRun(Side.Left));
        }
    }
}

private IEnumerator afterRun(Side side)
{
    // Just to be sure block concurrent routines
    if(IsAfterRun) yield break;
    IsAfterRun = true;

    isWallR = side == Side.Right;
    isWallL = side == Side.Left;
    jumpCount += 1;
    rb.useGravity = false;

    playerCamera.transform.Rotate(new Vector​3(0.0f, 0.0f, 12.5f * (side == Side.Right ? 1 : -1));

    // Your routine 
    ....


    // in the end reset your values
    rb.useGravity = false;
    playerCamera.transform.Rotate(new Vector​3(0.0f, 0.0f, 12.5f * (side == Side.Right ? -1 : 1));
    isWallR = false;
    isWallL = false;


    IsAfterRun = false;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...