防止单例随场景销毁和跨场景两个物体脚本问题

通过泛型封装单例类

NormalSingleton.cs
using System.Collections;using System.Collections.Generic;using UnityEngine;//标准单例类public class NormalSingleton where T : class, new(){    private static T _single;    public static T Singel    {        get        {            if (_single == null)            {                T t = new T();                if (t is MonoBehaviour)                {                    Debug.LogError("Mono类请使用MonoSingleTon!");                    return null;                }                _single = t;            }            return _single;        }    }}
MonoSingleton.cs
using System;using System.Collections;using System.Collections.Generic;using UnityEngine;//Mono单例类public class MonoSingleton : MonoBehaviour where T : MonoBehaviour{    private static T _singleton;    public static T SingleTon    {        get        {            if (_singleton == null)            {                _singleton = FindObjectOfType();                if (_singleton == null)                {                    Debug.LogError("场景中未找到类的对象,类名为:"+typeof(T).Name);                }            }            return _singleton;        }    }    private void Awake()    {        if (_singleton == null)        {            DontDestroyOnLoad(gameObject);        }        else        {            Destroy(gameObject);        }    }}

通过物体路径自动挂载脚本(游戏预制物体名字 和 脚本名字得一样)(方式一)

ILoader接口 给ResourceLoder 和 ABLoader实现

