Unity-带有锁定位置的MouseWheel进行武器切换竞技场射击游戏风格

问题描述

我一直在努力寻找如何使用鼠标滚轮实现竞技场风格射手武器切换的方法

到目前为止,我已经创建了3个列表;一个列表是所有可用的枪支(枪支类[0 =手枪,1 =中继器,2 =狙击手,3 =火箭发射器]),下一个列表是具有固定位置的布尔值列表,告诉您玩家是否已解锁那把枪(再次固定0、1、2、3)。我还有第三个清单,起初是您拥有的枪支,当您轻触拾音器时,就会添加一个新枪支。

我已经轻松地获得了Alpha键武器切换和一个快速的武器切换(在先前的武器和当前的武器之间切换),但是鼠标滚动使我疯狂。

我确定我已经考虑过了,但是我不确定在以下情况下该怎么做: 播放器只有狙击手和手枪,这意味着我不能只做简单的-1,否则我会向下滚动到播放器没有的中继器的索引。

我可以在可以与下一个武器互换的位置(即从0到3)工作,但是如果我拿起中继器或狙击手,它将仅通过手枪和火箭发射器进行切换。

我真的不知道我在这里做什么……我一直在尝试不同的for循环来遍历列表。我真正想知道的是,是否有一种简单的方法可以遍历列表并仅获取一个索引,或者如果我们到达列表的末尾,请转到第一个索引。

非常感谢您的帮助。

谢谢

Jacob

编辑:(按要求提供相关的代码段)

这是我的playercontroller中的变量:

//GUNS GUNS GUNS

public Gun activeGun;
public List<Gun> allGuns = new List<Gun>();
public List<bool> unlockedGuns = new List<bool>();
public List<Gun> gunsAvailable = new List<Gun>();
public int currentGun = 0;
private int prevIoUsGun;

在我的Update()函数中:

    if(Input.GetAxisRaw("Mouse ScrollWheel") != 0f)
    {
        SwitchGunByMouse(Input.GetAxis("Mouse ScrollWheel"));

    }

这里是SwitchGun()方法,它可以与alpha键或快速切换键配合使用。

public void SwitchGun(int gunNumber)
{
    if (cannotChangeWeapon) return;
    
    //if (currentGun == gunNumber) return;

    if (gunNumber < 0)
    {
        gunNumber = allGuns.Count - 1;
    }

    if (gunNumber > allGuns.Count - 1)
    {
        gunNumber = 0;
    }

    for (int i = 0; i < unlockedGuns.Count; i++)
    {
        if(i == gunNumber && unlockedGuns[i])
        {
            activeGun.gameObject.SetActive(false);
            activeGun = allGuns[gunNumber];
            activeGun.gameObject.SetActive(true);
            prevIoUsGun = currentGun;
            currentGun = gunNumber;
            UIController.instance.ammoText.text = "AMMO: " + activeGun.ammo;
        }
    }
}

这是被调用方法,不起作用,这是我上次尝试摆弄它的来源。

public void SwitchGunByMouse(float direction)
{

    if (direction == 0f) return;

    int nextGun = -1;

    if (gunsAvailable.Count -1 > 0)
    {
        if (direction > 0f)
        {
            for(int i = 0; i < gunsAvailable.Count -1; i++)
            {
                if (currentGun == gunsAvailable[i].idNumber) continue;
                if (currentGun < gunsAvailable[i].idNumber)
                    nextGun = gunsAvailable[i].idNumber;
            }

            if (nextGun == -1)
                nextGun = 0;
        }

        if (direction < 0f)
        {
            //int currentPos = gunsAvailable.idNumber;

            nextGun = gunsAvailable[currentGun].idNumber -1;
            
            List<Gun> g = gunsAvailable;
            
            g.Reverse();

            for(int i = 0; i < g.Count - 1; i++)
            {
                if (currentGun == g[i].idNumber) continue;
                if (currentGun < g[i].idNumber)
                    nextGun = g[i].idNumber;
            }
            
            //Okay so if we still haven't found a gun it means the other gun has a high id than our current gun
            //so Now we need to figure out how to cycle again

            if(nextGun == -1)
            {
                nextGun = 0;
            }

        }

        Debug.Log("NextGun: " + nextGun);

        if (nextGun > -1)
            SwitchGun(nextGun);
        else 
            Debug.Log("Something bad happened with SwitchGunByMouse()");

    }
    
}

