I'm having a weird issue where any input is not being triggered 'at all'.
Pulling my hairs out; can't find out where this is wrong.
Result is that nothing is being written; although all things are set.
In the input asset I have added the 'Interact' and 'Application Quit' entries.
Anyone could have a glimpse of what's wrong here ?
public class InputManager : MonoBehaviour
{
[SerializeField] private InputActionAsset _actions;
public InputActionAsset actions
{
get => _actions;
set => _actions = value;
}
private InputAction quitInputAction { get; set; }
private InputAction interactInputAction { get; set; }
private void OnEnable()
{
quitInputAction?.Enable();
interactInputAction?.Enable();
Setup();
}
private void Setup()
{
interactInputAction = actions.FindAction("Interact");
if (interactInputAction != null)
{
interactInputAction.started += OnInteract;
interactInputAction.performed += OnInteract;
interactInputAction.canceled += OnInteract;
}
else
{
Debug.LogError("Missing Interact Binding");
}
quitInputAction = actions.FindAction("Application Quit");
if (quitInputAction != null)
{
quitInputAction.started += OnAppQuit;
quitInputAction.performed += OnAppQuit;
quitInputAction.canceled += OnAppQuit;
}
else
{
Debug.LogError("Missing Application Quit Binding");
}
}
protected virtual void OnAppQuit(InputAction.CallbackContext context)
{
if (context.started || context.performed)
{
Debug.Log("Quit");
Application.Quit();
}
else if (context.canceled)
Debug.Log("Application Quit Cancelled");
}
protected virtual void OnInteract(InputAction.CallbackContext context)
{
if (context.started || context.performed)
{
Debug.Log("Interact");
}
else if (context.canceled)
Debug.Log("Application Quit Cancelled");
}
}
You need to run your setup before attempting to enable them:
private void OnEnable()
{
Setup();
quitInputAction?.Enable();
interactInputAction?.Enable();
}
Source: Disco Fever
Related
When calling GetComponent() just after my program starts up, I find that the method sometimes does not return a component quickly enough to prevent a null reference exception when code later tries to access the component member variable. My question is - is there a way to wait for GetComponent to finish finding what it needs to? I know can wait using coroutines, but is there another way to do this with some kind of lambda callback or event?
public class GameManager : MonoBehaviour
{
public bool AutosaveEnabled = true;
public static GameManager Instance;
[HideInInspector] public InputManager InputManager;
[HideInInspector] public UIManager UIManager;
...
private void Awake()
{
Setup();
}
public void Setup()
{
if (Instance == null)
{
Instance = this;
}
else
{
throw new Exception();
}
UIManager = GetComponent<UIManager>();
...
UIManager.Setup();
...
}
public class UIManager : StateMachine, IUIManager
{
public static UIManager Instance;
public ITitleMenu TitleMenu;
public void Setup()
{
if (Instance == null)
{
Instance = this;
}
else
{
throw new Exception();
}
TitleMenu = GetComponentInChildren<ITitleMenu>();
}
private void SetupScene()
{
UIManager.Instance.ChangeState<TitleMenuState>();
}
...
}
public interface ITitleMenu : IMenu
{
void ExitGame();
void LoadTitleMenuScene();
void OnNewGameClick();
}
public interface IMenu
{
public void Setup(IUIManager uiManager);
public void SetActive(bool toggle);
int selectedIndex { get; set; }
int previouslySelectedIndex { get; set; }
TextMeshProUGUI[] Options { get; set; }
void OnControllerMoveDown();
void OnControllerMoveUp();
void OnControllerConfirm();
}
public class TitleMenu : MenuBase, ITitleMenu
{
private enum MenuElements { Continue, NewGame, Controls, VideoSettings, AudioSettings, ExitGame };
public void Setup(IUIManager uiManager)
{
this.uiManager = uiManager;
DataManager.Instance.SaveFileMetadata = GameManager.Instance.SaveFileManager.GetSaveFileMetadata();
if (DataManager.Instance.SaveFileMetadata.Count > 0)
{
Options[(int)MenuElements.Continue].transform.parent.gameObject.SetActive(true);
selectedIndex = (int)MenuElements.Continue;
}
else
{
Options[(int)MenuElements.Continue].transform.parent.gameObject.SetActive(false);
selectedIndex = (int)MenuElements.NewGame;
}
previouslySelectedIndex = selectedIndex;
}
...
}
public class StateMachine : MonoBehaviour, IStateMachine
{
public virtual State CurrentState
{
get
{
return _currentState;
}
set
{
if (_currentState == value)
{
return;
}
if (_currentState != null)
{
_currentState.Exit();
}
_currentState = value;
if (_currentState != null)
{
_currentState.Enter();
}
}
}
protected State _currentState;
public virtual T GetState<T>() where T : State
{
T target = GetComponent<T>();
if (target == null)
{
target = gameObject.AddComponent<T>();
target.Initialize();
}
return target;
}
}
...
public class TitleMenuState : UIState
{
protected override void OnMove(object sender, InfoEventArgs<Vector2> e)
{
if (e.info.y == 1)
{
owner.TitleMenu.OnControllerMoveUp();
}
else if (e.info.y == -1)
{
owner.TitleMenu.OnControllerMoveDown();
}
}
protected override void OnInteract(object sender, EventArgs e)
{
owner.TitleMenu.OnControllerConfirm();
}
public override void Enter()
{
owner.TitleMenu.SetActive(true);
owner.TitleMenu.Setup(owner);
EventManager.UIMoveEvent += OnMove;
EventManager.UISubmitEvent += OnInteract;
}
public override void Exit()
{
UIManager.Instance.TitleMenu.SetActive(false);
EventManager.UIMoveEvent -= OnMove;
EventManager.UISubmitEvent -= OnInteract;
}
}
public abstract class State : MonoBehaviour
{
public virtual void Enter()
{
}
public virtual void Exit()
{
}
public virtual void Initialize()
{
}
}
public abstract class UIState : State
{
protected UIManager owner;
public override void Initialize()
{
owner = UIManager.Instance;
}
protected virtual void OnInteract(object sender, EventArgs e)
{
}
protected virtual void OnCancel(object sender, EventArgs args)
{
}
public override void Enter()
{
}
public override void Exit()
{
}
protected virtual void OnMove(object sender, InfoEventArgs<Vector2> e)
{
}
public virtual bool IsStateOfType(UIStates state)
{
return false;
}
}
Right now the game crashes in TitleMenuState.Enter() where I'm calling owner.TitleMenu.SetActive() because TitleMenu is null.
Hierarchy:
At the time TitleMenu = GetComponentInChildren<ITitleMenu>(); is run in the UIManager component of the GameManager gameobject, the child gameobject TitleMenu is inactive, and that child is what has the ITitleMenu on it. And, from the documentation on GetComponentInChildren (emphasis mine):
Returns the component of Type type in the GameObject or any of its children using depth first search.
A component is returned only if it is found on an active GameObject.
So that will return null. This has nothing to do with failing to return "quickly enough".
A very simple workaround is to use GetComponentsInChildren, which has an optional includeInactive parameter that will allow for searching inactive objects. Using GetComponentsInChildren, with includeInactive as true should have the desired result, only needing to index the first element (since it returns an array):
public class UIManager : StateMachine, IUIManager
{
public static UIManager Instance;
public ITitleMenu TitleMenu;
public void Setup()
{
if (Instance == null)
{
Instance = this;
}
else
{
throw new Exception();
}
TitleMenu = GetComponentsInChildren<ITitleMenu>(true)[0];
}
You should call GetComponent() before using the component. You could also check out Script Execution order menu (Edit - Project Settings - Script Execution order)
I'm trying to develop a warning if I try to connect to a specific SSID and some waiting time has passed. I've tried with a Timer class but there is some issues with Task and Threads I can't resolve.
This is my Wifi class in Xamarin.Droid
public class Wifi : Iwifi
{
private Context context;
private static WifiManager _manager;
private MyReceiver _receiver;
public void Initialize()
{
context = Android.App.Application.Context;
_manager = (WifiManager)context.GetSystemService(Context.WifiService);
_receiver = new MyReceiver();
}
public void Register()
{
IntentFilter intents = new IntentFilter();
intents.AddAction(WifiManager.ScanResultAction);
intents.AddAction(WifiManager.NetworkStateChangedAction);
context.RegisterReceiver(_receiver, intents);
}
public void Unregister()
{
context.UnregisterReceiver(_receiver);
}
public void ScanWirelessDevices()
{
_manager.StartScan();
}
public string GetConnectionSSID()
{
return _manager.ConnectionInfo.SSID;
}
public void ConnectToSSID(string SSID, string pwd)
{
if (!_manager.IsWifiEnabled)
{
_manager.SetWifiEnabled(true);
}
WifiConfiguration wifiConfiguration = new WifiConfiguration();
wifiConfiguration.Ssid = '"' + SSID + '"';
if (pwd.Empty)
{
wifiConfiguration.AllowedKeyManagement.Set((int)KeyManagementType.None);
}
else
{
//Configuration for protected Network
}
var addNet = _manager.AddNetwork(wifiConfiguration);
if (addNet == -1)
{
_manager.Disconnect();
_manager.EnableNetwork(addNet, true);
_manager.Reconnect();
return;
}
var list = _manager.ConfiguredNetworks;
foreach (WifiConfiguration conf in list)
{
if (conf.Ssid.Equals('"' + SSID + '"'))
{
_manager.Disconnect();
_manager.EnableNetwork(conf.NetworkId, true);
_manager.Reconnect();
return;
}
}
}
public class MyReceiver : BroadcastReceiver
{
public override void OnReceive(Context context, Intent intent)
{
if (intent.Action.Equals(WifiManager.ScanResultAvailableAction))
{
IList<ScanResult> scanResult = _manager.ScanResult;
App.Networks.NetworksList.Clear();
foreach (ScanResult result in scanResult)
{
App.Networks.NetworksList.Add(result.Ssid);
}
}
}
}
}
Then this is a part of App class in Xamarin.Forms
public partial class App: Application
{
private static ...
.
.
.
private static string _selectedSSID;
private static MainDetail _pageDetail;
public static IWifi WifiManager { get; } = DependencyService.Get<Iwifi>();
public static string SelectedSSID { get { return _selectedSSID; } set { _selectedSSID = value; } }
public static MainDetail PageDetail { get { return _pageDetail; } }
public App()
{
InitializeComponent();
WifiManager.Initialize();
WifiManager.Register();
InitViews();
MainPage = _mainPage;
Connectivity.ConnectivityChanged += NetworkEvents;
NetSearch();
}
.
.
.
public void NetSearch()
{
Task.Run(async () =>
{
while (true)
{
WifiManager.ScanWirelessDevices();
await Task.Delay(Utility.SCAN_WIFI_TIMER); //waiting 31000 milliseconds because of Scanning throttling
}
});
}
public void NetworkEvents(object sender, ConnectivityChangedEventArgs e)
{
MainMaster master = (MainMaster)_mainPage.Master;
if (e.NetworkAccess == NetworkAccess.Unknown)
{
Debug.WriteLine("Network Access Unknown " + e.ToString());
}
if (e.NetworkAccess == NetworkAccess.None)
{
Debug.WriteLine("Network Access None " + e.ToString());
}
if (e.NetworkAccess == NetworkAccess.Local)
{
Debug.WriteLine("Network Access Local " + e.ToString());
}
if (e.NetworkAccess == NetworkAccess.Internet)
{
if(selectedSSID == Wifimanager.GetConnectionInfo())
{
//WE CONNECTED!!
//Now I want to stop the Timeout Timer to attempt
}
}
if (e.NetworkAccess == NetworkAccess.ConstrainedInternet)
{
Debug.WriteLine("Network Access Constrainde Internet " + e.ToString());
}
}
}
And part of Detail page class in which I start the event of connection and where I want to start also the timeout timer
public partial class MainDetail : ContentPage
{
.
.
.
public void OnItemListClicked(object sender, SelectedItemChangedEventArgs e)
{
if (e.SelectedItem == null)
{
return;
}
ImageCell item = (ImageCell)e.SelectedItem;
App.SelectedSSID = item.Text;
App.WifiManager.ConnectToSSID(item.Text, "");
ActivityIndicator(true);
//Now the timer should start.
//And call PageDetail.ActivityIndicator(false) and warning the user if the timeout go to 0.
listView.SelectedItem = null;
}
}
I tried with the Timers Timer class but doesn't work.. any suggestion?
Ok I figured a solution! Instead of using Thread and Task, I used Device.StartTimer.
In the event on the DetailPage I wrote:
public void OnItemListClicked(object sender, SelectedItemChangedEventArgs e)
{
if (e.SelectedItem == null)
{
return;
}
ImageCell item = (ImageCell)e.SelectedItem;
App.SelectedSSID = item.Text;
App.WifiManager.ConnectToSSID(item.Text, "");
ActivityIndicator(true);
Device.StartTimer(TimeSpan.FromSeconds(10), () => //Waiting 10 second then if we are not connected fire the event.
{
Device.BeginInvokeOnMainThread(() =>
{
if (App.IsLogout) //variable I use to check if I can do the logout or not
{
ActivityIndicator(false);
App.SelectedSSID = "";
//My message to users "Fail to connect"
}
});
return false;
});
listView.SelectedItem = null;
}
Ok, so I found an open source script for Unity and it kinda don't want to be friends with the new input system. I have no idea how to replace InputActionAssetReference
If somebody helps - thank you. The errors are: Assets\Input\InputMaster.cs(7,28): error CS0246: The type or namespace name 'InputActionAssetReference' could not be found (are you missing a using directive or an assembly reference?) and Assets\Input\InputMaster.cs(50,26): error CS0115: 'InputMaster.MakePrivateCopyOfActions()': no suitable method found to override
I'd really like the help because I want to use this 2D platformer controller. The script:
using System;
using UnityEngine;
using UnityEngine.InputSystem;
[Serializable]
public class InputMaster : InputActionAssetReference
{
public InputMaster()
{
}
public InputMaster(InputActionAsset asset)
: base(asset)
{
}
[NonSerialized] private bool m_Initialized;
private void Initialize()
{
// Player
m_Player = asset.GetActionMap("Player");
m_Player_Movement = m_Player.GetAction("Movement");
m_Player_Jump = m_Player.GetAction("Jump");
m_Player_Dash = m_Player.GetAction("Dash");
m_Player_Interact = m_Player.GetAction("Interact");
m_Player_AttackA = m_Player.GetAction("Attack A");
m_Initialized = true;
}
private void Uninitialize()
{
if (m_PlayerActionsCallbackInterface != null)
{
Player.SetCallbacks(null);
}
m_Player = null;
m_Player_Movement = null;
m_Player_Jump = null;
m_Player_Dash = null;
m_Player_Interact = null;
m_Player_AttackA = null;
m_Initialized = false;
}
public void SetAsset(InputActionAsset newAsset)
{
if (newAsset == asset) return;
var PlayerCallbacks = m_PlayerActionsCallbackInterface;
if (m_Initialized) Uninitialize();
asset = newAsset;
Player.SetCallbacks(PlayerCallbacks);
}
public override void MakePrivateCopyOfActions()
{
SetAsset(ScriptableObject.Instantiate(asset));
}
// Player
private InputActionMap m_Player;
private IPlayerActions m_PlayerActionsCallbackInterface;
private InputAction m_Player_Movement;
private InputAction m_Player_Jump;
private InputAction m_Player_Dash;
private InputAction m_Player_Interact;
private InputAction m_Player_AttackA;
public struct PlayerActions
{
private InputMaster m_Wrapper;
public PlayerActions(InputMaster wrapper) { m_Wrapper = wrapper; }
public InputAction #Movement { get { return m_Wrapper.m_Player_Movement; } }
public InputAction #Jump { get { return m_Wrapper.m_Player_Jump; } }
public InputAction #Dash { get { return m_Wrapper.m_Player_Dash; } }
public InputAction #Interact { get { return m_Wrapper.m_Player_Interact; } }
public InputAction #AttackA { get { return m_Wrapper.m_Player_AttackA; } }
public InputActionMap Get() { return m_Wrapper.m_Player; }
public void Enable() { Get().Enable(); }
public void Disable() { Get().Disable(); }
public bool enabled { get { return Get().enabled; } }
public InputActionMap Clone() { return Get().Clone(); }
public static implicit operator InputActionMap(PlayerActions set) { return set.Get(); }
public void SetCallbacks(IPlayerActions instance)
{
if (m_Wrapper.m_PlayerActionsCallbackInterface != null)
{
Movement.started -= m_Wrapper.m_PlayerActionsCallbackInterface.OnMovement;
Movement.performed -= m_Wrapper.m_PlayerActionsCallbackInterface.OnMovement;
Movement.cancelled -= m_Wrapper.m_PlayerActionsCallbackInterface.OnMovement;
Jump.started -= m_Wrapper.m_PlayerActionsCallbackInterface.OnJump;
Jump.performed -= m_Wrapper.m_PlayerActionsCallbackInterface.OnJump;
Jump.cancelled -= m_Wrapper.m_PlayerActionsCallbackInterface.OnJump;
Dash.started -= m_Wrapper.m_PlayerActionsCallbackInterface.OnDash;
Dash.performed -= m_Wrapper.m_PlayerActionsCallbackInterface.OnDash;
Dash.cancelled -= m_Wrapper.m_PlayerActionsCallbackInterface.OnDash;
Interact.started -= m_Wrapper.m_PlayerActionsCallbackInterface.OnInteract;
Interact.performed -= m_Wrapper.m_PlayerActionsCallbackInterface.OnInteract;
Interact.cancelled -= m_Wrapper.m_PlayerActionsCallbackInterface.OnInteract;
AttackA.started -= m_Wrapper.m_PlayerActionsCallbackInterface.OnAttackA;
AttackA.performed -= m_Wrapper.m_PlayerActionsCallbackInterface.OnAttackA;
AttackA.cancelled -= m_Wrapper.m_PlayerActionsCallbackInterface.OnAttackA;
}
m_Wrapper.m_PlayerActionsCallbackInterface = instance;
if (instance != null)
{
Movement.started += instance.OnMovement;
Movement.performed += instance.OnMovement;
Movement.cancelled += instance.OnMovement;
Jump.started += instance.OnJump;
Jump.performed += instance.OnJump;
Jump.cancelled += instance.OnJump;
Dash.started += instance.OnDash;
Dash.performed += instance.OnDash;
Dash.cancelled += instance.OnDash;
Interact.started += instance.OnInteract;
Interact.performed += instance.OnInteract;
Interact.cancelled += instance.OnInteract;
AttackA.started += instance.OnAttackA;
AttackA.performed += instance.OnAttackA;
AttackA.cancelled += instance.OnAttackA;
}
}
}
public PlayerActions #Player
{
get
{
if (!m_Initialized) Initialize();
return new PlayerActions(this);
}
}
private int m_KeyboardSchemeIndex = -1;
public InputControlScheme KeyboardScheme
{
get
{
if (m_KeyboardSchemeIndex == -1) m_KeyboardSchemeIndex = asset.GetControlSchemeIndex("Keyboard");
return asset.controlSchemes[m_KeyboardSchemeIndex];
}
}
private int m_GamepadSchemeIndex = -1;
public InputControlScheme GamepadScheme
{
get
{
if (m_GamepadSchemeIndex == -1) m_GamepadSchemeIndex = asset.GetControlSchemeIndex("Gamepad");
return asset.controlSchemes[m_GamepadSchemeIndex];
}
}
}
public interface IPlayerActions
{
void OnMovement(InputAction.CallbackContext context);
void OnJump(InputAction.CallbackContext context);
void OnDash(InputAction.CallbackContext context);
void OnInteract(InputAction.CallbackContext context);
void OnAttackA(InputAction.CallbackContext context);
}
If there's too much to edit then can someone say what's the last supported version that has InputActionAssetReference?
Edited message --
I am replacing my answer without links as I have been told to. Basically instead of using InputActionAssetReference, another class like IInputActionCollection should be used. The first class must have been deprecated which is why it wasn't working properly.
Note: I have never used this new input system myself, but I am glad I was able to help! I get to learn something too which is a bonus.
InputActionAssetReference was removed at release [0.2.8-preview] - 2019-4-23
Generated wrapper code for Input Action Assets are now self-contained,
generating all the data from code and not needing a reference to the
asset; InputActionAssetReference has been removed.
link to changelog
I have project in Unity and also new to C#. Problem is that I got error The script needs to Derive from MonoBehaviour. I understand what does that mean but when I use MonoBehaviour I'm getting tons of Errors like this:
Errors in console
Will be glad if anyone can explain what am i doing wrong - thank you good people of stackoverflow!
Every script is connected to BaseWindow
namespace BlGame.View
{
public abstract class BaseWindow
{
protected Transform mRoot;
protected EScenesType mScenesType;
protected string mResName;
protected bool mResident;
protected bool mVisible = false;
public abstract void Init();
public abstract void Realse();
protected abstract void InitWidget();
protected abstract void RealseWidget();
protected abstract void OnAddListener();
protected abstract void OnRemoveListener();
public abstract void OnEnable();
public abstract void OnDisable();
public virtual void Update(float deltaTime) { }
public EScenesType GetScenseType()
{
return mScenesType;
}
public bool IsVisible() { return mVisible; }
public bool IsResident() { return mResident; }
public void Show()
{
if (mRoot == null)
{
if (Create())
{
InitWidget();
}
}
if (mRoot && mRoot.gameObject.activeSelf == false)
{
mRoot.gameObject.SetActive(true);
mVisible = true;
OnEnable();
OnAddListener();
}
}
public void Hide()
{
if (mRoot && mRoot.gameObject.activeSelf == true)
{
OnRemoveListener();
OnDisable();
if (mResident)
{
mRoot.gameObject.SetActive(false);
}
else
{
RealseWidget();
Destroy();
}
}
mVisible = false;
}
//预加载
public void PreLoad()
{
if (mRoot == null)
{
if (Create())
{
InitWidget();
}
}
}
//延时删除
public void DelayDestory()
{
if (mRoot)
{
RealseWidget();
Destroy();
}
}
private bool Create()
{
if (mRoot)
{
Debug.LogError("Window Create Error Exist!");
return false;
}
if (mResName == null || mResName == "")
{
Debug.LogError("Window Create Error ResName is empty!");
return false;
}
if (GameMethod.GetUiCamera.transform== null)
{
Debug.LogError("Window Create Error GetUiCamera is empty! WindowName = " + mResName);
return false;
}
GameObject obj = LoadUiResource.LoadRes(GameMethod.GetUiCamera.transform, mResName);
if (obj == null)
{
Debug.LogError("Window Create Error LoadRes WindowName = " + mResName);
return false;
}
mRoot = obj.transform;
mRoot.gameObject.SetActive(false);
return true;
}
//销毁窗体
protected void Destroy()
{
if (mRoot)
{
LoadUiResource.DestroyLoad(mRoot.gameObject);
mRoot = null;
}
}
public Transform GetRoot()
{
return mRoot;
}
}
}
Something like This:
public class UIGuideWindow : BaseWindow
{
public UIGuideWindow()
{
//mScenesType = EScenesType.EST_Login;
//mResName = GameConstDefine.UIGuideRestPath;
//mResident = false;
}
Unity Update Function cannot have any paramaters like this : Update(float deltaTime), this is unity not unreal engine:))
To fix this, Remove float deltaTime , and instead use Time.deltaTime inside the function implementation itself
I have a simple platformer game in which I'm using chartboost and unity ads t show ads and I it was working fine during the test mode but ever since I deployed to production and disabled the test mode in both chartboost and unity ads I noticed that my interstitial ads and videos don't load or show except once in a blue moon that too of a same game and then it start failing again.
I also noticed that my ads impression are quite low on the chartboost and Unity. Can you please tell me if I code for it correctly? I used the chartboost example an built my ad controller through it, oh and I'm using caching for ads and unless ad isn't cached already I won't show it.
Here's the code:
using UnityEngine;
using System.Collections;
using UnityEngine.Advertisements;
using ChartboostSDK;
using System;
public class AdsController : MonoBehaviour
{
public static AdsController instance;
// app id for unity apps
private const string _appId = "someID";
public bool canShowChartBoostInterstitial;
public bool canShowChartBoostVideo;
private void Awake()
{
MakeSingleton();
if (!canShowChartBoostInterstitial)
{
LoadChartBoostInterstitialAds();
}
if (!canShowChartBoostVideo)
{
LoadChartBoostVideoAds();
}
LoadUnityAds();
}
private void MakeSingleton()
{
if (instance != null)
{
Destroy(gameObject);
}
else
{
instance = this;
DontDestroyOnLoad(gameObject);
}
}
private void OnLevelWasLoaded()
{
if (Application.loadedLevelName == "LevelMenu")
{
if (GameController.instance.canShowAds)
{
if (canShowChartBoostInterstitial)
{
ShowChartBoostInterstitial();
}
else
{
LoadChartBoostInterstitialAds();
}
}
}
}
private void OnEnable()
{
Chartboost.didCompleteRewardedVideo += VideoCompleted;
Chartboost.didCacheInterstitial += DidCacheInterstitial;
Chartboost.didDismissInterstitial += DidDismissInterstitial;
Chartboost.didCloseInterstitial += DidCloseInterstitial;
Chartboost.didCacheRewardedVideo += DidCacheVideo;
Chartboost.didFailToLoadInterstitial += FailedToLoadInterstitial;
Chartboost.didFailToLoadRewardedVideo += FailedToLoadVideo;
}
private void OnDisable()
{
Chartboost.didCompleteRewardedVideo -= VideoCompleted;
Chartboost.didCacheInterstitial -= DidCacheInterstitial;
Chartboost.didDismissInterstitial -= DidDismissInterstitial;
Chartboost.didCloseInterstitial -= DidCloseInterstitial;
Chartboost.didCacheRewardedVideo -= DidCacheVideo;
Chartboost.didFailToLoadInterstitial -= FailedToLoadInterstitial;
Chartboost.didFailToLoadRewardedVideo -= FailedToLoadVideo;
}
public void VideoCompleted(CBLocation location, int reward)
{
canShowChartBoostVideo = false;
if (RewardController.instance != null)
{
RewardController.instance.VideoWatchedGiveUserAReward();
}
LoadChartBoostVideoAds();
}
public void DidCacheInterstitial(CBLocation location)
{
canShowChartBoostInterstitial = true;
}
public void DidDismissInterstitial(CBLocation location)
{
canShowChartBoostInterstitial = false;
LoadChartBoostVideoAds();
LoadChartBoostInterstitialAds();
}
public void DidCloseInterstitial(CBLocation location)
{
canShowChartBoostInterstitial = false;
LoadChartBoostVideoAds();
LoadChartBoostInterstitialAds();
}
public void DidCacheVideo(CBLocation location)
{
canShowChartBoostVideo = true;
}
private void FailedToLoadInterstitial(CBLocation location, CBImpressionError error)
{
canShowChartBoostInterstitial = false;
LoadChartBoostInterstitialAds();
}
private void FailedToLoadVideo(CBLocation location, CBImpressionError error)
{
canShowChartBoostVideo = false;
if (ShopMenuController.instance != null)
{
ShopMenuController.instance.FailedToLoadTheVideo();
}
LoadChartBoostVideoAds();
}
public void LoadChartBoostVideoAds()
{
Chartboost.cacheRewardedVideo(CBLocation.Default);
}
public void LoadChartBoostInterstitialAds()
{
Chartboost.cacheInterstitial(CBLocation.Default);
}
public void ShowChartBoostInterstitial()
{
if (canShowChartBoostInterstitial)
{
Chartboost.showInterstitial(CBLocation.Default);
}
else
{
LoadChartBoostInterstitialAds();
}
}
public void ShowChartBoostVideo()
{
if (canShowChartBoostVideo)
{
Chartboost.showRewardedVideo(CBLocation.Default);
}
else
{
LoadChartBoostVideoAds();
}
}
public void LoadUnityAds()
{
if (Advertisement.isSupported)
{
Advertisement.Initialize(_appId, false);
}
}
public void ShowUnityAds()
{
if (Advertisement.IsReady())
{
Advertisement.Show(null, new ShowOptions()
{
resultCallback = result =>
{
switch (result)
{
case ShowResult.Finished:
GameController.instance.RewardPlayerWithSomething();
LoadUnityAds();
break;
case ShowResult.Failed:
GameController.instance.VideoNotLoadedOrUserSkippedTheVideo("Failed to load the video. Please try again.");
LoadUnityAds();
break;
case ShowResult.Skipped:
GameController.instance.VideoNotLoadedOrUserSkippedTheVideo("Video skipped.");
LoadUnityAds();
break;
}
}
});
}
else
{
GameController.instance.VideoNotLoadedOrUserSkippedTheVideo("Failed to load the video. Please try again.");
LoadUnityAds();
}
}
}
Run cache after every time you show an interstitial.
like this :
Chartboost.showInterstitial(CBLocation.Default);
Chartboost.cacheInterstitial(CBLocation.Default);
That way you will replenish the cache every time you show an ad.
Remember to cache as soon as its initialized as well.