- Home /
Checking Separate ScoreManager values in another Script to load certain levels.
Hello all! First I'd like to preface this with saying that this is for a jam so ultimately it's not detrimental to be answered but I would like some input nonetheless. What I'm trying to do is have two separate collectables with different score managers in my game and then depending on if either collectables value is higher than the other it will load a different level. I have it loading the correct levels based on the values however I definitely know there is a better and more optimized approach than mine. Here are the separate ScoreManager scripts:
public class FutureScoreManager : MonoBehaviour
{
public static FutureScoreManager instance;
public TextMeshProUGUI FutureText;
public int FutureScore;
// Start is called before the first frame update
void Start()
{
if (instance == null)
{
instance = this;
}
}
public int ChangeFutureScore (int FutureValue)
{
FutureScore += FutureValue;
FutureText.text = "x" + FutureScore.ToString();
return FutureScore;
}
}
Here is the MemoryScoreManager:
public class MemoryScoreManager : MonoBehaviour
{
public static MemoryScoreManager instance;
public TextMeshProUGUI MemoryText;
public int MemoryScore;
// Start is called before the first frame update
void Start()
{
if (instance == null)
{
instance = this;
}
}
public int ChangeMemoryScore (int MemoryValue)
{
MemoryScore += MemoryValue;
MemoryText.text = "x" + MemoryScore.ToString();
return MemoryScore;
}
}
then I have a collider at the end of the level set to OnTrigger and I have a script attached to the player with an OnColliderTrigger2D:
private void OnTriggerEnter2D(Collider2D other)
{
if (other.gameObject.CompareTag("PickUp"))
{
MemoryScoreManager.instance.ChangeMemoryScore(MemoryValue);
Destroy(other.gameObject);
}
if (other.gameObject.CompareTag("PickUp2"))
{
FutureScoreManager.instance.ChangeFutureScore(FutureValue);
Destroy(other.gameObject);
}
if (other.gameObject.CompareTag("LevelTrigger"))
{
if (MemoryObj.GetComponent<MemoryScoreManager>().ChangeMemoryScore(MemoryValue) > FutureObj.GetComponent<FutureScoreManager>().ChangeFutureScore(FutureValue))
{
SceneManager.LoadScene(GoodSceneToLoad);
}
if (FutureObj.GetComponent<FutureScoreManager>().ChangeFutureScore(FutureValue) > MemoryObj.GetComponent<MemoryScoreManager>().ChangeMemoryScore(MemoryValue))
{
SceneManager.LoadScene(BadSceneToLoad);
}
}
}
This is working however I'm still very new to game dev in general and try to learn as much as possible. I researched scriptable objects as that seems like it might be a good approach? but I'm still trying to walk the logic around in my head and it's not landing very well lol. Any input is appreciated!!! Also, I apologize if the formatting of the post is incorrect. I think I used the code tags properly but if it's janky I'm sorry and will try to fix it.
Answer by UTus · Sep 23, 2020 at 05:44 AM
Use Singleton Pattern
EX) Singleton.Instance.Action();
public class SingletonMonoBase<T> :MonoBehaviour where T :MonoBehaviour
{
private static T instance = null;
private static object _synobj = new object();
private static bool appIsClosing = false;
public static T Instance
{
get
{
if (appIsClosing) return null;
lock (_synobj)
{
if(instance == null)
{
T[] objs = FindObjectsOfType<T>();
if (objs.Length > 0) instance = objs[0];
if (objs.Length > 1) Debug.LogError("There is more than one" + typeof(T).Name + "in the scene.");
string goName = typeof(T).ToString();
GameObject go = GameObject.Find(goName);
if (go == null) go = new GameObject(goName);
instance = go.AddComponent<T>();
}
return instance;
}
}
}
private void Awake()
{
StartCoroutine(OnAwakeCoroutine());
}
protected virtual IEnumerator OnAwakeCoroutine()
{
yield return null;
}
}