如果执行顺序同时

时间:2018-04-27 10:26:51

标签: c# unity3d

我遇到了问题..我希望每次按下其中一个箭头键都会创建我的火球。

- 它可以工作,但是:如果(例如)我按向下箭头,然后,在按下向下箭头的同时,我同时按下另一个箭头,(例如)向左箭头,它不会创建一个左边的火球。 但是使用右箭头,一切正常(因为它是if语句中的第一个)。

- 我知道代码从上到下都有效,我无法改变这一点。但也许我可以找到一种方法来避免这种情况,让我的工作成为我想要的。

(我想要创建fireSphere就像在Isaac的Binding中一样:如果你按下左边它会向左射击,如果向右,它会向右射击,但是如果先按向左箭头,然后向左射击按下箭头,你按向右箭头,它会向右射击。如果你先按右键也一样)

(英语是我的第二语言,如果你不理解我,请告诉我!我会更好地解释自己) 谢谢!

    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 :(得分:2)

此代码允许同时按下并保持所有箭头键,最后一个箭头键指示方向。

实施例: 按住←→↓,将使用↓。如果你放开→然后↓,它将使用←。

(也使用Input.GetKeyKeyCode

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个或更多键时。

由于列表操作,此解决方案可能不是最高性能,但我现在可以提出的其他选项也有其缺点或不允许这种灵活性。

答案 1 :(得分:0)

请参阅代码部分:

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);
}

如果按下LeftArrowUpArrow键,则会满足两个if语句的第一个条件。

我假设Time.time在开头大于timeToFire,因此第一个语句会触发。在第一个状态中,您将timeToFire设置为大于Time.time+ (1/fireRate))的值。

=&GT;这使得第二个if语句无法评估为true。 那就像

一样
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" && ...)
...
...

答案 2 :(得分:0)

事实证明我的想法与@ Gunnar-b非常相似:

    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);
    }