object reference required to to access non-static member, userSession
I'm trying to get userSession, a variable to put in to my highscore database but i keep getting object reference error. My SessionScript get the user's name that is logged in from the User table database and display it.
public class SessionScript : MonoBehaviour {
public Text userName;
public static string userSession;
void Start()
{
userSession = "";
userName.text = "";
if (!DBContoller.newAcc)
userSession = MainMenu.userName;
else
userSession = CreateAcc.username;
userName.text = "Hi, " + userSession;
Debug.Log ("New Session: " + userSession + "\nNew Account: " + DBContoller.newAcc);
}
}
Then i want to access the userSession variable and when the user finish playing the game, it will insert the user's highscore and stuff. Heres where is insert the score.
if(card.cardPosition == 42)
{
TimerScript.SetTimeStop();
Debug.Log("Wrong Key Press = " + wrongKeyPress);
Debug.Log("Time Passed = " + Mathf.RoundToInt(TimerScript.seconds));
wrongKeyPress = FinalWrongKeyPress;
finalSeconds = Mathf.RoundToInt(TimerScript.seconds);
if( SessionScript.userSession == null)
{
return;
}
if ( SessionScript.userSession!= null)
{
HighScoreManager.InsertScores(SessionScript.userSession,finalSeconds,wrongKeyPress);
}
GameEnd();
}
But i keep getting the error : An object reference is required to access non-static member `HighScoreManager.InsertScores(string, int, int)'
Thanks for helping me in advance!
EDIT** I realized that my InsertScore is on another scene. Therefore i can't even reference an object as InsertScore is on another scene that is on another script.
Where do you get HighScore$$anonymous$$anager? If it is a singleton living somewhere, then it has to be fully static and accessed through .instance:
private static HighScore$$anonymous$$anager m_instance;
public static HighScore$$anonymous$$anager instance {
get {
if (m_instance == null) {
m_instance = GameObject.FindObjectOfType< HighScore$$anonymous$$anager >();
}
return m_instance;
}
}
If not, then use getComponent< HighScore$$anonymous$$anager>() on the object that instantiates it. Is it instantiated somewhere?
If you do all these things, please inform me further ;)
Hi. Thanks for your reply. $$anonymous$$y HighScore$$anonymous$$anager is a script on an empty object that is on another scene. That scene is where I display all my the HighScore from my database.
I did not use any singleton(very little to no knowledge on how to use singleton). $$anonymous$$y HighScore$$anonymous$$anager contains methods like InsertScore, DeleteScore, ShowScore, etc, to calls score from my database to display. It all working fine.
I can't use getComponent as its on another scene that would be destroy when i load the next scene.
So far what i have done is i made those three variable that i need to insert to my database, SessionScript.userSession, CardGame.finalSeconds, CardGame.wrong$$anonymous$$eyPress, static, then i put into HighScore$$anonymous$$anager Start(). It will work but i have to finish my game, the click a button to load the HighScore scene and then it will insert. Due to being in another scene, i can't call the InsertScore $$anonymous$$ethod from the HighScore$$anonymous$$anager script. Here a small part of my HighScore$$anonymous$$anager script
public class HighScore$$anonymous$$anager : $$anonymous$$onoBehaviour {
private string connectionString;
private List<HighScore> highScores = new List<HighScore>();
public GameObject scorePrefab;
public Transform scoreParent;
public int topRanks;
public int saveScores;
// Use this for initialization
void Start ()
{
connectionString = "URI=file:" + Application.dataPath + "/FYPDB";
CreateTable ();
//InsertScores ("$$anonymous$$ENNETH", 9, 1);
//DeleteScore (2);
InsertScores (SessionScript.userSession, CardGame.finalSeconds, CardGame.wrong$$anonymous$$eyPress);
DeleteExtraScores ();
ShowScores ();
}
// Update is called once per frame
void Update ()
{
}
public void InsertScores(string name, int newScore, int newWrong$$anonymous$$eyPress)
{
GetScores ();
int hsCount = highScores.Count;
if (highScores.Count > 0)
{
HighScore lowestScore = highScores[highScores.Count - 1];
if(lowestScore != null && saveScores > 0 && highScores.Count >= saveScores && newScore > lowestScore.Score)
{
DeleteScore(lowestScore.ID);
hsCount--;
}
}
if (hsCount < saveScores)
{
using (IDbConnection dbConnection = new SqliteConnection(connectionString))
{
dbConnection.Open ();
using (IDbCommand dbCmd = dbConnection.CreateCommand())
{
string sqlQuery = String.Format ("INSERT INTO HighScores(Name,Score,Wrong$$anonymous$$eyPress) VALUES(\"{0}\",\"{1}\",\"{2}\")", name, newScore, newWrong$$anonymous$$eyPress);
dbCmd.CommandText = sqlQuery;
dbCmd.ExecuteScalar ();
dbConnection.Close ();
}
}
}
}
@Socapex so do i make my HighScore$$anonymous$$anager a singleton, put it in a empty object on the game scene itself, then i can call the function InsertScore() from my CardGame script?
Answer by DFT-Games · Oct 30, 2015 at 01:35 AM
Hi @roszetm,
I believe that you are mixing things a bit, that's why you are getting into architectural problems. The correct approach to this kind of management (databases, cloud services and the like) is to design the code using the Singleton Design Pattern.
To implement this in Unity is quite easy. First off, you need the proper structure and you must make it "invulnerable" to the scene loading/unloading. Moreover, you don't want to load it if you don't need it, so you have to implement a lazy instancing approach. Here's a good generic skeleton that you can use for any similar implementation:
using UnityEngine;
using System.Collections;
public class SingletonSkeleton : MonoBehaviour {
private static SingletonSkeleton me;
private static SingletonSkeleton Me
{
get
{
if (me != null) return me;
GameObject tmp = new GameObject("My Singleton Manager");
me = tmp.AddComponent<SingletonSkeleton>();
DontDestroyOnLoad(tmp);
return me;
}
}
private int someScoreVariable;
public int SomeScoreVariable
{
get
{
return Me.someScoreVariable
}
set
{
Me.someScoreVariable = value;
}
}
public static void SomeStaticHelper()
{
Me.SomeInstanceMethodHere();
}
void Start()
{
// Your start code here
}
void SomeInstanceMethodHere()
{
// Some code here
}
}
As you can see this will create a game object to contain its own instance if it does not exists, and will make it persistent across scenes. Basically you will only call the static helpers to get access to the instance and its services, and you can do that from any scene in your game. you can also add static properties the same way as shown in the code,
Hope this helps ;)
Pino
Ugh, that is ugly. Access it through .instance ins$$anonymous$$d. See the comment above.
Hi @Socapex,
The old habit of using the Instance accessor is long gone... I have no idea why it's still used by so many people, but there are 2 reasons for it to be gone away from the scene, as follows:
It makes the code less readable because of the ugly syntax
It assumes that you only want to get access to the instance, but quite often you don't, in many cases you are using private static members managed via static helpers. As a consequence calls to helpers in the same class would read inconsistently.
Because of the above two points, in the Singleton Design Pattern exposing "instance" ("me" in my code sample) is no longer a good practice. I know that in universities they still $$anonymous$$ch that... as usual there is quite a gap between real world (industry) and school (academia).
Cheers,
Pino
Because I understand that my original (didactic) code was not nice, I changed it using my current real life skeleton that should be less difficult to understand.
Oh look, you fixed it.
It makes the code less readable because of the ugly syntax
Lmao dude who calls Check$$anonymous$$e() in every single method, hahaha! However wonderful and professional you think you are, calling Check$$anonymous$$e() in every single getter is uglier.
I've heard that whole static helper argument before. I have nothing against it, that wasn't my point. I don't care how you get to B. You care how you get to B.
Your answer
Follow this Question
Related Questions
object reference not set to instance of an object On last line 0 Answers
Object reference not set to instance of an object? 1 Answer
NullReferenceException: Object reference not set to an instance of an object 2 Answers
Why is object reference not set to an instance? 1 Answer
Errors appear when i get a bad Raycast hit. Meaning when it hits another object in the scene. 0 Answers