Updates to my Skybox Portal Reign Game

Btw, I knew about some of the code I had to get rid of I was just merely excited that I got it working I was getting syntax warnings I knew I had to fix errors this is what I changed so far testing now.

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityStandardAssets.CrossPlatformInput;

public class GunLaser : MonoBehaviour
{
    
    AudioSource audioSource;
    private AudioSource playAudio;
    private bool isActive = true;

    void Start()
    {
       audioSource = gameObject.GetComponent<AudioSource>();
    }
    void Update()
    {
        if (isActive)
        {
            ProcessFiring();
        }

    }
    void ProcessFiring()
    {
        if (CrossPlatformInputManager.GetButton("Fire"))
        {
            SetAudioSourceActive(true);
        }
        else
        {
            SetAudioSourceActive(false);
        }
    }
    private void SetAudioSourceActive(bool isActive)
        {
           playAudio = gameObject.GetComponent<AudioSource>();
           playAudio.enabled = isActive;
        }
}

 

It was not looping the sound only played when I hit fire/spacebar.

How long is the duration of the audio clip you are using?

What happens if you hold fire down continuously?

You, presumably, have Play on Awake enabled on the AudioSource?

It stays quite if I hold it down. I would like to fix that. Yes, it is Play on Awake.

I receive this warning in the console:
After building to WebGL:
The laser sound does not work in WebGL build Only in PC build How much longer can you work with if not to long I will go to class? :confused:
Assets/Scripts/GunLaser.cs(10,17): warning CS0414: The private field `GunLaser.audioSource’ is assigned but its value is never used

The warning is because you have created a variable named audioSource but then are not using it. Instead you are still using playAudio.

So this is what I got done after you explained the warning.
Do I need to change anything else in the code or is this Okay?

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityStandardAssets.CrossPlatformInput;

public class GunLaser : MonoBehaviour
{
    
  
    private AudioSource playAudio;
    private bool isActive = true;

    void Start()
    {
        playAudio = FindObjectOfType<AudioSource>();

    }
    void Update()
    {
        if (isActive)
        {
            ProcessFiring();
        }

    }
    void ProcessFiring()
    {
        if (CrossPlatformInputManager.GetButton("Fire"))
        {
            SetAudioSourceActive(true);
            playAudio.enabled = true;
            playAudio.loop = true;
        }
        else
        {
            SetAudioSourceActive(false);
            playAudio.enabled = false;
            playAudio.loop = false;
        }
    }
    private void SetAudioSourceActive(bool isActive)
        {
           playAudio = gameObject.GetComponent<AudioSource>();
           playAudio.enabled = isActive;
        }
}

 

Hi Martin,

I feel like each time I reply I am saying the same things…

Take a look at your ProcessFiring method.

You call SetAudioSourceActive and pass in either true or false, then in either case within the if statement you have two further lines of code, one of which does exactly what you have already done in the call to SetAudioSourceActive

With the SetAudioSourceActive method you first go off to get a reference to the AudioSource component, which you have already done in the Start method, although in oen case you are trying to get a component by using GetComponent and in the other you are searching the entire scene, iterating through every single GameObject trying to find anything which is of type AudioSource.

Do you not see these issues yourself?

I don’t see what is wrong with this before I added
playAudio.enabled = true;
playAudio.enabled = true;
playAudio.loop = false;
playAudio.loop = false;
The laser sound would not play when I hold down fire/spacebar it does play now since I added those lines of code.

How can I get the Get Component only to find the audio source? this portion I’m a bit confused?

You shouldn’t need to use both a Find and a GetComponent to do the same thing, just one or the other. If the AudioSource component is attached to the GameObject thus script is attached to the use GetComponent because it is a component of the same GameObject. If the AudioSource isn’t a component on the same GameObject then, either use the Find, although better architecture wouldn’t require this, or, create the reference by exposing a field and dragging the AudioSource in to it in the Inspector.

I suspect in your case you have the AudioSource as a component, as the use of the Find statement is something you appear to have only introduced in the last few posts and after you previously said you could play Audio.

The other issue is the duplicate, you are setting enabled to either true or false twice.

Looping you should be able to disable on the AudioSource in the Inspector, along with Play on Awake. Better to control the playing of the audio through code in this specific case.

I made these changes you suggested it still works. Is there anything else I’m overlooking? Well I just fixed the guns from firing at start I needed to adjust the y coordinates for the landing pad its fixed? Thank you

using System;
using System. Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityStandardAssets.CrossPlatformInput;

public class GunLaser: MonoBehaviour
{
    
  
    private AudioSource playAudio;
    private bool isActive = true;

    void Start()
    {
        playAudio = gameObject.GetComponent<AudioSource>();

    }
    void Update()
    {
        if (isActive)
        {
            ProcessFiring();
        }

    }
    void ProcessFiring()
    {
        if (CrossPlatformInputManager.GetButton("Fire"))
        {
            SetAudioSourceActive(true);
            playAudio.loop = true;
        }
        else
        {
            SetAudioSourceActive(false);
            playAudio.loop = false;
        }
    }
    private void SetAudioSourceActive(bool isActive)
        {
           playAudio = gameObject.GetComponent<AudioSource>();
           playAudio.enabled = isActive;
        }
}

You are still using GetComponent twice in the above code Martin - let me challenge you;

Explain why you are currently using GetComponent twice.

It will be interesting to see your thinking.

Regarding the Game Over, it relies on making contact with the collider, if you’ve made that smaller, the ship is most likely no longer making contact with it and thus doesn’t trigger the game over condition. With regards to your query above fixing it, change the size back, and resolve the firing at the start of the scene in a different way.

Hi Rob, I already changed the size for the landing pad back I only needed to move or lower it away from the ship. Why I use get component twice is because I believed I needed to add a void start method with the script retrieving the audioSource but I’m wrong I still learning Okay. I just deleted the startup method and it still works. I,m going to start working on getting the enemies to shoot back once I do this I will give the player and the enemies all health bars. finally for this sample game I will add characters on the Terrain to shoot for health bonuses for the player. how does this sound to you? I need to know am I doing better?

If for some reason the collider on that landing pad is what is triggering the guns to shoot then I would investigate that and determine why, it shouldn’t happen so perhaps it needs a bit of code wrapped around whatever is there are the moment to prevent the ship from firing when it’s either landed, landing, and/or the player no longer has control of the ship.

That makes sense, typically you would get these references before any of your other code executes, so using the Awake or Start method makes perfect sense, so your code here;

private void Start()
{
    playAudio = gameObject.GetComponent<AudioSource>();
}

…is fine, again, I’d raise the issue of the naming of the variable but getting the component at this point in your code is good.

However, getting it again here;

private void SetAudioSourceActive(bool isActive)
{
    playAudio = gameObject.GetComponent<AudioSource>();
    playAudio.enabled = isActive;
}

…then becomes unnecessary, e.g. there is no need to get it twice, all you are doing is overwriting the first reference with the second, which is actually the same thing.

It would, because of the second reference above, typically though you will find it much easier to have the getting of components, or finding of objects in these Awake/Start methods, and as you keep developing this is typically where you yourself would look for them.

You do, of course, only need to have this reference as a member variable if it is actually going to be used across multiple methods, or serve some other purpose within the class, or, if it removes the repetitiveness of getting it.

So, if we look at what your code currently does in layman’s terms, leaving the GetComponent call in the SetAudioSourceActive method;

  • Update gets called every frame
  • Every time Update is called you check to see if isActive is true, it always will be because you’ve set it to be when declaring the member variable.
  • ProcessFiring is then called, every frame, regardless of the isActive variable, as nothing else changes it
  • ProcessFiring checks to see if the fire button is being pressed, in either case, you call SetAudioSourceActive which calls the GetComponent method

There is no value in calling the GetComponent method every single frame, its redundant and costs you in performance.

The isActive member variable you have declared is also not providing any benefit, you could remove that, and the if statement within the Update method and just literally call ProcessFiring.

I’m not sure why you want to set the AudioSource.loop property to either true/false, I would have though that when the player presses fire you want to play an audio clip just the once?

I’m also not sure why you want to enabled/disable the AudioSource within the SetAudioSourceActive method?

Somethings you could try, one at a time;

  • put the Start method back in, and put the GetComponent code back in, then comment out this line from the SetAudioSourceActive method;

    playAudio = gameObject.GetComponent<AudioSource>();
    

    Run the game, it should still work as it did before, but now it’s not getting the component over and over again for no reason.

  • Within the Update method, comment out the two lines of code which set the AudioSource.loop property to either true/false

    Run the game, do you notice any difference in the sound?

    Assuming not, you could delete those two lines.

  • Within the SetAudioSourceActive method, comment out the following line;

    playAudio.enabled = isActive;
    

    Run the game, does anything adverse happen, or is everything still working as expected?

    Assuming all is well, that leaves the SetAudioSourceActive method with two commented out lines of code, which means it is now not doing anything.

    You could then remove the method and the two statements in the Update method which call it.

    If the sound effect wasn’t heard, that will be because you are relying on Play on Awake on the AudioSource component, if you disable this, and instead call the AudioSource’s Play method within ProcessFiring it should be heard again.

    The above would strip out a lot of unnecessary code, increase the performance of your code, and still leave you with the sound effect being controlled via this script.

With all of the above, make the changes one at a time and review, don’t do them all, then post “It didn’t work”. Instead, make each change and let me know what the effect of that change was, in the case of it being ok and no problems, move on to the next change etc.

Okay starting now hold on.

This is what I got done so far. The game still works sound is better a bit.

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityStandardAssets.CrossPlatformInput;

public class GunLaser : MonoBehaviour
{
    
  
    private AudioSource playAudio;
    private bool isActive = true;

   void Start()
    {
        playAudio = gameObject.GetComponent<AudioSource>();
    }
    void Update()
        {
            ProcessFiring();
        }
    void ProcessFiring()
    {
        if (CrossPlatformInputManager.GetButton("Fire"))
        {
            SetAudioSourceActive(true);
        }
        else
        {
            SetAudioSourceActive(false);
        }
    }
    private void SetAudioSourceActive(bool isActive)
        {
           playAudio = gameObject.GetComponent<AudioSource>();
           playAudio.enabled = isActive;
        }
}

 

I commented out the // playAudio.enabled = isActive; but now I get no laser sound

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityStandardAssets.CrossPlatformInput;

public class GunLaser : MonoBehaviour
{
    
  
    private AudioSource playAudio;
    private bool isActive = true;

   void Start()
    {
        playAudio = gameObject.GetComponent<AudioSource>();
    }
    void Update()
        {
            ProcessFiring();
        }
    void ProcessFiring()
    {
        if (CrossPlatformInputManager.GetButton("Fire"))
        {
            SetAudioSourceActive(true);
        }
        else
        {
            SetAudioSourceActive(false);
        }
    }
    private void SetAudioSourceActive(bool isActive)
        {
           playAudio = gameObject.GetComponent<AudioSource>();
           //playAudio.enabled = isActive;
        }
}

That was what I expected. Check to see if you have Play on Awake ticked on the AudioSource, I would imagine you do, which was why enabling the AudioSource through your statement;

playAudio.enabled = true;

…would play the sound, instead, you can use the Play method of the AudioSource;

playAudio.Play();

This would need to go in the if statement within the Update method, e.g for when the player is pressing fire.

You’ll see now how the name of the variable looks a bit weird when you call the Play method, e.g. playAudio.Play

This is what I got done so far i just fixed the sound. I Thank you :slight_smile:

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityStandardAssets.CrossPlatformInput;

public class GunLaser : MonoBehaviour
{


    private AudioSource AudioSound;

    void Start()
    {
        AudioSound = gameObject.GetComponent<AudioSource>();
    }
    void Update()
    {
        if (AudioSound)
        {
            ProcessFiring();
        }
    }
    void ProcessFiring()
    {

        if (CrossPlatformInputManager.GetButton("Fire"))
        {
            AudioSound.Play();
        }
    }
}

 

Lower case the “a” for AudioSource in your variable name, only types, properties and methods should use PascalCase, it will get consuming whether you are referring to a variable or type other wise.

Glad you have had some success.

Thank you for everything :wink:

1 Like

Privacy & Terms