Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Join us on Thursday, June 8, for a Q&A with Unity's Content Pipeline group here on the forum, and on the Unity Discord, and discuss topics around Content Build, Import Workflows, Asset Database, and Addressables!
    Dismiss Notice

Use to Singleton

Discussion in 'Scripting' started by omermertguner, Sep 6, 2022.

  1. omermertguner


    May 21, 2022
    hello everyone. I have 3 different scripts. Let's call them the 1st, 2nd and 3rd. I need to access the data in the 3rd script from the 1st script through the 2nd script and the 2nd script should be a singleton. how can I do it. I would be very happy if you can help.
  2. Franco_Voisard


    Apr 30, 2018
    Hello, mmm... If I don't misunderstood anything... Something like that could do the trick.

    Code (CSharp):
    1. public class FirstScript
    2. {
    3.     private readonly ThirdScript _thirdScript;
    5.     public FirstScript(ThirdScript thirdScript)
    6.     {
    7.         _thirdScript = thirdScript;
    8.     }
    10.     private void MethodUsingThirdScript()
    11.     {
    12.         Debug.Log(_thirdScript.SomeIntProperty);
    13.     }
    14. }
    16. public class SecondScript
    17. {
    18.     public static SecondScript Instance;
    19.     private readonly ThirdScript _thirdScript;
    20.     public SecondScript(ThirdScript thirdScriptReference)
    21.     {
    22.         _thirdScript = thirdScriptReference;
    23.         Instance = this;
    24.     }
    26.     private void MethodUsingThirdScript()
    27.     {
    28.         Debug.Log(_thirdScript.SomeIntProperty);
    29.     }
    30. }
    32. public class ThirdScript
    33. {
    34.     public int SomeIntProperty;
    35. }
    mopthrow likes this.
  3. Kurt-Dekker


    Mar 16, 2013
    I like this pattern: Simple Singleton (UnitySingleton):

    Some super-simple Singleton examples to take and modify:

    Simple Unity3D Singleton (no predefined data):

    Unity3D Singleton with a Prefab (or a ScriptableObject) used for predefined data:

    These are pure-code solutions, do not put anything into any scene, just access it via .Instance!

    If it is a GameManager, when the game is over, make a function in that singleton that Destroys itself so the next time you access it you get a fresh one, something like:

    Code (csharp):
    1. public void DestroyThyself()
    2. {
    3.    Destroy(gameObject);
    4.    Instance = null;    // because destroy doesn't happen until end of frame
    5. }
    There are also lots of Youtube tutorials on the concepts involved in making a suitable GameManager, which obviously depends a lot on what your game might need.
    mopthrow likes this.
  4. orionsyndrome


    May 4, 2014
    It matters whether your scripts are MonoBehaviour or not. @Franco_Voisard's script is pure C# and if you want a MonoBehaviour singleton, check out Kurt's answer. But basically, when you want this kind of behavior with MonoBehaviours you must be mindful of the object's initialization states, because their execution order is now in Unity's hands.

    For this check out the Script Execution Order in settings. For example your singletons are probably "the eldest" of the objects, in terms of importance, because it's likely the other objects will refer to them for some services. They should have a priority (i.e. their Script Execution Order should be lower than default).

    This is just a heads up, if you ever stumble upon this problem.
    Franco_Voisard and mopthrow like this.
  5. Franco_Voisard


    Apr 30, 2018
    When coding in Unity, a common mistake is to make every script as a MonoBehaviour. Often is better (To take advantage from constructors, dependency injection or avoid depending on the Unity lifecycle) using the "Humble Object" pattern, basically you encapsulate a common C# class inside a MonoBehaviour (This way you can take advantage of both things, Unity lifecycle and plain C# advantages)
  6. SisusCo


    Jan 29, 2019
    Humble Object is an interesting pattern, I agree - but it's pretty advanced stuff, and pretty out of the norm, so I would not personally recommend it for somebody who's still getting to grips with the basics (also dependency injection, and even assigning to class members in the constructor are possible to pull off with MonoBehaviours as well... but that's getting off-topic :D).

    Singleton is a simple, functional pattern to use starting off, but at least at some point I would recommend also looking into the service locator pattern. It has some benefits compared to the singleton pattern, such as being able to retrieve instances by an interface they implement.
    Code (CSharp):
    1. using System;
    2. using System.Linq;
    3. using UnityEngine;
    4. using Object = UnityEngine.Object;
    6. public static class Get
    7. {
    8.     public static IPlayer Player => GetOrCreate<Player>();
    9.     // TODO: Add more service getters here...
    11.     private static T GetOrCreate<T>() where T : class
    12.     {
    13.         var instance = Cached<T>.instance;
    14.         if(instance is null)
    15.         {
    16.             if(typeof(Component).IsAssignableFrom(typeof(T)))
    17.             {
    18.                 instance = (T)(object)Object.FindObjectsOfType(typeof(T)).Single();
    19.             }
    20.             else
    21.             {
    22.                 instance = Activator.CreateInstance<T>();
    23.             }
    25.             Cached<T>.instance = instance;
    26.         }
    28.         return instance;
    29.     }
    31.     private static class Cached<T> where T : class
    32.     {
    33.         public static T instance;
    34.     }
    35. }
    Code (CSharp):
    1. public class First : MonoBehaviour
    2. {
    3.     public void Example()
    4.     {
    5.         Second second = Get.Second;
    6.         Third third = second.Third;
    7.     }
    8. }
    orionsyndrome likes this.
  7. Kurt-Dekker


    Mar 16, 2013
    And while we're at it, let's not forget the time-honored process of just putting a bunch of shared data into a ScriptableObject instance and dragging it into everything that needs it.

    Doesn't even need to have any predefined data... you can just make it all runtime data, mark everything as
    and get on with your game.
  8. Gamadrila


    Sep 5, 2021
    It is possible to copy data from the first script to the second one.