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.
Related
I am trying to make it so when you get in a certain range of the GUI it activates. It was working perfectly when I was testing with Debug.Log("hit") however I changed it to obj.setActive and it stops working. I don't understand why this is?
here's the code:
private void Update()
{
if (IsInRange())
{
canvas.SetActive(true);
} else
{
canvas.SetActive(false);
}
}
private bool IsInRange()
{
origin = canvas.transform.position;
direction = canvas.transform.forward;
Collider[] hitColliders = Physics.OverlapSphere(origin, range, playerLayer);
foreach (var hitCollider in hitColliders)
{
if (hitCollider.name == player.name)
{
playerInRange = true;
playerInRangeF1 = true;
}
else
{
count += 1;
}
}
if (count != hitColliders.Length)
{
return true;
} else
{
return false;
}
}
I have finally figured out the answer to my problem. The script I was running was a component of the game object I was trying to hide and show. When you hide a game object it obviously stops all of its components from working. All I had to do was place the script on an object that would not be hidden.
I have created a Windows Form App for our works Windows Tablets (windows 10) to track location.
The class I have created is below:
class LocationServices
{
private GeoCoordinateWatcher myWatcher;
private bool fgWatcherStarted = false;
public LocationServices()
{
myWatcher = new GeoCoordinateWatcher(GeoPositionAccuracy.High);
fgWatcherStarted = myWatcher.TryStart(true, System.TimeSpan.FromMilliseconds(1000));
}
public LatLon GetDeviceLocation()
{
LatLon myReturn = new LatLon();
System.Device.Location.GeoCoordinate myPosition = new System.Device.Location.GeoCoordinate();
try
{
if (!fgWatcherStarted)
{
fgWatcherStarted = myWatcher.TryStart(true, System.TimeSpan.FromMilliseconds(1000));
}
myPosition = myWatcher.Position.Location;
if (myPosition.IsUnknown)
{
myReturn.Latitude = 0;
myReturn.Longitude = 0;
myReturn.strMessage = "Unknown Position";
}
else
{
myReturn.Latitude = myPosition.Latitude;
myReturn.Longitude = myPosition.Longitude;
myReturn.strMessage = myPosition.Course.ToString();
}
}
catch (Exception ex)
{
myReturn.Latitude = 0;
myReturn.Longitude = 0;
myReturn.strMessage = ex.Message.ToString();
}
return myReturn;
}
}
In my code I am running through every few seconds and getting the location by calling the class above.
If I am connected to wifi (running from my desk) it gets the location instantly and works as expected, but from the device it returns 0 for a significant amount of time and then suddenly starts working and works perfectly fine with no issues.
Is there anything I can do to make this start quicker? I initially thought it could be the location/signal but I have tried loading in the same place and leaving it and once it initialises it works perfectly but it's the initial coordinates that take ages to load.
Looks as though there needs to be a position change for it to return a value, see the answer here: https://stackoverflow.com/a/52910209/6639187
Not quite sure about your way of getting the coordinates, I used to do the following method - hope this helps (run it in a console app and check as follows)
class Program
{
private static GeoCoordinateWatcher Watcher;
static void Main(string[] args)
{
Watcher = new GeoCoordinateWatcher();
Watcher.StatusChanged += Watcher_StatusChanged;
Watcher.Start();
Console.ReadLine();
}
static void Watcher_StatusChanged(object sender, GeoPositionStatusChangedEventArgs e)
{
if (e.Status == GeoPositionStatus.Ready)
{
if (Watcher.Position.Location.IsUnknown)
{
Console.Write("Cannot find location");
}
else
{
Console.WriteLine("Lat: " + Watcher.Position.Location.Latitude.ToString());
Console.WriteLine("Lon: " + Watcher.Position.Location.Longitude.ToString());
}
}
}
}
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;
}
I have this code and after I execute it with a button console every time that prints out that video, it fails. Maybe I just don't know how to enable ads in Unity. I have test mode enabled. This is my code. :
FIXED i just needed to replace this line
public string placementId = "rewardedVideo";
with this:
Advertisement.Show(placementId, options);
private string gameId = "1523603";
void Start(){
Advertisement.Initialize (gameId);
}
public void ShowAd (){
var options = new ShowOptions();
options.resultCallback = HandleShowResult;
Debug.Log (Advertisement.IsReady ("rewardedVideo"));
Advertisement.Show(gameId, options);
}
void HandleShowResult (ShowResult result){
if(result == ShowResult.Finished) {
Debug.Log("Video completed - Offer a reward to the player");
OnemoreTry ();
}else if(result == ShowResult.Skipped) {
Debug.LogWarning("Video was skipped - Do NOT reward the player");
}else if(result == ShowResult.Failed) {
Debug.LogError("Video failed to show");
}
}
I'm currently working with the Raspberry PI 3 with Windows 10 IoT and I'm trying to make the game 'Simon Says' in Visual Studio 2015.
Everything is plugged in as followed:
Fritzing image
I got the LEDs working but I can't really figure out how to detect when a button is being pressed.
Parts of the source code:
Variables
private const int BTNRED = 5;
private const int BTNBLUE = 6;
private const int BTNYELLOW = 13;
private const int BTNGREEN = 19;
private GpioPin _btnRed;
private GpioPin _btnBlue;
private GpioPin _btnYellow;
private GpioPin _btnGreen;
private Random rnd;
private static GpioController _gpioController;
Method to recognize when a button is being pressed.
public static IList<Step> PressedButtons
{
get
{
List<Step> returnVal = new List<Step>();
if (GetMap._btnBlue.Read() == GpioPinValue.High)
{ returnVal.Add(Step.Blue); }
if (GetMap._btnGreen.Read() == GpioPinValue.High)
{ returnVal.Add(Step.Green); }
if (GetMap._btnRed.Read() == GpioPinValue.High)
{ returnVal.Add(Step.Red); }
if (GetMap._btnYellow.Read() == GpioPinValue.High)
{ returnVal.Add(Step.Yellow); }
return returnVal;
}
}
/// <summary>
/// Checks if any of the 4 buttons is pressed.
/// </summary>
/// <returns>Returns false if no button is pressed.</returns>
public static bool isButtonPressed
{
get
{
if (GetMap._btnBlue.Read() == GpioPinValue.Low)
{ return true; }
if (GetMap._btnGreen.Read() == GpioPinValue.Low)
{ return true; }
if (GetMap._btnRed.Read() == GpioPinValue.Low)
{ return true; }
if (GetMap._btnYellow.Read() == GpioPinValue.Low)
{ return true; ; }
return false;
}
}
Assigning the right pins on the GPIO to the corresponding variables
private GPIOMap()
{
rnd = new Random();
_gpioController = GpioController.GetDefault();
if (_gpioController == null) { return; }
_ledRed = _gpioController.OpenPin(LEDRED);
_ledRed.SetDriveMode(GpioPinDriveMode.Output);
_ledYellow = _gpioController.OpenPin(LEDYELLOW);
_ledYellow.SetDriveMode(GpioPinDriveMode.Output);
_ledGreen = _gpioController.OpenPin(LEDGREEN);
_ledGreen.SetDriveMode(GpioPinDriveMode.Output);
_ledBlue = _gpioController.OpenPin(LEDBLUE);
_ledBlue.SetDriveMode(GpioPinDriveMode.Output);
_btnBlue = _gpioController.OpenPin(BTNBLUE);
_btnGreen = _gpioController.OpenPin(BTNGREEN);
_btnRed = _gpioController.OpenPin(BTNRED);
_btnYellow = _gpioController.OpenPin(BTNYELLOW);
}
private static GPIOMap GPIOMapInstance;
public static GPIOMap GetMap
{
get
{
if (GPIOMapInstance == null || _gpioController == null)
{ GPIOMapInstance = new GPIOMap(); }
return GPIOMapInstance;
}
}
Run game, where as you can see it should bring me to state 2 whenever a button is being pressed. However this isn't quite the case as the idle animation keeps on going on.
private void RunGame()
{
while (_isRunning)
{
switch (_state)
{
//Idle state
case (0x01):
//If any button is pressed, start the game.
if (GPIOMap.isButtonPressed)
{
_state = 0x02;
Task.Delay(500).Wait();
GPIOMap.PlayStartAnimation();
Task.Delay(1000).Wait();
break;
}
//If nothing happens, continue playing the idle animation.
GPIOMap.PlayIdleAnimationOnce();
break;
//Playback state
case (0x02):
//Play all the currently existing steps.
for (int i = 0; i <= _gameInstance.TotalSteps; i++)
{ GPIOMap.BlinkLight(_gameInstance.GetNextStep(), 500); }
//Generate and play a new step.
GPIOMap.BlinkLight(_gameInstance.GetNextStep(), 500);
//Switch to the input state.
_state = 0x03;
//Set the start time for the input.
_answerPending = DateTime.UtcNow;
break;
//Input state
case (0x03):
if(_gameInstance.CurrentStep > MAXSTEPS)
{
//Win Game
ResetGame();
break;
}
//If the player waits too long before answering, lose the game.
if ((DateTime.UtcNow - _answerPending) > _timeout)
{
GPIOMap.ConfirmWrongAnswer();
ResetGame();
break;
}
//If there are no more steps to re-trace, go back to playback state.
if (_gameInstance.CurrentStep > _gameInstance.TotalSteps)
{ _gameInstance.ResetSteps(); _state = 0x02; break; }
//If no buttons are pressed, keep polling.
if (!GPIOMap.isButtonPressed) { break; }
IList<Step> pressedButtons = GPIOMap.PressedButtons;
//If anything but one button is pressed, lose the game.
if (pressedButtons.Count != 1)
{
GPIOMap.ConfirmWrongAnswer();
ResetGame();
break;
}
if (_gameInstance.VerifyStep(pressedButtons[0]))
{
GPIOMap.BlinkLight(pressedButtons[0], 500);
}
else//Wrong step, end game
{
GPIOMap.ConfirmWrongAnswer();
ResetGame();
break;
}
break;
}
}
}
How can I get my source code to recognize when a button is being pressed so I can go to the next state which involves getting user input on the buttons.
You can use GPIO ValueChanged to catch the button pressed event like this:
_btnBlue = _gpioController.OpenPin(BTNBLUE);
_btnBlue.ValueChanged += btnValueChanged;
public void btnValueChanged(GpioPin pin, GpioPinValueChangedEventArgs e)
{
if (_btnBlue.Read() == GpioPinValue.Low)
{
isBlueButtonPressed = true;
}
}