Recommended reading
- CSDN home page
- GitHub open source address
- Unity3D plugin sharing
- Jane’s address book
- My personal blog
- QQ group: 1040082875
A. Preface
Today, a colleague asked me, “How do I use singletons in Unity?”
And then I just threw my code away.
Colleague: “Oh, that’s how it works. Why don’t you show me?”
Ii. Introduction to singleton mode
First of all, we should understand that singleton pattern is a common software design pattern. The class defined as singleton object can only allow one instance to exist. In many cases, the whole system only needs to have a global object, which is beneficial to coordinate the behavior of the whole system.
For example, a server program can store configuration information in a file and use a singleton to read the configuration information, which is then retrieved by other objects in other server processes, simplifying configuration management.
The structure diagram of the singleton pattern is as follows:So what are the scenarios where singletons can be used in Unity:
1, in the use of Unity development projects, often encounter the need for a management class to manage some global variables and methods, such as GameManager used to record all kinds of data needed in the whole game.
2. Some data that needs to be read from external documents can also be used by other script objects, and other objects can get data from this singleton.
Assume the following requirements:
DataManager singleton = DataManager singleton = DataManager singleton = DataManager The DataManager object cannot be destroyed when switching scenarios. 4. The values read by the DataManager singleton can be read in different scripts
Let’s implement a DataManager under a singleton step by step.
DataManager implements the singleton pattern
3-1. Define a singleton
We define a DataManager object that inherits from MonoBehaviour as follows:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class DataManager : MonoBehaviour
{
public static DataManager Instance;
private void Awake()
{
Instance = this; DontDestroyOnLoad(gameObject); }}Copy the code
Using the static DataManager property Instance ensures that it can be accessed by the class, not by instantiation. 3. Assign to Instance in Awake; 4. Use DontDestroyOnLoad to prevent the mounted script from being destroyed in a switching scenario. 5. Use the DontDestroyOnLoad argument (gameObject) to prevent the script from being destroyed in a switching scenario. Using this only guarantees that the current script will not be destroyed, but when the object is destroyed, the script is no more.
After creating this object, create a new DataManager object in the scene and drag the script onto it:
3-2, singleton object to read data saved
The code is as follows:
using System.Collections;
using System.Collections.Generic;
using System.IO;
using UnityEngine;
public class DataManager : MonoBehaviour
{
public static DataManager Instance;
string m_JsonContent;// Temporary document data
RootData m_JsonData;// Temporarily receive JSON parsing data
// The data is stored in the List, and other scripts can be called
public List<StationAllInfo> m_StationsAllInfo = new List<StationAllInfo>();
private void Awake()
{
Instance = this;
DontDestroyOnLoad(gameObject);
}
private void Start()
{
ReadJSONData();
}
void ReadJSONData()
{
string pathstations = Application.streamingAssetsPath + "/ subway station.json";
using (StreamReader SR = new StreamReader(pathstations))
{
m_JsonContent = SR.ReadToEnd();
Debug.Log(m_JsonContent);
SR.Close();
SR.Dispose();
// Save JSON data
m_JsonData = JsonUtility.FromJson<RootData>(m_JsonContent);
}
for (int i = 0; i < m_JsonData.GisJosnDatas.Count; i++)
{
if(m_JsonData.GisJosnDatas[i].properties.LINE_ID ! ="")// Discard useless information and save useful information
{
StationAllInfo item = new StationAllInfo();
item.X = m_JsonData.GisJosnDatas[i].properties.X;
item.Y = m_JsonData.GisJosnDatas[i].properties.Y;
item.STACODE = m_JsonData.GisJosnDatas[i].properties.STACODE;
item.S_NAME = m_JsonData.GisJosnDatas[i].properties.S_NAME;
item.LINE_ID = m_JsonData.GisJosnDatas[i].properties.LINE_ID;
// Switch from 05 to 5
if (m_JsonData.GisJosnDatas[i].properties.LINE_ID.Substring(0.1) = ="0")
{
item.LINE_NAME = m_JsonData.GisJosnDatas[i].properties.LINE_ID.Substring(1.1) + "Line";
}
else
{
switch (m_JsonData.GisJosnDatas[i].properties.LINE_ID)// Handle abbreviations of station names
{
case "fs":
item.LINE_NAME = "Fangshan Line";
break;
case "bt":
item.LINE_NAME = "Eight-way line";
break;
case "yz":
item.LINE_NAME = "Yizhuang Line";
break;
case "cp":
item.LINE_NAME = "Changping line";
break;
case "jc":
item.LINE_NAME = "Airport Line";
break;
default:
item.LINE_NAME = m_JsonData.GisJosnDatas[i].properties.LINE_ID + "Line";
break; } } item.STYPE = m_JsonData.GisJosnDatas[i].properties.STYPE; m_StationsAllInfo.Add(item); }}}}Copy the code
3-3. Use data in other scripts
Let’s create a new usedata. cs script to use the data:
using UnityEngine;
public class UseData : MonoBehaviour
{
private void Update()
{
// Click the keyboard W to display data
if(Input.GetKeyDown(KeyCode.W)) { ShowData(); }}private void ShowData()
{
for (int i = 0; i < DataManager.Instance.m_StationsAllInfo.Count; i++)
{
Debug.Log(DataManager.Instance.m_StationsAllInfo[i].X + ""
+DataManager.Instance.m_StationsAllInfo[i].Y + ""
+ DataManager.Instance.m_StationsAllInfo[i].STACODE + ""
+ DataManager.Instance.m_StationsAllInfo[i].S_NAME + ""
+ DataManager.Instance.m_StationsAllInfo[i].LINE_ID + ""
+ DataManager.Instance.m_StationsAllInfo[i].LINE_NAME + ""
+ DataManager.Instance.m_StationsAllInfo[i].STYPE + ""); }}}Copy the code
Drag this script onto the object in the scene:
Run the program, hit W:
All values are read from the m_StationsAllInfo array of InStance of the singleton DataManager.
3-4. Read data in switching scenario
We create two new scenarios: Index and Next, and then mount the changescenes.cs script on the objects in the Index scenario as follows:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
public class ChangeScenes : MonoBehaviour
{
// Start is called before the first frame update
void Start(){}// Update is called once per frame
void Update()
{
if (Input.GetKeyDown(KeyCode.Q))
{
SceneManager.LoadScene(1); }}}Copy the code
That is, switch the scene, then create a new DataManager object in the Index scene and drag the DataManager script onto it.
Then mount the UseData script from a random object in the Next scenario. There is no need to create a DataManager object
Then add two scenarios to Build Setting:
Run the program:
Switching to the Next scenario, the DataManager object also exists:
Key W:
All values are read from the m_StationsAllInfo array of the InStance datamanager.cs singleton of the mount script of the DataManager object in the previous scenario.
Fourth, the last word
This is a simple application of Unity using singletons, the main points are;
1. Object switching scenarios will not be destroyed
Static properties of singletons
3. Data preservation
4. Other scripts use singleton data methods
End, good good study refueling!