0
\$\begingroup\$

So I'm trying to add a "Rewarded video ad" with the reward being more time to play in the next game. my RewardedAd.cs:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Advertisements;
using UnityEngine.SceneManagement;

public class RewardedAd : MonoBehaviour
{
    public static RewardedAd singleton;

    private void Awake()
    {
        if (singleton == null)
        {
            singleton = this;
        }
        else if (singleton != this)
        {
            Destroy(gameObject);
        }
    }

    public void ShowRewardedAd()
    {
        if (Advertisement.IsReady("rewardedVideo"))
        {
            var options = new ShowOptions { resultCallback = HandleShowResult };
            Advertisement.Show("rewardedVideo", options);

        }
    }

    private void HandleShowResult(ShowResult result)
    {
        switch (result)
        {
            case ShowResult.Finished:
                Debug.Log("The ad was successfully shown.");
                StartCoroutine(NewGameWithTime());
                break;
            case ShowResult.Skipped:
                Debug.Log("The ad was skipped before reaching the end.");
                SceneManager.LoadScene(0);
                break;
            case ShowResult.Failed:
                Debug.LogError("The ad failed to be shown.");
                SceneManager.LoadScene(0);
                break;
        }
    }

    IEnumerator NewGameWithTime()
    {
        Debug.Log("NewGame Started");
        GameOverManager.singleton.GameOverAfterRewardAd();
        SceneManager.LoadScene(1);
        Timer.singleton.AddBonusTime(20);
        Debug.Log("NewGame Ended");
        yield return new WaitForSeconds(1);
    }
}

and my Timer.cs:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.UI;
using System;


public class Timer : MonoBehaviour
{
    public static Timer singleton;
    public Text timeTF;
    private float seconds = 10f;

    private void Awake()
    {

        if (singleton == null)
        {
            singleton = this;
        }
        else if (singleton != this)
        {
            Destroy(gameObject);
        }
    }
    private void Update()
    {
        if (seconds > 0f)
        {
            seconds -= Time.deltaTime;
            TimeSpan timeSpan = TimeSpan.FromSeconds(seconds);
            string timeLeft = string.Format("{0:D2}",timeSpan.Seconds);
            timeTF.text = timeLeft;
            TimeLeftCheck(seconds);
        }
    }

    public void AddBonusTime(float bonusTime)
    {
        seconds += bonusTime;
        Debug.Log("New Timer script:");
        Debug.Log(seconds);
    }

    private void TimeLeftCheck(float _time)
    {
        if (_time < 5)
        {
            //Debug.Log("RunningOutTime sound");
            //SoundManager.singleton.Sound_RunningOutofTime();
        }
        if (_time < 2)
        {
            //Debug.Log("Out of Time sound");
            //SoundManager.singleton.Sound_OutofTime();
        }
        if (_time < 1)
        {
            Debug.Log("Game Over");
            GameOverManager.singleton.GameOver();
        }
    }

The video ad is playing fine and it's resetting my ad counter in my game over manager but I can't seem to figure out how to start the next game with more time (20 seconds to so) but ONLY if they've watched the ad.

Also, I'm still learning so any suggestions or things I can improve, more than happy to take that criticism too!

\$\endgroup\$
1
  • \$\begingroup\$ What does GameOverManager.singleton.GameOverAfterRewardAd(); do? \$\endgroup\$ Commented May 15, 2019 at 2:54

1 Answer 1

0
\$\begingroup\$
IEnumerator NewGameWithTime()
{
    Debug.Log("NewGame Started");
    GameOverManager.singleton.GameOverAfterRewardAd();
    SceneManager.LoadScene(1);
    Timer.singleton.AddBonusTime(20);
    Debug.Log("NewGame Ended");
    yield return new WaitForSeconds(1);
}

The order of events here might not be what you expect:

  1. We ask the SceneManager to unload this scene when the engine is ready to do so, and load the new scene.

    This call doesn't block until the new scene is initialized, so our next line runs right away:

  2. We ask our Timer class for its current singleton member. Because the new scene hasn't loaded and initialized yet, this points to the Timer instance in the current scene.

    So we add 20 seconds of extra time to the scene that we're leaving.

  3. We yield control back to the Unity engine.

    Now it can finish unloading our scene (destroying this object, so it never resumes after the yield return new WaitForSeconds(1); so that might as well have been a yield break;) and loading the new scene.

  4. The Timer instance in the new scene is instantiated and runs its Awake method, setting the singleton member to point at itself - but this is now long after we tried to use it, so it doesn't get the 20 seconds of bonus time.

So, instead, I'd recommend that you create an object whose job it is to carry information between scenes. Let's call it a Bonus Tracker, and we'll create it as a MonoBehaviour so you can use the Inspector to peek at its state and verify it's tracking the data you want. We'll use DontDestroyOnLoad so that it persists between scenes once one exists, and construct it lazily so you don't need to remember to place it in each scene (but we'll check for that case and handle it to be safe).

public class BonusTracker : MonoBehaviour {
    static BonusTracker _instance;

    public BonusTracker GetInstance() {
        if(_instance == null) {
            var go = new GameObject("Bonus Tracker");
            go.AddComponent<BonusTracker>();
        }
        return _instance;
    }

    private void Awake()
    {
        if (_instance == null) {
            _instance = this;
            DontDestroyOnLoad(gameObject);
        } else {
            Destroy(gameObject);
        }
    }

    int _bonusTime = 0;
    public void AddBonusTime(int time) {
        _bonusTime += time;
    }

    public int ClaimBonusTime() {
        int time = _bonusTime;
        _bonusTime = 0;
        return time;
    }
}

Now before we load the next scene we can say:

BonusTracker.GetInstance().AddBonusTime(20);

And when we start a new timer sometime much much later in a different script, it can say:

seconds += BonusTracker.GetInstance().ClaimBonusTime();
\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .