mirror of
https://gitee.com/jisol/jisol-game/
synced 2025-09-27 02:36:14 +00:00
提交Unity 联机Pro
This commit is contained in:
@@ -0,0 +1,74 @@
|
||||
namespace SRF.Components
|
||||
{
|
||||
using System.Diagnostics;
|
||||
using UnityEngine;
|
||||
using Debug = UnityEngine.Debug;
|
||||
|
||||
/// <summary>
|
||||
/// Singleton MonoBehaviour class which automatically creates an instance if one does not already exist.
|
||||
/// </summary>
|
||||
public abstract class SRAutoSingleton<T> : SRMonoBehaviour where T : SRAutoSingleton<T>
|
||||
{
|
||||
private static T _instance;
|
||||
|
||||
/// <summary>
|
||||
/// Get (or create) the instance of this Singleton
|
||||
/// </summary>
|
||||
public static T Instance
|
||||
{
|
||||
[DebuggerStepThrough]
|
||||
get
|
||||
{
|
||||
// Instance required for the first time, we look for it
|
||||
if (_instance == null && Application.isPlaying)
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
// Support reloading scripts after a recompile - static reference will be cleared, but we can find it again.
|
||||
T autoSingleton = FindObjectOfType<T>();
|
||||
if (autoSingleton != null)
|
||||
{
|
||||
_instance = autoSingleton;
|
||||
return _instance;
|
||||
}
|
||||
#endif
|
||||
|
||||
var go = new GameObject("_" + typeof (T).Name);
|
||||
go.AddComponent<T>(); // _instance set by Awake() constructor
|
||||
}
|
||||
return _instance;
|
||||
}
|
||||
}
|
||||
|
||||
public static bool HasInstance
|
||||
{
|
||||
get { return _instance != null; }
|
||||
}
|
||||
|
||||
// If no other monobehaviour request the instance in an awake function
|
||||
// executing before this one, no need to search the object.
|
||||
protected virtual void Awake()
|
||||
{
|
||||
if (_instance != null)
|
||||
{
|
||||
Debug.LogWarning("More than one singleton object of type {0} exists.".Fmt(typeof (T).Name));
|
||||
return;
|
||||
}
|
||||
|
||||
_instance = (T) this;
|
||||
}
|
||||
|
||||
protected virtual void OnEnable()
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
// Restore reference after C# recompile.
|
||||
_instance = (T) this;
|
||||
#endif
|
||||
}
|
||||
|
||||
// Make sure the instance isn't referenced anymore when the user quit, just in case.
|
||||
private void OnApplicationQuit()
|
||||
{
|
||||
_instance = null;
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 73f72db4fa1856540bbe92740280c8e2
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
@@ -0,0 +1,202 @@
|
||||
namespace SRF
|
||||
{
|
||||
using System.Diagnostics;
|
||||
using UnityEngine;
|
||||
|
||||
/// <summary>
|
||||
/// Base MonoBehaviour which provides useful common functionality
|
||||
/// </summary>
|
||||
public abstract class SRMonoBehaviour : MonoBehaviour
|
||||
{
|
||||
/// <summary>
|
||||
/// Get the Transform component, using a cached reference if possible.
|
||||
/// </summary>
|
||||
public Transform CachedTransform
|
||||
{
|
||||
[DebuggerStepThrough]
|
||||
[DebuggerNonUserCode]
|
||||
get
|
||||
{
|
||||
if (_transform == null)
|
||||
{
|
||||
_transform = base.transform;
|
||||
}
|
||||
|
||||
return _transform;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the Collider component, using a cached reference if possible.
|
||||
/// </summary>
|
||||
public Collider CachedCollider
|
||||
{
|
||||
[DebuggerStepThrough]
|
||||
[DebuggerNonUserCode]
|
||||
get
|
||||
{
|
||||
if (_collider == null)
|
||||
{
|
||||
_collider = GetComponent<Collider>();
|
||||
}
|
||||
|
||||
return _collider;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the Collider component, using a cached reference if possible.
|
||||
/// </summary>
|
||||
public Collider2D CachedCollider2D
|
||||
{
|
||||
[DebuggerStepThrough]
|
||||
[DebuggerNonUserCode]
|
||||
get
|
||||
{
|
||||
if (_collider2D == null)
|
||||
{
|
||||
_collider2D = GetComponent<Collider2D>();
|
||||
}
|
||||
|
||||
return _collider2D;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the Rigidbody component, using a cached reference if possible.
|
||||
/// </summary>
|
||||
public Rigidbody CachedRigidBody
|
||||
{
|
||||
[DebuggerStepThrough]
|
||||
[DebuggerNonUserCode]
|
||||
get
|
||||
{
|
||||
if (_rigidBody == null)
|
||||
{
|
||||
_rigidBody = GetComponent<Rigidbody>();
|
||||
}
|
||||
|
||||
return _rigidBody;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the Rigidbody2D component, using a cached reference if possible.
|
||||
/// </summary>
|
||||
public Rigidbody2D CachedRigidBody2D
|
||||
{
|
||||
[DebuggerStepThrough]
|
||||
[DebuggerNonUserCode]
|
||||
get
|
||||
{
|
||||
if (_rigidbody2D == null)
|
||||
{
|
||||
_rigidbody2D = GetComponent<Rigidbody2D>();
|
||||
}
|
||||
|
||||
return _rigidbody2D;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the GameObject this behaviour is attached to, using a cached reference if possible.
|
||||
/// </summary>
|
||||
public GameObject CachedGameObject
|
||||
{
|
||||
[DebuggerStepThrough]
|
||||
[DebuggerNonUserCode]
|
||||
get
|
||||
{
|
||||
if (_gameObject == null)
|
||||
{
|
||||
_gameObject = base.gameObject;
|
||||
}
|
||||
|
||||
return _gameObject;
|
||||
}
|
||||
}
|
||||
|
||||
// Override existing getters for legacy usage
|
||||
|
||||
// ReSharper disable InconsistentNaming
|
||||
public new Transform transform
|
||||
{
|
||||
get { return CachedTransform; }
|
||||
}
|
||||
|
||||
#if !UNITY_5 && !UNITY_2017_1_OR_NEWER
|
||||
|
||||
public new Collider collider
|
||||
{
|
||||
get { return CachedCollider; }
|
||||
}
|
||||
public new Collider2D collider2D
|
||||
{
|
||||
get { return CachedCollider2D; }
|
||||
}
|
||||
public new Rigidbody rigidbody
|
||||
{
|
||||
get { return CachedRigidBody; }
|
||||
}
|
||||
public new Rigidbody2D rigidbody2D
|
||||
{
|
||||
get { return CachedRigidBody2D; }
|
||||
}
|
||||
public new GameObject gameObject
|
||||
{
|
||||
get { return CachedGameObject; }
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
// ReSharper restore InconsistentNaming
|
||||
|
||||
private Collider _collider;
|
||||
private Transform _transform;
|
||||
private Rigidbody _rigidBody;
|
||||
private GameObject _gameObject;
|
||||
private Rigidbody2D _rigidbody2D;
|
||||
private Collider2D _collider2D;
|
||||
|
||||
/// <summary>
|
||||
/// Assert that the value is not null, disable the object and print a debug error message if it is.
|
||||
/// </summary>
|
||||
/// <param name="value">Object to check</param>
|
||||
/// <param name="fieldName">Debug name to pass in</param>
|
||||
[DebuggerNonUserCode]
|
||||
[DebuggerStepThrough]
|
||||
protected void AssertNotNull(object value, string fieldName = null)
|
||||
{
|
||||
SRDebugUtil.AssertNotNull(value, fieldName, this);
|
||||
}
|
||||
|
||||
[DebuggerNonUserCode]
|
||||
[DebuggerStepThrough]
|
||||
protected void Assert(bool condition, string message = null)
|
||||
{
|
||||
SRDebugUtil.Assert(condition, message, this);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Assert that the value is not null, disable the object and print a debug error message if it is.
|
||||
/// </summary>
|
||||
/// <param name="value">Object to check</param>
|
||||
/// <param name="fieldName">Debug name to pass in</param>
|
||||
/// <returns>True if object is not null</returns>
|
||||
[Conditional("UNITY_EDITOR")]
|
||||
[DebuggerNonUserCode]
|
||||
[DebuggerStepThrough]
|
||||
protected void EditorAssertNotNull(object value, string fieldName = null)
|
||||
{
|
||||
AssertNotNull(value, fieldName);
|
||||
}
|
||||
|
||||
[Conditional("UNITY_EDITOR")]
|
||||
[DebuggerNonUserCode]
|
||||
[DebuggerStepThrough]
|
||||
protected void EditorAssert(bool condition, string message = null)
|
||||
{
|
||||
Assert(condition, message);
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a97a8611d5d683b4aa89a5054bc3774e
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
@@ -0,0 +1,215 @@
|
||||
// ReSharper disable once RedundantUsingDirective
|
||||
using System.Linq;
|
||||
|
||||
namespace SRF
|
||||
{
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
using Helpers;
|
||||
using Service;
|
||||
using UnityEngine;
|
||||
|
||||
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Field)]
|
||||
public sealed class RequiredFieldAttribute : Attribute
|
||||
{
|
||||
private bool _autoCreate;
|
||||
private bool _autoSearch;
|
||||
private bool _editorOnly = true;
|
||||
|
||||
public RequiredFieldAttribute(bool autoSearch)
|
||||
{
|
||||
AutoSearch = autoSearch;
|
||||
}
|
||||
|
||||
public RequiredFieldAttribute() {}
|
||||
|
||||
public bool AutoSearch
|
||||
{
|
||||
get { return _autoSearch; }
|
||||
set { _autoSearch = value; }
|
||||
}
|
||||
|
||||
public bool AutoCreate
|
||||
{
|
||||
get { return _autoCreate; }
|
||||
set { _autoCreate = value; }
|
||||
}
|
||||
|
||||
[Obsolete]
|
||||
public bool EditorOnly
|
||||
{
|
||||
get { return _editorOnly; }
|
||||
set { _editorOnly = value; }
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Add to a field to attempt to use SRServiceManager to get an instance of the field type
|
||||
/// </summary>
|
||||
[AttributeUsage(AttributeTargets.Field)]
|
||||
public class ImportAttribute : Attribute
|
||||
{
|
||||
public readonly Type Service;
|
||||
public ImportAttribute() {}
|
||||
|
||||
public ImportAttribute(Type serviceType)
|
||||
{
|
||||
Service = serviceType;
|
||||
}
|
||||
}
|
||||
|
||||
public abstract class SRMonoBehaviourEx : SRMonoBehaviour
|
||||
{
|
||||
private static Dictionary<Type, IList<FieldInfo>> _checkedFields;
|
||||
|
||||
private static void CheckFields(SRMonoBehaviourEx instance, bool justSet = false)
|
||||
{
|
||||
if (_checkedFields == null)
|
||||
{
|
||||
_checkedFields = new Dictionary<Type, IList<FieldInfo>>();
|
||||
}
|
||||
|
||||
var t = instance.GetType();
|
||||
|
||||
IList<FieldInfo> cache;
|
||||
|
||||
if (!_checkedFields.TryGetValue(instance.GetType(), out cache))
|
||||
{
|
||||
cache = ScanType(t);
|
||||
|
||||
_checkedFields.Add(t, cache);
|
||||
}
|
||||
|
||||
PopulateObject(cache, instance, justSet);
|
||||
}
|
||||
|
||||
private static void PopulateObject(IList<FieldInfo> cache, SRMonoBehaviourEx instance, bool justSet)
|
||||
{
|
||||
for (var i = 0; i < cache.Count; i++)
|
||||
{
|
||||
var f = cache[i];
|
||||
|
||||
if (!EqualityComparer<object>.Default.Equals(f.Field.GetValue(instance), null))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// If import is enabled, use SRServiceManager to import the reference
|
||||
if (f.Import)
|
||||
{
|
||||
var t = f.ImportType ?? f.Field.FieldType;
|
||||
|
||||
var service = SRServiceManager.GetService(t);
|
||||
|
||||
if (service == null)
|
||||
{
|
||||
Debug.LogWarning("Field {0} import failed (Type {1})".Fmt(f.Field.Name, t));
|
||||
continue;
|
||||
}
|
||||
|
||||
f.Field.SetValue(instance, service);
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
// If autoset is enabled on field, try and find the component on the GameObject
|
||||
|
||||
if (f.AutoSet)
|
||||
{
|
||||
var newValue = instance.GetComponent(f.Field.FieldType);
|
||||
|
||||
if (!EqualityComparer<object>.Default.Equals(newValue, null))
|
||||
{
|
||||
f.Field.SetValue(instance, newValue);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (justSet)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (f.AutoCreate)
|
||||
{
|
||||
var newValue = instance.CachedGameObject.AddComponent(f.Field.FieldType);
|
||||
f.Field.SetValue(instance, newValue);
|
||||
}
|
||||
|
||||
throw new UnassignedReferenceException(
|
||||
"Field {0} is unassigned, but marked with RequiredFieldAttribute".Fmt(f.Field.Name));
|
||||
}
|
||||
}
|
||||
|
||||
private static List<FieldInfo> ScanType(Type t)
|
||||
{
|
||||
var cache = new List<FieldInfo>();
|
||||
|
||||
// Check for attribute added to the class
|
||||
var globalAttr = SRReflection.GetAttribute<RequiredFieldAttribute>(t);
|
||||
|
||||
#if NETFX_CORE
|
||||
var fields = t.GetTypeInfo().DeclaredFields.Where(f => !f.IsStatic);
|
||||
#else
|
||||
// Check each field for the attribute
|
||||
var fields = t.GetFields(BindingFlags.Public | BindingFlags.Instance | BindingFlags.NonPublic);
|
||||
#endif
|
||||
|
||||
foreach (var f in fields)
|
||||
{
|
||||
var requiredFieldAttribute = SRReflection.GetAttribute<RequiredFieldAttribute>(f);
|
||||
var importAttribute = SRReflection.GetAttribute<ImportAttribute>(f);
|
||||
|
||||
if (globalAttr == null && requiredFieldAttribute == null && importAttribute == null)
|
||||
{
|
||||
continue; // Early out if no attributes found.
|
||||
}
|
||||
|
||||
var info = new FieldInfo();
|
||||
info.Field = f;
|
||||
|
||||
if (importAttribute != null)
|
||||
{
|
||||
info.Import = true;
|
||||
info.ImportType = importAttribute.Service;
|
||||
}
|
||||
else if (requiredFieldAttribute != null)
|
||||
{
|
||||
info.AutoSet = requiredFieldAttribute.AutoSearch;
|
||||
info.AutoCreate = requiredFieldAttribute.AutoCreate;
|
||||
}
|
||||
else
|
||||
{
|
||||
info.AutoSet = globalAttr.AutoSearch;
|
||||
info.AutoCreate = globalAttr.AutoCreate;
|
||||
}
|
||||
|
||||
cache.Add(info);
|
||||
}
|
||||
|
||||
return cache;
|
||||
}
|
||||
|
||||
protected virtual void Awake()
|
||||
{
|
||||
CheckFields(this);
|
||||
}
|
||||
|
||||
protected virtual void Start() {}
|
||||
protected virtual void Update() {}
|
||||
protected virtual void FixedUpdate() {}
|
||||
protected virtual void OnEnable() {}
|
||||
protected virtual void OnDisable() {}
|
||||
protected virtual void OnDestroy() {}
|
||||
|
||||
private struct FieldInfo
|
||||
{
|
||||
public bool AutoCreate;
|
||||
public bool AutoSet;
|
||||
public System.Reflection.FieldInfo Field;
|
||||
public bool Import;
|
||||
public Type ImportType;
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 82088ea802108344da1e919daa6881fd
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
@@ -0,0 +1,82 @@
|
||||
namespace SRF.Components
|
||||
{
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using UnityEngine;
|
||||
using Debug = UnityEngine.Debug;
|
||||
|
||||
/// <summary>
|
||||
/// Inherit from this component to easily create a singleton gameobject.
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
public abstract class SRSingleton<T> : SRMonoBehaviour where T : SRSingleton<T>
|
||||
{
|
||||
private static T _instance;
|
||||
|
||||
/// <summary>
|
||||
/// Get the instance of this singleton.
|
||||
/// </summary
|
||||
public static T Instance
|
||||
{
|
||||
[DebuggerStepThrough]
|
||||
get
|
||||
{
|
||||
// Instance requiered for the first time, we look for it
|
||||
if (_instance == null)
|
||||
{
|
||||
throw new InvalidOperationException("No instance of {0} present in scene".Fmt(typeof (T).Name));
|
||||
}
|
||||
return _instance;
|
||||
}
|
||||
}
|
||||
|
||||
public static bool HasInstance
|
||||
{
|
||||
[DebuggerStepThrough] get { return _instance != null; }
|
||||
}
|
||||
|
||||
private void Register()
|
||||
{
|
||||
if (_instance != null)
|
||||
{
|
||||
Debug.LogWarning("More than one singleton object of type {0} exists.".Fmt(typeof (T).Name));
|
||||
|
||||
// Check if gameobject only contains Transform and this component
|
||||
if (GetComponents<Component>().Length == 2)
|
||||
{
|
||||
Destroy(gameObject);
|
||||
}
|
||||
else
|
||||
{
|
||||
Destroy(this);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
_instance = (T) this;
|
||||
}
|
||||
|
||||
// If no other monobehaviour request the instance in an awake function
|
||||
// executing before this one, no need to search the object.
|
||||
protected virtual void Awake()
|
||||
{
|
||||
Register();
|
||||
}
|
||||
|
||||
protected virtual void OnEnable()
|
||||
{
|
||||
// In case of code-reload, this should restore the single instance
|
||||
if (_instance == null)
|
||||
{
|
||||
Register();
|
||||
}
|
||||
}
|
||||
|
||||
// Make sure the instance isn't referenced anymore when the user quit, just in case.
|
||||
private void OnApplicationQuit()
|
||||
{
|
||||
_instance = null;
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ca9e6e61f807f3442b520b02db3a48c7
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
Reference in New Issue
Block a user