首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >在Unity中重新加载原型并不能正确减少弹药和子弹

在Unity中重新加载原型并不能正确减少弹药和子弹
EN

Stack Overflow用户
提问于 2017-07-15 00:25:15
回答 2查看 695关注 0票数 -2

所以我是一个新的C#程序员(我知道是震撼的),我试着在Unity中创建一个重播系统的原型,但只是在Unity中使用声音和仪表。

问题是,当我重新装弹时,它不能正确地减少弹药。因为我这样做了,当你仍然有子弹的时候重新装弹时,它会从射击中减去弹药,我已经实现了它只会减去一个if (镜头== 0)。

在我遇到一些问题(另一个令人震惊的问题)后,我发现我的整个程序都是if()语句。在重写和重构之后,我仍然有我的问题和if语句。我被告知不要张贴200行代码,而且要具体。

我要发布200行代码,因为我不知道更好的。真抱歉。

公共类快照: MonoBehaviour {

代码语言:javascript
复制
//"CoolDown" is used to limit rate of fire of my gun
public int CoolDown = 5;

//used to prevent shooting while realoding
public int ReloadCoolDown;
public bool IsReloading = false;

//obvious
public int Shots = 0;
public int TotalShots;
public int Magazine = 25;
public int Ammo = 125;
public bool NoAmmo = false;



void Start() 
{
    ReloadCoolDown = 150;
}

void Update()
{
    //Checks if ammo is still present
    CheckForAmmo();
    //just so i could test some stuff faster, can be ignored
    Skip();
    //Also checks for ammo
    if(!NoAmmo)
    {
        GameShot();
        ReloadEmpty();
        ReloadHalf();
        if (IsReloading == true)
        {
            ReloadCoolDown--;
        }
        if (CoolDown <= 0)
        {
            CoolDown = 0;
        }
        CoolDown--;
    }
    else if (NoAmmo)
    {
        ExecNoAmo();
    }
}

//Just getting the audio clips from unity
AudioSource GetAudio(int index)
{
   AudioSource[] audio = GetComponents<AudioSource>();
    if (index == 1)
    {
        return audio[0];
    }
    else if (index == 2)
    {
        return audio[1];
    }
    else if (index == 3)
    {
        return audio[2];
    }
    else if (index == 4)
    {
        return audio[3];
    }
    else
        return null;


}

void GameShot()
{
    //Shoots, increases total shots and shots (for that mag), plays audio, sets the cooldown for the next shot, decreases bullets in mag
    if (Input.GetKey(KeyCode.Space) &&
        CoolDown <= 0 && IsReloading == false)
    {
        TotalShots++;
        GetAudio(1).Play();
        CoolDown = 5;
        Shots++;
        Magazine--;
    }
}

//Reloads if every bullet in the magazine has been fired
void ReloadEmpty()
{
    //this and ReloadHalf() is where you can find so many if statements and where most of my code is tangled up...
    //im trying to check for ammo and if the mag is completely empty to trigger the empty reload
    if (Magazine == 0 && Ammo > 0)
    {

        if(Ammo >= 25)
        {
            Magazine = 25;
        }
        else
        {
            Magazine = Ammo; 
        }

        Ammo -= Shots;
        Shots = 0;
        ReloadCoolDown = 130;
        GetAudio(2).Play();

        IsReloading = true;
    }
    if (ReloadCoolDown <= 0)
    {
        ReloadCoolDown = 150;
        IsReloading = false;
    }
}
void ReloadHalf()
{
    //Again, many if statements and entaglement...
    if ((Input.GetKeyDown(KeyCode.R) && Magazine < 26) && Ammo > 0)
    {
        if (Shots == 0)
            Ammo -= 1;
        ReloadCoolDown = 80;
        GetAudio(3).Play();
        if(Ammo >= 25)
        { 
            Magazine = 26;
            Ammo -= Shots;
        }
        else if (Ammo <= 25)
        {
            Magazine += Ammo;
            if(Magazine > 26)
            {
                int i = Magazine - 25;
                Ammo = i;
                Magazine = 26;
            }

        }
        Shots = 0;
        IsReloading = true;
    }
    if (ReloadCoolDown <= 0)
    {
        ReloadCoolDown = 100;
        IsReloading = false;
    }
}

void ExecNoAmo()
{
    //plays no ammo sound if ammo == 0
    if(Input.GetKeyDown(KeyCode.Space) || Input.GetKeyDown(KeyCode.R))
        GetAudio(4).Play();

}

void CheckForAmmo()
{
    if (Ammo <= 0 && Magazine <= 0)
        NoAmmo = true;
}

void Skip()
{
    if (Input.GetKeyDown(KeyCode.Z))
    {
        Ammo = 25;
    }
}

}

EN

回答 2

Stack Overflow用户

发布于 2018-05-31 18:48:34

你的反子弹方法是如此罕见。我把我的方法留在这里,以防它对某人有用。

(值的示例)

代码语言:javascript
复制
    bulletsTotal = 30;
    bulletsMagazine = 15;
    bulletsMagazineSize = 15;

关于更新方法

代码语言:javascript
复制
if (Input.GetKey(KeyCode.R))
        {
            if(bulletsMagazine!= 15)
            {   
                if (bulletsTotal > 0)
                {
                    asGun.clip = reload;
                    asGun.Play();
                    Reloadgun();
                } 
            }
        }

这是reload的函数

