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

时间:2017-07-14 16:25:15

标签: c# unity3d reload

所以我是C#中的一名新程序员(震惊,我知道),我试图在Unity中对原始编码系统进行原型设计,但只是在Unity中使用声音和仪表。

问题在于,当我重新加载时,它并没有正确地减少弹药。因为我这样做是为了当你还有子弹时重新加载,它只会从镜头中减去Ammo,我已经必须实现它只会减去一个if(shots == 0)

在我遇到一些问题(另一个令人震惊)之后,看到我的整个程序只是if()语句。在重写和重构之后,我仍然遇到了我的问题和if语句。我被告知不要发布200行代码并具体说明。

我要发布200行代码&因为我不知道更好。我很抱歉。

公共课射击:MonoBehaviour {

//"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;
    }
}

}

2 个答案:

答案 0 :(得分:1)

你的计数器子弹方法很少。我留下我的方法以防万一有用的人

(值的示例)

    bulletsTotal = 30;
    bulletsMagazine = 15;
    bulletsMagazineSize = 15;

更新方法

if (Input.GetKey(KeyCode.R))
        {
            if(bulletsMagazine!= 15)
            {   
                if (bulletsTotal > 0)
                {
                    asGun.clip = reload;
                    asGun.Play();
                    Reloadgun();
                } 
            }
        }

这是重装的功能

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

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

我创建了新的类PlayerSounds,其中包含在代码中播放声音的方法,但是我懒得完全重构它,所以代码的逻辑仍然在一个类中,尽管它应该分成3个类,一个管理射击,管理重装,一个用于弹药和杂志。此外,我对重新加载的逻辑感到十分困惑,所以我完全改变了,这将取决于你是否符合你的需要。

我做过的事情:在某种程度上移除了魔法数字,它们被改为常数。删除了字段NoAmmo,IsReloading,Shots。删除了所有注释,任何方法和字段都应该是自我解释的。逆转的负面情况 - 他们更难阅读。

我也完全改变了重新加载的逻辑,我觉得你是在思考它,有些if语句总是假的所以我删除它们,我也把数字25和26改为常数我不明白为什么你需要根据拍摄次数减去弹药,当你所要做的就是填充弹匣,所以我简化了它。改变它以满足您的需要。 查看代码之后,您甚至可能会发现两种重新加载方法几乎完全相同,可以合并为一种,根据您重新加载的项目符号消除if语句和播放声音。

要摆脱ifs是为了让方法按照你的意图行事,如果你的方法有太多ifs它可能做了很多事情,那么只需将它拆分并以某种方式命名方法就可以很容易地理解它们是什么正在做。

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

你的射击课:

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