Unity play pause audio not working well - c#

I cannot figure out the right code for playing and pausing the audio source in a single button click.
Here is my Code
ButtonAction.GetComponent().onClick.AddListener(delegate
{
if (soundTarget.isPlaying)
{
soundTarget.Pause();
}
else if(!soundTarget.isPlaying)
{
soundTarget.Play();
playSound("sounds/English");
}
});
Note: By default it is not playing because if I play it by default it will just loop around. It is somehow working but I need to click the button multiple times before it plays or pauses.
Help me.

It's quite simple :
Your Unity scene should be something like this :
For the script that I called "UnityUI" is like below :
public AudioSource MyAudioSource;
public Button PlayBtn;
public PlayButtonText;
void Start()
{
PlayBtn.onClick.AddListener(() =>
{
if (MyAudioSource.isPlaying)
{
MyAudioSource.Stop();
PlayButtonText.text = "Play me!";
}
else
{
MyAudioSource.Play();
PlayButtonText.text = "Stop me!";
}
});
}
Hope that this helped!
Happy coding!

My code is supposed to be like this. When the button is clicked it will play the sound and when clicked again it will be paused.
playSound("sounds/English");
soundTarget.Play();
if (soundTarget.isPlaying)
{
soundTarget.Stop();
}
else
{
soundTarget.Play();
}
But this code is just looping around and doesn't play the sound.