代码语言:javascript
复制
public void Reloadgun()
    {
        int bulletToReload= bulletsMagazineSize-bulletsMagazine;

        if(bulletToReload< bulletsTotal)
        {
            bulletsTotal = bulletsTotal - bulletToReload;
            bulletsMagazine = bulletsMagazine + bulletToReload;
        }
        else
        {
            bulletsMagazine = bulletsMagazine + bulletsTotal;
            bulletsTotal = 0;

        }

        bulletsTxt.text = "M92\n   " + (bulletsMagazine) + "/" + bulletsTotal;
    }
票数 1
EN

Stack Overflow用户

发布于 2017-07-15 02:42:13

我试过重构你的代码,问题是你想做太多的事情,你应该把关注点分开,把它分成几个类。

我创建了一个新的类PlayerSounds,它包含了播放你代码中的声音的方法,但是我懒于完全重构它,所以你的代码的逻辑仍然在一个类中,尽管它应该被分成3个类,一个管理射击,一个管理重新加载,一个用于你的弹药和弹夹。另外,我完全不明白重新加载的逻辑,所以我完全改变了,这将取决于你的需要。

我所做的事情:在某种程度上删除了幻数,将它们改为常量。删除了字段NoAmmo、IsReloading、Shots。删除所有注释,任何方法和字段都应该是自解释的。逆转了负面条件--它们更难读懂。

我还完全改变了重新加载的逻辑,我觉得你想得太多了,有些if语句总是错误的,所以我删除了它们,我还把数字25和26改成了常量,我不明白为什么你需要根据射击次数来减去弹药,而你所要做的就是填满弹夹,所以我简化了它。更改它以满足您的需要。看过代码后,你甚至可能意识到这两种重载方法几乎完全相同,可以合并为一种方法,去掉if语句,并根据重新加载的子弹数播放声音。

去掉if就是让方法做你想做的事情,如果你的方法有太多的if,它可能正在做很多事情,所以只需拆分它,并以一种易于理解的方式命名方法即可。

代码语言:javascript
复制
class PlayerSounds
    {
        private const int PlayerShootingSound = 0;
        private const int PlayerReloadingMagazineSound = 1;
        private const int PlayerReloadingHalfOfMagazineSound = 2;
        private const int PlayerHasNoAmmoSound = 3;
        private AudioSource[] audio;

        public PlayerSounds(AudioSource[] audio)
        {
            if (audio == null)
                throw new ArgumentNullException(nameof(audio));

            this.audio = audio;
        }

        public void PlayerShot()
        {
            audio[PlayerShootingSound].Play();
        }

        public void PlayerReloadingMagazine()
        {
            audio[PlayerReloadingMagazineSound].Play();
        }

        public void PlayerRealodingHalfMagazine()
        {
            audio[PlayerReloadingHalfOfMagazineSound].Play();
        }

        public void PlayerHasNoAmmo()
        {
            audio[PlayerHasNoAmmoSound].Play();
        }
    }

还有你的射击课:

代码语言:javascript
复制
public class Shot : MonoBehaviour
{
    private const int MagazineSize = 25; // to remove magic number 25 and 26, also to give this number a meaning
    private PlayerSounds playerSounds;

    public int CoolDown = 5;
    public int ReloadCoolDown;
    public int Shots = 0;
    public int TotalShots;
    public int Magazine = 25;
    public int Ammo = 125;

    void Start()
    {
        ReloadCoolDown = 150;
        playerSounds = new PlayerSounds(GetComponents<AudioSource>());
    }

    void Update()
    {
        if (playerTryingToFire())
        {
            tryToShoot();
            playNoAmmoSoundWhenWithoutAmmo();
        }
        else if (playerTryingToReload())
        {
            tryToReloadHalfMagazine();
            playNoAmmoSoundWhenWithoutAmmo();
        }

        tryToReloadEntireMagazine();

        if (CoolDown > 0) CoolDown--;
        if (ReloadCoolDown > 0) ReloadCoolDown--;
    }

    bool playerTryingToFire()
    {
        return Input.GetKey(KeyCode.Space);
    }

    bool playerTryingToReload()
    {
        return Input.GetKeyDown(KeyCode.R);
    }

    void tryToShoot()
    {
        if (playerCanFire())
        {
            TotalShots++;
            playerSounds.PlayerShot();
            CoolDown = 5;
            Magazine--;
        }
    }

    bool playerCanFire()
    {
        return CoolDown == 0 && ReloadCoolDown == 0 && Magazine > 0;
    }

    void playNoAmmoSoundWhenWithoutAmmo()
    {
        if (!hasAmmo())
        {
            playerSounds.PlayerHasNoAmmo();
        }
    }

    void tryToReloadHalfMagazine()
    {
        if (magazineIsNotFull() && hasAmmo())
        {
            int missingBulletCountInMagazine = MagazineSize - Magazine;
            transferAmmoToMagazine(missingBulletCountInMagazine);
            ReloadCoolDown = 80;
            playerSounds.PlayerRealodingHalfMagazine();
        }
    }

    private bool magazineIsNotFull()
    {
        return Magazine < MagazineSize;
    }

    void tryToReloadEntireMagazine()
    {
        if (Magazine == 0 && hasAmmo())
        {
            transferAmmoToMagazine(MagazineSize);
            ReloadCoolDown = 130;
            playerSounds.PlayerReloadingMagazine();
        }
    }

    private void transferAmmoToMagazine(int maximumAmountToFitMagazine)
    {
        int possibleBulletCountToFit = Math.Min(Ammo, maximumAmountToFitMagazine);
        Magazine += possibleBulletCountToFit;
        Ammo -= possibleBulletCountToFit;
    }

    bool hasAmmo()
    {
        return Ammo > 0;
    }
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/45107667

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档