NullReferenceException on Public Method Unity3D - c#

void Update () {
if (isSaveNeeded){
AutoSaveData();
isSaveNeeded = false;
}
string status;
if (Social.localUser.authenticated) {
status = "Authenticated ";
if (isLoaded == false){
LoadAutoSave();
isLoaded = true;
}
}
else {
status = "Not Authenticated";
}
statusToPass = status + " " + mMsg;
}
public void OnSignIn() {
if (Social.localUser.authenticated) {
PlayGamesPlatform.Instance.SignOut();
}
else {
PlayGamesPlatform.Instance.Authenticate(mAuthCallback, false);
}
}
public void LoadData() {
((PlayGamesPlatform)Social.Active).SavedGame.ShowSelectSavedGameUI("Select Saved Game to Load",
10,
false,
true,
SaveGameSelectedForRead);
}
public void SaveData() {
((PlayGamesPlatform)Social.Active).SavedGame.ShowSelectSavedGameUI("Save Game Progress",
10,
true,
false,
SaveGameSelectedForWrite);
}
public void AutoSaveData() {
((PlayGamesPlatform)Social.Active).SavedGame.OpenWithAutomaticConflictResolution(autoSaveFileName,
DataSource.ReadCacheOrNetwork,
ConflictResolutionStrategy.UseLongestPlaytime,
SavedGameOpenedForWrite);
}
public void LoadAutoSave() {
((PlayGamesPlatform)Social.Active).SavedGame.OpenWithAutomaticConflictResolution(autoSaveFileName,
DataSource.ReadCacheOrNetwork,
ConflictResolutionStrategy.UseLongestPlaytime,
SavedGameOpenedForRead);
}
I am trying to call a public method in the same script called AutoSaveData()
and it is giving me Null reference exception.
I have also added DontDestroyOnLoad to this script so that the game object persists between scenes.
I have been looking into it for some hours now and couldn't figure out the cause for it. It might be a simple mistake on my part but as I am new to coding, probably I am not able to figure it out.
Thanks

I fixed it by adding condition to my AutoSaveData() function.
Now it is like
if(Social.localuser.authenticated){ AutoSaveData(){
} }
Thanks

Related

How do I wait until a bool is true in unity?

I am trying to make it so that when a button is pressed, the text would update.
My code:
public Text TextField;
public bool narrationGoing = true;
public void SetText(string text)
{
TextField.text = text;
}
public void ResumeNarration()
{
narrationGoing=true;
}
IEnumerator WaitNarration()
{
narrationGoing = false;
Debug.Log(narrationGoing);
yield return new WaitWhile(() => narrationGoing == false);
}
void Start()
{
Narration();
}
void Narration()
{
SetText("HeLlO wOrLd");
StartCoroutine(WaitNarration());
SetText("The button worked!");
}
However, when I launch the game it triggers the "WaitNarration()" coroutine, because it does write "false", but then it skips over the yield completely. I've tried to find a solution but sadly nothing worked, does anyone have an answer for how I can fix this? Thank you in advance!
Also, ResumeNarration() is a function for the button, that's why it's not triggered in the code.
You can yield inside of a while loop until the condition is met.
IEnumerator WaitNarration()
{
Debug.Log("WaitNarration started");
while (!narrationGoing)
{
yield return null;
}
Debug.Log("WaitNarration complete");
}

Unity - Advertisment called multiple times

