Если исполнение заказа в то же время - PullRequest
0 голосов
/ 27 апреля 2018

У меня проблема ... Я хочу, чтобы моя огненная сфера создавалась каждый раз, когда я нажимаю одну из клавиш со стрелками.

-Это работает, но: если (например) я нажимаю стрелку вниз, а затем, пока нажата стрелка вниз, одновременно нажимаю другую стрелку, (например) стрелку влево, это не создаст огненная сфера слева. Но со стрелкой вправо все работает просто отлично (потому что это первый из операторов if).

-Я знаю, что код работает сверху вниз, и я не могу это изменить. Но, возможно, я смогу найти способ избежать этого, заставить эту работу работать так, как я хочу.

(Я хочу, чтобы создание fireSphere было похоже на Binding of Isaac: если вы нажмете влево, он будет стрелять влево, если вправо, то будет стрелять вправо, НО, если вы сначала нажмете стрелку влево, а затем, пока налево Стрелка нажата, вы нажимаете стрелку вправо, она будет стрелять вправо. То же самое, если вы нажмете сначала вправо)

(английский - мой второй язык, если ты меня не понимаешь, скажи мне! Я постараюсь объяснить себя лучше) Спасибо!

    if (Input.GetButton("RightArrow") && Time.time > timeToFire)
    {
        timeToFire = Time.time + 1 / fireRate;
        Instantiate(fireSphere, firePoint.position, firePoint.rotation);
    }

    if (Input.GetButton("LeftArrow") && Time.time > timeToFire)
    {
        timeToFire = Time.time + 1 / fireRate;
        Instantiate(fireSphere, firePoint.position, firePoint.rotation);
    }

    if (Input.GetButton("UpArrow") && Time.time > timeToFire)
    {
        timeToFire = Time.time + 1 / fireRate;
        Instantiate(fireSphere, firePoint.position, firePoint.rotation);
    }

    if (Input.GetButton("DownArrow") && Time.time > timeToFire)
    {
        timeToFire = Time.time + 1 / fireRate;
        Instantiate(fireSphere, firePoint.position, firePoint.rotation);
    }

Ответы [ 3 ]

0 голосов
/ 27 апреля 2018

Этот код позволит иметь все клавиши для нажатия и удержания клавиш со стрелками одновременно с последней из них, определяющей направление.

Пример: Нажмите и удерживайте ← → ↓, он будет использовать ↓. Если вы отпустите → и затем ↓, он будет использовать ←.

(также используется Input.GetKey и KeyCode)

public float FireRate;

public float NextFire;

private List<KeyCode> keysPressed;

private KeyCode right = KeyCode.RightArrow;
private KeyCode left = KeyCode.LeftArrow;
private KeyCode up = KeyCode.UpArrow;
private KeyCode down = KeyCode.DownArrow;

private void Awake()
{
    keysPressed = new List<KeyCode>();
}

private void Update()
{
    if(Input.GetKeyDown(right))
        AddKey(right);
    if(Input.GetKeyDown(left))
        AddKey(left);
    if(Input.GetKeyDown(up))
        AddKey(up);
    if(Input.GetKeyDown(down))
        AddKey(down);

    if(Input.GetKeyUp(right))
        RemoveKey(right);
    if(Input.GetKeyUp(left))
        RemoveKey(left);
    if(Input.GetKeyUp(up))
        RemoveKey(up);
    if(Input.GetKeyUp(down))
        RemoveKey(down);

    if((Time.time > NextFire) == false)
        return;

    if(Input.GetKey(right) || Input.GetKey(left) || Input.GetKey(up) || Input.GetKey(down))
    {
        NextFire = Time.time + FireRate;
        Fire();
    }
}

private void AddKey(KeyCode k)
{
    keysPressed.Add(k);
}

private void RemoveKey(KeyCode k)
{
    keysPressed.Remove(k);
}