void Update()
{
StateManager sm = TrackerManager.Instance.GetStateManager();
IEnumerable<TrackableBehaviour> tbs = sm.GetActiveTrackableBehaviours();
foreach (TrackableBehaviour tb in tbs)
{
string name = tb.TrackableName;
ImageTarget it = tb.Trackable as ImageTarget;
Vector2 size = it.GetSize();
Debug.Log("Active image target:" + name + " -size: " + size.x + ", "
+ size.y);
ButtonAction.gameObject.SetActive(true);
TextDescription.gameObject.SetActive(true);
PanelDescription.gameObject.SetActive(true);
ButtonMute.gameObject.SetActive(true);
if (name == "quezon")
{
ButtonAction.GetComponent<Button>().onClick.AddListener(delegate
{
if (soundTarget.isPlaying)
{
soundTarget.Pause();
btn.image.overrideSprite = Play;
}
else
{
btn.image.overrideSprite = Pause;
playSound("sounds/English");
soundTarget.Play();
}
});
TextDescription.GetComponent<Text>().text = "Manuel L. Quezon was
born on August 19, 1878, and died on August 1, 1944. He was a
Filipino statesman, soldier, and politician who served as president
of the Commonwealth of the Philippines from 1935 to 1944.";
Narrator.gameObject.SetActive(true);
void playSound(string ss)
{
clipTarget = (AudioClip)Resources.Load(ss);
soundTarget.clip = clipTarget;
soundTarget.loop = false;
soundTarget.playOnAwake = false;
soundTarget.ignoreListenerPause = true;
}

Related

Unity Instantiated gameobject does not run function unless it is the most recently Instantiated object. Why might that be happening and how to fix it?

So, I have a series of gameobject instances all with a script on them. When i select one of these instances a black circle appears AND a UI element should be instantiated with some stats.
It works if there is only one instance of the gameobject without any issues.
When more object are added and selection changed from one to the other, the circle works perfectly fine, but the UI instantiate only works for the most recently instantiated of the objects.
Here is the code:https://hatebin.com/oihkmmbmeq
This is the function on the Tower(the object that has more instances):
private void Selected_Change()
{
if (IsSelected)
{
line.enabled = true;
GameObject.FindGameObjectWithTag("UI").GetComponent<UI>().Spawn_Tower_Panel(this.gameObject, 150, "Radius: " + XRad + "\nValue: " + 150 + "\nRotSpeed: " + 7f + "\nDamage: " + Damage + "\n UpPrice" + UpPrice);
}
else
{
line.enabled = false;
GameObject.FindGameObjectWithTag("UI").GetComponent<UI>().Despawn_Tower_Panel();
}
}
And this is the code in the UI script:
public void Spawn_Tower_Panel(GameObject tower,int Value, string Stats)
{
Tower_Panel_Inst = Instantiate(Tower_Panel, Tower_Panel.transform.position, Tower_Panel.transform.rotation);
Tower_Panel_Inst.transform.SetParent(this.transform, false);
Selected_Object = tower;
Tower_Panel_Inst.transform.Find("TowerTypeBackground").transform.Find("TowerType").GetComponent<Text>().text = tower.name.Remove(tower.name.Length - 7);
Tower_Panel_Inst.transform.Find("Values_Stuff").GetComponent<Text>().text = Stats;
TempInt = Value;
}
public void Despawn_Tower_Panel()
{
Destroy(Tower_Panel_Inst);
}
public void Scrap_Tower()
{
TempInt = Mathf.RoundToInt(TempInt * 0.5f);
CreditsChange(TempInt);
Destroy(Tower_Panel_Inst);
Destroy(Selected_Object);
TempInt = 0;
}
public void Upgrade_Tower()
{
if(Selected_Object.name == "Tower_Cannon(Clone)")
{
int temp = Selected_Object.GetComponent<Tower_Cannon>().Upgrade_Price();
if(Materials - temp > 0)
{
CreditsChange(-temp);
Selected_Object.GetComponent<Tower_Cannon>().Upgrade();
}
Destroy(Tower_Panel_Inst);
}
}
https://youtu.be/JN1IgFd_qyU This is a video that shows what happens, and what the problem is.
Thank you for taking the time to look into this

Game objects scaling up when transform.parent set to null

I'm working on a small game where objects are put in a boat, then a key press makes the boat "sail".
To move all the objects that are standing on the boat, i am setting the parent of each object to an empty guide object in the boat then changing the position of the boat. (I have also tried parenting the objects into the boat object itself)
The following is a script applied to the boat object.
variables set in the BoatScript class:
public class BoatScript : MonoBehaviour {
public List<string> boatList;
public KeyCode interact;
public GameObject tempObject;
public string whichSide;
public string direction;
public bool canSail;
}
Start and Update method:
void Start () {
canSail = false;
whichSide = "start";
direction = "toFinish";
speed = 0f;
}
void Update () {
if (canSail == true)
{
SetSail();
}
if (boatList.Contains("FARMER") && whichSide == "start" && Input.GetKeyDown(interact))
{
speed = 0.5f;
CharacterCheck();
}
else if (boatList.Contains("FARMER") && whichSide == "finish" && Input.GetKeyDown(interact))
{
speed = -0.05f;
CharacterCheck();
}
}
Here are my OnTrigger methods:
void OnTriggerEnter(Collider other)
{
Debug.Log(other.gameObject.name + " collided with " + gameObject.name);
promptText.text = "";
if(CheckValidObject(other.gameObject.name) == true) {
boatList.Add(other.gameObject.name);
logBox.text = logBox.text + "\nThe " + other.gameObject.name + " is in the boat";
}
if (other.gameObject.name == "FARMER")
{
promptText2.text = "Press E to set sail";
}
}
void OnTriggerExit(Collider other)
{
boatList.Remove(other.gameObject.name);
logBox.text = logBox.text + "\nThe " + other.gameObject.name + " has left the boat";
promptText.text = "";
if (other.gameObject.name == "FARMER")
{
promptText2.text = "";
}
}
Setting sail:
void SetSail()
{
promptText.text = "";
promptText2.text = "";
addParents();
if (whichSide == "sailing" && direction == "toFinish")
{
speed = 0.05f;
gameObject.transform.Translate(speed, 0, 0);
}
else if (whichSide == "sailing" && direction == "toStart")
{
speed = -0.05f;
gameObject.transform.Translate(speed, 0, 0);
}
else if (whichSide == "start" || whichSide == "finish")
{
gameObject.transform.Translate(speed, 0, 0);
removeParents();
}
}
void addParents()
{
foreach(string o in boatList)
{
GameObject obj = GameObject.Find(o);
obj.GetComponent<Rigidbody>().useGravity = false;
obj.GetComponent<Rigidbody>().isKinematic = true;
if (obj.name == "FARMER") { obj.transform.parent = playerGuide.transform; }
else {obj.transform.parent = itemGuide.transform; }
}
}
void removeParents()
{
foreach (string o in boatList)
{
GameObject obj = GameObject.Find(o);
obj.GetComponent<Rigidbody>().useGravity = true;
if(obj.name != "FARMER") {obj.GetComponent<Rigidbody>().isKinematic = false; }
obj.transform.parent = null;
}
}
The problem: Once the boat reaches and hits the collider for the other side, the boat stops as expected but the objects that were just removed from the parent begin to scale up continuously like this:
e.g 1 https://i.gyazo.com/d35ae729757b8e71c25fd1b4a3857dae.mp4
e.g 2 https://i.gyazo.com/80637919bfd114a42d187300b7faef25.mp4
I'm not too sure what is causing this. Any help is much appreciated, thank you.
Instead of setting the parent via transform.parent, use transform.SetParent(targetTransform, false);. The second, bool, parameter determines if the game object's transform will maintain it's position, orientation, and scale. By setting it to false, the transform will maintain it's current values, while setting it to true will modify the position, orientation, and scale to maintain the world position. You can check this for further info transform.SetParent
Are youu sure it is scaling up and not moving up in the Z axes? From what im looking it is going towards the camera but not scaling up. You should debug the position and scale in the update method to see whats really happening there.
Below comment: "Well then you will have to debug it more carefully, i would first try, setting canSail to false as soon as it reaches the end. Perhaps the method addParent which is always being executed is wrong, what does the object itemGuide does? edit: i just seen the second video, from my perspective that seems gravity, what you meant with problems with scaling up is because its moving out from the boat?"
Solution:
void SetSail()
{
promptText.text = "";
promptText2.text = "";
addParents();
if (whichSide == "sailing" && direction == "toFinish")
{
speed = 0.05f;
gameObject.transform.Translate(speed, 0, 0);
}
else if (whichSide == "sailing" && direction == "toStart")
{
speed = -0.05f;
gameObject.transform.Translate(speed, 0, 0);
}
else if (whichSide == "start" || whichSide == "finish")
{
gameObject.transform.Translate(speed, 0, 0);
canSail = false; //Adding this line solves the issues, must have been affecting transform properties to child objects.
removeParents();
}
}

(Monogame) Update method causes extreme lag

I am currently creating a 2d platformer in monogame.
I created a block that, when hit by the player, starts dissapearing. When it dissapears, i draw a rectangle around it. Every Tile of the same type (BrittleTile) also starts dissapearing, untill the entire connected mob of BrittleTiles has dissapeared.
The problem is that for every BrittleTile that is destroyed, my game runs noticably slower, until it becomes a slideshow after 10 or so BrittleTiles destroyed. I have no idea as to what may cause this, i've been trying to ease the Update method of the class but nothing seems to help.
Any idea as to what may cause this?
class BrittleTile: Tile, IIncludeSound
{
public Rectangle DestroyedCheckRectangle;
private BrittleTile brittle;
private bool _isPlayed;
private bool _hasBroken;
private SoundEffect _sfxBreak;
private SoundEffectInstance _sfxiBreak;
private TimeSpan _breakTimer = new TimeSpan();
public Rectangle BrokenViewRectangle { get; set; }
private bool _isBreaking = false;
public BrittleTile(Texture2D texture, Rectangle baseViewRectangle, Rectangle brokenViewRectangle):base(texture, baseViewRectangle, true )
{
this.BrokenViewRectangle = brokenViewRectangle;
this.ViewRectangle = baseViewRectangle;
}
public void Update(GameTime gameTime, Hero hero, Entity[,] grid)
{
if (!this._hasBroken)
{
if (!this._isBreaking && !this._hasBroken && this.hasCollision)
_checkCollision(hero, grid);
if (this._isBreaking)
{
if (!this._isPlayed)
_sfxiBreak.Play();
this._isPlayed = true;
this._breakTimer += gameTime.ElapsedGameTime;
if (this._breakTimer.TotalMilliseconds < 250)
this.GhostMode(gameTime);
else
{
this._isBreaking = false;
this.hasCollision = false;
this._breakTimer -= this._breakTimer;
}
}
else
{
if (!this.hasCollision && this.DestroyedCheckRectangle.Width == 0)
{
this.DestroyedCheckRectangle.X = this.DestinationRectangle.X - 10;
this.DestroyedCheckRectangle.Y = this.DestinationRectangle.Y - 10;
this.DestroyedCheckRectangle.Height = this.DestinationRectangle.Height + 20;
this.DestroyedCheckRectangle.Width = this.DestinationRectangle.Width + 20;
this._hasBroken = true;
}
}
}
}
public override void Draw(SpriteBatch spriteBatch)
{
spriteBatch.Draw(this.Texture, this.DestinationRectangle, this.BrokenViewRectangle, Color.White);
if (this.hasCollision)
spriteBatch.Draw(this.Texture, this.DestinationRectangle, this.ViewRectangle, Color.White * this.GhostDraw * 0.9f);
spriteBatch.Draw(this.Texture, DestroyedCheckRectangle, new Rectangle(1, 1, 1, 1), Color.Yellow);
Console.WriteLine(this.DestroyedCheckRectangle.X + ", " + this.DestroyedCheckRectangle.Y + ", " + this.DestroyedCheckRectangle.Width + ", " + this.DestroyedCheckRectangle.Height);
}
private void _checkCollision(Hero hero, Entity[,] grid)
{
if (this.DestinationRectangle.Intersects(hero.AttackHitBox))
{
this._isBreaking = true;
}
foreach (Shuriken star in hero.Stars)
{
if (this.DestinationRectangle.Intersects(star.DestinationRectangle))
this._isBreaking = true;
}
foreach (Entity entityObject in grid)
{
if (hasCollision && entityObject.GetType() == typeof(BrittleTile)){
brittle = entityObject.DeepCopy() as BrittleTile;
if (this.DestinationRectangle.Intersects(brittle.DestroyedCheckRectangle))
this._isBreaking = true;
}
}
}
override public void LoadSounds(ContentManager content)
{
this._sfxBreak = content.Load<SoundEffect>("SFX/brittleBreak");
_sfxiBreak = _sfxBreak.CreateInstance();
_sfxiBreak.Volume = 0.2f;
}
}
First, this line:
if (!this._isBreaking && !this._hasBroken && this.hasCollision)
the !this._hasBroken is superfluous.
My first warning sign is this line:
brittle = entityObject.DeepCopy() as BrittleTile;
I assume DeepCopy() makes a new version of the object, and copies all it's properties, right? Seeing the code of that might help pin it down, but on that assumption...
For every Tile, you're cycling through every object in you're grid and you're completely duplicating that object as a BrittleTile, why?
My first change would be to modify that foreach to have this within it:
var brittle = entityObject as BrittleTile
if (brittle != null && hasCollision){
if (this.DestinationRectangle.Intersects(brittle.DestroyedCheckRectangle))
this._isBreaking = true;
}
}
Not sure this is the primary cause of the slowdown, but it is definitely an issue. If you're cloning an object and then immediately throwing an object away, you're almost certainly doing something wrong. If you're cloning an object and you're not editing the properties of that copy at all (and using those edits), you're definitely doing something wrong. I'd be wary before using a method like that unless you're really sure that's what you want.

How to stop auto fetching/loading of ads from UnityAds and Vungle?

I'm using both Unity Ads and Vungle to my game. I installed them using their .unitypackage.
I already finished the codes for displaying ads from them alternately. My problem now is how to stop them from fetching/loading after closing their 1st ads? Or have the option to stop the fetching while it fetches.
It make my game crashes due to memory pressure since 2 ads are already in the memory plus the resources for my game.
I browsed the source codes and can't find any API to stop fetching or unload a waiting-to-be-displayed ads. I looked on their documentations but there's no detail to do that.
Here is my current code:
using UnityEngine;
using System.Collections;
using UnityEngine.Advertisements;
public class AdsMngr : MonoManager<AdsMngr> {
enum AdsEngine{
VUNGLE,
UNITY_ADS,
MAXNUM
};
enum AdsStatus{
IDLE,
WAITING,
SHOWING,
MAXNUM
}
AdsEngine m_curAdsEngine = AdsEngine.UNITY_ADS;
AdsStatus m_curAdsStatus = AdsStatus.IDLE;
#if UNITY_IPHONE || UNITY_ANDROID
protected override void Awake(){
base.Awake ();
m_curAdsEngine = AdsEngine.UNITY_ADS; //VUNGLE;
SetupAdsCallback ();
}
protected override void OnDestroy(){
base.OnDestroy();
UnsetupAdsCallback();
}
void SetNextAdEngine (){
m_curAdsEngine = (AdsEngine)((int)(m_curAdsEngine + 1) % (int)AdsEngine.MAXNUM);
}
void Update(){
if (m_curAdsStatus == AdsStatus.WAITING) {
Debug.Log ("Waiting for ads to load: "+m_curAdsEngine+"\n");
bool bHasReadyAds = false;
switch(m_curAdsEngine){
case AdsEngine.VUNGLE: if( Vungle.isAdvertAvailable()){bHasReadyAds = true;} break;
case AdsEngine.UNITY_ADS: if( Advertisement.isReady() ){bHasReadyAds = true;} break;
}
if (bHasReadyAds) {
LoadingOverlay.Instance.Close();
PromptOverlay.Instance.Close();
ShowAd ();
}
}
}
public void StartAd(){
LoadingOverlay.Instance.Open();
//---start refetching/recaching the ads here
switch(m_curAdsEngine){
case AdsEngine.VUNGLE: {
Vungle.init( "mygame_forAndroid", "mygame_forIOS" );
}break;
case AdsEngine.UNITY_ADS: {
if (Advertisement.isSupported) {
//Advertisement.allowPrecache = true;
Advertisement.Initialize ("12345", true);
Debug.Log("Advertisement Initialized.\n");
} else {
Debug.Log("Platform not supported\n");
}
}break;
}
m_curAdsStatus = AdsStatus.WAITING;
}
public void StopWaitingAds(){
m_curAdsStatus = AdsStatus.IDLE;
//TODO: cancel the loading of ads.
//xxx: test code only
SetNextAdEngine ();
}
public void ShowAd(){
switch(m_curAdsEngine){
case AdsEngine.VUNGLE: {
Debug.Log("*** Vungle Ads is available. Now playing...\n");
Vungle.playAd();
Vungle.setSoundEnabled(false);
}break;
case AdsEngine.UNITY_ADS: {
Debug.Log("*** Unity Ads is available. Now playing...\n");
Advertisement.Show(null, new ShowOptions {
pause = true,
resultCallback = result => {
Debug.Log(result.ToString());
onAdEndedEvent();
}
});
}break;
}
m_curAdsStatus = AdsStatus.SHOWING;
}
#region Optional: Example of Subscribing to All Events
void SetupAdsCallback()
{
Vungle.onAdStartedEvent += onAdStartedEvent;
Vungle.onAdEndedEvent += onAdEndedEvent;
Vungle.onAdViewedEvent += onAdViewedEvent;
Vungle.onCachedAdAvailableEvent += onCachedAdAvailableEvent;
}
void UnsetupAdsCallback()
{
Vungle.onAdStartedEvent -= onAdStartedEvent;
Vungle.onAdEndedEvent -= onAdEndedEvent;
Vungle.onAdViewedEvent -= onAdViewedEvent;
Vungle.onCachedAdAvailableEvent -= onCachedAdAvailableEvent;
}
void onAdStartedEvent()
{
Debug.Log( "onAdStartedEvent" );
}
void onAdEndedEvent()
{
Debug.Log( "onAdEndedEvent" );
EndGameRewardOverlay.Instance.SetMultiplier(2);
EndGameRewardOverlay.Instance.Open();
if (m_curAdsEngine == AdsEngine.VUNGLE) {
Vungle.setSoundEnabled(true);
}
m_curAdsStatus = AdsStatus.IDLE;
SetNextAdEngine();
}
void onAdViewedEvent( double watched, double length )
{
Debug.Log( "onAdViewedEvent. watched: " + watched + ", length: " + length );
}
void onCachedAdAvailableEvent()
{
Debug.Log( "onCachedAdAvailableEvent" );
}
#endregion
#endif
}
Unity Ads and Vungle handle Ad Cacheing them self and there is not way to stop it. It is done as both networks show video Ads and video Ads take time to buffer if not pre cached before displaying.

Dart Scoring Game Using C# Visual Studio 2010 - Alternating player score after evey 3rd score

Just bought a dartboard and thought to create a little scoring application, so far i have set up the player names and individual buttons to start the game. three games - 301, 501 and 1001, these are the targets scores to get to zero by throwing three darts each in turn by two players.
I have included many buttons for the score of each dart from 20 down to 1, each for single, double, triple, bull, outer bull and a no score button. Once the games starts the first three button presses should be attributed to player one then the following three buttons pressed to allocate the corresponding score to player 2. The games ends with the winning player achieving the target score (or whittles it down to zero).
I could have a player selection button to do this but was after some tips on a way of coding the alternate pattern of scoring to be automatic.
Any help greatly appreciated. Thank you
namespace dbstats
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
btnPlay.Visible = false;
btnReset.Visible = false;
btnUndo.Visible = false;
gbDartBoard.Visible = false;
gbScoreBoard.Visible = false;
lbP1Select.Visible = false;;
lbP2Select.Visible = false;
cmbP1.Visible = false;
cmbP2.Visible = false;
string[] lines = File.ReadAllLines(#"playerStats.csv");
foreach (var line in lines)
{
string[] names = line.Split(',');
if (names[0] != "NAME")
{
cmbP1.Items.Add(names[0]);
cmbP2.Items.Add(names[0]);
}
}
}
private void tsm301_Click(object sender, EventArgs e)
{
lbP1Select.Visible = true;
cmbP1.Visible = true;
lbP2Select.Visible = true;
cmbP2.Visible = true;
btnPlay.Visible = true;
tbPlayer1.Text = "301";
tbPlayer2.Text = "301";
gamesToolStripMenuItem.Visible = false;
manageToolStripMenuItem.Visible = false;
}
private void btnPlay_Click(object sender, EventArgs e)
{
if (cmbP1.SelectedItem == cmbP2.SelectedItem || cmbP1.SelectedItem == null || cmbP2.SelectedItem == null)
{
MessageBox.Show("Make Sure:" + "\n\n"
+ "The Players are NOT the same." + "\n"
+ "&" + "\n"
+ "At least one selection is NOT left blank", "Choose Again!");
}
else
{
lbP1Select.Visible = false;
cmbP1.Visible = false;
lbP2Select.Visible = false;
cmbP2.Visible = false;
btnPlay.Visible = false;
lbPlayer1.Text = cmbP1.SelectedItem.ToString();
lbPlayer2.Text = cmbP2.SelectedItem.ToString();
btnReset.Visible = true;
btnUndo.Visible = true;
gbDartBoard.Visible = true;
gbScoreBoard.Visible = true;
lbPlayer1.Visible = true; ;
lbPlayer2.Visible = true;
}
}
}
Keep a turnsEntered member variable to whatever class is managing turns/scoring.
// Call after every time a new score is entered. Start at 0.
turnsEntered++;
if (turnsEntered % 3 == 0)
{
SwitchPlayer(); // However you keep track of current player - switch here
}
After the 3rd score is entered it will switch players...after 3 more it will switch again, etc...
You can later check turnsEntered to determine when the game is over. Set it back to zero when you reinitialize for a new game.

Categories