最后:

public bool WeaponPickup(string gunToAdd,Gun myGun)
{
    switch(gunToAdd)
    {
        case "Repeater":
            if(unlockedGuns[1] == true)
                return false;
            else
            {
                unlockedGuns[1] = true;
                myGun.isCollected = true;
                gunsAvailable.Add(allGuns[1]);
                return true;
            }
        case "Sniper":
            if (unlockedGuns[2] == true)
                return false;
            else
            {
                unlockedGuns[2] = true;
                myGun.isCollected = true;
                gunsAvailable.Add(allGuns[2]);
                return true;
            }
        case "Rocket Launcher":
            if (unlockedGuns[3] == true)
                return false;
            else
            {
                unlockedGuns[3] = true;
                myGun.isCollected = true;
                gunsAvailable.Add(allGuns[3]);

                return true;
            }
        default:
            Debug.Log("Weapon Pickup ran into a problem with gunToAdd not matching a predefined string.");
            break;
    }

    return false;
}

解决方法

当我们找到一个正确的元素时,如果尝试向上或向下搜索数组并停止搜索,该怎么办?

public void SwitchGunByMouse(float direction)
{
    if (gunsAvailable.Count > 1)
    {
        int up = 1 ? direction > 0f: -1;
        for(int i = currentGun + direction; i == currentGun; i += direction)
        {
             // first we make sure our index is not going to be under 0 which does not exist in a array element
             if(i < 0)
             { 
                 i = unlockedGuns.Count-1;
             }
             // next we make sure our index doesn't crush the upper bounds of our array
             if(i > unlockedGuns.Count - 1)
             {
                 i = 0;
             }
             // if the index is in the bounds of our array we check if the boolean is true 
             // if yes,the loop will finish and we have our new weapon
             if(unlockGuns[i])
             {
                currentGun = i;
                return;
             }
        }
    }
}
,

这应该可以解决问题:

    public void SwitchGunByMouse(float direction)
    {
        if (gunsAvailable.Count <= 1 || cannotChangeWeapon)
        {
            return;
        }

        int gunSwitchDirection = Mathf.Sign(direction);
        int gunCandidate = currentGun;
        bool isCorrect = false;

        do
        {
            gunCandidate += gunSwitchDirection;

            if (gunCandidate < 0)
            {
                gunCandidate = allGuns.Count -1;
            }
            else
            {
                gunCandidate %= allGuns.Count;
            }

            isCorrect = gunCandidate != currentGun && unlockedGuns[gunCandidate];
        }
        while (gunCandidate==currentGun || !unlockedGuns[gunCandidate]);

        SwitchGun(gunCandidate);
    }

编辑:

您还可以稍微清理SwitchGun方法:

    public void SwitchGun(int gunNumber)
    {
        if (cannotChangeWeapon) return;

        //if (currentGun == gunNumber) return;

        if (gunNumber < 0)
        {
            gunNumber = allGuns.Count - 1;
        }
        else if (gunNumber > allGuns.Count - 1)
        {
            gunNumber = 0;
        }

        if (unlockedGuns[gunNumber])
        {
            activeGun.gameObject.SetActive(false);
            activeGun = allGuns[gunNumber];
            activeGun.gameObject.SetActive(true);
            previousGun = currentGun;
            currentGun = gunNumber;
            UIController.instance.ammoText.text = "AMMO: " + activeGun.ammo;
        }
    }