private void Fire()
{
    if(keysPressed[keysPressed.Count - 1] == right)
        Debug.Log("right");
    else if(keysPressed[keysPressed.Count - 1] == left)
        Debug.Log("left");
    else if(keysPressed[keysPressed.Count - 1] == up)
        Debug.Log("up");
    else if(keysPressed[keysPressed.Count - 1] == down)
        Debug.Log("down");
}

Единственная точка, в которой все еще есть небольшая проблема с ордером - это когда вы нажимаете одновременно 2 или более клавиш.

Это решение, вероятно, не самое эффективное из-за операций со списками, но другие варианты, которые я могу предложить прямо сейчас, будут иметь свои недостатки или не учитывать такую ​​гибкость.

0 голосов
/ 28 апреля 2018

Оказывается, моя идея была очень похожа на @ Gunnar-b's:

    protected List<KeyCode> Directions = new List<KeyCode>();

    protected void Update()
    {
        var hasDirection = TrackKey(KeyCode.UpArrow) || TrackKey(KeyCode.DownArrow) || TrackKey(KeyCode.LeftArrow) || TrackKey(KeyCode.RightArrow);
        if (!hasDirection)
        {
            Directions.Clear();
            return;
        }

        // Has a direction.  Check "Last" item in list (top of stack) and proceed.
        Quaternion rotation = Quaternion.identity;
        switch (Directions[Directions.Count -1])
        {
            case KeyCode.UpArrow: // Set Rotation Here
                break;
            case KeyCode.DownArrow: // Set Rotation Here
                break;
            case KeyCode.LeftArrow: // Set Rotation Here
                break;
            case KeyCode.RightArrow: // Set Rotation Here
                break;

        }

        // Instantiate fireball using rotation from above

        Instantiate(prefab, position, rotation);
    }

    protected bool TrackKey(KeyCode key)
    {
        // if key was released, remove each item where the item equals key
        if (Input.GetKeyUp(key)) Directions.RemoveAll(item => item == key);

        // Always adds to end, virtual 'Stack'
        if (Input.GetKeyDown(key)) Directions.Add(key);

        return Input.GetKey(key);
    }
0 голосов
/ 27 апреля 2018

См. Часть вашего кода:

if (Input.GetButton("LeftArrow") && Time.time > timeToFire)
{
    timeToFire = Time.time + 1 / fireRate;
    Instantiate(fireSphere, firePoint.position, firePoint.rotation);
}

if (Input.GetButton("UpArrow") && Time.time > timeToFire)
{
    timeToFire = Time.time + 1 / fireRate;
    Instantiate(fireSphere, firePoint.position, firePoint.rotation);
}

Если вы нажмете клавиши LeftArrow и UpArrow, первое условие обоих операторов if будет выполнено.

Я предполагаю, что Time.time больше, чем timeToFire в начале, поэтому первый оператор срабатывает. В этом первом состоянии вы устанавливаете для timeToFire значение, большее Time.time (+ (1/fireRate)).

=> Это делает невозможным оценку второго оператора if. Это так же, как

int a = 5;
if(SomeTrueStatement() && a < 10)
{
    a = 20;
}
//This never happens because a is now > 10
if(SomeOtherTrueStatement() a < 10)
{
    //Code
}

Возможное решение: Я не знаю «из коробки», можете ли вы определить, какая клавиша была нажата первой, но если вы сохранили последнюю нажатую клавишу, когда была нажата только одна клавиша, вы знаете, если сейчас нажаты 2 клавиши, какая из них позже нажатая клавиша.

[Pseudocode]
if(OnlyOneKeyPressed())
{
    savedPressedKey = SaveKeyPressed(GetPressedKey());
    pressedKey = GetPressedKey();
}
else if(TwoKeysPressed())
    pressedKey = GetAllPressedKeys().Exclude(savedPressedKey);

if(pressedKey == "ArrowUp" && ...)
...
...
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...