I'm having this problem using Unity's Advertisment. Specifically after watching the video and clicking the X button to close the video, I should give the prize to the player (go to the next level). The problem is that the OnUnityAdsDidFinish function calls if (showResult == ShowResult.Finished) multiple times. What am I doing wrong? how do I call the FindObjectOfType () .LoadNextLevel () function once; ? Thank you in advance
public class UnityAdsInterstitial : MonoBehaviour, IUnityAdsListener
{
private string gameID = "******";
//nome scelto nella DashBoard di Unity
private string interstitialID = "interstitial";
private string myPlacementId = "rewardedVideo";
public int randomHighValue = 30;
private bool TestMode = true;
private bool adsClosed = false;
public Button _button;
private void Awake()
{
_button = GetComponent<Button>();
}
void Start()
{
Debug.Log("Ads start");
_button = GameObject.Find("StartAds").GetComponent<Button>();
_button.interactable = Advertisement.IsReady(myPlacementId);
if (_button) _button.onClick.AddListener(ShowRewardedVideo);
Advertisement.Initialize(gameID, TestMode);
Advertisement.AddListener(this);
if (adsClosed)
{
adsClosed = false;
}
}
public void ShowInterstitial()
{
if (Advertisement.IsReady(interstitialID) )
{
Advertisement.Show(interstitialID);
}
}
public void ShowRewardedVideo()
{
if (Advertisement.IsReady(myPlacementId))
{
Debug.Log("Rewarded video is Ready");
Advertisement.Show(myPlacementId);
}
else
{
Debug.Log("Rewarded video is not ready at the moment! Please try again later!");
}
}
public void HideBanner()
{
Advertisement.Banner.Hide();
}
public void OnUnityAdsReady(string placementdID)
{
if (placementdID == interstitialID)
{
Debug.Log("InterstitialIsReady");
}
if (placementdID == myPlacementId)
{
Debug.Log("RewardedIsReady");
_button.interactable = true;
}
}
public void OnUnityAdsDidFinish(string placementdID, ShowResult showResult)
{
if (showResult == ShowResult.Finished)
{
// Reward the user for watching the ad to completion.
if (!adsClosed)
{
adsClosed = true;
FindObjectOfType<LevelLoader>().LoadNextLevel();
}
}
else if (showResult == ShowResult.Skipped)
{
// Do not reward the user for skipping the ad.
}
else if (showResult == ShowResult.Failed)
{
Debug.LogWarning("The ad did not finish due to an error.");
}
}
public void OnUnityAdsDidError(string message)
{
Debug.Log("OnUnityAdsDidError");
}
public void OnUnityAdsDidStart(string message)
{
Debug.Log("OnUnityAdsDidStart");
}
I would start my investigation by checking the placement id (in case there are more placements)
Checking that the callback is for the proper placement id
if (showResult == ShowResult.Finished && placementId == myPlacementId)
{
// Reward the user for watching the ad to completion.
if (!adsClosed)
{
adsClosed = true;
FindObjectOfType<LevelLoader>().LoadNextLevel();
}
}
The second would be that I only have one active instance of UnityAdsInterstitial. You can check this in debug mode by the reference of the object. If more than one instance starts from somewhere else in your code, then you should just limit to one.

How to call keycodes from ui buttons in unity C#

This is the script.. in the starting lines you can see the usage of keycodes. I want to add UI buttons for android. When the user tap on that button it acts as Keycode.A or any Keycode which I want and I don't want to change the script. Any solution ? I am totally beginner I don't understand much of this code so don't want to change it. I got it with the free asset 2D Game Kit in which character ellen moves with pc controls. All I want is to change character controls from pc to ui buttons. Please help if I have to change the script I will get a lot of errors which I can't handle so please help.
using UnityEngine;
using UnityEngine.UIElements;
namespace Gamekit2D
{
public class PlayerInput : InputComponent, IDataPersister
{
public static PlayerInput Instance
{
get { return s_Instance; }
}
protected static PlayerInput s_Instance;
public bool HaveControl { get { return m_HaveControl; } }
public InputButton Pause = new InputButton(KeyCode.Escape, XboxControllerButtons.Menu);
public InputButton Interact = new InputButton(KeyCode.E, XboxControllerButtons.Y);
public InputButton MeleeAttack = new InputButton(KeyCode.K, XboxControllerButtons.X);
public InputButton RangedAttack = new InputButton(KeyCode.O, XboxControllerButtons.B);
public InputButton Jump = new InputButton(KeyCode.Space, XboxControllerButtons.A);
public InputAxis Horizontal = new InputAxis(KeyCode.D, KeyCode.A, XboxControllerAxes.LeftstickHorizontal);
public InputAxis Vertical = new InputAxis(KeyCode.W, KeyCode.S, XboxControllerAxes.LeftstickVertical);
[HideInInspector]
public DataSettings dataSettings;
protected bool m_HaveControl = true;
protected bool m_DebugMenuIsOpen = false;
void Awake ()
{
if (s_Instance == null)
s_Instance = this;
else
throw new UnityException("There cannot be more than one PlayerInput script. The instances are " + s_Instance.name + " and " + name + ".");
}
void OnEnable()
{
if (s_Instance == null)
s_Instance = this;
else if(s_Instance != this)
throw new UnityException("There cannot be more than one PlayerInput script. The instances are " + s_Instance.name + " and " + name + ".");
PersistentDataManager.RegisterPersister(this);
}
void OnDisable()
{
PersistentDataManager.UnregisterPersister(this);
s_Instance = null;
}
protected override void GetInputs(bool fixedUpdateHappened)
{
Pause.Get(fixedUpdateHappened, inputType);
Interact.Get(fixedUpdateHappened, inputType);
MeleeAttack.Get(fixedUpdateHappened, inputType);
RangedAttack.Get(fixedUpdateHappened, inputType);
Jump.Get(fixedUpdateHappened, inputType);
Horizontal.Get(inputType);
Vertical.Get(inputType);
if (Input.GetKeyDown(KeyCode.F12))
{
m_DebugMenuIsOpen = !m_DebugMenuIsOpen;
}
}
public override void GainControl()
{
m_HaveControl = true;
GainControl(Pause);
GainControl(Interact);
GainControl(MeleeAttack);
GainControl(RangedAttack);
GainControl(Jump);
GainControl(Horizontal);
GainControl(Vertical);
}
public override void ReleaseControl(bool resetValues = true)
{
m_HaveControl = false;
ReleaseControl(Pause, resetValues);
ReleaseControl(Interact, resetValues);
ReleaseControl(MeleeAttack, resetValues);
ReleaseControl(RangedAttack, resetValues);
ReleaseControl(Jump, resetValues);
ReleaseControl(Horizontal, resetValues);
ReleaseControl(Vertical, resetValues);
}
public void DisableMeleeAttacking()
{
MeleeAttack.Disable();
}
public void EnableMeleeAttacking()
{
MeleeAttack.Enable();
}
public void DisableRangedAttacking()
{
RangedAttack.Disable();
}
public void EnableRangedAttacking()
{
RangedAttack.Enable();
}
public DataSettings GetDataSettings()
{
return dataSettings;
}
public void SetDataSettings(string dataTag, DataSettings.PersistenceType persistenceType)
{
dataSettings.dataTag = dataTag;
dataSettings.persistenceType = persistenceType;
}
public Data SaveData()
{
return new Data<bool, bool>(MeleeAttack.Enabled, RangedAttack.Enabled);
}
public void LoadData(Data data)
{
Data<bool, bool> playerInputData = (Data<bool, bool>)data;
if (playerInputData.value0)
MeleeAttack.Enable();
else
MeleeAttack.Disable();
if (playerInputData.value1)
RangedAttack.Enable();
else
RangedAttack.Disable();
}
void OnGUI()
{
if (m_DebugMenuIsOpen)
{
const float height = 100;
GUILayout.BeginArea(new Rect(30, Screen.height - height, 200, height));
GUILayout.BeginVertical("box");
GUILayout.Label("Press F12 to close");
bool meleeAttackEnabled = GUILayout.Toggle(MeleeAttack.Enabled, "Enable Melee Attack");
bool rangeAttackEnabled = GUILayout.Toggle(RangedAttack.Enabled, "Enable Range Attack");
if (meleeAttackEnabled != MeleeAttack.Enabled)
{
if (meleeAttackEnabled)
MeleeAttack.Enable();
else
MeleeAttack.Disable();
}
if (rangeAttackEnabled != RangedAttack.Enabled)
{
if (rangeAttackEnabled)
RangedAttack.Enable();
else
RangedAttack.Disable();
}
GUILayout.EndVertical();
GUILayout.EndArea();
}
}
}
}
It's not possible. I rather advice you to directly call the functions you want when the button is pressed.

Unity Photon PUN 2 Error Trying to connect

I have a problem here with Photon's PUN 2. Sometimes It works, but other times it doesn't. Since the last 2 weeks it isn't working that fine. Before it were better, I joined to the master, and then, to the lobby and It allowed me to list the rooms and join them without any problem. Now, I haven't changed that code that much, I only changed it after the errors started. Now, sometimes it joins a match, but another it doesn't, showing the following error:
JoinRandomRoom failed. Client is not on Master Server or not yet ready to call operations. Wait for callback: OnJoinedLobby or OnConnectedToMaster.
I only have 2 devices to test my online with PUN, but, even if I created a room is not working anymore, it just seems like works randomly. Here's my code if you want to check it:
void Start()
{
PhotonNetwork.ConnectUsingSettings();
}
// Update is called once per frame
void Update()
{
}
public override void OnJoinedLobby()
{
// /* print("Connected to lobby")*/;
}
public override void OnConnectedToMaster()
{
//This shows a popup to let know the player that is connected
//PhotonNetwork.JoinLobby();
base.OnJoinedLobby();
GameObject.Find("IWifi").SetActive(false);
print("Puga");
StatePScript.IsShow = true;
Connected = true;
GameObject.Find("IOk").GetComponent<Image>().color = Color.white;
print("IOKS Value is " + IOKS.Show);
GameObject.Find("StatusText").GetComponent<Text>().text = "Connected!";
GameObject.Find("StatusText").GetComponent<Text>().color = Color.green;
A.Play();
GameObject.Find("StatePanel").GetComponent<Animator>().SetBool("Show", false);
IOKS.Show = false;
GameObject.Find("IOk").GetComponent<Image>().color = new Color(0, 0, 0, 0);
Connected = false;
StatePScript.IsShow = false;
}
I have other photon scripts like this that is the random room code:
using UnityEngine.UI;
using Photon.Pun;
public class RandomBScript : MonoBehaviourPunCallbacks
{
// Use this for initialization
private Button B;
void Start ()
{
B = GetComponent<Button>();
B.onClick.AddListener(Clicker);
}
void Clicker()
{
PhotonNetwork.JoinRandomRoom();
print("Random");
}
public override void OnJoinRandomFailed(short returnCode, string message)
{
base.OnJoinRandomFailed(returnCode, message);
print(message);
}
}
The create room code:
using Photon.Pun;
using Photon.Realtime;
public class CreateRoomS : MonoBehaviourPunCallbacks
{
// Use this for initialization
private Button B;
private InputField IF;
private InputField PlayerField;
public AudioSource A;
void Start ()
{
B = GetComponent<Button>();
PlayerField = GameObject.Find("PlayerInput").GetComponent<InputField>();
IF = GameObject.Find("NameInput").GetComponent<InputField>();
B.onClick.AddListener(Clicker);
}
private void Awake()
{
}
void Clicker()
{
print("Trying To create a room...");
if (IF.text.Length > 0 && IF.text.Length <= 20)
{
int PlayerAmount = Int32.Parse(PlayerField.text);
RoomOptions roompos = new RoomOptions()
{
IsVisible = true, IsOpen = true, MaxPlayers = (byte)PlayerAmount
};
PhotonNetwork.CreateRoom(IF.text, roompos);
print("RoomCreated!");
}
else
{
A.Play();
}
}
public override void OnJoinedRoom()
{
print("We are in a room");
PhotonNetwork.LoadLevel("WaitScene");
}
public override void OnCreateRoomFailed(short returnCode, string message)
{
base.OnCreateRoomFailed(returnCode, message);
}
public override void OnCreatedRoom()
{
base.OnCreatedRoom();
print("We created the room");
}
// Update is called once per frame
public override void OnConnectedToMaster()
{
base.OnConnectedToMaster();
print("Connected to the master");
}
And finally, the list rooms code:
using Photon.Pun;
using Photon.Realtime;
using System.Reflection;
using System;
public class RooManager : MonoBehaviourPunCallbacks
{
// Use this for initialization
public GameObject roomPrefab;
public Sprite Four, Two, Three;
private string RoomName;
private int PlayerAmount;
private int MaxPlayers;
private Image I;
private Vector2 RoomVector;
private bool Lock = false;
public GameObject Content;
private List<RoomInfo> RoomList;
private bool IsntNull = false;
private Dictionary<string, RoomInfo> cachedRoomList;
private Dictionary<string, GameObject> roomListEntries;
private void Awake()
{
GameObject.Find("StatePanel").GetComponent<Animator>().SetBool("Show", true);
cachedRoomList = new Dictionary<string, RoomInfo>();
roomListEntries = new Dictionary<string, GameObject>();
}
void Start ()
{
Content = GameObject.Find("Content").GetComponent<GameObject>();
RoomVector = new Vector2(370, this.transform.position.y);
}
void Rooming()
{
PhotonNetwork.JoinLobby();
}
private void ClearRoomListView()
{
foreach (GameObject entry in roomListEntries.Values)
{
Destroy(entry.gameObject);
}
roomListEntries.Clear();
}
private void UpdateRoomListView()
{
foreach (RoomInfo Item in cachedRoomList.Values)
{
RoomName = Item.Name;
PlayerAmount = Item.PlayerCount;
MaxPlayers = Item.MaxPlayers;
RoomVector.y -= 100;
GameObject RoomPrefab = Instantiate(roomPrefab, RoomVector, transform.rotation) as GameObject;
if (Item.PlayerCount == 0)
{
Destroy(RoomPrefab);
}
print(PhotonNetwork.CurrentLobby.Name);
RoomPrefab.transform.Find("RoomName").GetComponent<Text>().text = RoomName;
RoomPrefab.transform.Find("PlayerInt").GetComponent<Text>().text = PlayerAmount.ToString();
if (Item.PlayerCount == 0)
{
}
if (Item.MaxPlayers == 4)
{
GameObject.Find("IPlayerA").GetComponent<Image>().sprite = Four;
}
else if (Item.MaxPlayers == 2)
{
GameObject.Find("IPlayerA").GetComponent<Image>().sprite = Two;
}
else if (Item.MaxPlayers == 3)
{
GameObject.Find("IPlayerA").GetComponent<Image>().sprite = Three;
}
RoomPrefab.transform.SetParent(Content.transform);
}
}
public override void OnRoomListUpdate(List<RoomInfo> roomList)
{
ClearRoomListView();
UpdateCachedRoomList(roomList);
UpdateRoomListView();
print("Updated");
}
private void UpdateCachedRoomList(List<RoomInfo> roomList)
{
foreach (RoomInfo info in roomList)
{
// Remove room from cached room list if it got closed, became invisible or was marked as removed
if (!info.IsOpen || !info.IsVisible || info.RemovedFromList)
{
if (cachedRoomList.ContainsKey(info.Name))
{
cachedRoomList.Remove(info.Name);
}
continue;
}
// Update cached room info
if (cachedRoomList.ContainsKey(info.Name))
{
cachedRoomList[info.Name] = info;
}
// Add new room info to cache
else
{
cachedRoomList.Add(info.Name, info);
}
}
}
This script instantiates a button for every room in photon's server. If you click one button, you join that room. As I said, sometimes it work and sometimes it doesn't, sometimes it helped to comment the line PhotonNetwork.JoinLobby(), but that means that you wont see the romos. Actually, even with or without the JoinLobby() line, it isn't working that well.

Facebook.init() function still causing null exception

Background:
I am trying to integrate facebook for a unity-android project and I can't seem to make it working, I have looked on the fb page and allot of other place but can't seem to find a what I am doing wrong.
Problem:
When trying FB.Login i get the reference exception: Facebook object is not loaded. Did you call FB.init?
Code for InitializeFB.cs
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using Facebook.MiniJSON;
using System;
public class ConncetToFaceBook : MonoBehaviour {
// Connect to facebook
void Awake () {
// Required
DontDestroyOnLoad(gameObject);
// Initialize FB SDK
enabled = false;
FB.Init(onInitComplete, OnHideUnity);
//Display id
Debug.Log (FB.UserId);
//Login to facebook
FB.Login("email,publish_actions", LoginCallback);
}
/* Helper Methods */
private void onInitComplete ()
{
enabled = true; // "enabled" is a property inherited from MonoBehaviour
if (FB.IsLoggedIn)
{
//Some Code
}
}
private void OnHideUnity(bool isGameShown)
{
//some code
}
void LoginCallback(FBResult result)
{
if (FB.IsLoggedIn)
{
OnLoggedIn();
}
}
void OnLoggedIn()
{
Debug.Log("Logged in. ID: " + FB.UserId);
}
}
Code for FB.cs.init()
public static void Init(
InitDelegate onInitComplete,
string appId = "{My app ID}", //I did put my own here. Plus I use " instead of ' because ' give me a error.
bool cookie = true,
bool logging = true,
bool status = true,
bool xfbml = true,
bool frictionlessRequests = true,
HideUnityDelegate onHideUnity = null,
string authResponse = null)
FB.Init() is asynchronous method - it doesn't make the program wait until it is finished. And your FB.Login() is called too soon, you need to call it after FB.Init() is ready - inside the onInitComplete() method.
My setup:
void FBConnect(){
if(!FB.IsInitialized){
Debug.Log("Initializing FB");
FB.Init(FBInitCallback, null,null);
} else {
Debug.Log("No need for FB init");
FBInitCallback();
}
}
private void FBInitCallback(){
Debug.Log("FB init OK");
if(!FB.IsLoggedIn){
FB.Login("email,user_friends", FBLoginCallback);
} else {
//GetHisFBDataNow();
Debug.Log("Everything is known about this guy");
}
}
private void FBLoginCallback(FBResult result){
if (result.Error != null){
Debug.Log("FB Error Response:\n" + result.Error);
} else if (!FB.IsLoggedIn) {
Debug.Log("FB Login cancelled by Player");
} else {
//GetHisFBDataNow();
Debug.Log("Now also everything is known about this guy");
}
}
Hey idk if that will help but can you try and put fb.log in init complete?

Categories