ILoader.cs
using System.Collections;using System.Collections.Generic;using UnityEngine;public interface ILoader {    ///     /// Resource方法加载物体    ///     /// 加载物体的路径    /// 指定父物体    ///     GameObject LoadPrefab(string path, Transform parent = null);}

Resource加载器

ResourceLoader.cs
using System.Collections;using System.Collections.Generic;using UnityEngine;public class ResourceLoader : ILoader{   ///    /// Resource方法加载物体   ///    /// 加载物体的路径   /// 指定父物体   ///    public GameObject LoadPrefab(string path,Transform parent = null)   {      GameObject go = Resources.Load(path);      GameObject go2 = Object.Instantiate(go, parent);      return go2;   }      }

AB包加载器 (没有实现 共理清逻辑使用)

ABLoader.cs
using System.Collections;using System.Collections.Generic;using UnityEngine;public class ABLoader : ILoader{    public GameObject LoadPrefab(string path, Transform parent = null)    {        throw new System.NotImplementedException();    }}

LoadManager场景加载器

LoadManager.cs
using System;using System.Collections;using System.Collections.Generic;using UnityEngine;//加载管理器public class LoadManager : NormalSingleton{       [SerializeField]    private ILoader iLoader;    public LoadManager()    {           //Resource加载方式        iLoader = new ResourceLoader();        //AB包加载方式        // iLoader = new ABLoader();    }        //自动挂载脚本加载物体方式一(通过脚本与游戏物体同名)    public GameObject LoadPrefab(string path, Transform parent = null)    {        GameObject go = iLoader.LoadPrefab(path, parent);        //通过物体名 自动挂载脚本(游戏物体名字 和 脚本名字得一样)        Type type = Type.GetType(go.name.Remove(go.name.Length - 7));        go.AddComponent(type);        return go;    }        //自动挂载脚本加载物体方式二(通过反射特性)    // public GameObject LoadPrefab(string path, Transform parent = null)    // {    //     GameObject go = iLoader.LoadPrefab(path, parent);    //     Type type = BindUtil.GetType(path);    //     go.AddComponent(type);    //     return go;    // }}using System;using System.Collections;using System.Collections.Generic;using UnityEngine;//加载管理器public class LoadManager : NormalSingleton{       [SerializeField]    private ILoader iLoader;    public LoadManager()    {           //Resource加载方式        iLoader = new ResourceLoader();        //AB包加载方式        // iLoader = new ABLoader();    }        //自动挂载脚本加载物体方式一(通过脚本与游戏物体同名)    public GameObject LoadPrefab(string path, Transform parent = null)    {        GameObject go = iLoader.LoadPrefab(path, parent);        //通过物体名 自动挂载脚本(游戏物体名字 和 脚本名字得一样)        Type type = Type.GetType(go.name.Remove(go.name.Length - 7));        go.AddComponent(type);        return go;    }        //自动挂载脚本加载物体方式二(通过反射特性)    // public GameObject LoadPrefab(string path, Transform parent = null)    // {    //     GameObject go = iLoader.LoadPrefab(path, parent);    //     Type type = BindUtil.GetType(path);    //     go.AddComponent(type);    //     return go;    // }}

启动游戏入口 需要挂在在游戏物体上

    using System.Collections;using System.Collections.Generic;using UnityEngine;//启动游戏入口public class LaunchGame : MonoBehaviour{    // Start is called before the first frame update    void Start()    {           //通过反射特性 加载方式二        // InitCustermonAttribute initCustermonAttribute = new InitCustermonAttribute();        // initCustermonAttribute.init();                LoadManager.Singel.LoadPrefab("Prefab/StartView",transform);    }    }

启动入口挂载在Cavas上 加载的预制体 会做为其子物体

运行效果:

通过游戏物体路径 反射特性 自动加载预制体和脚本(方式二)

绑定物体特性

BindPrefab.cs
using System;using System.Collections;using System.Collections.Generic;using UnityEngine;//绑定物体特性[AttributeUsage(AttributeTargets.Class)]public class BindPrefab : Attribute{    public string Path { get; private set;}    public BindPrefab(string path)    {        Path = path;    }}

加载物体同名脚本 通过路径反射

StartView.cs
using System;using System.Collections;using System.Collections.Generic;using UnityEngine;//加载物体同名脚本 通过路径反射[BindPrefab("Prefab/StartView")]public class StartView : MonoBehaviour{  }

绑定工具类

BindUtil.cs

using System;using System.Collections;using System.Collections.Generic;using System.Linq;using UnityEngine;//绑定工具类public class BindUtil : MonoBehaviour{    public static Dictionary _Dictionary = new Dictionary();    public static void Bind(string path,Type type)    {        if (!_Dictionary.ContainsKey(path))        {            _Dictionary.Add(path,type);        }        else        {            Debug.LogError("当前数据已存在路径: "+path);        }    }    public static Type GetType(string path)    {        if (_Dictionary.ContainsKey(path))        {            return _Dictionary[path];        }        else        {            Debug.LogError("数据未包含路径:"+path);            return null;        }    }}

初始化自定义特性

InitCustermonAttribute.cs
using System;using System.Collections;using System.Collections.Generic;using System.Reflection;using UnityEngine;//初始化自定义特性public class InitCustermonAttribute : MonoBehaviour{   public void init()   {      Assembly assembly = Assembly.GetAssembly(typeof(BindPrefab));      Type[] types = assembly.GetExportedTypes();      foreach (Type type in types)      {         foreach (Attribute attribute in Attribute.GetCustomAttributes(type,true))         {            if (attribute is BindPrefab)            {               BindPrefab data = attribute as BindPrefab;               BindUtil.Bind(data.Path,type);            }         }      }   }}

加载管理器

LoadManager.cs
using System;using System.Collections;using System.Collections.Generic;using UnityEngine;//加载管理器public class LoadManager : NormalSingleton{       [SerializeField]    private ILoader iLoader;    public LoadManager()    {           //Resource加载方式        iLoader = new ResourceLoader();        //AB包加载方式        // iLoader = new ABLoader();    }        //自动挂载脚本加载物体方式一(通过脚本与游戏物体同名)    // public GameObject LoadPrefab(string path, Transform parent = null)    // {    //     GameObject go = iLoader.LoadPrefab(path, parent);    //     //通过物体名 自动挂载脚本(游戏物体名字 和 脚本名字得一样)    //     Type type = Type.GetType(go.name.Remove(go.name.Length - 7));    //     go.AddComponent(type);    //     return go;    // }        //自动挂载脚本加载物体方式二(通过反射特性)    public GameObject LoadPrefab(string path, Transform parent = null)    {        GameObject go = iLoader.LoadPrefab(path, parent);        Type type = BindUtil.GetType(path);        go.AddComponent(type);        return go;    }}

启动游戏入口

LaunchGame.cs
    using System.Collections;using System.Collections.Generic;using UnityEngine;//启动游戏入口public class LaunchGame : MonoBehaviour{    // Start is called before the first frame update    void Start()    {           //通过反射特性 加载方式二        InitCustermonAttribute initCustermonAttribute = new InitCustermonAttribute();        initCustermonAttribute.init();                LoadManager.Singel.LoadPrefab("Prefab/StartView",transform);    }    }

运行效果:

加载器结构目录