mirror of
https://gitee.com/jisol/jisol-game/
synced 2025-09-27 10:46:17 +00:00
提交
This commit is contained in:
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3e39d7858311e1b458907e8eb53802c2
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,474 @@
|
||||
using UnityEngine;
|
||||
using UnityEngine.Audio;
|
||||
using YooAsset;
|
||||
|
||||
namespace SHFrame
|
||||
{
|
||||
public class AudioData : MemoryObject
|
||||
{
|
||||
public AssetHandle AssetOperationHandle { private set; get; }
|
||||
|
||||
public bool InPool { private set; get; } = false;
|
||||
|
||||
public override void InitFromPool()
|
||||
{
|
||||
}
|
||||
|
||||
public override void RecycleToPool()
|
||||
{
|
||||
if (!InPool)
|
||||
{
|
||||
AssetOperationHandle.Dispose();
|
||||
}
|
||||
|
||||
InPool = false;
|
||||
AssetOperationHandle = null;
|
||||
}
|
||||
|
||||
internal static AudioData Alloc(AssetHandle assetOperationHandle, bool inPool)
|
||||
{
|
||||
AudioData ret = ReferencePool.Acquire<AudioData>();
|
||||
ret.AssetOperationHandle = assetOperationHandle;
|
||||
ret.InPool = inPool;
|
||||
ret.InitFromPool();
|
||||
return ret;
|
||||
}
|
||||
|
||||
internal static void DeAlloc(AudioData audioData)
|
||||
{
|
||||
if (audioData != null)
|
||||
{
|
||||
ReferencePool.Release(audioData);
|
||||
audioData.RecycleToPool();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 音频代理辅助器。
|
||||
/// </summary>
|
||||
public class AudioAgent
|
||||
{
|
||||
private int _instanceId;
|
||||
private AudioSource _source;
|
||||
private AudioData _audioData;
|
||||
private AudioModuleImp _audioModuleImp;
|
||||
private Transform _transform;
|
||||
float _volume = 1.0f;
|
||||
float _duration;
|
||||
private float _fadeoutTimer;
|
||||
private const float FadeoutDuration = 0.2f;
|
||||
private bool _inPool;
|
||||
|
||||
private Transform _bindTransform;
|
||||
|
||||
/// <summary>
|
||||
/// 音频代理辅助器运行时状态。
|
||||
/// </summary>
|
||||
AudioAgentRuntimeState _audioAgentRuntimeState = AudioAgentRuntimeState.None;
|
||||
|
||||
/// <summary>
|
||||
/// 音频代理加载请求。
|
||||
/// </summary>
|
||||
class LoadRequest
|
||||
{
|
||||
public string Path;
|
||||
public bool BAsync;
|
||||
public bool BInPool;
|
||||
public Transform BindTransform;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 音频代理加载请求。
|
||||
/// </summary>
|
||||
LoadRequest _pendingLoad = null;
|
||||
|
||||
/// <summary>
|
||||
/// AudioSource实例化Id
|
||||
/// </summary>
|
||||
public int InstanceId => _instanceId;
|
||||
|
||||
/// <summary>
|
||||
/// 资源操作句柄。
|
||||
/// </summary>
|
||||
public AudioData AudioData => _audioData;
|
||||
|
||||
/// <summary>
|
||||
/// 音频代理辅助器音频大小。
|
||||
/// </summary>
|
||||
public float Volume
|
||||
{
|
||||
set
|
||||
{
|
||||
if (_source != null)
|
||||
{
|
||||
_volume = value;
|
||||
_source.volume = _volume;
|
||||
}
|
||||
}
|
||||
get => _volume;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 音频代理辅助器当前是否空闲。
|
||||
/// </summary>
|
||||
public bool IsFree
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_source != null)
|
||||
{
|
||||
return _audioAgentRuntimeState == AudioAgentRuntimeState.End;
|
||||
}
|
||||
else
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 音频代理辅助器播放秒数。
|
||||
/// </summary>
|
||||
public float Duration => _duration;
|
||||
|
||||
/// <summary>
|
||||
/// 音频代理辅助器当前音频长度。
|
||||
/// </summary>
|
||||
public float Length
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_source != null && _source.clip != null)
|
||||
{
|
||||
return _source.clip.length;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 音频代理辅助器实例位置。
|
||||
/// </summary>
|
||||
public Vector3 Position
|
||||
{
|
||||
get => _transform.position;
|
||||
set => _transform.position = value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 音频代理辅助器是否循环。
|
||||
/// </summary>
|
||||
public bool IsLoop
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_source != null)
|
||||
{
|
||||
return _source.loop;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
set
|
||||
{
|
||||
if (_source != null)
|
||||
{
|
||||
_source.loop = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 音频代理辅助器是否正在播放。
|
||||
/// </summary>
|
||||
internal bool IsPlaying
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_source != null && _source.isPlaying)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 音频代理辅助器获取当前声源。
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public AudioSource AudioResource()
|
||||
{
|
||||
return _source;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 创建音频代理辅助器。
|
||||
/// </summary>
|
||||
/// <param name="path">生效路径。</param>
|
||||
/// <param name="bAsync">是否异步。</param>
|
||||
/// <param name="audioCategory">音频轨道(类别)。</param>
|
||||
/// <param name="bInPool">是否池化。</param>
|
||||
/// <param name="bindTransform"></param>
|
||||
/// <returns>音频代理辅助器。</returns>
|
||||
public static AudioAgent Create(string path, bool bAsync, AudioCategory audioCategory, bool bInPool = false, Transform bindTransform = null)
|
||||
{
|
||||
AudioAgent audioAgent = new AudioAgent();
|
||||
audioAgent.Init(audioCategory);
|
||||
audioAgent.Load(path, bAsync, bInPool, bindTransform);
|
||||
return audioAgent;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 初始化音频代理辅助器。
|
||||
/// </summary>
|
||||
/// <param name="audioCategory">音频轨道(类别)。</param>
|
||||
/// <param name="index">音频代理辅助器编号。</param>
|
||||
public void Init(AudioCategory audioCategory, int index = 0)
|
||||
{
|
||||
_audioModuleImp = ModuleImpSystem.GetModule<AudioModuleImp>();
|
||||
GameObject host = new GameObject(Utility.Text.Format("Audio Agent Helper - {0} - {1}", audioCategory.AudioMixerGroup.name, index));
|
||||
host.transform.SetParent(audioCategory.InstanceRoot);
|
||||
host.transform.localPosition = Vector3.zero;
|
||||
_transform = host.transform;
|
||||
_source = host.AddComponent<AudioSource>();
|
||||
_source.playOnAwake = false;
|
||||
|
||||
AudioMixerGroup[] audioMixerGroups;
|
||||
if (audioCategory.AudioMixerGroup.name == "Sound")
|
||||
{
|
||||
audioMixerGroups = audioCategory.AudioMixer.FindMatchingGroups(Utility.Text.Format("Master/{0}/{1}", audioCategory.AudioMixerGroup.name,
|
||||
$"{audioCategory.AudioMixerGroup.name} - {index % 4}"));
|
||||
_source.spatialBlend = 1;
|
||||
_source.spread = 180f;
|
||||
}
|
||||
else
|
||||
{
|
||||
audioMixerGroups = audioCategory.AudioMixer.FindMatchingGroups(Utility.Text.Format("Master/{0}/{1}", audioCategory.AudioMixerGroup.name,
|
||||
$"{audioCategory.AudioMixerGroup.name} - {index}"));
|
||||
}
|
||||
|
||||
_source.outputAudioMixerGroup = audioMixerGroups.Length > 0 ? audioMixerGroups[0] : audioCategory.AudioMixerGroup;
|
||||
_source.rolloffMode = audioCategory.AudioGroupConfig.audioRolloffMode;
|
||||
_source.minDistance = audioCategory.AudioGroupConfig.minDistance;
|
||||
_source.maxDistance = audioCategory.AudioGroupConfig.maxDistance;
|
||||
_instanceId = _source.GetInstanceID();
|
||||
_bindTransform = null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 加载音频代理辅助器。
|
||||
/// </summary>
|
||||
/// <param name="path">资源路径。</param>
|
||||
/// <param name="bAsync">是否异步。</param>
|
||||
/// <param name="bInPool">是否池化。</param>
|
||||
/// <param name="bindTransform"></param>
|
||||
public void Load(string path, bool bAsync, bool bInPool = false, Transform bindTransform = null)
|
||||
{
|
||||
_inPool = bInPool;
|
||||
_bindTransform = bindTransform;
|
||||
if (_audioAgentRuntimeState == AudioAgentRuntimeState.None || _audioAgentRuntimeState == AudioAgentRuntimeState.End)
|
||||
{
|
||||
_duration = 0;
|
||||
if (!string.IsNullOrEmpty(path))
|
||||
{
|
||||
if (bInPool && _audioModuleImp.AudioClipPool.TryGetValue(path, out var operationHandle))
|
||||
{
|
||||
OnAssetLoadComplete(operationHandle);
|
||||
return;
|
||||
}
|
||||
|
||||
if (bAsync)
|
||||
{
|
||||
_audioAgentRuntimeState = AudioAgentRuntimeState.Loading;
|
||||
AssetHandle handle = YooAssets.LoadAssetAsync<AudioClip>(path);
|
||||
handle.Completed += OnAssetLoadComplete;
|
||||
}
|
||||
else
|
||||
{
|
||||
AssetHandle handle = YooAssets.LoadAssetSync<AudioClip>(path);
|
||||
OnAssetLoadComplete(handle);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_pendingLoad = new LoadRequest { Path = path, BAsync = bAsync, BInPool = bInPool, BindTransform = bindTransform };
|
||||
|
||||
if (_audioAgentRuntimeState == AudioAgentRuntimeState.Playing)
|
||||
{
|
||||
Stop(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 停止播放音频代理辅助器。
|
||||
/// </summary>
|
||||
/// <param name="fadeout">是否渐出。</param>
|
||||
public void Stop(bool fadeout = false)
|
||||
{
|
||||
if (_source != null)
|
||||
{
|
||||
if (fadeout)
|
||||
{
|
||||
_fadeoutTimer = FadeoutDuration;
|
||||
_audioAgentRuntimeState = AudioAgentRuntimeState.FadingOut;
|
||||
}
|
||||
else
|
||||
{
|
||||
_source.Stop();
|
||||
_audioAgentRuntimeState = AudioAgentRuntimeState.End;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 暂停音频代理辅助器。
|
||||
/// </summary>
|
||||
public void Pause()
|
||||
{
|
||||
if (_source != null)
|
||||
{
|
||||
_source.Pause();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 取消暂停音频代理辅助器。
|
||||
/// </summary>
|
||||
public void UnPause()
|
||||
{
|
||||
if (_source != null)
|
||||
{
|
||||
_source.UnPause();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 资源加载完成。
|
||||
/// </summary>
|
||||
/// <param name="handle">资源操作句柄。</param>
|
||||
void OnAssetLoadComplete(AssetHandle handle)
|
||||
{
|
||||
if (handle != null)
|
||||
{
|
||||
if (_inPool)
|
||||
{
|
||||
_audioModuleImp.AudioClipPool.TryAdd(handle.GetAssetInfo().Address, handle);
|
||||
}
|
||||
}
|
||||
|
||||
if (_pendingLoad != null)
|
||||
{
|
||||
if (!_inPool && handle != null)
|
||||
{
|
||||
handle.Dispose();
|
||||
}
|
||||
|
||||
_audioAgentRuntimeState = AudioAgentRuntimeState.End;
|
||||
string path = _pendingLoad.Path;
|
||||
bool bAsync = _pendingLoad.BAsync;
|
||||
bool bInPool = _pendingLoad.BInPool;
|
||||
Transform bindTransform = _pendingLoad.BindTransform;
|
||||
_pendingLoad = null;
|
||||
Load(path, bAsync, bInPool, bindTransform);
|
||||
}
|
||||
else if (handle != null)
|
||||
{
|
||||
if (_audioData != null)
|
||||
{
|
||||
AudioData.DeAlloc(_audioData);
|
||||
_audioData = null;
|
||||
}
|
||||
|
||||
_audioData = AudioData.Alloc(handle, _inPool);
|
||||
|
||||
_source.clip = handle.AssetObject as AudioClip;
|
||||
if (_source.clip != null)
|
||||
{
|
||||
_source.Play();
|
||||
_audioAgentRuntimeState = AudioAgentRuntimeState.Playing;
|
||||
}
|
||||
else
|
||||
{
|
||||
_audioAgentRuntimeState = AudioAgentRuntimeState.End;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_audioAgentRuntimeState = AudioAgentRuntimeState.End;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 轮询音频代理辅助器。
|
||||
/// </summary>
|
||||
/// <param name="elapseSeconds">逻辑流逝时间,以秒为单位。</param>
|
||||
public void Update(float elapseSeconds)
|
||||
{
|
||||
if (_audioAgentRuntimeState == AudioAgentRuntimeState.Playing)
|
||||
{
|
||||
if (_bindTransform != null)
|
||||
{
|
||||
_transform.position = _bindTransform.position;
|
||||
}
|
||||
|
||||
if (!_source.isPlaying)
|
||||
{
|
||||
_audioAgentRuntimeState = AudioAgentRuntimeState.End;
|
||||
}
|
||||
}
|
||||
else if (_audioAgentRuntimeState == AudioAgentRuntimeState.FadingOut)
|
||||
{
|
||||
if (_fadeoutTimer > 0f)
|
||||
{
|
||||
_fadeoutTimer -= elapseSeconds;
|
||||
_source.volume = _volume * _fadeoutTimer / FadeoutDuration;
|
||||
}
|
||||
else
|
||||
{
|
||||
Stop();
|
||||
if (_pendingLoad != null)
|
||||
{
|
||||
string path = _pendingLoad.Path;
|
||||
bool bAsync = _pendingLoad.BAsync;
|
||||
bool bInPool = _pendingLoad.BInPool;
|
||||
Transform bindTransform = _pendingLoad.BindTransform;
|
||||
_pendingLoad = null;
|
||||
Load(path, bAsync, bInPool, bindTransform);
|
||||
}
|
||||
|
||||
_source.volume = _volume;
|
||||
}
|
||||
}
|
||||
|
||||
_duration += elapseSeconds;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 销毁音频代理辅助器。
|
||||
/// </summary>
|
||||
public void Destroy()
|
||||
{
|
||||
if (_transform != null)
|
||||
{
|
||||
Object.Destroy(_transform.gameObject);
|
||||
}
|
||||
|
||||
if (_audioData != null)
|
||||
{
|
||||
AudioData.DeAlloc(_audioData);
|
||||
}
|
||||
|
||||
_bindTransform = null;
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6d4824a14181a0d4d921eb98fec100fe
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,33 @@
|
||||
namespace SHFrame
|
||||
{
|
||||
/// <summary>
|
||||
/// 音频代理辅助器运行时状态枚举。
|
||||
/// </summary>
|
||||
public enum AudioAgentRuntimeState
|
||||
{
|
||||
/// <summary>
|
||||
/// 无状态。
|
||||
/// </summary>
|
||||
None,
|
||||
|
||||
/// <summary>
|
||||
/// 加载中状态。
|
||||
/// </summary>
|
||||
Loading,
|
||||
|
||||
/// <summary>
|
||||
/// 播放中状态。
|
||||
/// </summary>
|
||||
Playing,
|
||||
|
||||
/// <summary>
|
||||
/// 渐渐消失状态。
|
||||
/// </summary>
|
||||
FadingOut,
|
||||
|
||||
/// <summary>
|
||||
/// 结束状态。
|
||||
/// </summary>
|
||||
End,
|
||||
};
|
||||
}
|
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f4ad4b8dc4cf4ecd813e58ec37406ba0
|
||||
timeCreated: 1694849619
|
@@ -0,0 +1,193 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Audio;
|
||||
|
||||
namespace SHFrame
|
||||
{
|
||||
/// <summary>
|
||||
/// 音频轨道(类别)。
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
public class AudioCategory
|
||||
{
|
||||
[SerializeField] private AudioMixer audioMixer = null;
|
||||
public List<AudioAgent> AudioAgents;
|
||||
private readonly AudioMixerGroup _audioMixerGroup;
|
||||
private AudioGroupConfig _audioGroupConfig;
|
||||
private int _maxChannel;
|
||||
private bool _bEnable = true;
|
||||
|
||||
/// <summary>
|
||||
/// 音频混响器。
|
||||
/// </summary>
|
||||
public AudioMixer AudioMixer => audioMixer;
|
||||
|
||||
/// <summary>
|
||||
/// 音频混响器组。
|
||||
/// </summary>
|
||||
public AudioMixerGroup AudioMixerGroup => _audioMixerGroup;
|
||||
|
||||
/// <summary>
|
||||
/// 音频组配置。
|
||||
/// </summary>
|
||||
public AudioGroupConfig AudioGroupConfig => _audioGroupConfig;
|
||||
|
||||
/// <summary>
|
||||
/// 实例化根节点。
|
||||
/// </summary>
|
||||
public Transform InstanceRoot { private set; get; }
|
||||
|
||||
/// <summary>
|
||||
/// 音频轨道是否启用。
|
||||
/// </summary>
|
||||
public bool Enable
|
||||
{
|
||||
get => _bEnable;
|
||||
set
|
||||
{
|
||||
if (_bEnable != value)
|
||||
{
|
||||
_bEnable = value;
|
||||
if (!_bEnable)
|
||||
{
|
||||
foreach (var audioAgent in AudioAgents)
|
||||
{
|
||||
if (audioAgent != null)
|
||||
{
|
||||
audioAgent.Stop();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 音频轨道构造函数。
|
||||
/// </summary>
|
||||
/// <param name="maxChannel">最大Channel。</param>
|
||||
/// <param name="audioMixer">音频混响器。</param>
|
||||
/// <param name="audioGroupConfig">音频轨道组配置。</param>
|
||||
public AudioCategory(int maxChannel, AudioMixer audioMixer, AudioGroupConfig audioGroupConfig)
|
||||
{
|
||||
this.audioMixer = audioMixer;
|
||||
_maxChannel = maxChannel;
|
||||
_audioGroupConfig = audioGroupConfig;
|
||||
AudioMixerGroup[] audioMixerGroups = audioMixer.FindMatchingGroups(Utility.Text.Format("Master/{0}", audioGroupConfig.AudioType.ToString()));
|
||||
if (audioMixerGroups.Length > 0)
|
||||
{
|
||||
_audioMixerGroup = audioMixerGroups[0];
|
||||
}
|
||||
else
|
||||
{
|
||||
_audioMixerGroup = audioMixer.FindMatchingGroups("Master")[0];
|
||||
}
|
||||
|
||||
AudioAgents = new List<AudioAgent>(32);
|
||||
InstanceRoot = new GameObject(Utility.Text.Format("Audio Category - {0}", _audioMixerGroup.name)).transform;
|
||||
InstanceRoot.SetParent(GameModule.Audio.InstanceRoot);
|
||||
for (int index = 0; index < _maxChannel; index++)
|
||||
{
|
||||
AudioAgent audioAgent = new AudioAgent();
|
||||
audioAgent.Init(this, index);
|
||||
AudioAgents.Add(audioAgent);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 增加音频。
|
||||
/// </summary>
|
||||
/// <param name="num"></param>
|
||||
public void AddAudio(int num)
|
||||
{
|
||||
_maxChannel += num;
|
||||
for (int i = 0; i < num; i++)
|
||||
{
|
||||
AudioAgents.Add(null);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 播放音频。
|
||||
/// </summary>
|
||||
/// <param name="path"></param>
|
||||
/// <param name="bAsync"></param>
|
||||
/// <param name="bInPool"></param>
|
||||
/// <param name="bindTransform"></param>
|
||||
/// <returns></returns>
|
||||
public AudioAgent Play(string path, bool bAsync, bool bInPool = false, Transform bindTransform = null)
|
||||
{
|
||||
if (!_bEnable)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
int freeChannel = -1;
|
||||
float duration = -1;
|
||||
|
||||
for (int i = 0; i < AudioAgents.Count; i++)
|
||||
{
|
||||
if (AudioAgents[i].AudioData?.AssetOperationHandle == null || AudioAgents[i].IsFree)
|
||||
{
|
||||
freeChannel = i;
|
||||
break;
|
||||
}
|
||||
else if (AudioAgents[i].Duration > duration)
|
||||
{
|
||||
duration = AudioAgents[i].Duration;
|
||||
freeChannel = i;
|
||||
}
|
||||
}
|
||||
|
||||
if (freeChannel >= 0)
|
||||
{
|
||||
if (AudioAgents[freeChannel] == null)
|
||||
{
|
||||
AudioAgents[freeChannel] = AudioAgent.Create(path, bAsync, this, bInPool, bindTransform);
|
||||
}
|
||||
else
|
||||
{
|
||||
AudioAgents[freeChannel].Load(path, bAsync, bInPool, bindTransform);
|
||||
}
|
||||
|
||||
return AudioAgents[freeChannel];
|
||||
}
|
||||
else
|
||||
{
|
||||
Log.Error($"Here is no channel to play audio {path}");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 暂停音频。
|
||||
/// </summary>
|
||||
/// <param name="fadeout">是否渐出</param>
|
||||
public void Stop(bool fadeout)
|
||||
{
|
||||
for (int i = 0; i < AudioAgents.Count; ++i)
|
||||
{
|
||||
if (AudioAgents[i] != null)
|
||||
{
|
||||
AudioAgents[i].Stop(fadeout);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 音频轨道轮询。
|
||||
/// </summary>
|
||||
/// <param name="elapseSeconds">逻辑流逝时间,以秒为单位。</param>
|
||||
public void Update(float elapseSeconds)
|
||||
{
|
||||
for (int i = 0; i < AudioAgents.Count; ++i)
|
||||
{
|
||||
if (AudioAgents[i] != null)
|
||||
{
|
||||
AudioAgents[i].Update(elapseSeconds);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6aefbd5a06fe1784590d373a93d1cf8a
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,48 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
namespace SHFrame
|
||||
{
|
||||
/// <summary>
|
||||
/// 音频轨道组配置。
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
public sealed class AudioGroupConfig
|
||||
{
|
||||
[SerializeField] private string m_Name = null;
|
||||
|
||||
[SerializeField] private bool m_Mute = false;
|
||||
|
||||
[SerializeField, Range(0f, 1f)] private float m_Volume = 1f;
|
||||
|
||||
[SerializeField] private int m_AgentHelperCount = 1;
|
||||
|
||||
public AudioType AudioType;
|
||||
|
||||
public AudioRolloffMode audioRolloffMode = AudioRolloffMode.Logarithmic;
|
||||
|
||||
public float minDistance = 1f;
|
||||
|
||||
public float maxDistance = 500f;
|
||||
|
||||
public string Name
|
||||
{
|
||||
get { return m_Name; }
|
||||
}
|
||||
|
||||
public bool Mute
|
||||
{
|
||||
get { return m_Mute; }
|
||||
}
|
||||
|
||||
public float Volume
|
||||
{
|
||||
get { return m_Volume; }
|
||||
}
|
||||
|
||||
public int AgentHelperCount
|
||||
{
|
||||
get { return m_AgentHelperCount; }
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 067935df275fd1340a935f81e7f3a768
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,217 @@
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Audio;
|
||||
|
||||
namespace SHFrame
|
||||
{
|
||||
/// <summary>
|
||||
/// 音效管理,为游戏提供统一的音效播放接口。
|
||||
/// </summary>
|
||||
/// <remarks>场景3D音效挂到场景物件、技能3D音效挂到技能特效上,并在AudioSource的Output上设置对应分类的AudioMixerGroup</remarks>
|
||||
public class AudioModule : Module
|
||||
{
|
||||
[SerializeField] private AudioMixer m_AudioMixer;
|
||||
|
||||
[SerializeField] private Transform m_InstanceRoot = null;
|
||||
|
||||
[SerializeField] private AudioGroupConfig[] m_AudioGroupConfigs = null;
|
||||
|
||||
public IAudioModule AudioModuleImp;
|
||||
|
||||
#region Public Propreties
|
||||
|
||||
/// <summary>
|
||||
/// 音频混响器。
|
||||
/// </summary>
|
||||
public AudioMixer MAudioMixer => m_AudioMixer;
|
||||
|
||||
/// <summary>
|
||||
/// 实例化根节点。
|
||||
/// </summary>
|
||||
public Transform InstanceRoot
|
||||
{
|
||||
get => m_InstanceRoot;
|
||||
set => m_InstanceRoot = value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 总音量控制。
|
||||
/// </summary>
|
||||
public float Volume
|
||||
{
|
||||
get => AudioModuleImp.Volume;
|
||||
set => AudioModuleImp.Volume = value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 总开关。
|
||||
/// </summary>
|
||||
public bool Enable
|
||||
{
|
||||
get => AudioModuleImp.Enable;
|
||||
set => AudioModuleImp.Enable = value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 音乐音量。
|
||||
/// </summary>
|
||||
public float MusicVolume
|
||||
{
|
||||
get => AudioModuleImp.MusicVolume;
|
||||
set => AudioModuleImp.MusicVolume = value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 音效音量。
|
||||
/// </summary>
|
||||
public float SoundVolume
|
||||
{
|
||||
get => AudioModuleImp.SoundVolume;
|
||||
set => AudioModuleImp.SoundVolume = value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// UI音效音量。
|
||||
/// </summary>
|
||||
public float UISoundVolume
|
||||
{
|
||||
get => AudioModuleImp.UISoundVolume;
|
||||
set => AudioModuleImp.UISoundVolume = value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 语音音量。
|
||||
/// </summary>
|
||||
public float VoiceVolume
|
||||
{
|
||||
get => AudioModuleImp.VoiceVolume;
|
||||
set => AudioModuleImp.VoiceVolume = value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 音乐开关
|
||||
/// </summary>
|
||||
public bool MusicEnable
|
||||
{
|
||||
get => AudioModuleImp.MusicEnable;
|
||||
set => AudioModuleImp.MusicEnable = value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 音效开关。
|
||||
/// </summary>
|
||||
public bool SoundEnable
|
||||
{
|
||||
get => AudioModuleImp.SoundEnable;
|
||||
set => AudioModuleImp.SoundEnable = value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// UI音效开关。
|
||||
/// </summary>
|
||||
public bool UISoundEnable
|
||||
{
|
||||
get => AudioModuleImp.UISoundEnable;
|
||||
set => AudioModuleImp.UISoundEnable = value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 语音开关。
|
||||
/// </summary>
|
||||
public bool VoiceEnable
|
||||
{
|
||||
get => AudioModuleImp.VoiceEnable;
|
||||
set => AudioModuleImp.VoiceEnable = value;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// 初始化音频模块。
|
||||
/// </summary>
|
||||
void Start()
|
||||
{
|
||||
if (AudioModuleImp == null)
|
||||
{
|
||||
AudioModuleImp = ModuleImpSystem.GetModule<AudioModuleImp>();
|
||||
}
|
||||
|
||||
if (m_InstanceRoot == null)
|
||||
{
|
||||
m_InstanceRoot = new GameObject("AudioModule Instances").transform;
|
||||
m_InstanceRoot.SetParent(gameObject.transform);
|
||||
m_InstanceRoot.localScale = Vector3.one;
|
||||
}
|
||||
|
||||
AudioModuleImp.Initialize(m_AudioGroupConfigs, m_InstanceRoot, m_AudioMixer);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 重启音频模块。
|
||||
/// </summary>
|
||||
public void Restart()
|
||||
{
|
||||
AudioModuleImp.Restart();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 播放,如果超过最大发声数采用fadeout的方式复用最久播放的AudioSource。
|
||||
/// </summary>
|
||||
/// <param name="type">声音类型</param>
|
||||
/// <param name="path">声音文件路径</param>
|
||||
/// <param name="bLoop">是否循环播放</param>>
|
||||
/// <param name="volume">音量(0-1.0)</param>
|
||||
/// <param name="bAsync">是否异步加载</param>
|
||||
/// <param name="bInPool">是否支持资源池</param>
|
||||
/// <param name="bindTransform"></param>
|
||||
public AudioAgent Play(AudioType type, string path, bool bLoop = false, float volume = 1.0f, bool bAsync = false, bool bInPool = false, Transform bindTransform = null)
|
||||
{
|
||||
return AudioModuleImp.Play(type, path, bLoop, volume, bAsync, bInPool, bindTransform);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 停止某类声音播放。
|
||||
/// </summary>
|
||||
/// <param name="type">声音类型。</param>
|
||||
/// <param name="fadeout">是否渐消。</param>
|
||||
public void Stop(AudioType type, bool fadeout)
|
||||
{
|
||||
AudioModuleImp.Stop(type, fadeout);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 停止所有声音。
|
||||
/// </summary>
|
||||
/// <param name="fadeout">是否渐消。</param>
|
||||
public void StopAll(bool fadeout)
|
||||
{
|
||||
AudioModuleImp.StopAll(fadeout);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 预先加载AudioClip,并放入对象池。
|
||||
/// </summary>
|
||||
/// <param name="list">AudioClip的AssetPath集合。</param>
|
||||
public void PutInAudioPool(List<string> list)
|
||||
{
|
||||
AudioModuleImp.PutInAudioPool(list);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 将部分AudioClip从对象池移出。
|
||||
/// </summary>
|
||||
/// <param name="list">AudioClip的AssetPath集合。</param>
|
||||
public void RemoveClipFromPool(List<string> list)
|
||||
{
|
||||
AudioModuleImp.RemoveClipFromPool(list);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 清空AudioClip的对象池。
|
||||
/// </summary>
|
||||
public void CleanSoundPool()
|
||||
{
|
||||
AudioModuleImp.CleanSoundPool();
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7d0b3cff83fd3874394b1b456bb54dab
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,561 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Audio;
|
||||
using YooAsset;
|
||||
|
||||
namespace SHFrame
|
||||
{
|
||||
[UpdateModule]
|
||||
internal class AudioModuleImp : ModuleImp, IAudioModule
|
||||
{
|
||||
private AudioMixer _audioMixer;
|
||||
private Transform _instanceRoot = null;
|
||||
private AudioGroupConfig[] _audioGroupConfigs = null;
|
||||
|
||||
private float _volume = 1f;
|
||||
private bool _enable = true;
|
||||
private readonly AudioCategory[] _audioCategories = new AudioCategory[(int)AudioType.Max];
|
||||
private readonly float[] _categoriesVolume = new float[(int)AudioType.Max];
|
||||
public readonly Dictionary<string, AssetHandle> AudioClipPool = new Dictionary<string, AssetHandle>();
|
||||
private bool _bUnityAudioDisabled = false;
|
||||
|
||||
#region Public Propreties
|
||||
|
||||
/// <summary>
|
||||
/// 音频混响器。
|
||||
/// </summary>
|
||||
public AudioMixer AudioMixer => _audioMixer;
|
||||
|
||||
/// <summary>
|
||||
/// 实例化根节点。
|
||||
/// </summary>
|
||||
public Transform InstanceRoot => _instanceRoot;
|
||||
|
||||
/// <summary>
|
||||
/// 总音量控制。
|
||||
/// </summary>
|
||||
public float Volume
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_bUnityAudioDisabled)
|
||||
{
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
return _volume;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (_bUnityAudioDisabled)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_volume = value;
|
||||
AudioListener.volume = _volume;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 总开关。
|
||||
/// </summary>
|
||||
public bool Enable
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_bUnityAudioDisabled)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return _enable;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (_bUnityAudioDisabled)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_enable = value;
|
||||
AudioListener.volume = _enable ? _volume : 0f;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 音乐音量。
|
||||
/// </summary>
|
||||
public float MusicVolume
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_bUnityAudioDisabled)
|
||||
{
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
return _categoriesVolume[(int)AudioType.Music];
|
||||
}
|
||||
set
|
||||
{
|
||||
if (_bUnityAudioDisabled)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
float volume = Mathf.Clamp(value, 0.0001f, 1.0f);
|
||||
_categoriesVolume[(int)AudioType.Music] = volume;
|
||||
_audioMixer.SetFloat("MusicVolume", Mathf.Log10(volume) * 20f);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 音效音量。
|
||||
/// </summary>
|
||||
public float SoundVolume
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_bUnityAudioDisabled)
|
||||
{
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
return _categoriesVolume[(int)AudioType.Sound];
|
||||
}
|
||||
set
|
||||
{
|
||||
if (_bUnityAudioDisabled)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
float volume = Mathf.Clamp(value, 0.0001f, 1.0f);
|
||||
_categoriesVolume[(int)AudioType.Sound] = volume;
|
||||
_audioMixer.SetFloat("SoundVolume", Mathf.Log10(volume) * 20f);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// UI音效音量。
|
||||
/// </summary>
|
||||
public float UISoundVolume
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_bUnityAudioDisabled)
|
||||
{
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
return _categoriesVolume[(int)AudioType.UISound];
|
||||
}
|
||||
set
|
||||
{
|
||||
if (_bUnityAudioDisabled)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
float volume = Mathf.Clamp(value, 0.0001f, 1.0f);
|
||||
_categoriesVolume[(int)AudioType.UISound] = volume;
|
||||
_audioMixer.SetFloat("UISoundVolume", Mathf.Log10(volume) * 20f);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 语音音量。
|
||||
/// </summary>
|
||||
public float VoiceVolume
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_bUnityAudioDisabled)
|
||||
{
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
return _categoriesVolume[(int)AudioType.Voice];
|
||||
}
|
||||
set
|
||||
{
|
||||
if (_bUnityAudioDisabled)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
float volume = Mathf.Clamp(value, 0.0001f, 1.0f);
|
||||
_categoriesVolume[(int)AudioType.Voice] = volume;
|
||||
_audioMixer.SetFloat("VoiceVolume", Mathf.Log10(volume) * 20f);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 音乐开关
|
||||
/// </summary>
|
||||
public bool MusicEnable
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_bUnityAudioDisabled)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (_audioMixer.GetFloat("MusicVolume", out var db))
|
||||
{
|
||||
return db > -80f;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
set
|
||||
{
|
||||
if (_bUnityAudioDisabled)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_audioCategories[(int)AudioType.Music].Enable = value;
|
||||
|
||||
// 音乐采用0音量方式,避免恢复播放时的复杂逻辑
|
||||
if (value)
|
||||
{
|
||||
_audioMixer.SetFloat("MusicVolume", Mathf.Log10(_categoriesVolume[(int)AudioType.Music]) * 20f);
|
||||
}
|
||||
else
|
||||
{
|
||||
_audioMixer.SetFloat("MusicVolume", -80f);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 音效开关。
|
||||
/// </summary>
|
||||
public bool SoundEnable
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_bUnityAudioDisabled)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return _audioCategories[(int)AudioType.Sound].Enable;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (_bUnityAudioDisabled)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_audioCategories[(int)AudioType.Sound].Enable = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// UI音效开关。
|
||||
/// </summary>
|
||||
public bool UISoundEnable
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_bUnityAudioDisabled)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return _audioCategories[(int)AudioType.UISound].Enable;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (_bUnityAudioDisabled)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_audioCategories[(int)AudioType.UISound].Enable = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 语音开关。
|
||||
/// </summary>
|
||||
public bool VoiceEnable
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_bUnityAudioDisabled)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return _audioCategories[(int)AudioType.Voice].Enable;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (_bUnityAudioDisabled)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_audioCategories[(int)AudioType.Voice].Enable = value;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
internal override void Shutdown()
|
||||
{
|
||||
StopAll(fadeout: false);
|
||||
CleanSoundPool();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 初始化音频模块。
|
||||
/// </summary>
|
||||
/// <param name="audioGroupConfigs">音频轨道组配置。</param>
|
||||
/// <param name="instanceRoot">实例化根节点。</param>
|
||||
/// <param name="audioMixer">音频混响器。</param>
|
||||
/// <exception cref="GameFrameworkException"></exception>
|
||||
public void Initialize(AudioGroupConfig[] audioGroupConfigs, Transform instanceRoot = null, AudioMixer audioMixer = null)
|
||||
{
|
||||
if (_instanceRoot == null)
|
||||
{
|
||||
_instanceRoot = instanceRoot;
|
||||
}
|
||||
|
||||
if (audioGroupConfigs == null)
|
||||
{
|
||||
throw new GameFrameworkException("AudioGroupConfig[] is invalid.");
|
||||
}
|
||||
|
||||
_audioGroupConfigs = audioGroupConfigs;
|
||||
|
||||
if (_instanceRoot == null)
|
||||
{
|
||||
_instanceRoot = new GameObject("AudioModule Instances").transform;
|
||||
_instanceRoot.SetParent(GameModule.Audio.transform);
|
||||
_instanceRoot.localScale = Vector3.one;
|
||||
GameModule.Audio.InstanceRoot = _instanceRoot;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
TypeInfo typeInfo = typeof(AudioSettings).GetTypeInfo();
|
||||
PropertyInfo propertyInfo = typeInfo.GetDeclaredProperty("unityAudioDisabled");
|
||||
_bUnityAudioDisabled = (bool)propertyInfo.GetValue(null);
|
||||
if (_bUnityAudioDisabled)
|
||||
{
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Log.Error(e.ToString());
|
||||
}
|
||||
|
||||
if (audioMixer != null)
|
||||
{
|
||||
_audioMixer = audioMixer;
|
||||
}
|
||||
|
||||
if (_audioMixer == null)
|
||||
{
|
||||
_audioMixer = Resources.Load<AudioMixer>("AudioMixer");
|
||||
}
|
||||
|
||||
for (int index = 0; index < (int)AudioType.Max; ++index)
|
||||
{
|
||||
AudioType audioType = (AudioType)index;
|
||||
AudioGroupConfig audioGroupConfig = _audioGroupConfigs.First(t => t.AudioType == audioType);
|
||||
_audioCategories[index] = new AudioCategory(audioGroupConfig.AgentHelperCount, _audioMixer, audioGroupConfig);
|
||||
_categoriesVolume[index] = audioGroupConfig.Volume;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 重启音频模块。
|
||||
/// </summary>
|
||||
public void Restart()
|
||||
{
|
||||
if (_bUnityAudioDisabled)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
CleanSoundPool();
|
||||
|
||||
for (int i = 0; i < (int)AudioType.Max; ++i)
|
||||
{
|
||||
var audioCategory = _audioCategories[i];
|
||||
if (audioCategory != null)
|
||||
{
|
||||
for (int j = 0; j < audioCategory.AudioAgents.Count; ++j)
|
||||
{
|
||||
var audioAgent = audioCategory.AudioAgents[j];
|
||||
if (audioAgent != null)
|
||||
{
|
||||
audioAgent.Destroy();
|
||||
audioAgent = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
audioCategory = null;
|
||||
}
|
||||
|
||||
Initialize(_audioGroupConfigs);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 播放,如果超过最大发声数采用fadeout的方式复用最久播放的AudioSource。
|
||||
/// </summary>
|
||||
/// <param name="type">声音类型</param>
|
||||
/// <param name="path">声音文件路径</param>
|
||||
/// <param name="bLoop">是否循环播放</param>>
|
||||
/// <param name="volume">音量(0-1.0)</param>
|
||||
/// <param name="bAsync">是否异步加载</param>
|
||||
/// <param name="bInPool">是否支持资源池</param>
|
||||
/// <param name="bindTransform"></param>
|
||||
public AudioAgent Play(AudioType type, string path, bool bLoop = false, float volume = 1.0f, bool bAsync = false, bool bInPool = false, Transform bindTransform = null)
|
||||
{
|
||||
if (_bUnityAudioDisabled)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
AudioAgent audioAgent = _audioCategories[(int)type].Play(path, bAsync, bInPool, bindTransform);
|
||||
{
|
||||
if (audioAgent != null)
|
||||
{
|
||||
audioAgent.IsLoop = bLoop;
|
||||
audioAgent.Volume = volume;
|
||||
}
|
||||
|
||||
return audioAgent;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 停止某类声音播放。
|
||||
/// </summary>
|
||||
/// <param name="type">声音类型。</param>
|
||||
/// <param name="fadeout">是否渐消。</param>
|
||||
public void Stop(AudioType type, bool fadeout)
|
||||
{
|
||||
if (_bUnityAudioDisabled)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_audioCategories[(int)type].Stop(fadeout);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 停止所有声音。
|
||||
/// </summary>
|
||||
/// <param name="fadeout">是否渐消。</param>
|
||||
public void StopAll(bool fadeout)
|
||||
{
|
||||
if (_bUnityAudioDisabled)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
for (int i = 0; i < (int)AudioType.Max; ++i)
|
||||
{
|
||||
if (_audioCategories[i] != null)
|
||||
{
|
||||
_audioCategories[i].Stop(fadeout);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 预先加载AudioClip,并放入对象池。
|
||||
/// </summary>
|
||||
/// <param name="list">AudioClip的AssetPath集合。</param>
|
||||
public void PutInAudioPool(List<string> list)
|
||||
{
|
||||
if (_bUnityAudioDisabled)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
foreach (string path in list)
|
||||
{
|
||||
if (AudioClipPool != null && !AudioClipPool.ContainsKey(path))
|
||||
{
|
||||
AssetHandle assetData = YooAssets.LoadAssetSync<AudioClip>(path);
|
||||
AudioClipPool?.Add(path, assetData);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 将部分AudioClip从对象池移出。
|
||||
/// </summary>
|
||||
/// <param name="list">AudioClip的AssetPath集合。</param>
|
||||
public void RemoveClipFromPool(List<string> list)
|
||||
{
|
||||
if (_bUnityAudioDisabled)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
foreach (string path in list)
|
||||
{
|
||||
if (AudioClipPool.ContainsKey(path))
|
||||
{
|
||||
AudioClipPool[path].Dispose();
|
||||
AudioClipPool.Remove(path);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 清空AudioClip的对象池。
|
||||
/// </summary>
|
||||
public void CleanSoundPool()
|
||||
{
|
||||
if (_bUnityAudioDisabled)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
foreach (var dic in AudioClipPool)
|
||||
{
|
||||
dic.Value.Dispose();
|
||||
}
|
||||
|
||||
AudioClipPool.Clear();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 音频模块轮询。
|
||||
/// </summary>
|
||||
/// <param name="elapseSeconds">逻辑流逝时间,以秒为单位。</param>
|
||||
/// <param name="realElapseSeconds">真实流逝时间,以秒为单位。</param>
|
||||
internal override void Update(float elapseSeconds, float realElapseSeconds)
|
||||
{
|
||||
foreach (var audioCategory in _audioCategories)
|
||||
{
|
||||
if (audioCategory != null)
|
||||
{
|
||||
audioCategory.Update(elapseSeconds);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c35bbf6a82844c72b71b9bbe44f44a1e
|
||||
timeCreated: 1694847017
|
@@ -0,0 +1,34 @@
|
||||
namespace SHFrame
|
||||
{
|
||||
/// <summary>
|
||||
/// 音效分类,可分别关闭/开启对应分类音效。
|
||||
/// </summary>
|
||||
/// <remarks>命名与AudioMixer中分类名保持一致。</remarks>
|
||||
public enum AudioType
|
||||
{
|
||||
/// <summary>
|
||||
/// 声音音效。
|
||||
/// </summary>
|
||||
Sound,
|
||||
|
||||
/// <summary>
|
||||
/// UI声效。
|
||||
/// </summary>
|
||||
UISound,
|
||||
|
||||
/// <summary>
|
||||
/// 背景音乐音效。
|
||||
/// </summary>
|
||||
Music,
|
||||
|
||||
/// <summary>
|
||||
/// 人声音效。
|
||||
/// </summary>
|
||||
Voice,
|
||||
|
||||
/// <summary>
|
||||
/// 最大。
|
||||
/// </summary>
|
||||
Max
|
||||
}
|
||||
}
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b4b86f93180273b4996d4f8c428def09
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,116 @@
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Audio;
|
||||
|
||||
namespace SHFrame
|
||||
{
|
||||
public interface IAudioModule
|
||||
{
|
||||
/// <summary>
|
||||
/// 总音量控制。
|
||||
/// </summary>
|
||||
public float Volume { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 总开关。
|
||||
/// </summary>
|
||||
public bool Enable { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 音乐音量
|
||||
/// </summary>
|
||||
public float MusicVolume { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 音效音量。
|
||||
/// </summary>
|
||||
public float SoundVolume { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// UI音效音量。
|
||||
/// </summary>
|
||||
public float UISoundVolume { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 语音音量。
|
||||
/// </summary>
|
||||
public float VoiceVolume { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 音乐开关。
|
||||
/// </summary>
|
||||
public bool MusicEnable { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 音效开关。
|
||||
/// </summary>
|
||||
public bool SoundEnable { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// UI音效开关。
|
||||
/// </summary>
|
||||
public bool UISoundEnable { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 语音开关。
|
||||
/// </summary>
|
||||
public bool VoiceEnable { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 初始化音频模块。
|
||||
/// </summary>
|
||||
/// <param name="audioGroupConfigs">音频轨道组配置。</param>
|
||||
/// <param name="instanceRoot">实例化根节点。</param>
|
||||
/// <param name="audioMixer">音频混响器。</param>
|
||||
/// <exception cref="GameFrameworkException"></exception>
|
||||
public void Initialize(AudioGroupConfig[] audioGroupConfigs, Transform instanceRoot = null, AudioMixer audioMixer = null);
|
||||
|
||||
/// <summary>
|
||||
/// 重启音频模块。
|
||||
/// </summary>
|
||||
public void Restart();
|
||||
|
||||
/// <summary>
|
||||
/// 播放音频接口。
|
||||
/// </summary>
|
||||
/// <remarks>如果超过最大发声数采用fadeout的方式复用最久播放的AudioSource。</remarks>
|
||||
/// <param name="type">声音类型。</param>
|
||||
/// <param name="path">声音文件路径。</param>
|
||||
/// <param name="bLoop">是否循环播放。</param>>
|
||||
/// <param name="volume">音量(0-1.0)。</param>
|
||||
/// <param name="bAsync">是否异步加载。</param>
|
||||
/// <param name="bInPool">是否支持资源池。</param>
|
||||
/// <param name="bindTransform"></param>
|
||||
public AudioAgent Play(AudioType type, string path, bool bLoop = false, float volume = 1.0f, bool bAsync = false, bool bInPool = false, Transform bindTransform = null);
|
||||
|
||||
/// <summary>
|
||||
/// 停止某类声音播放。
|
||||
/// </summary>
|
||||
/// <param name="type">声音类型。</param>
|
||||
/// <param name="fadeout">是否渐消。</param>
|
||||
public void Stop(AudioType type, bool fadeout);
|
||||
|
||||
/// <summary>
|
||||
/// 停止所有声音。
|
||||
/// </summary>
|
||||
/// <param name="fadeout">是否渐消。</param>
|
||||
public void StopAll(bool fadeout);
|
||||
|
||||
/// <summary>
|
||||
/// 预先加载AudioClip,并放入对象池。
|
||||
/// </summary>
|
||||
/// <param name="list">AudioClip的AssetPath集合。</param>
|
||||
public void PutInAudioPool(List<string> list);
|
||||
|
||||
/// <summary>
|
||||
/// 将部分AudioClip从对象池移出。
|
||||
/// </summary>
|
||||
/// <param name="list">AudioClip的AssetPath集合。</param>
|
||||
public void RemoveClipFromPool(List<string> list);
|
||||
|
||||
/// <summary>
|
||||
/// 清空AudioClip的对象池。
|
||||
/// </summary>
|
||||
public void CleanSoundPool();
|
||||
}
|
||||
}
|
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f2a332020228453d8546d5d74aa60f9c
|
||||
timeCreated: 1694847151
|
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 64a654fc0d761c24e9676a185ea4df8e
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,708 @@
|
||||
%YAML 1.1
|
||||
%TAG !u! tag:unity3d.com,2011:
|
||||
--- !u!244 &-8255999005317483048
|
||||
AudioMixerEffectController:
|
||||
m_ObjectHideFlags: 3
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_Name:
|
||||
m_EffectID: 5256fbc85eb3f884eb780f730c8da825
|
||||
m_EffectName: Attenuation
|
||||
m_MixLevel: 989fcb1cc28d4de4ea6e56c14101e674
|
||||
m_Parameters: []
|
||||
m_SendTarget: {fileID: 0}
|
||||
m_EnableWetMix: 0
|
||||
m_Bypass: 0
|
||||
--- !u!244 &-8165904320333843496
|
||||
AudioMixerEffectController:
|
||||
m_ObjectHideFlags: 3
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_Name:
|
||||
m_EffectID: 6b8ac75d99b7e57489701e084ea19b1f
|
||||
m_EffectName: Attenuation
|
||||
m_MixLevel: b19e64315aff6dc4a81ae36b22fc0492
|
||||
m_Parameters: []
|
||||
m_SendTarget: {fileID: 0}
|
||||
m_EnableWetMix: 0
|
||||
m_Bypass: 0
|
||||
--- !u!244 &-7861682458482441818
|
||||
AudioMixerEffectController:
|
||||
m_ObjectHideFlags: 3
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_Name:
|
||||
m_EffectID: dcc48474d251d554e9f6f95668853a39
|
||||
m_EffectName: Receive
|
||||
m_MixLevel: e6248274fab455749bc046d72eace6de
|
||||
m_Parameters: []
|
||||
m_SendTarget: {fileID: 0}
|
||||
m_EnableWetMix: 0
|
||||
m_Bypass: 0
|
||||
--- !u!243 &-7758028812591520460
|
||||
AudioMixerGroupController:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_Name: Sound - 2
|
||||
m_AudioMixer: {fileID: 24100000}
|
||||
m_GroupID: 039cd795affa7134a8d5f5d43d3b659d
|
||||
m_Children: []
|
||||
m_Volume: 2a8ce0f3383c3f0468a04fa3fc5e317d
|
||||
m_Pitch: b47f0c73299cd9b4fba9896e70683903
|
||||
m_Send: 00000000000000000000000000000000
|
||||
m_Effects:
|
||||
- {fileID: -3825599753161013374}
|
||||
m_UserColorIndex: 2
|
||||
m_Mute: 0
|
||||
m_Solo: 0
|
||||
m_BypassEffects: 0
|
||||
--- !u!243 &-6280614258348125054
|
||||
AudioMixerGroupController:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_Name: Sound - 1
|
||||
m_AudioMixer: {fileID: 24100000}
|
||||
m_GroupID: c0d40106c2ffb1a44bd48f50b210ee20
|
||||
m_Children: []
|
||||
m_Volume: f62a8b3fe89df00409532af739ee4e02
|
||||
m_Pitch: 77212647508232a458ac7d48fb55d037
|
||||
m_Send: 00000000000000000000000000000000
|
||||
m_Effects:
|
||||
- {fileID: -1890011256548497850}
|
||||
m_UserColorIndex: 2
|
||||
m_Mute: 0
|
||||
m_Solo: 0
|
||||
m_BypassEffects: 0
|
||||
--- !u!244 &-4958177229083455073
|
||||
AudioMixerEffectController:
|
||||
m_ObjectHideFlags: 3
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_Name:
|
||||
m_EffectID: 104113b95764fe344a5d25469377c800
|
||||
m_EffectName: Attenuation
|
||||
m_MixLevel: 9ef29befaad178d4386e9d5ac022f964
|
||||
m_Parameters: []
|
||||
m_SendTarget: {fileID: 0}
|
||||
m_EnableWetMix: 0
|
||||
m_Bypass: 0
|
||||
--- !u!243 &-4372808504093502661
|
||||
AudioMixerGroupController:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_Name: Sound - 3
|
||||
m_AudioMixer: {fileID: 24100000}
|
||||
m_GroupID: 5f20d1b8f9ac1914dac8beae718e7d40
|
||||
m_Children: []
|
||||
m_Volume: e54edf7c1bf7ee44297e65adce5b10b7
|
||||
m_Pitch: 8542b6bfd7b7bfc4d9b961ba97edf0d2
|
||||
m_Send: 00000000000000000000000000000000
|
||||
m_Effects:
|
||||
- {fileID: 6637688299338053042}
|
||||
m_UserColorIndex: 2
|
||||
m_Mute: 0
|
||||
m_Solo: 0
|
||||
m_BypassEffects: 0
|
||||
--- !u!243 &-4209890294574411305
|
||||
AudioMixerGroupController:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_Name: Music
|
||||
m_AudioMixer: {fileID: 24100000}
|
||||
m_GroupID: efe8591c00084024187b9df78858c0af
|
||||
m_Children:
|
||||
- {fileID: 1543978434442340687}
|
||||
m_Volume: 6d4c2b8bc0ef38d44b2fbff2b3298ab4
|
||||
m_Pitch: 862389c428a73854ab442dd043008729
|
||||
m_Send: 00000000000000000000000000000000
|
||||
m_Effects:
|
||||
- {fileID: 246003612463095956}
|
||||
m_UserColorIndex: 1
|
||||
m_Mute: 0
|
||||
m_Solo: 0
|
||||
m_BypassEffects: 0
|
||||
--- !u!244 &-3825599753161013374
|
||||
AudioMixerEffectController:
|
||||
m_ObjectHideFlags: 3
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_Name:
|
||||
m_EffectID: d1bbcc7cbe0a53c459c9064925118e41
|
||||
m_EffectName: Attenuation
|
||||
m_MixLevel: e43bb5de098a2ec49807913fa5fdd2f7
|
||||
m_Parameters: []
|
||||
m_SendTarget: {fileID: 0}
|
||||
m_EnableWetMix: 0
|
||||
m_Bypass: 0
|
||||
--- !u!243 &-3720557753501792270
|
||||
AudioMixerGroupController:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_Name: UISound - 1
|
||||
m_AudioMixer: {fileID: 24100000}
|
||||
m_GroupID: e012b6d2e0501df43a88eb6beff8ae07
|
||||
m_Children: []
|
||||
m_Volume: 265eaf7c8910ab842a845c7bb5e570c4
|
||||
m_Pitch: bf3ca9b57c9a67b40944a59839b12f62
|
||||
m_Send: 00000000000000000000000000000000
|
||||
m_Effects:
|
||||
- {fileID: 5734415080786067514}
|
||||
m_UserColorIndex: 3
|
||||
m_Mute: 0
|
||||
m_Solo: 0
|
||||
m_BypassEffects: 0
|
||||
--- !u!243 &-3395020342500439107
|
||||
AudioMixerGroupController:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_Name: Voice
|
||||
m_AudioMixer: {fileID: 24100000}
|
||||
m_GroupID: 5117f9b5a365ec049a9d5891c563b893
|
||||
m_Children:
|
||||
- {fileID: -1649243360580130678}
|
||||
m_Volume: fe15a1b40c14ea646a13dacb15b6a73b
|
||||
m_Pitch: 3398197a464677a4186e0cecd66bb13c
|
||||
m_Send: 00000000000000000000000000000000
|
||||
m_Effects:
|
||||
- {fileID: -8165904320333843496}
|
||||
m_UserColorIndex: 6
|
||||
m_Mute: 0
|
||||
m_Solo: 0
|
||||
m_BypassEffects: 0
|
||||
--- !u!243 &-2659745067392564156
|
||||
AudioMixerGroupController:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_Name: Sound - 0
|
||||
m_AudioMixer: {fileID: 24100000}
|
||||
m_GroupID: 71c50c6b966d1f548a63193919ebfbad
|
||||
m_Children: []
|
||||
m_Volume: 7835f2c4248cb3e43a1a773bab1f8b9d
|
||||
m_Pitch: 30975daa872456b41bc18e0277e301e6
|
||||
m_Send: 00000000000000000000000000000000
|
||||
m_Effects:
|
||||
- {fileID: -284252157345190109}
|
||||
m_UserColorIndex: 2
|
||||
m_Mute: 0
|
||||
m_Solo: 0
|
||||
m_BypassEffects: 0
|
||||
--- !u!244 &-1890011256548497850
|
||||
AudioMixerEffectController:
|
||||
m_ObjectHideFlags: 3
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_Name:
|
||||
m_EffectID: 520975c71ea21c249b3cdf1f22032e57
|
||||
m_EffectName: Attenuation
|
||||
m_MixLevel: 932e3e893621c5b46bff3c368017e689
|
||||
m_Parameters: []
|
||||
m_SendTarget: {fileID: 0}
|
||||
m_EnableWetMix: 0
|
||||
m_Bypass: 0
|
||||
--- !u!243 &-1649243360580130678
|
||||
AudioMixerGroupController:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_Name: Voice - 0
|
||||
m_AudioMixer: {fileID: 24100000}
|
||||
m_GroupID: f46651e8ad3c6034b8764fd635dda3fd
|
||||
m_Children: []
|
||||
m_Volume: 0bc64c1c6cebbeb40ba2f724fdcaa257
|
||||
m_Pitch: fff252bdd985513469f8607e016fc594
|
||||
m_Send: 00000000000000000000000000000000
|
||||
m_Effects:
|
||||
- {fileID: -890847686165078200}
|
||||
m_UserColorIndex: 6
|
||||
m_Mute: 0
|
||||
m_Solo: 0
|
||||
m_BypassEffects: 0
|
||||
--- !u!244 &-998299258853400712
|
||||
AudioMixerEffectController:
|
||||
m_ObjectHideFlags: 3
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_Name:
|
||||
m_EffectID: d7d19927abbe5584080506164cb4e644
|
||||
m_EffectName: Attenuation
|
||||
m_MixLevel: 0b4264524e3eafc49b2daba7fba2ce97
|
||||
m_Parameters: []
|
||||
m_SendTarget: {fileID: 0}
|
||||
m_EnableWetMix: 0
|
||||
m_Bypass: 0
|
||||
--- !u!244 &-890847686165078200
|
||||
AudioMixerEffectController:
|
||||
m_ObjectHideFlags: 3
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_Name:
|
||||
m_EffectID: 4b41d8aa7a7944041a8b9428add83eff
|
||||
m_EffectName: Attenuation
|
||||
m_MixLevel: 73b7a9825978be245a1962a1001b0212
|
||||
m_Parameters: []
|
||||
m_SendTarget: {fileID: 0}
|
||||
m_EnableWetMix: 0
|
||||
m_Bypass: 0
|
||||
--- !u!244 &-284252157345190109
|
||||
AudioMixerEffectController:
|
||||
m_ObjectHideFlags: 3
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_Name:
|
||||
m_EffectID: 15668b74147caee41a72f695c3a2de56
|
||||
m_EffectName: Attenuation
|
||||
m_MixLevel: f71e84fb9a62ff24cad690a0a86cc47e
|
||||
m_Parameters: []
|
||||
m_SendTarget: {fileID: 0}
|
||||
m_EnableWetMix: 0
|
||||
m_Bypass: 0
|
||||
--- !u!244 &-21257493329335984
|
||||
AudioMixerEffectController:
|
||||
m_ObjectHideFlags: 3
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_Name:
|
||||
m_EffectID: c9a6f7a9214534644bf2e6d83ff86569
|
||||
m_EffectName: Distortion
|
||||
m_MixLevel: 3f356cddae5dba949a6e8f4d20564d3e
|
||||
m_Parameters:
|
||||
- m_ParameterName: Level
|
||||
m_GUID: 080be1914d960974481df4bebe2a2d77
|
||||
m_SendTarget: {fileID: 0}
|
||||
m_EnableWetMix: 0
|
||||
m_Bypass: 0
|
||||
--- !u!241 &24100000
|
||||
AudioMixerController:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_Name: AudioMixer
|
||||
m_OutputGroup: {fileID: 0}
|
||||
m_MasterGroup: {fileID: 24300002}
|
||||
m_Snapshots:
|
||||
- {fileID: 24500006}
|
||||
m_StartSnapshot: {fileID: 24500006}
|
||||
m_SuspendThreshold: -80
|
||||
m_EnableSuspend: 1
|
||||
m_UpdateMode: 0
|
||||
m_ExposedParameters:
|
||||
- guid: 7835f2c4248cb3e43a1a773bab1f8b9d
|
||||
name: SoundVolume0
|
||||
- guid: 41591fd4a32f4034f880ecbc14ee69f1
|
||||
name: MusicVolume0
|
||||
- guid: 6e0d1a5935a802d41b27d9e2fad3ba2f
|
||||
name: UISoundVolume0
|
||||
- guid: 0bc64c1c6cebbeb40ba2f724fdcaa257
|
||||
name: VoiceVolume0
|
||||
- guid: f62a8b3fe89df00409532af739ee4e02
|
||||
name: SoundVolume1
|
||||
- guid: 265eaf7c8910ab842a845c7bb5e570c4
|
||||
name: UISoundVolume1
|
||||
- guid: 2a8ce0f3383c3f0468a04fa3fc5e317d
|
||||
name: SoundVolume2
|
||||
- guid: e83be6d6c4ae85142a51f584159c4ff6
|
||||
name: UISoundVolume2
|
||||
- guid: e54edf7c1bf7ee44297e65adce5b10b7
|
||||
name: SoundVolume3
|
||||
- guid: 2dd26f9dadf160f4bbd77f307c3f4f2e
|
||||
name: UISoundVolume3
|
||||
- guid: ba83e724007d7e9459f157db3a54a741
|
||||
name: MasterVolume
|
||||
- guid: 6d4c2b8bc0ef38d44b2fbff2b3298ab4
|
||||
name: MusicVolume
|
||||
- guid: 3bbd22597ed32714eb271cf06b098c63
|
||||
name: SoundVolume
|
||||
- guid: 7d1c7ed015f5dba4f934c33ef330c5eb
|
||||
name: UISoundVolume
|
||||
- guid: fe15a1b40c14ea646a13dacb15b6a73b
|
||||
name: VoiceVolume
|
||||
m_AudioMixerGroupViews:
|
||||
- guids:
|
||||
- 72c1e77b100e3274fbfb88ca2ca12c4d
|
||||
- efe8591c00084024187b9df78858c0af
|
||||
- 648e49a020cf83346a9220d606e4ff39
|
||||
- 5117f9b5a365ec049a9d5891c563b893
|
||||
- f46651e8ad3c6034b8764fd635dda3fd
|
||||
- 1cf576bd46399874d9494863d6502d94
|
||||
- 71c50c6b966d1f548a63193919ebfbad
|
||||
- df986418fa3e4ae448a1909ffbb633fb
|
||||
- 29257697b1e6be546aa0558e342a15a6
|
||||
- c0d40106c2ffb1a44bd48f50b210ee20
|
||||
- 039cd795affa7134a8d5f5d43d3b659d
|
||||
- 5f20d1b8f9ac1914dac8beae718e7d40
|
||||
- e012b6d2e0501df43a88eb6beff8ae07
|
||||
- e84c25a476798ea43a2f6de217af7dba
|
||||
- 98657376d4096a947953ee04d82830c1
|
||||
name: View
|
||||
m_CurrentViewIndex: 0
|
||||
m_TargetSnapshot: {fileID: 24500006}
|
||||
--- !u!243 &24300002
|
||||
AudioMixerGroupController:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_Name: Master
|
||||
m_AudioMixer: {fileID: 24100000}
|
||||
m_GroupID: 72c1e77b100e3274fbfb88ca2ca12c4d
|
||||
m_Children:
|
||||
- {fileID: -4209890294574411305}
|
||||
- {fileID: 7235523536312936115}
|
||||
- {fileID: 7185772616558441635}
|
||||
- {fileID: -3395020342500439107}
|
||||
m_Volume: ba83e724007d7e9459f157db3a54a741
|
||||
m_Pitch: a2d2b77391464bb4887f0bcd3835015b
|
||||
m_Send: 00000000000000000000000000000000
|
||||
m_Effects:
|
||||
- {fileID: 24400004}
|
||||
m_UserColorIndex: 8
|
||||
m_Mute: 0
|
||||
m_Solo: 0
|
||||
m_BypassEffects: 0
|
||||
--- !u!244 &24400004
|
||||
AudioMixerEffectController:
|
||||
m_ObjectHideFlags: 3
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_Name:
|
||||
m_EffectID: ce944d90cb57ee4418426132d391d900
|
||||
m_EffectName: Attenuation
|
||||
m_MixLevel: 891c3ec10e0ae1b42a95c83727d411f1
|
||||
m_Parameters: []
|
||||
m_SendTarget: {fileID: 0}
|
||||
m_EnableWetMix: 0
|
||||
m_Bypass: 0
|
||||
--- !u!245 &24500006
|
||||
AudioMixerSnapshotController:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_Name: Snapshot
|
||||
m_AudioMixer: {fileID: 24100000}
|
||||
m_SnapshotID: 91dee90f8902c804c9da7728ea355157
|
||||
m_FloatValues:
|
||||
b47f0c73299cd9b4fba9896e70683903: 1
|
||||
ba83e724007d7e9459f157db3a54a741: 0
|
||||
fe15a1b40c14ea646a13dacb15b6a73b: 0
|
||||
77212647508232a458ac7d48fb55d037: 1
|
||||
3bbd22597ed32714eb271cf06b098c63: 0
|
||||
30975daa872456b41bc18e0277e301e6: 1
|
||||
6d4c2b8bc0ef38d44b2fbff2b3298ab4: -0.03
|
||||
8542b6bfd7b7bfc4d9b961ba97edf0d2: 1
|
||||
m_TransitionOverrides: {}
|
||||
--- !u!244 &246003612463095956
|
||||
AudioMixerEffectController:
|
||||
m_ObjectHideFlags: 3
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_Name:
|
||||
m_EffectID: 860c45ba06e3cbd4794061eaefe970a3
|
||||
m_EffectName: Attenuation
|
||||
m_MixLevel: bb4c221c9e3208941b1a2107831692ab
|
||||
m_Parameters: []
|
||||
m_SendTarget: {fileID: 0}
|
||||
m_EnableWetMix: 0
|
||||
m_Bypass: 0
|
||||
--- !u!244 &281287199725387719
|
||||
AudioMixerEffectController:
|
||||
m_ObjectHideFlags: 3
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_Name:
|
||||
m_EffectID: 812fbfe4555eb1641aeaeee69a13b4a6
|
||||
m_EffectName: Lowpass Simple
|
||||
m_MixLevel: 391139084347578409e42387008bd110
|
||||
m_Parameters:
|
||||
- m_ParameterName: Cutoff freq
|
||||
m_GUID: b19756871f24b194d87c7d1fce3159e9
|
||||
m_SendTarget: {fileID: 0}
|
||||
m_EnableWetMix: 0
|
||||
m_Bypass: 0
|
||||
--- !u!244 &1413273517213151576
|
||||
AudioMixerEffectController:
|
||||
m_ObjectHideFlags: 3
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_Name:
|
||||
m_EffectID: ce0c93d89826c7349a19b232116484db
|
||||
m_EffectName: Attenuation
|
||||
m_MixLevel: 7625365898787684c9bce9298a96f044
|
||||
m_Parameters: []
|
||||
m_SendTarget: {fileID: 0}
|
||||
m_EnableWetMix: 0
|
||||
m_Bypass: 0
|
||||
--- !u!243 &1543978434442340687
|
||||
AudioMixerGroupController:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_Name: Music - 0
|
||||
m_AudioMixer: {fileID: 24100000}
|
||||
m_GroupID: 1cf576bd46399874d9494863d6502d94
|
||||
m_Children: []
|
||||
m_Volume: 41591fd4a32f4034f880ecbc14ee69f1
|
||||
m_Pitch: 9ad7e859a0cd1f142b59ffc659be28a7
|
||||
m_Send: 00000000000000000000000000000000
|
||||
m_Effects:
|
||||
- {fileID: -8255999005317483048}
|
||||
m_UserColorIndex: 1
|
||||
m_Mute: 0
|
||||
m_Solo: 0
|
||||
m_BypassEffects: 0
|
||||
--- !u!243 &1601410790413250045
|
||||
AudioMixerGroupController:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_Name: UISound - 3
|
||||
m_AudioMixer: {fileID: 24100000}
|
||||
m_GroupID: 98657376d4096a947953ee04d82830c1
|
||||
m_Children: []
|
||||
m_Volume: 2dd26f9dadf160f4bbd77f307c3f4f2e
|
||||
m_Pitch: 5627fa8b0176a344bbb4e59ac5e648d3
|
||||
m_Send: 00000000000000000000000000000000
|
||||
m_Effects:
|
||||
- {fileID: 1413273517213151576}
|
||||
m_UserColorIndex: 3
|
||||
m_Mute: 0
|
||||
m_Solo: 0
|
||||
m_BypassEffects: 0
|
||||
--- !u!244 &2567082640316932351
|
||||
AudioMixerEffectController:
|
||||
m_ObjectHideFlags: 3
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_Name:
|
||||
m_EffectID: a7394d86e1e2a1e4389182f0aec98773
|
||||
m_EffectName: Attenuation
|
||||
m_MixLevel: cb8b6dfd682072d4fb81143ba077bc3f
|
||||
m_Parameters: []
|
||||
m_SendTarget: {fileID: 0}
|
||||
m_EnableWetMix: 0
|
||||
m_Bypass: 0
|
||||
--- !u!243 &3865010338301366421
|
||||
AudioMixerGroupController:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_Name: UISound - 2
|
||||
m_AudioMixer: {fileID: 24100000}
|
||||
m_GroupID: e84c25a476798ea43a2f6de217af7dba
|
||||
m_Children: []
|
||||
m_Volume: e83be6d6c4ae85142a51f584159c4ff6
|
||||
m_Pitch: c45439925e1cfd547894fd886160a11c
|
||||
m_Send: 00000000000000000000000000000000
|
||||
m_Effects:
|
||||
- {fileID: 7834155774142160187}
|
||||
m_UserColorIndex: 3
|
||||
m_Mute: 0
|
||||
m_Solo: 0
|
||||
m_BypassEffects: 0
|
||||
--- !u!244 &5734415080786067514
|
||||
AudioMixerEffectController:
|
||||
m_ObjectHideFlags: 3
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_Name:
|
||||
m_EffectID: 20eac414948135e49b2b54a89235f15e
|
||||
m_EffectName: Attenuation
|
||||
m_MixLevel: d087be8c429707c4db724a61186f67f6
|
||||
m_Parameters: []
|
||||
m_SendTarget: {fileID: 0}
|
||||
m_EnableWetMix: 0
|
||||
m_Bypass: 0
|
||||
--- !u!244 &5954042604037024145
|
||||
AudioMixerEffectController:
|
||||
m_ObjectHideFlags: 3
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_Name:
|
||||
m_EffectID: ba434c984ec3c4442bfe3a399c11572b
|
||||
m_EffectName: Echo
|
||||
m_MixLevel: 0323002ce01f29a4abebc242337ea816
|
||||
m_Parameters:
|
||||
- m_ParameterName: Delay
|
||||
m_GUID: f4cc548867353f843bc36a61722c6cbf
|
||||
- m_ParameterName: Decay
|
||||
m_GUID: e67c7b4426842f948a83f3dada794a99
|
||||
- m_ParameterName: Max channels
|
||||
m_GUID: 75c7951a8373f4644a44979a8c5776ed
|
||||
- m_ParameterName: Drymix
|
||||
m_GUID: 4d26b3b7a84b31d499176a7879734ba1
|
||||
- m_ParameterName: Wetmix
|
||||
m_GUID: 6efaeec45de20b045a4d560994684cba
|
||||
m_SendTarget: {fileID: 0}
|
||||
m_EnableWetMix: 0
|
||||
m_Bypass: 0
|
||||
--- !u!244 &6255340296135181231
|
||||
AudioMixerEffectController:
|
||||
m_ObjectHideFlags: 3
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_Name:
|
||||
m_EffectID: 3a251f2e65751b349bb255f73f0caeaf
|
||||
m_EffectName: Duck Volume
|
||||
m_MixLevel: 58cfdd03ab24c874cbe074238d636208
|
||||
m_Parameters:
|
||||
- m_ParameterName: Threshold
|
||||
m_GUID: b1b5c57689fc533408e6195c0a9e26a9
|
||||
- m_ParameterName: Ratio
|
||||
m_GUID: dc9c2c635bce58746bd68c7dffb99ca0
|
||||
- m_ParameterName: Attack Time
|
||||
m_GUID: 078ff252301e4594c880cd5754b8a563
|
||||
- m_ParameterName: Release Time
|
||||
m_GUID: b3918efd0a966ea4882714c0f9edd40b
|
||||
- m_ParameterName: Make-up Gain
|
||||
m_GUID: 3cf881ca64b7cdb46b35d3593ff2cbe9
|
||||
- m_ParameterName: Knee
|
||||
m_GUID: 31ea47a78d927ab4abf12f854bd4c626
|
||||
- m_ParameterName: Sidechain Mix
|
||||
m_GUID: 468d86503d3572541a33c33bb9693dfd
|
||||
m_SendTarget: {fileID: 0}
|
||||
m_EnableWetMix: 0
|
||||
m_Bypass: 0
|
||||
--- !u!244 &6554641470784401750
|
||||
AudioMixerEffectController:
|
||||
m_ObjectHideFlags: 3
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_Name:
|
||||
m_EffectID: 4499c94d696ee5741a71370ed7431e12
|
||||
m_EffectName: Send
|
||||
m_MixLevel: f01b57f2509f26f4b8f2772993c2b8c6
|
||||
m_Parameters: []
|
||||
m_SendTarget: {fileID: 0}
|
||||
m_EnableWetMix: 0
|
||||
m_Bypass: 0
|
||||
--- !u!244 &6637688299338053042
|
||||
AudioMixerEffectController:
|
||||
m_ObjectHideFlags: 3
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_Name:
|
||||
m_EffectID: e84926aaeedf4074698e7d7f7f36b78b
|
||||
m_EffectName: Attenuation
|
||||
m_MixLevel: 8141a348079ee934686d3569f4758582
|
||||
m_Parameters: []
|
||||
m_SendTarget: {fileID: 0}
|
||||
m_EnableWetMix: 0
|
||||
m_Bypass: 0
|
||||
--- !u!243 &7040861873718444651
|
||||
AudioMixerGroupController:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_Name: UISound - 0
|
||||
m_AudioMixer: {fileID: 24100000}
|
||||
m_GroupID: 29257697b1e6be546aa0558e342a15a6
|
||||
m_Children: []
|
||||
m_Volume: 6e0d1a5935a802d41b27d9e2fad3ba2f
|
||||
m_Pitch: 7d01f3677fe8c5b41a877b64cc509766
|
||||
m_Send: 00000000000000000000000000000000
|
||||
m_Effects:
|
||||
- {fileID: -4958177229083455073}
|
||||
m_UserColorIndex: 3
|
||||
m_Mute: 0
|
||||
m_Solo: 0
|
||||
m_BypassEffects: 0
|
||||
--- !u!243 &7185772616558441635
|
||||
AudioMixerGroupController:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_Name: UISound
|
||||
m_AudioMixer: {fileID: 24100000}
|
||||
m_GroupID: df986418fa3e4ae448a1909ffbb633fb
|
||||
m_Children:
|
||||
- {fileID: 7040861873718444651}
|
||||
- {fileID: -3720557753501792270}
|
||||
- {fileID: 3865010338301366421}
|
||||
- {fileID: 1601410790413250045}
|
||||
m_Volume: 7d1c7ed015f5dba4f934c33ef330c5eb
|
||||
m_Pitch: 611d9d89c8a65b548b591e852596c35d
|
||||
m_Send: 00000000000000000000000000000000
|
||||
m_Effects:
|
||||
- {fileID: -998299258853400712}
|
||||
m_UserColorIndex: 3
|
||||
m_Mute: 0
|
||||
m_Solo: 0
|
||||
m_BypassEffects: 0
|
||||
--- !u!243 &7235523536312936115
|
||||
AudioMixerGroupController:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_Name: Sound
|
||||
m_AudioMixer: {fileID: 24100000}
|
||||
m_GroupID: 648e49a020cf83346a9220d606e4ff39
|
||||
m_Children:
|
||||
- {fileID: -2659745067392564156}
|
||||
- {fileID: -6280614258348125054}
|
||||
- {fileID: -7758028812591520460}
|
||||
- {fileID: -4372808504093502661}
|
||||
m_Volume: 3bbd22597ed32714eb271cf06b098c63
|
||||
m_Pitch: 7f8a6510dd472ff4db8b07c5079a2013
|
||||
m_Send: 00000000000000000000000000000000
|
||||
m_Effects:
|
||||
- {fileID: 2567082640316932351}
|
||||
m_UserColorIndex: 2
|
||||
m_Mute: 0
|
||||
m_Solo: 0
|
||||
m_BypassEffects: 0
|
||||
--- !u!244 &7834155774142160187
|
||||
AudioMixerEffectController:
|
||||
m_ObjectHideFlags: 3
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_Name:
|
||||
m_EffectID: 09e809d6183106b4a804ff08ca8ff9ed
|
||||
m_EffectName: Attenuation
|
||||
m_MixLevel: 92339d91519b09543844a84cea03aed3
|
||||
m_Parameters: []
|
||||
m_SendTarget: {fileID: 0}
|
||||
m_EnableWetMix: 0
|
||||
m_Bypass: 0
|
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1af7a1b121ae17541a1967d430cef006
|
||||
NativeFormatImporter:
|
||||
externalObjects: {}
|
||||
mainObjectFileID: 0
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c872a7dcbc4579241baeccf1691f56fd
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
588
JNFrame2/Assets/UsePlugins/SHFrame/Runtime/Modules/Fsm/Fsm.cs
Normal file
588
JNFrame2/Assets/UsePlugins/SHFrame/Runtime/Modules/Fsm/Fsm.cs
Normal file
@@ -0,0 +1,588 @@
|
||||
//------------------------------------------------------------
|
||||
// Game Framework
|
||||
// Copyright © 2013-2021 Jiang Yin. All rights reserved.
|
||||
// Homepage: https://gameframework.cn/
|
||||
// Feedback: mailto:ellan@gameframework.cn
|
||||
//------------------------------------------------------------
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace SHFrame.FSM
|
||||
{
|
||||
/// <summary>
|
||||
/// 有限状态机。
|
||||
/// </summary>
|
||||
/// <typeparam name="T">有限状态机持有者类型。</typeparam>
|
||||
internal sealed class Fsm<T> : FsmBase, IReference, IFsm<T> where T : class
|
||||
{
|
||||
private T m_Owner;
|
||||
private readonly Dictionary<Type, FsmState<T>> m_States;
|
||||
private Dictionary<string, Variable> m_Datas;
|
||||
private FsmState<T> m_CurrentState;
|
||||
private float m_CurrentStateTime;
|
||||
private bool m_IsDestroyed;
|
||||
|
||||
/// <summary>
|
||||
/// 初始化有限状态机的新实例。
|
||||
/// </summary>
|
||||
public Fsm()
|
||||
{
|
||||
m_Owner = null;
|
||||
m_States = new Dictionary<Type, FsmState<T>>();
|
||||
m_Datas = null;
|
||||
m_CurrentState = null;
|
||||
m_CurrentStateTime = 0f;
|
||||
m_IsDestroyed = true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取有限状态机持有者。
|
||||
/// </summary>
|
||||
public T Owner
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_Owner;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取有限状态机持有者类型。
|
||||
/// </summary>
|
||||
public override Type OwnerType
|
||||
{
|
||||
get
|
||||
{
|
||||
return typeof(T);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取有限状态机中状态的数量。
|
||||
/// </summary>
|
||||
public override int FsmStateCount
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_States.Count;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取有限状态机是否正在运行。
|
||||
/// </summary>
|
||||
public override bool IsRunning
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_CurrentState != null;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取有限状态机是否被销毁。
|
||||
/// </summary>
|
||||
public override bool IsDestroyed
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_IsDestroyed;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取当前有限状态机状态。
|
||||
/// </summary>
|
||||
public FsmState<T> CurrentState
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_CurrentState;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取当前有限状态机状态名称。
|
||||
/// </summary>
|
||||
public override string CurrentStateName
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_CurrentState != null ? m_CurrentState.GetType().FullName : null;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取当前有限状态机状态持续时间。
|
||||
/// </summary>
|
||||
public override float CurrentStateTime
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_CurrentStateTime;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 创建有限状态机。
|
||||
/// </summary>
|
||||
/// <param name="name">有限状态机名称。</param>
|
||||
/// <param name="owner">有限状态机持有者。</param>
|
||||
/// <param name="states">有限状态机状态集合。</param>
|
||||
/// <returns>创建的有限状态机。</returns>
|
||||
public static Fsm<T> Create(string name, T owner, params FsmState<T>[] states)
|
||||
{
|
||||
if (owner == null)
|
||||
{
|
||||
throw new GameFrameworkException("FSM owner is invalid.");
|
||||
}
|
||||
|
||||
if (states == null || states.Length < 1)
|
||||
{
|
||||
throw new GameFrameworkException("FSM states is invalid.");
|
||||
}
|
||||
|
||||
Fsm<T> fsm = ReferencePool.Acquire<Fsm<T>>();
|
||||
fsm.Name = name;
|
||||
fsm.m_Owner = owner;
|
||||
fsm.m_IsDestroyed = false;
|
||||
foreach (FsmState<T> state in states)
|
||||
{
|
||||
if (state == null)
|
||||
{
|
||||
throw new GameFrameworkException("FSM states is invalid.");
|
||||
}
|
||||
|
||||
Type stateType = state.GetType();
|
||||
if (fsm.m_States.ContainsKey(stateType))
|
||||
{
|
||||
throw new GameFrameworkException(Utility.Text.Format("FSM '{0}' state '{1}' is already exist.", new TypeNamePair(typeof(T), name), stateType.FullName));
|
||||
}
|
||||
|
||||
fsm.m_States.Add(stateType, state);
|
||||
state.OnInit(fsm);
|
||||
}
|
||||
|
||||
return fsm;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 创建有限状态机。
|
||||
/// </summary>
|
||||
/// <param name="name">有限状态机名称。</param>
|
||||
/// <param name="owner">有限状态机持有者。</param>
|
||||
/// <param name="states">有限状态机状态集合。</param>
|
||||
/// <returns>创建的有限状态机。</returns>
|
||||
public static Fsm<T> Create(string name, T owner, List<FsmState<T>> states)
|
||||
{
|
||||
if (owner == null)
|
||||
{
|
||||
throw new GameFrameworkException("FSM owner is invalid.");
|
||||
}
|
||||
|
||||
if (states == null || states.Count < 1)
|
||||
{
|
||||
throw new GameFrameworkException("FSM states is invalid.");
|
||||
}
|
||||
|
||||
Fsm<T> fsm = ReferencePool.Acquire<Fsm<T>>();
|
||||
fsm.Name = name;
|
||||
fsm.m_Owner = owner;
|
||||
fsm.m_IsDestroyed = false;
|
||||
foreach (FsmState<T> state in states)
|
||||
{
|
||||
if (state == null)
|
||||
{
|
||||
throw new GameFrameworkException("FSM states is invalid.");
|
||||
}
|
||||
|
||||
Type stateType = state.GetType();
|
||||
if (fsm.m_States.ContainsKey(stateType))
|
||||
{
|
||||
throw new GameFrameworkException(Utility.Text.Format("FSM '{0}' state '{1}' is already exist.", new TypeNamePair(typeof(T), name), stateType.FullName));
|
||||
}
|
||||
|
||||
fsm.m_States.Add(stateType, state);
|
||||
state.OnInit(fsm);
|
||||
}
|
||||
|
||||
return fsm;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 清理有限状态机。
|
||||
/// </summary>
|
||||
public void Clear()
|
||||
{
|
||||
if (m_CurrentState != null)
|
||||
{
|
||||
m_CurrentState.OnLeave(this, true);
|
||||
}
|
||||
|
||||
foreach (KeyValuePair<Type, FsmState<T>> state in m_States)
|
||||
{
|
||||
state.Value.OnDestroy(this);
|
||||
}
|
||||
|
||||
Name = null;
|
||||
m_Owner = null;
|
||||
m_States.Clear();
|
||||
|
||||
if (m_Datas != null)
|
||||
{
|
||||
foreach (KeyValuePair<string, Variable> data in m_Datas)
|
||||
{
|
||||
if (data.Value == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
ReferencePool.Release(data.Value);
|
||||
}
|
||||
|
||||
m_Datas.Clear();
|
||||
}
|
||||
|
||||
m_CurrentState = null;
|
||||
m_CurrentStateTime = 0f;
|
||||
m_IsDestroyed = true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 开始有限状态机。
|
||||
/// </summary>
|
||||
/// <typeparam name="TState">要开始的有限状态机状态类型。</typeparam>
|
||||
public void Start<TState>() where TState : FsmState<T>
|
||||
{
|
||||
if (IsRunning)
|
||||
{
|
||||
throw new GameFrameworkException("FSM is running, can not start again.");
|
||||
}
|
||||
|
||||
FsmState<T> state = GetState<TState>();
|
||||
if (state == null)
|
||||
{
|
||||
throw new GameFrameworkException(Utility.Text.Format("FSM '{0}' can not start state '{1}' which is not exist.", new TypeNamePair(typeof(T), Name), typeof(TState).FullName));
|
||||
}
|
||||
|
||||
m_CurrentStateTime = 0f;
|
||||
m_CurrentState = state;
|
||||
m_CurrentState.OnEnter(this);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 开始有限状态机。
|
||||
/// </summary>
|
||||
/// <param name="stateType">要开始的有限状态机状态类型。</param>
|
||||
public void Start(Type stateType)
|
||||
{
|
||||
if (IsRunning)
|
||||
{
|
||||
throw new GameFrameworkException("FSM is running, can not start again.");
|
||||
}
|
||||
|
||||
if (stateType == null)
|
||||
{
|
||||
throw new GameFrameworkException("State type is invalid.");
|
||||
}
|
||||
|
||||
if (!typeof(FsmState<T>).IsAssignableFrom(stateType))
|
||||
{
|
||||
throw new GameFrameworkException(Utility.Text.Format("State type '{0}' is invalid.", stateType.FullName));
|
||||
}
|
||||
|
||||
FsmState<T> state = GetState(stateType);
|
||||
if (state == null)
|
||||
{
|
||||
throw new GameFrameworkException(Utility.Text.Format("FSM '{0}' can not start state '{1}' which is not exist.", new TypeNamePair(typeof(T), Name), stateType.FullName));
|
||||
}
|
||||
|
||||
m_CurrentStateTime = 0f;
|
||||
m_CurrentState = state;
|
||||
m_CurrentState.OnEnter(this);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 是否存在有限状态机状态。
|
||||
/// </summary>
|
||||
/// <typeparam name="TState">要检查的有限状态机状态类型。</typeparam>
|
||||
/// <returns>是否存在有限状态机状态。</returns>
|
||||
public bool HasState<TState>() where TState : FsmState<T>
|
||||
{
|
||||
return m_States.ContainsKey(typeof(TState));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 是否存在有限状态机状态。
|
||||
/// </summary>
|
||||
/// <param name="stateType">要检查的有限状态机状态类型。</param>
|
||||
/// <returns>是否存在有限状态机状态。</returns>
|
||||
public bool HasState(Type stateType)
|
||||
{
|
||||
if (stateType == null)
|
||||
{
|
||||
throw new GameFrameworkException("State type is invalid.");
|
||||
}
|
||||
|
||||
if (!typeof(FsmState<T>).IsAssignableFrom(stateType))
|
||||
{
|
||||
throw new GameFrameworkException(Utility.Text.Format("State type '{0}' is invalid.", stateType.FullName));
|
||||
}
|
||||
|
||||
return m_States.ContainsKey(stateType);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取有限状态机状态。
|
||||
/// </summary>
|
||||
/// <typeparam name="TState">要获取的有限状态机状态类型。</typeparam>
|
||||
/// <returns>要获取的有限状态机状态。</returns>
|
||||
public TState GetState<TState>() where TState : FsmState<T>
|
||||
{
|
||||
FsmState<T> state = null;
|
||||
if (m_States.TryGetValue(typeof(TState), out state))
|
||||
{
|
||||
return (TState)state;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取有限状态机状态。
|
||||
/// </summary>
|
||||
/// <param name="stateType">要获取的有限状态机状态类型。</param>
|
||||
/// <returns>要获取的有限状态机状态。</returns>
|
||||
public FsmState<T> GetState(Type stateType)
|
||||
{
|
||||
if (stateType == null)
|
||||
{
|
||||
throw new GameFrameworkException("State type is invalid.");
|
||||
}
|
||||
|
||||
if (!typeof(FsmState<T>).IsAssignableFrom(stateType))
|
||||
{
|
||||
throw new GameFrameworkException(Utility.Text.Format("State type '{0}' is invalid.", stateType.FullName));
|
||||
}
|
||||
|
||||
FsmState<T> state = null;
|
||||
if (m_States.TryGetValue(stateType, out state))
|
||||
{
|
||||
return state;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取有限状态机的所有状态。
|
||||
/// </summary>
|
||||
/// <returns>有限状态机的所有状态。</returns>
|
||||
public FsmState<T>[] GetAllStates()
|
||||
{
|
||||
int index = 0;
|
||||
FsmState<T>[] results = new FsmState<T>[m_States.Count];
|
||||
foreach (KeyValuePair<Type, FsmState<T>> state in m_States)
|
||||
{
|
||||
results[index++] = state.Value;
|
||||
}
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取有限状态机的所有状态。
|
||||
/// </summary>
|
||||
/// <param name="results">有限状态机的所有状态。</param>
|
||||
public void GetAllStates(List<FsmState<T>> results)
|
||||
{
|
||||
if (results == null)
|
||||
{
|
||||
throw new GameFrameworkException("Results is invalid.");
|
||||
}
|
||||
|
||||
results.Clear();
|
||||
foreach (KeyValuePair<Type, FsmState<T>> state in m_States)
|
||||
{
|
||||
results.Add(state.Value);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 是否存在有限状态机数据。
|
||||
/// </summary>
|
||||
/// <param name="name">有限状态机数据名称。</param>
|
||||
/// <returns>有限状态机数据是否存在。</returns>
|
||||
public bool HasData(string name)
|
||||
{
|
||||
if (string.IsNullOrEmpty(name))
|
||||
{
|
||||
throw new GameFrameworkException("Data name is invalid.");
|
||||
}
|
||||
|
||||
if (m_Datas == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return m_Datas.ContainsKey(name);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取有限状态机数据。
|
||||
/// </summary>
|
||||
/// <typeparam name="TData">要获取的有限状态机数据的类型。</typeparam>
|
||||
/// <param name="name">有限状态机数据名称。</param>
|
||||
/// <returns>要获取的有限状态机数据。</returns>
|
||||
public TData GetData<TData>(string name) where TData : Variable
|
||||
{
|
||||
return (TData)GetData(name);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取有限状态机数据。
|
||||
/// </summary>
|
||||
/// <param name="name">有限状态机数据名称。</param>
|
||||
/// <returns>要获取的有限状态机数据。</returns>
|
||||
public Variable GetData(string name)
|
||||
{
|
||||
if (string.IsNullOrEmpty(name))
|
||||
{
|
||||
throw new GameFrameworkException("Data name is invalid.");
|
||||
}
|
||||
|
||||
if (m_Datas == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
Variable data = null;
|
||||
if (m_Datas.TryGetValue(name, out data))
|
||||
{
|
||||
return data;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 设置有限状态机数据。
|
||||
/// </summary>
|
||||
/// <typeparam name="TData">要设置的有限状态机数据的类型。</typeparam>
|
||||
/// <param name="name">有限状态机数据名称。</param>
|
||||
/// <param name="data">要设置的有限状态机数据。</param>
|
||||
public void SetData<TData>(string name, TData data) where TData : Variable
|
||||
{
|
||||
SetData(name, (Variable)data);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 设置有限状态机数据。
|
||||
/// </summary>
|
||||
/// <param name="name">有限状态机数据名称。</param>
|
||||
/// <param name="data">要设置的有限状态机数据。</param>
|
||||
public void SetData(string name, Variable data)
|
||||
{
|
||||
if (string.IsNullOrEmpty(name))
|
||||
{
|
||||
throw new GameFrameworkException("Data name is invalid.");
|
||||
}
|
||||
|
||||
if (m_Datas == null)
|
||||
{
|
||||
m_Datas = new Dictionary<string, Variable>(StringComparer.Ordinal);
|
||||
}
|
||||
|
||||
Variable oldData = GetData(name);
|
||||
if (oldData != null)
|
||||
{
|
||||
ReferencePool.Release(oldData);
|
||||
}
|
||||
|
||||
m_Datas[name] = data;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 移除有限状态机数据。
|
||||
/// </summary>
|
||||
/// <param name="name">有限状态机数据名称。</param>
|
||||
/// <returns>是否移除有限状态机数据成功。</returns>
|
||||
public bool RemoveData(string name)
|
||||
{
|
||||
if (string.IsNullOrEmpty(name))
|
||||
{
|
||||
throw new GameFrameworkException("Data name is invalid.");
|
||||
}
|
||||
|
||||
if (m_Datas == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
Variable oldData = GetData(name);
|
||||
if (oldData != null)
|
||||
{
|
||||
ReferencePool.Release(oldData);
|
||||
}
|
||||
|
||||
return m_Datas.Remove(name);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 有限状态机轮询。
|
||||
/// </summary>
|
||||
/// <param name="elapseSeconds">逻辑流逝时间,以秒为单位。</param>
|
||||
/// <param name="realElapseSeconds">真实流逝时间,以秒为单位。</param>
|
||||
internal override void Update(float elapseSeconds, float realElapseSeconds)
|
||||
{
|
||||
if (m_CurrentState == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
m_CurrentStateTime += elapseSeconds;
|
||||
m_CurrentState.OnUpdate(this, elapseSeconds, realElapseSeconds);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 关闭并清理有限状态机。
|
||||
/// </summary>
|
||||
internal override void Shutdown()
|
||||
{
|
||||
ReferencePool.Release(this);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 切换当前有限状态机状态。
|
||||
/// </summary>
|
||||
/// <typeparam name="TState">要切换到的有限状态机状态类型。</typeparam>
|
||||
internal void ChangeState<TState>() where TState : FsmState<T>
|
||||
{
|
||||
ChangeState(typeof(TState));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 切换当前有限状态机状态。
|
||||
/// </summary>
|
||||
/// <param name="stateType">要切换到的有限状态机状态类型。</param>
|
||||
internal void ChangeState(Type stateType)
|
||||
{
|
||||
if (m_CurrentState == null)
|
||||
{
|
||||
throw new GameFrameworkException("Current state is invalid.");
|
||||
}
|
||||
|
||||
FsmState<T> state = GetState(stateType);
|
||||
if (state == null)
|
||||
{
|
||||
throw new GameFrameworkException(Utility.Text.Format("FSM '{0}' can not change state to '{1}' which is not exist.", new TypeNamePair(typeof(T), Name), stateType.FullName));
|
||||
}
|
||||
|
||||
m_CurrentState.OnLeave(this, false);
|
||||
m_CurrentStateTime = 0f;
|
||||
m_CurrentState = state;
|
||||
m_CurrentState.OnEnter(this);
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9b7d188f470e45e44b41524dc607b0a1
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,113 @@
|
||||
//------------------------------------------------------------
|
||||
// Game Framework
|
||||
// Copyright © 2013-2021 Jiang Yin. All rights reserved.
|
||||
// Homepage: https://gameframework.cn/
|
||||
// Feedback: mailto:ellan@gameframework.cn
|
||||
//------------------------------------------------------------
|
||||
|
||||
using System;
|
||||
|
||||
namespace SHFrame.FSM
|
||||
{
|
||||
/// <summary>
|
||||
/// 有限状态机基类。
|
||||
/// </summary>
|
||||
public abstract class FsmBase
|
||||
{
|
||||
private string m_Name;
|
||||
|
||||
/// <summary>
|
||||
/// 初始化有限状态机基类的新实例。
|
||||
/// </summary>
|
||||
public FsmBase()
|
||||
{
|
||||
m_Name = string.Empty;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取有限状态机名称。
|
||||
/// </summary>
|
||||
public string Name
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_Name;
|
||||
}
|
||||
protected set
|
||||
{
|
||||
m_Name = value ?? string.Empty;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取有限状态机完整名称。
|
||||
/// </summary>
|
||||
public string FullName
|
||||
{
|
||||
get
|
||||
{
|
||||
return new TypeNamePair(OwnerType, m_Name).ToString();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取有限状态机持有者类型。
|
||||
/// </summary>
|
||||
public abstract Type OwnerType
|
||||
{
|
||||
get;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取有限状态机中状态的数量。
|
||||
/// </summary>
|
||||
public abstract int FsmStateCount
|
||||
{
|
||||
get;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取有限状态机是否正在运行。
|
||||
/// </summary>
|
||||
public abstract bool IsRunning
|
||||
{
|
||||
get;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取有限状态机是否被销毁。
|
||||
/// </summary>
|
||||
public abstract bool IsDestroyed
|
||||
{
|
||||
get;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取当前有限状态机状态名称。
|
||||
/// </summary>
|
||||
public abstract string CurrentStateName
|
||||
{
|
||||
get;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取当前有限状态机状态持续时间。
|
||||
/// </summary>
|
||||
public abstract float CurrentStateTime
|
||||
{
|
||||
get;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 有限状态机轮询。
|
||||
/// </summary>
|
||||
/// <param name="elapseSeconds">逻辑流逝时间,以秒为单位。</param>
|
||||
/// <param name="realElapseSeconds">当前已流逝时间,以秒为单位。</param>
|
||||
internal abstract void Update(float elapseSeconds, float realElapseSeconds);
|
||||
|
||||
/// <summary>
|
||||
/// 关闭并清理有限状态机。
|
||||
/// </summary>
|
||||
internal abstract void Shutdown();
|
||||
}
|
||||
}
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 21c38565ed73dcb43b4cfb6c1ceda566
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,412 @@
|
||||
//------------------------------------------------------------
|
||||
// Game Framework
|
||||
// Copyright © 2013-2021 Jiang Yin. All rights reserved.
|
||||
// Homepage: https://gameframework.cn/
|
||||
// Feedback: mailto:ellan@gameframework.cn
|
||||
//------------------------------------------------------------
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace SHFrame.FSM
|
||||
{
|
||||
/// <summary>
|
||||
/// 有限状态机管理器。
|
||||
/// </summary>
|
||||
[UpdateModule]
|
||||
internal sealed class FsmManager : ModuleImp, IFsmManager
|
||||
{
|
||||
private readonly Dictionary<TypeNamePair, FsmBase> m_Fsms;
|
||||
private readonly List<FsmBase> m_TempFsms;
|
||||
|
||||
/// <summary>
|
||||
/// 初始化有限状态机管理器的新实例。
|
||||
/// </summary>
|
||||
public FsmManager()
|
||||
{
|
||||
m_Fsms = new Dictionary<TypeNamePair, FsmBase>();
|
||||
m_TempFsms = new List<FsmBase>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取游戏框架模块优先级。
|
||||
/// </summary>
|
||||
/// <remarks>优先级较高的模块会优先轮询,并且关闭操作会后进行。</remarks>
|
||||
internal override int Priority
|
||||
{
|
||||
get
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取有限状态机数量。
|
||||
/// </summary>
|
||||
public int Count
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_Fsms.Count;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 有限状态机管理器轮询。
|
||||
/// </summary>
|
||||
/// <param name="elapseSeconds">逻辑流逝时间,以秒为单位。</param>
|
||||
/// <param name="realElapseSeconds">真实流逝时间,以秒为单位。</param>
|
||||
internal override void Update(float elapseSeconds, float realElapseSeconds)
|
||||
{
|
||||
m_TempFsms.Clear();
|
||||
if (m_Fsms.Count <= 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
foreach (KeyValuePair<TypeNamePair, FsmBase> fsm in m_Fsms)
|
||||
{
|
||||
m_TempFsms.Add(fsm.Value);
|
||||
}
|
||||
|
||||
foreach (FsmBase fsm in m_TempFsms)
|
||||
{
|
||||
if (fsm.IsDestroyed)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
fsm.Update(elapseSeconds, realElapseSeconds);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 关闭并清理有限状态机管理器。
|
||||
/// </summary>
|
||||
internal override void Shutdown()
|
||||
{
|
||||
foreach (KeyValuePair<TypeNamePair, FsmBase> fsm in m_Fsms)
|
||||
{
|
||||
fsm.Value.Shutdown();
|
||||
}
|
||||
|
||||
m_Fsms.Clear();
|
||||
m_TempFsms.Clear();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 检查是否存在有限状态机。
|
||||
/// </summary>
|
||||
/// <typeparam name="T">有限状态机持有者类型。</typeparam>
|
||||
/// <returns>是否存在有限状态机。</returns>
|
||||
public bool HasFsm<T>() where T : class
|
||||
{
|
||||
return InternalHasFsm(new TypeNamePair(typeof(T)));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 检查是否存在有限状态机。
|
||||
/// </summary>
|
||||
/// <param name="ownerType">有限状态机持有者类型。</param>
|
||||
/// <returns>是否存在有限状态机。</returns>
|
||||
public bool HasFsm(Type ownerType)
|
||||
{
|
||||
if (ownerType == null)
|
||||
{
|
||||
throw new GameFrameworkException("Owner type is invalid.");
|
||||
}
|
||||
|
||||
return InternalHasFsm(new TypeNamePair(ownerType));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 检查是否存在有限状态机。
|
||||
/// </summary>
|
||||
/// <typeparam name="T">有限状态机持有者类型。</typeparam>
|
||||
/// <param name="name">有限状态机名称。</param>
|
||||
/// <returns>是否存在有限状态机。</returns>
|
||||
public bool HasFsm<T>(string name) where T : class
|
||||
{
|
||||
return InternalHasFsm(new TypeNamePair(typeof(T), name));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 检查是否存在有限状态机。
|
||||
/// </summary>
|
||||
/// <param name="ownerType">有限状态机持有者类型。</param>
|
||||
/// <param name="name">有限状态机名称。</param>
|
||||
/// <returns>是否存在有限状态机。</returns>
|
||||
public bool HasFsm(Type ownerType, string name)
|
||||
{
|
||||
if (ownerType == null)
|
||||
{
|
||||
throw new GameFrameworkException("Owner type is invalid.");
|
||||
}
|
||||
|
||||
return InternalHasFsm(new TypeNamePair(ownerType, name));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取有限状态机。
|
||||
/// </summary>
|
||||
/// <typeparam name="T">有限状态机持有者类型。</typeparam>
|
||||
/// <returns>要获取的有限状态机。</returns>
|
||||
public IFsm<T> GetFsm<T>() where T : class
|
||||
{
|
||||
return (IFsm<T>)InternalGetFsm(new TypeNamePair(typeof(T)));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取有限状态机。
|
||||
/// </summary>
|
||||
/// <param name="ownerType">有限状态机持有者类型。</param>
|
||||
/// <returns>要获取的有限状态机。</returns>
|
||||
public FsmBase GetFsm(Type ownerType)
|
||||
{
|
||||
if (ownerType == null)
|
||||
{
|
||||
throw new GameFrameworkException("Owner type is invalid.");
|
||||
}
|
||||
|
||||
return InternalGetFsm(new TypeNamePair(ownerType));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取有限状态机。
|
||||
/// </summary>
|
||||
/// <typeparam name="T">有限状态机持有者类型。</typeparam>
|
||||
/// <param name="name">有限状态机名称。</param>
|
||||
/// <returns>要获取的有限状态机。</returns>
|
||||
public IFsm<T> GetFsm<T>(string name) where T : class
|
||||
{
|
||||
return (IFsm<T>)InternalGetFsm(new TypeNamePair(typeof(T), name));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取有限状态机。
|
||||
/// </summary>
|
||||
/// <param name="ownerType">有限状态机持有者类型。</param>
|
||||
/// <param name="name">有限状态机名称。</param>
|
||||
/// <returns>要获取的有限状态机。</returns>
|
||||
public FsmBase GetFsm(Type ownerType, string name)
|
||||
{
|
||||
if (ownerType == null)
|
||||
{
|
||||
throw new GameFrameworkException("Owner type is invalid.");
|
||||
}
|
||||
|
||||
return InternalGetFsm(new TypeNamePair(ownerType, name));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取所有有限状态机。
|
||||
/// </summary>
|
||||
/// <returns>所有有限状态机。</returns>
|
||||
public FsmBase[] GetAllFsms()
|
||||
{
|
||||
int index = 0;
|
||||
FsmBase[] results = new FsmBase[m_Fsms.Count];
|
||||
foreach (KeyValuePair<TypeNamePair, FsmBase> fsm in m_Fsms)
|
||||
{
|
||||
results[index++] = fsm.Value;
|
||||
}
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取所有有限状态机。
|
||||
/// </summary>
|
||||
/// <param name="results">所有有限状态机。</param>
|
||||
public void GetAllFsms(List<FsmBase> results)
|
||||
{
|
||||
if (results == null)
|
||||
{
|
||||
throw new GameFrameworkException("Results is invalid.");
|
||||
}
|
||||
|
||||
results.Clear();
|
||||
foreach (KeyValuePair<TypeNamePair, FsmBase> fsm in m_Fsms)
|
||||
{
|
||||
results.Add(fsm.Value);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 创建有限状态机。
|
||||
/// </summary>
|
||||
/// <typeparam name="T">有限状态机持有者类型。</typeparam>
|
||||
/// <param name="owner">有限状态机持有者。</param>
|
||||
/// <param name="states">有限状态机状态集合。</param>
|
||||
/// <returns>要创建的有限状态机。</returns>
|
||||
public IFsm<T> CreateFsm<T>(T owner, params FsmState<T>[] states) where T : class
|
||||
{
|
||||
return CreateFsm(string.Empty, owner, states);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 创建有限状态机。
|
||||
/// </summary>
|
||||
/// <typeparam name="T">有限状态机持有者类型。</typeparam>
|
||||
/// <param name="name">有限状态机名称。</param>
|
||||
/// <param name="owner">有限状态机持有者。</param>
|
||||
/// <param name="states">有限状态机状态集合。</param>
|
||||
/// <returns>要创建的有限状态机。</returns>
|
||||
public IFsm<T> CreateFsm<T>(string name, T owner, params FsmState<T>[] states) where T : class
|
||||
{
|
||||
TypeNamePair typeNamePair = new TypeNamePair(typeof(T), name);
|
||||
if (HasFsm<T>(name))
|
||||
{
|
||||
throw new GameFrameworkException(Utility.Text.Format("Already exist FSM '{0}'.", typeNamePair));
|
||||
}
|
||||
|
||||
Fsm<T> fsm = Fsm<T>.Create(name, owner, states);
|
||||
m_Fsms.Add(typeNamePair, fsm);
|
||||
return fsm;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 创建有限状态机。
|
||||
/// </summary>
|
||||
/// <typeparam name="T">有限状态机持有者类型。</typeparam>
|
||||
/// <param name="owner">有限状态机持有者。</param>
|
||||
/// <param name="states">有限状态机状态集合。</param>
|
||||
/// <returns>要创建的有限状态机。</returns>
|
||||
public IFsm<T> CreateFsm<T>(T owner, List<FsmState<T>> states) where T : class
|
||||
{
|
||||
return CreateFsm(string.Empty, owner, states);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 创建有限状态机。
|
||||
/// </summary>
|
||||
/// <typeparam name="T">有限状态机持有者类型。</typeparam>
|
||||
/// <param name="name">有限状态机名称。</param>
|
||||
/// <param name="owner">有限状态机持有者。</param>
|
||||
/// <param name="states">有限状态机状态集合。</param>
|
||||
/// <returns>要创建的有限状态机。</returns>
|
||||
public IFsm<T> CreateFsm<T>(string name, T owner, List<FsmState<T>> states) where T : class
|
||||
{
|
||||
TypeNamePair typeNamePair = new TypeNamePair(typeof(T), name);
|
||||
if (HasFsm<T>(name))
|
||||
{
|
||||
throw new GameFrameworkException(Utility.Text.Format("Already exist FSM '{0}'.", typeNamePair));
|
||||
}
|
||||
|
||||
Fsm<T> fsm = Fsm<T>.Create(name, owner, states);
|
||||
m_Fsms.Add(typeNamePair, fsm);
|
||||
return fsm;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 销毁有限状态机。
|
||||
/// </summary>
|
||||
/// <typeparam name="T">有限状态机持有者类型。</typeparam>
|
||||
/// <returns>是否销毁有限状态机成功。</returns>
|
||||
public bool DestroyFsm<T>() where T : class
|
||||
{
|
||||
return InternalDestroyFsm(new TypeNamePair(typeof(T)));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 销毁有限状态机。
|
||||
/// </summary>
|
||||
/// <param name="ownerType">有限状态机持有者类型。</param>
|
||||
/// <returns>是否销毁有限状态机成功。</returns>
|
||||
public bool DestroyFsm(Type ownerType)
|
||||
{
|
||||
if (ownerType == null)
|
||||
{
|
||||
throw new GameFrameworkException("Owner type is invalid.");
|
||||
}
|
||||
|
||||
return InternalDestroyFsm(new TypeNamePair(ownerType));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 销毁有限状态机。
|
||||
/// </summary>
|
||||
/// <typeparam name="T">有限状态机持有者类型。</typeparam>
|
||||
/// <param name="name">要销毁的有限状态机名称。</param>
|
||||
/// <returns>是否销毁有限状态机成功。</returns>
|
||||
public bool DestroyFsm<T>(string name) where T : class
|
||||
{
|
||||
return InternalDestroyFsm(new TypeNamePair(typeof(T), name));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 销毁有限状态机。
|
||||
/// </summary>
|
||||
/// <param name="ownerType">有限状态机持有者类型。</param>
|
||||
/// <param name="name">要销毁的有限状态机名称。</param>
|
||||
/// <returns>是否销毁有限状态机成功。</returns>
|
||||
public bool DestroyFsm(Type ownerType, string name)
|
||||
{
|
||||
if (ownerType == null)
|
||||
{
|
||||
throw new GameFrameworkException("Owner type is invalid.");
|
||||
}
|
||||
|
||||
return InternalDestroyFsm(new TypeNamePair(ownerType, name));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 销毁有限状态机。
|
||||
/// </summary>
|
||||
/// <typeparam name="T">有限状态机持有者类型。</typeparam>
|
||||
/// <param name="fsm">要销毁的有限状态机。</param>
|
||||
/// <returns>是否销毁有限状态机成功。</returns>
|
||||
public bool DestroyFsm<T>(IFsm<T> fsm) where T : class
|
||||
{
|
||||
if (fsm == null)
|
||||
{
|
||||
throw new GameFrameworkException("FSM is invalid.");
|
||||
}
|
||||
|
||||
return InternalDestroyFsm(new TypeNamePair(typeof(T), fsm.Name));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 销毁有限状态机。
|
||||
/// </summary>
|
||||
/// <param name="fsm">要销毁的有限状态机。</param>
|
||||
/// <returns>是否销毁有限状态机成功。</returns>
|
||||
public bool DestroyFsm(FsmBase fsm)
|
||||
{
|
||||
if (fsm == null)
|
||||
{
|
||||
throw new GameFrameworkException("FSM is invalid.");
|
||||
}
|
||||
|
||||
return InternalDestroyFsm(new TypeNamePair(fsm.OwnerType, fsm.Name));
|
||||
}
|
||||
|
||||
private bool InternalHasFsm(TypeNamePair typeNamePair)
|
||||
{
|
||||
return m_Fsms.ContainsKey(typeNamePair);
|
||||
}
|
||||
|
||||
private FsmBase InternalGetFsm(TypeNamePair typeNamePair)
|
||||
{
|
||||
FsmBase fsm = null;
|
||||
if (m_Fsms.TryGetValue(typeNamePair, out fsm))
|
||||
{
|
||||
return fsm;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private bool InternalDestroyFsm(TypeNamePair typeNamePair)
|
||||
{
|
||||
FsmBase fsm = null;
|
||||
if (m_Fsms.TryGetValue(typeNamePair, out fsm))
|
||||
{
|
||||
fsm.Shutdown();
|
||||
return m_Fsms.Remove(typeNamePair);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: cd3e68474eff7b94bb1e4ddf976e2ad1
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,254 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace SHFrame.FSM
|
||||
{
|
||||
public sealed class FsmModule : Module
|
||||
{
|
||||
private IFsmManager m_FsmManager;
|
||||
|
||||
/// <summary>
|
||||
/// 获取有限状态机数量。
|
||||
/// </summary>
|
||||
public int Count
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_FsmManager.Count;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 游戏框架组件初始化。
|
||||
/// </summary>
|
||||
protected override void Awake()
|
||||
{
|
||||
base.Awake();
|
||||
|
||||
m_FsmManager = ModuleImpSystem.GetModule<IFsmManager>();
|
||||
if (m_FsmManager == null)
|
||||
{
|
||||
Log.Fatal("FSM manager is invalid.");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
private void Start()
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 检查是否存在有限状态机。
|
||||
/// </summary>
|
||||
/// <typeparam name="T">有限状态机持有者类型。</typeparam>
|
||||
/// <returns>是否存在有限状态机。</returns>
|
||||
public bool HasFsm<T>() where T : class
|
||||
{
|
||||
return m_FsmManager.HasFsm<T>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 检查是否存在有限状态机。
|
||||
/// </summary>
|
||||
/// <param name="ownerType">有限状态机持有者类型。</param>
|
||||
/// <returns>是否存在有限状态机。</returns>
|
||||
public bool HasFsm(Type ownerType)
|
||||
{
|
||||
return m_FsmManager.HasFsm(ownerType);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 检查是否存在有限状态机。
|
||||
/// </summary>
|
||||
/// <typeparam name="T">有限状态机持有者类型。</typeparam>
|
||||
/// <param name="name">有限状态机名称。</param>
|
||||
/// <returns>是否存在有限状态机。</returns>
|
||||
public bool HasFsm<T>(string name) where T : class
|
||||
{
|
||||
return m_FsmManager.HasFsm<T>(name);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 检查是否存在有限状态机。
|
||||
/// </summary>
|
||||
/// <param name="ownerType">有限状态机持有者类型。</param>
|
||||
/// <param name="name">有限状态机名称。</param>
|
||||
/// <returns>是否存在有限状态机。</returns>
|
||||
public bool HasFsm(Type ownerType, string name)
|
||||
{
|
||||
return m_FsmManager.HasFsm(ownerType, name);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取有限状态机。
|
||||
/// </summary>
|
||||
/// <typeparam name="T">有限状态机持有者类型。</typeparam>
|
||||
/// <returns>要获取的有限状态机。</returns>
|
||||
public IFsm<T> GetFsm<T>() where T : class
|
||||
{
|
||||
return m_FsmManager.GetFsm<T>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取有限状态机。
|
||||
/// </summary>
|
||||
/// <param name="ownerType">有限状态机持有者类型。</param>
|
||||
/// <returns>要获取的有限状态机。</returns>
|
||||
public FsmBase GetFsm(Type ownerType)
|
||||
{
|
||||
return m_FsmManager.GetFsm(ownerType);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取有限状态机。
|
||||
/// </summary>
|
||||
/// <typeparam name="T">有限状态机持有者类型。</typeparam>
|
||||
/// <param name="name">有限状态机名称。</param>
|
||||
/// <returns>要获取的有限状态机。</returns>
|
||||
public IFsm<T> GetFsm<T>(string name) where T : class
|
||||
{
|
||||
return m_FsmManager.GetFsm<T>(name);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取有限状态机。
|
||||
/// </summary>
|
||||
/// <param name="ownerType">有限状态机持有者类型。</param>
|
||||
/// <param name="name">有限状态机名称。</param>
|
||||
/// <returns>要获取的有限状态机。</returns>
|
||||
public FsmBase GetFsm(Type ownerType, string name)
|
||||
{
|
||||
return m_FsmManager.GetFsm(ownerType, name);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取所有有限状态机。
|
||||
/// </summary>
|
||||
public FsmBase[] GetAllFsms()
|
||||
{
|
||||
return m_FsmManager.GetAllFsms();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取所有有限状态机。
|
||||
/// </summary>
|
||||
/// <param name="results">所有有限状态机。</param>
|
||||
public void GetAllFsms(List<FsmBase> results)
|
||||
{
|
||||
m_FsmManager.GetAllFsms(results);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 创建有限状态机。
|
||||
/// </summary>
|
||||
/// <typeparam name="T">有限状态机持有者类型。</typeparam>
|
||||
/// <param name="owner">有限状态机持有者。</param>
|
||||
/// <param name="states">有限状态机状态集合。</param>
|
||||
/// <returns>要创建的有限状态机。</returns>
|
||||
public IFsm<T> CreateFsm<T>(T owner, params FsmState<T>[] states) where T : class
|
||||
{
|
||||
return m_FsmManager.CreateFsm(owner, states);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 创建有限状态机。
|
||||
/// </summary>
|
||||
/// <typeparam name="T">有限状态机持有者类型。</typeparam>
|
||||
/// <param name="name">有限状态机名称。</param>
|
||||
/// <param name="owner">有限状态机持有者。</param>
|
||||
/// <param name="states">有限状态机状态集合。</param>
|
||||
/// <returns>要创建的有限状态机。</returns>
|
||||
public IFsm<T> CreateFsm<T>(string name, T owner, params FsmState<T>[] states) where T : class
|
||||
{
|
||||
return m_FsmManager.CreateFsm(name, owner, states);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 创建有限状态机。
|
||||
/// </summary>
|
||||
/// <typeparam name="T">有限状态机持有者类型。</typeparam>
|
||||
/// <param name="owner">有限状态机持有者。</param>
|
||||
/// <param name="states">有限状态机状态集合。</param>
|
||||
/// <returns>要创建的有限状态机。</returns>
|
||||
public IFsm<T> CreateFsm<T>(T owner, List<FsmState<T>> states) where T : class
|
||||
{
|
||||
return m_FsmManager.CreateFsm(owner, states);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 创建有限状态机。
|
||||
/// </summary>
|
||||
/// <typeparam name="T">有限状态机持有者类型。</typeparam>
|
||||
/// <param name="name">有限状态机名称。</param>
|
||||
/// <param name="owner">有限状态机持有者。</param>
|
||||
/// <param name="states">有限状态机状态集合。</param>
|
||||
/// <returns>要创建的有限状态机。</returns>
|
||||
public IFsm<T> CreateFsm<T>(string name, T owner, List<FsmState<T>> states) where T : class
|
||||
{
|
||||
return m_FsmManager.CreateFsm(name, owner, states);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 销毁有限状态机。
|
||||
/// </summary>
|
||||
/// <typeparam name="T">有限状态机持有者类型。</typeparam>
|
||||
/// <returns>是否销毁有限状态机成功。</returns>
|
||||
public bool DestroyFsm<T>() where T : class
|
||||
{
|
||||
return m_FsmManager.DestroyFsm<T>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 销毁有限状态机。
|
||||
/// </summary>
|
||||
/// <param name="ownerType">有限状态机持有者类型。</param>
|
||||
/// <returns>是否销毁有限状态机成功。</returns>
|
||||
public bool DestroyFsm(Type ownerType)
|
||||
{
|
||||
return m_FsmManager.DestroyFsm(ownerType);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 销毁有限状态机。
|
||||
/// </summary>
|
||||
/// <typeparam name="T">有限状态机持有者类型。</typeparam>
|
||||
/// <param name="name">要销毁的有限状态机名称。</param>
|
||||
/// <returns>是否销毁有限状态机成功。</returns>
|
||||
public bool DestroyFsm<T>(string name) where T : class
|
||||
{
|
||||
return m_FsmManager.DestroyFsm<T>(name);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 销毁有限状态机。
|
||||
/// </summary>
|
||||
/// <param name="ownerType">有限状态机持有者类型。</param>
|
||||
/// <param name="name">要销毁的有限状态机名称。</param>
|
||||
/// <returns>是否销毁有限状态机成功。</returns>
|
||||
public bool DestroyFsm(Type ownerType, string name)
|
||||
{
|
||||
return m_FsmManager.DestroyFsm(ownerType, name);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 销毁有限状态机。
|
||||
/// </summary>
|
||||
/// <typeparam name="T">有限状态机持有者类型。</typeparam>
|
||||
/// <param name="fsm">要销毁的有限状态机。</param>
|
||||
/// <returns>是否销毁有限状态机成功。</returns>
|
||||
public bool DestroyFsm<T>(IFsm<T> fsm) where T : class
|
||||
{
|
||||
return m_FsmManager.DestroyFsm(fsm);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 销毁有限状态机。
|
||||
/// </summary>
|
||||
/// <param name="fsm">要销毁的有限状态机。</param>
|
||||
/// <returns>是否销毁有限状态机成功。</returns>
|
||||
public bool DestroyFsm(FsmBase fsm)
|
||||
{
|
||||
return m_FsmManager.DestroyFsm(fsm);
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 27e7fc213b60e4d44aab99a7fb00c2cf
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,103 @@
|
||||
using System;
|
||||
|
||||
namespace SHFrame.FSM
|
||||
{
|
||||
/// <summary>
|
||||
/// 有限状态机状态基类。
|
||||
/// </summary>
|
||||
/// <typeparam name="T">有限状态机持有者类型。</typeparam>
|
||||
public abstract class FsmState<T> where T : class
|
||||
{
|
||||
/// <summary>
|
||||
/// 初始化有限状态机状态基类的新实例。
|
||||
/// </summary>
|
||||
public FsmState()
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 有限状态机状态初始化时调用。
|
||||
/// </summary>
|
||||
/// <param name="fsm">有限状态机引用。</param>
|
||||
protected internal virtual void OnInit(IFsm<T> fsm)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 有限状态机状态进入时调用。
|
||||
/// </summary>
|
||||
/// <param name="fsm">有限状态机引用。</param>
|
||||
protected internal virtual void OnEnter(IFsm<T> fsm)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 有限状态机状态轮询时调用。
|
||||
/// </summary>
|
||||
/// <param name="fsm">有限状态机引用。</param>
|
||||
/// <param name="elapseSeconds">逻辑流逝时间,以秒为单位。</param>
|
||||
/// <param name="realElapseSeconds">真实流逝时间,以秒为单位。</param>
|
||||
protected internal virtual void OnUpdate(IFsm<T> fsm, float elapseSeconds, float realElapseSeconds)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 有限状态机状态离开时调用。
|
||||
/// </summary>
|
||||
/// <param name="fsm">有限状态机引用。</param>
|
||||
/// <param name="isShutdown">是否是关闭有限状态机时触发。</param>
|
||||
protected internal virtual void OnLeave(IFsm<T> fsm, bool isShutdown)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 有限状态机状态销毁时调用。
|
||||
/// </summary>
|
||||
/// <param name="fsm">有限状态机引用。</param>
|
||||
protected internal virtual void OnDestroy(IFsm<T> fsm)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 切换当前有限状态机状态。
|
||||
/// </summary>
|
||||
/// <typeparam name="TState">要切换到的有限状态机状态类型。</typeparam>
|
||||
/// <param name="fsm">有限状态机引用。</param>
|
||||
protected void ChangeState<TState>(IFsm<T> fsm) where TState : FsmState<T>
|
||||
{
|
||||
Fsm<T> fsmImplement = (Fsm<T>)fsm;
|
||||
if (fsmImplement == null)
|
||||
{
|
||||
throw new GameFrameworkException("FSM is invalid.");
|
||||
}
|
||||
|
||||
fsmImplement.ChangeState<TState>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 切换当前有限状态机状态。
|
||||
/// </summary>
|
||||
/// <param name="fsm">有限状态机引用。</param>
|
||||
/// <param name="stateType">要切换到的有限状态机状态类型。</param>
|
||||
protected void ChangeState(IFsm<T> fsm, Type stateType)
|
||||
{
|
||||
Fsm<T> fsmImplement = (Fsm<T>)fsm;
|
||||
if (fsmImplement == null)
|
||||
{
|
||||
throw new GameFrameworkException("FSM is invalid.");
|
||||
}
|
||||
|
||||
if (stateType == null)
|
||||
{
|
||||
throw new GameFrameworkException("State type is invalid.");
|
||||
}
|
||||
|
||||
if (!typeof(FsmState<T>).IsAssignableFrom(stateType))
|
||||
{
|
||||
throw new GameFrameworkException(Utility.Text.Format("State type '{0}' is invalid.", stateType.FullName));
|
||||
}
|
||||
|
||||
fsmImplement.ChangeState(stateType);
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 60b86155028a80c43b1f645ecf4a34f9
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
179
JNFrame2/Assets/UsePlugins/SHFrame/Runtime/Modules/Fsm/IFsm.cs
Normal file
179
JNFrame2/Assets/UsePlugins/SHFrame/Runtime/Modules/Fsm/IFsm.cs
Normal file
@@ -0,0 +1,179 @@
|
||||
//------------------------------------------------------------
|
||||
// Game Framework
|
||||
// Copyright © 2013-2021 Jiang Yin. All rights reserved.
|
||||
// Homepage: https://gameframework.cn/
|
||||
// Feedback: mailto:ellan@gameframework.cn
|
||||
//------------------------------------------------------------
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace SHFrame.FSM
|
||||
{
|
||||
/// <summary>
|
||||
/// 有限状态机接口。
|
||||
/// </summary>
|
||||
/// <typeparam name="T">有限状态机持有者类型。</typeparam>
|
||||
public interface IFsm<T> where T : class
|
||||
{
|
||||
/// <summary>
|
||||
/// 获取有限状态机名称。
|
||||
/// </summary>
|
||||
string Name
|
||||
{
|
||||
get;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取有限状态机完整名称。
|
||||
/// </summary>
|
||||
string FullName
|
||||
{
|
||||
get;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取有限状态机持有者。
|
||||
/// </summary>
|
||||
T Owner
|
||||
{
|
||||
get;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取有限状态机中状态的数量。
|
||||
/// </summary>
|
||||
int FsmStateCount
|
||||
{
|
||||
get;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取有限状态机是否正在运行。
|
||||
/// </summary>
|
||||
bool IsRunning
|
||||
{
|
||||
get;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取有限状态机是否被销毁。
|
||||
/// </summary>
|
||||
bool IsDestroyed
|
||||
{
|
||||
get;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取当前有限状态机状态。
|
||||
/// </summary>
|
||||
FsmState<T> CurrentState
|
||||
{
|
||||
get;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取当前有限状态机状态持续时间。
|
||||
/// </summary>
|
||||
float CurrentStateTime
|
||||
{
|
||||
get;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 开始有限状态机。
|
||||
/// </summary>
|
||||
/// <typeparam name="TState">要开始的有限状态机状态类型。</typeparam>
|
||||
void Start<TState>() where TState : FsmState<T>;
|
||||
|
||||
/// <summary>
|
||||
/// 开始有限状态机。
|
||||
/// </summary>
|
||||
/// <param name="stateType">要开始的有限状态机状态类型。</param>
|
||||
void Start(Type stateType);
|
||||
|
||||
/// <summary>
|
||||
/// 是否存在有限状态机状态。
|
||||
/// </summary>
|
||||
/// <typeparam name="TState">要检查的有限状态机状态类型。</typeparam>
|
||||
/// <returns>是否存在有限状态机状态。</returns>
|
||||
bool HasState<TState>() where TState : FsmState<T>;
|
||||
|
||||
/// <summary>
|
||||
/// 是否存在有限状态机状态。
|
||||
/// </summary>
|
||||
/// <param name="stateType">要检查的有限状态机状态类型。</param>
|
||||
/// <returns>是否存在有限状态机状态。</returns>
|
||||
bool HasState(Type stateType);
|
||||
|
||||
/// <summary>
|
||||
/// 获取有限状态机状态。
|
||||
/// </summary>
|
||||
/// <typeparam name="TState">要获取的有限状态机状态类型。</typeparam>
|
||||
/// <returns>要获取的有限状态机状态。</returns>
|
||||
TState GetState<TState>() where TState : FsmState<T>;
|
||||
|
||||
/// <summary>
|
||||
/// 获取有限状态机状态。
|
||||
/// </summary>
|
||||
/// <param name="stateType">要获取的有限状态机状态类型。</param>
|
||||
/// <returns>要获取的有限状态机状态。</returns>
|
||||
FsmState<T> GetState(Type stateType);
|
||||
|
||||
/// <summary>
|
||||
/// 获取有限状态机的所有状态。
|
||||
/// </summary>
|
||||
/// <returns>有限状态机的所有状态。</returns>
|
||||
FsmState<T>[] GetAllStates();
|
||||
|
||||
/// <summary>
|
||||
/// 获取有限状态机的所有状态。
|
||||
/// </summary>
|
||||
/// <param name="results">有限状态机的所有状态。</param>
|
||||
void GetAllStates(List<FsmState<T>> results);
|
||||
|
||||
/// <summary>
|
||||
/// 是否存在有限状态机数据。
|
||||
/// </summary>
|
||||
/// <param name="name">有限状态机数据名称。</param>
|
||||
/// <returns>有限状态机数据是否存在。</returns>
|
||||
bool HasData(string name);
|
||||
|
||||
/// <summary>
|
||||
/// 获取有限状态机数据。
|
||||
/// </summary>
|
||||
/// <typeparam name="TData">要获取的有限状态机数据的类型。</typeparam>
|
||||
/// <param name="name">有限状态机数据名称。</param>
|
||||
/// <returns>要获取的有限状态机数据。</returns>
|
||||
TData GetData<TData>(string name) where TData : Variable;
|
||||
|
||||
/// <summary>
|
||||
/// 获取有限状态机数据。
|
||||
/// </summary>
|
||||
/// <param name="name">有限状态机数据名称。</param>
|
||||
/// <returns>要获取的有限状态机数据。</returns>
|
||||
Variable GetData(string name);
|
||||
|
||||
/// <summary>
|
||||
/// 设置有限状态机数据。
|
||||
/// </summary>
|
||||
/// <typeparam name="TData">要设置的有限状态机数据的类型。</typeparam>
|
||||
/// <param name="name">有限状态机数据名称。</param>
|
||||
/// <param name="data">要设置的有限状态机数据。</param>
|
||||
void SetData<TData>(string name, TData data) where TData : Variable;
|
||||
|
||||
/// <summary>
|
||||
/// 设置有限状态机数据。
|
||||
/// </summary>
|
||||
/// <param name="name">有限状态机数据名称。</param>
|
||||
/// <param name="data">要设置的有限状态机数据。</param>
|
||||
void SetData(string name, Variable data);
|
||||
|
||||
/// <summary>
|
||||
/// 移除有限状态机数据。
|
||||
/// </summary>
|
||||
/// <param name="name">有限状态机数据名称。</param>
|
||||
/// <returns>是否移除有限状态机数据成功。</returns>
|
||||
bool RemoveData(string name);
|
||||
}
|
||||
}
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5605e679eb1695f4a82968f89875453c
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,181 @@
|
||||
//------------------------------------------------------------
|
||||
// Game Framework
|
||||
// Copyright © 2013-2021 Jiang Yin. All rights reserved.
|
||||
// Homepage: https://gameframework.cn/
|
||||
// Feedback: mailto:ellan@gameframework.cn
|
||||
//------------------------------------------------------------
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace SHFrame.FSM
|
||||
{
|
||||
/// <summary>
|
||||
/// 有限状态机管理器。
|
||||
/// </summary>
|
||||
public interface IFsmManager
|
||||
{
|
||||
/// <summary>
|
||||
/// 获取有限状态机数量。
|
||||
/// </summary>
|
||||
int Count
|
||||
{
|
||||
get;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 检查是否存在有限状态机。
|
||||
/// </summary>
|
||||
/// <typeparam name="T">有限状态机持有者类型。</typeparam>
|
||||
/// <returns>是否存在有限状态机。</returns>
|
||||
bool HasFsm<T>() where T : class;
|
||||
|
||||
/// <summary>
|
||||
/// 检查是否存在有限状态机。
|
||||
/// </summary>
|
||||
/// <param name="ownerType">有限状态机持有者类型。</param>
|
||||
/// <returns>是否存在有限状态机。</returns>
|
||||
bool HasFsm(Type ownerType);
|
||||
|
||||
/// <summary>
|
||||
/// 检查是否存在有限状态机。
|
||||
/// </summary>
|
||||
/// <typeparam name="T">有限状态机持有者类型。</typeparam>
|
||||
/// <param name="name">有限状态机名称。</param>
|
||||
/// <returns>是否存在有限状态机。</returns>
|
||||
bool HasFsm<T>(string name) where T : class;
|
||||
|
||||
/// <summary>
|
||||
/// 检查是否存在有限状态机。
|
||||
/// </summary>
|
||||
/// <param name="ownerType">有限状态机持有者类型。</param>
|
||||
/// <param name="name">有限状态机名称。</param>
|
||||
/// <returns>是否存在有限状态机。</returns>
|
||||
bool HasFsm(Type ownerType, string name);
|
||||
|
||||
/// <summary>
|
||||
/// 获取有限状态机。
|
||||
/// </summary>
|
||||
/// <typeparam name="T">有限状态机持有者类型。</typeparam>
|
||||
/// <returns>要获取的有限状态机。</returns>
|
||||
IFsm<T> GetFsm<T>() where T : class;
|
||||
|
||||
/// <summary>
|
||||
/// 获取有限状态机。
|
||||
/// </summary>
|
||||
/// <param name="ownerType">有限状态机持有者类型。</param>
|
||||
/// <returns>要获取的有限状态机。</returns>
|
||||
FsmBase GetFsm(Type ownerType);
|
||||
|
||||
/// <summary>
|
||||
/// 获取有限状态机。
|
||||
/// </summary>
|
||||
/// <typeparam name="T">有限状态机持有者类型。</typeparam>
|
||||
/// <param name="name">有限状态机名称。</param>
|
||||
/// <returns>要获取的有限状态机。</returns>
|
||||
IFsm<T> GetFsm<T>(string name) where T : class;
|
||||
|
||||
/// <summary>
|
||||
/// 获取有限状态机。
|
||||
/// </summary>
|
||||
/// <param name="ownerType">有限状态机持有者类型。</param>
|
||||
/// <param name="name">有限状态机名称。</param>
|
||||
/// <returns>要获取的有限状态机。</returns>
|
||||
FsmBase GetFsm(Type ownerType, string name);
|
||||
|
||||
/// <summary>
|
||||
/// 获取所有有限状态机。
|
||||
/// </summary>
|
||||
/// <returns>所有有限状态机。</returns>
|
||||
FsmBase[] GetAllFsms();
|
||||
|
||||
/// <summary>
|
||||
/// 获取所有有限状态机。
|
||||
/// </summary>
|
||||
/// <param name="results">所有有限状态机。</param>
|
||||
void GetAllFsms(List<FsmBase> results);
|
||||
|
||||
/// <summary>
|
||||
/// 创建有限状态机。
|
||||
/// </summary>
|
||||
/// <typeparam name="T">有限状态机持有者类型。</typeparam>
|
||||
/// <param name="owner">有限状态机持有者。</param>
|
||||
/// <param name="states">有限状态机状态集合。</param>
|
||||
/// <returns>要创建的有限状态机。</returns>
|
||||
IFsm<T> CreateFsm<T>(T owner, params FsmState<T>[] states) where T : class;
|
||||
|
||||
/// <summary>
|
||||
/// 创建有限状态机。
|
||||
/// </summary>
|
||||
/// <typeparam name="T">有限状态机持有者类型。</typeparam>
|
||||
/// <param name="name">有限状态机名称。</param>
|
||||
/// <param name="owner">有限状态机持有者。</param>
|
||||
/// <param name="states">有限状态机状态集合。</param>
|
||||
/// <returns>要创建的有限状态机。</returns>
|
||||
IFsm<T> CreateFsm<T>(string name, T owner, params FsmState<T>[] states) where T : class;
|
||||
|
||||
/// <summary>
|
||||
/// 创建有限状态机。
|
||||
/// </summary>
|
||||
/// <typeparam name="T">有限状态机持有者类型。</typeparam>
|
||||
/// <param name="owner">有限状态机持有者。</param>
|
||||
/// <param name="states">有限状态机状态集合。</param>
|
||||
/// <returns>要创建的有限状态机。</returns>
|
||||
IFsm<T> CreateFsm<T>(T owner, List<FsmState<T>> states) where T : class;
|
||||
|
||||
/// <summary>
|
||||
/// 创建有限状态机。
|
||||
/// </summary>
|
||||
/// <typeparam name="T">有限状态机持有者类型。</typeparam>
|
||||
/// <param name="name">有限状态机名称。</param>
|
||||
/// <param name="owner">有限状态机持有者。</param>
|
||||
/// <param name="states">有限状态机状态集合。</param>
|
||||
/// <returns>要创建的有限状态机。</returns>
|
||||
IFsm<T> CreateFsm<T>(string name, T owner, List<FsmState<T>> states) where T : class;
|
||||
|
||||
/// <summary>
|
||||
/// 销毁有限状态机。
|
||||
/// </summary>
|
||||
/// <typeparam name="T">有限状态机持有者类型。</typeparam>
|
||||
/// <returns>是否销毁有限状态机成功。</returns>
|
||||
bool DestroyFsm<T>() where T : class;
|
||||
|
||||
/// <summary>
|
||||
/// 销毁有限状态机。
|
||||
/// </summary>
|
||||
/// <param name="ownerType">有限状态机持有者类型。</param>
|
||||
/// <returns>是否销毁有限状态机成功。</returns>
|
||||
bool DestroyFsm(Type ownerType);
|
||||
|
||||
/// <summary>
|
||||
/// 销毁有限状态机。
|
||||
/// </summary>
|
||||
/// <typeparam name="T">有限状态机持有者类型。</typeparam>
|
||||
/// <param name="name">要销毁的有限状态机名称。</param>
|
||||
/// <returns>是否销毁有限状态机成功。</returns>
|
||||
bool DestroyFsm<T>(string name) where T : class;
|
||||
|
||||
/// <summary>
|
||||
/// 销毁有限状态机。
|
||||
/// </summary>
|
||||
/// <param name="ownerType">有限状态机持有者类型。</param>
|
||||
/// <param name="name">要销毁的有限状态机名称。</param>
|
||||
/// <returns>是否销毁有限状态机成功。</returns>
|
||||
bool DestroyFsm(Type ownerType, string name);
|
||||
|
||||
/// <summary>
|
||||
/// 销毁有限状态机。
|
||||
/// </summary>
|
||||
/// <typeparam name="T">有限状态机持有者类型。</typeparam>
|
||||
/// <param name="fsm">要销毁的有限状态机。</param>
|
||||
/// <returns>是否销毁有限状态机成功。</returns>
|
||||
bool DestroyFsm<T>(IFsm<T> fsm) where T : class;
|
||||
|
||||
/// <summary>
|
||||
/// 销毁有限状态机。
|
||||
/// </summary>
|
||||
/// <param name="fsm">要销毁的有限状态机。</param>
|
||||
/// <returns>是否销毁有限状态机成功。</returns>
|
||||
bool DestroyFsm(FsmBase fsm);
|
||||
}
|
||||
}
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: eb277f41379f3a54983bdf668629a0d6
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
150
JNFrame2/Assets/UsePlugins/SHFrame/Runtime/Modules/GameModule.cs
Normal file
150
JNFrame2/Assets/UsePlugins/SHFrame/Runtime/Modules/GameModule.cs
Normal file
@@ -0,0 +1,150 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace SHFrame
|
||||
{
|
||||
/// <summary>
|
||||
/// 游戏模块。
|
||||
/// </summary>
|
||||
public partial class GameModule : MonoBehaviour
|
||||
{
|
||||
private static readonly Dictionary<Type, Module> _moduleMaps = new Dictionary<Type, Module>(ModuleImpSystem.DesignModuleCount);
|
||||
|
||||
private static GameObject _gameModuleRoot;
|
||||
|
||||
#region 框架模块
|
||||
/// <summary>
|
||||
/// 获取游戏基础模块。
|
||||
/// </summary>
|
||||
public static RootModule Base
|
||||
{
|
||||
get => _base ??= Get<RootModule>();
|
||||
private set => _base = value;
|
||||
}
|
||||
|
||||
private static RootModule _base;
|
||||
|
||||
// /// <summary>
|
||||
// /// 获取调试模块。
|
||||
// /// </summary>
|
||||
// public static DebuggerModule Debugger
|
||||
// {
|
||||
// get => _debugger ??= Get<DebuggerModule>();
|
||||
// private set => _debugger = value;
|
||||
// }
|
||||
//
|
||||
//
|
||||
// private static DebuggerModule _debugger;
|
||||
|
||||
/// <summary>
|
||||
/// 获取有限状态机模块。
|
||||
/// </summary>
|
||||
public static FSM.FsmModule Fsm => _fsm ??= Get<FSM.FsmModule>();
|
||||
|
||||
private static FSM.FsmModule _fsm;
|
||||
|
||||
/// <summary>
|
||||
/// 流程管理模块。
|
||||
/// </summary>
|
||||
public static ProcedureModule Procedure => _procedure ??= Get<ProcedureModule>();
|
||||
|
||||
private static ProcedureModule _procedure;
|
||||
|
||||
/// <summary>
|
||||
/// 获取对象池模块。
|
||||
/// </summary>
|
||||
public static ObjectPoolModule ObjectPool => _objectPool ??= Get<ObjectPoolModule>();
|
||||
|
||||
private static ObjectPoolModule _objectPool;
|
||||
|
||||
// /// <summary>
|
||||
// /// 获取资源模块。
|
||||
// /// </summary>
|
||||
// public static ResourceModule Resource => _resource ??= Get<ResourceModule>();
|
||||
//
|
||||
// private static ResourceModule _resource;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 获取音频模块。
|
||||
/// </summary>
|
||||
public static AudioModule Audio => _audio ??= Get<AudioModule>();
|
||||
|
||||
private static AudioModule _audio;
|
||||
|
||||
// /// <summary>
|
||||
// /// 获取配置模块。
|
||||
// /// </summary>
|
||||
// public static SettingModule Setting => _setting ??= Get<SettingModule>();
|
||||
//
|
||||
// private static SettingModule _setting;
|
||||
|
||||
// /// <summary>
|
||||
// /// 获取多语言模块。
|
||||
// /// </summary>
|
||||
// public static LocalizationModule Localization => _localization ??= Get<LocalizationModule>();
|
||||
//
|
||||
// private static LocalizationModule _localization;
|
||||
|
||||
// /// <summary>
|
||||
// /// 获取计时器模块。
|
||||
// /// </summary>
|
||||
// public static TimerModule Timer => _timer ??= Get<TimerModule>();
|
||||
//
|
||||
// private static TimerModule _timer;
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// 获取游戏框架模块类。
|
||||
/// </summary>
|
||||
/// <typeparam name="T">游戏框架模块类。</typeparam>
|
||||
/// <returns>游戏框架模块实例。</returns>
|
||||
public static T Get<T>() where T : Module
|
||||
{
|
||||
Type type = typeof(T);
|
||||
|
||||
if (_moduleMaps.TryGetValue(type, out var ret))
|
||||
{
|
||||
return ret as T;
|
||||
}
|
||||
|
||||
T module = ModuleSystem.GetModule<T>();
|
||||
|
||||
|
||||
Log.Assert(condition: module != null, $"{typeof(T)} is null");
|
||||
|
||||
_moduleMaps.Add(type, module);
|
||||
|
||||
return module;
|
||||
}
|
||||
|
||||
private void Start()
|
||||
{
|
||||
Log.Info("GameModule Active");
|
||||
_gameModuleRoot = gameObject;
|
||||
_gameModuleRoot.name = $"[{nameof(GameModule)}]";
|
||||
DontDestroyOnLoad(_gameModuleRoot);
|
||||
}
|
||||
|
||||
public static void Shutdown(ShutdownType shutdownType)
|
||||
{
|
||||
Log.Info("GameModule Shutdown");
|
||||
if (_gameModuleRoot != null)
|
||||
{
|
||||
Destroy(_gameModuleRoot);
|
||||
_gameModuleRoot = null;
|
||||
}
|
||||
_moduleMaps.Clear();
|
||||
|
||||
_base = null;
|
||||
// _debugger = null;
|
||||
_fsm = null;
|
||||
_procedure = null;
|
||||
_objectPool = null;
|
||||
// _resource = null;
|
||||
_audio = null;
|
||||
// _setting = null;
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f47aaf5c712947a69bb25051c81a1be1
|
||||
timeCreated: 1727610588
|
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9b0bcf6dd7924a66874dca3b02137324
|
||||
timeCreated: 1709188061
|
@@ -0,0 +1,56 @@
|
||||
using UnityEngine;
|
||||
|
||||
// ReSharper disable InconsistentNaming
|
||||
namespace SHFrame
|
||||
{
|
||||
/// <summary>
|
||||
/// 游戏时间。
|
||||
/// <remarks>提供从Unity获取时间信息的接口。</remarks>
|
||||
/// </summary>
|
||||
public static class GameTime
|
||||
{
|
||||
/// <summary>
|
||||
/// 此帧开始时的时间(只读)。
|
||||
/// </summary>
|
||||
public static float time;
|
||||
|
||||
/// <summary>
|
||||
/// 从上一帧到当前帧的间隔(秒)(只读)。
|
||||
/// </summary>
|
||||
public static float deltaTime;
|
||||
|
||||
/// <summary>
|
||||
/// timeScale从上一帧到当前帧的独立时间间隔(以秒为单位)(只读)。
|
||||
/// </summary>
|
||||
public static float unscaledDeltaTime;
|
||||
|
||||
/// <summary>
|
||||
/// 执行物理和其他固定帧速率更新的时间间隔(以秒为单位)。
|
||||
/// <remarks>如MonoBehavior的MonoBehaviour.FixedUpdate。</remarks>
|
||||
/// </summary>
|
||||
public static float fixedDeltaTime;
|
||||
|
||||
/// <summary>
|
||||
/// 自游戏开始以来的总帧数(只读)。
|
||||
/// </summary>
|
||||
public static float frameCount;
|
||||
|
||||
/// <summary>
|
||||
/// timeScale此帧的独立时间(只读)。这是自游戏开始以来的时间(以秒为单位)。
|
||||
/// </summary>
|
||||
public static float unscaledTime;
|
||||
|
||||
/// <summary>
|
||||
/// 采样一帧的时间。
|
||||
/// </summary>
|
||||
public static void StartFrame()
|
||||
{
|
||||
time = Time.time;
|
||||
deltaTime = Time.deltaTime;
|
||||
unscaledDeltaTime = Time.unscaledDeltaTime;
|
||||
fixedDeltaTime = Time.fixedDeltaTime;
|
||||
frameCount = Time.frameCount;
|
||||
unscaledTime = Time.unscaledTime;
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8b8ef95462cc493fbbc3250e6992a818
|
||||
timeCreated: 1694855463
|
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 254c83d52519d15489b51a2ff35341d9
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,18 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace SHFrame
|
||||
{
|
||||
/// <summary>
|
||||
/// 游戏框架模块抽象类。
|
||||
/// </summary>
|
||||
public abstract class Module : MonoBehaviour
|
||||
{
|
||||
/// <summary>
|
||||
/// 游戏框架模块初始化。
|
||||
/// </summary>
|
||||
protected virtual void Awake()
|
||||
{
|
||||
ModuleSystem.RegisterModule(this);
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8d03a2850c3d46bfbb20c1b3f0ba28cc
|
||||
timeCreated: 1694836036
|
@@ -0,0 +1,67 @@
|
||||
using System;
|
||||
|
||||
namespace SHFrame
|
||||
{
|
||||
/// <summary>
|
||||
/// 模块需要框架轮询属性。
|
||||
/// </summary>
|
||||
/// <remarks> 注入此属性标识模块需要轮询。</remarks>
|
||||
[AttributeUsage(AttributeTargets.Class)]
|
||||
internal class UpdateModuleAttribute : Attribute
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 游戏框架模块抽象类。
|
||||
/// <remarks>实现游戏框架具体逻辑。</remarks>
|
||||
/// </summary>
|
||||
internal abstract class ModuleImp
|
||||
{
|
||||
/// <summary>
|
||||
/// 获取游戏框架模块优先级。
|
||||
/// </summary>
|
||||
/// <remarks>优先级较高的模块会优先轮询,并且关闭操作会后进行。</remarks>
|
||||
internal virtual int Priority => 0;
|
||||
|
||||
/// <summary>
|
||||
/// 游戏框架模块轮询。
|
||||
/// </summary>
|
||||
/// <param name="elapseSeconds">逻辑流逝时间,以秒为单位。</param>
|
||||
/// <param name="realElapseSeconds">真实流逝时间,以秒为单位。</param>
|
||||
internal virtual void Update(float elapseSeconds, float realElapseSeconds)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 关闭并清理游戏框架模块。
|
||||
/// </summary>
|
||||
internal abstract void Shutdown();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 游戏框架模块抽象类。
|
||||
/// <remarks>实现游戏框架具体逻辑。</remarks>
|
||||
/// </summary>
|
||||
public interface IModuleImp2
|
||||
{
|
||||
/// <summary>
|
||||
/// 获取游戏框架模块优先级。
|
||||
/// </summary>
|
||||
/// <remarks>优先级较高的模块会优先轮询,并且关闭操作会后进行。</remarks>
|
||||
internal virtual int Priority => 0;
|
||||
|
||||
/// <summary>
|
||||
/// 游戏框架模块轮询。
|
||||
/// </summary>
|
||||
/// <param name="elapseSeconds">逻辑流逝时间,以秒为单位。</param>
|
||||
/// <param name="realElapseSeconds">真实流逝时间,以秒为单位。</param>
|
||||
internal virtual void Update(float elapseSeconds, float realElapseSeconds)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 关闭并清理游戏框架模块。
|
||||
/// </summary>
|
||||
internal abstract void Shutdown();
|
||||
}
|
||||
}
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b4db746c6b3928b4a89a3ce316a8870b
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,160 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace SHFrame
|
||||
{
|
||||
/// <summary>
|
||||
/// 游戏框架模块实现类管理系统。
|
||||
/// </summary>
|
||||
public static class ModuleImpSystem
|
||||
{
|
||||
/// <summary>
|
||||
/// 默认设计的模块数量。
|
||||
/// <remarks>有增删可以自行修改减少内存分配与GCAlloc。</remarks>
|
||||
/// </summary>
|
||||
internal const int DesignModuleCount = 16;
|
||||
private const string ModuleRootNameSpace = "SHFrame.";
|
||||
|
||||
private static readonly Dictionary<Type, ModuleImp> _moduleMaps = new Dictionary<Type, ModuleImp>(DesignModuleCount);
|
||||
private static readonly GameFrameworkLinkedList<ModuleImp> _modules = new GameFrameworkLinkedList<ModuleImp>();
|
||||
private static readonly GameFrameworkLinkedList<ModuleImp> _updateModules = new GameFrameworkLinkedList<ModuleImp>();
|
||||
private static readonly List<ModuleImp> _updateExecuteList = new List<ModuleImp>(DesignModuleCount);
|
||||
|
||||
/// <summary>
|
||||
/// 所有游戏框架模块轮询。
|
||||
/// </summary>
|
||||
/// <param name="elapseSeconds">逻辑流逝时间,以秒为单位。</param>
|
||||
/// <param name="realElapseSeconds">真实流逝时间,以秒为单位。</param>
|
||||
public static void Update(float elapseSeconds, float realElapseSeconds)
|
||||
{
|
||||
int executeCount = _updateExecuteList.Count;
|
||||
for (int i = 0; i < executeCount; i++)
|
||||
{
|
||||
_updateExecuteList[i].Update(elapseSeconds, realElapseSeconds);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 关闭并清理所有游戏框架模块。
|
||||
/// </summary>
|
||||
public static void Shutdown()
|
||||
{
|
||||
for (LinkedListNode<ModuleImp> current = _modules.Last; current != null; current = current.Previous)
|
||||
{
|
||||
current.Value.Shutdown();
|
||||
}
|
||||
|
||||
_modules.Clear();
|
||||
_moduleMaps.Clear();
|
||||
_updateModules.Clear();
|
||||
_updateExecuteList.Clear();
|
||||
ReferencePool.ClearAll();
|
||||
Utility.Marshal.FreeCachedHGlobal();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取游戏框架模块。
|
||||
/// </summary>
|
||||
/// <typeparam name="T">要获取的游戏框架模块类型。</typeparam>
|
||||
/// <returns>要获取的游戏框架模块。</returns>
|
||||
/// <remarks>如果要获取的游戏框架模块不存在,则自动创建该游戏框架模块。</remarks>
|
||||
public static T GetModule<T>() where T : class
|
||||
{
|
||||
Type module = typeof(T);
|
||||
|
||||
if (module.FullName != null && !module.FullName.StartsWith(ModuleRootNameSpace, StringComparison.Ordinal))
|
||||
{
|
||||
throw new GameFrameworkException(Utility.Text.Format("You must get a Framework module, but '{0}' is not.", module.FullName));
|
||||
}
|
||||
|
||||
string moduleName = Utility.Text.Format("{0}.{1}", module.Namespace, module.Name.Substring(1));
|
||||
Type moduleType = Type.GetType(moduleName);
|
||||
if (moduleType == null)
|
||||
{
|
||||
moduleName = Utility.Text.Format("{0}.{1}", module.Namespace, module.Name);
|
||||
moduleType = Type.GetType(moduleName);
|
||||
if (moduleType == null)
|
||||
{
|
||||
throw new GameFrameworkException(Utility.Text.Format("Can not find Game Framework module type '{0}'.", moduleName));
|
||||
}
|
||||
}
|
||||
|
||||
return GetModule(moduleType) as T;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取游戏框架模块。
|
||||
/// </summary>
|
||||
/// <param name="moduleType">要获取的游戏框架模块类型。</param>
|
||||
/// <returns>要获取的游戏框架模块。</returns>
|
||||
/// <remarks>如果要获取的游戏框架模块不存在,则自动创建该游戏框架模块。</remarks>
|
||||
private static ModuleImp GetModule(Type moduleType)
|
||||
{
|
||||
return _moduleMaps.TryGetValue(moduleType, out ModuleImp module) ? module : CreateModule(moduleType);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 创建游戏框架模块。
|
||||
/// </summary>
|
||||
/// <param name="moduleType">要创建的游戏框架模块类型。</param>
|
||||
/// <returns>要创建的游戏框架模块。</returns>
|
||||
private static ModuleImp CreateModule(Type moduleType)
|
||||
{
|
||||
ModuleImp moduleImp = (ModuleImp)Activator.CreateInstance(moduleType);
|
||||
if (moduleImp == null)
|
||||
{
|
||||
throw new GameFrameworkException(Utility.Text.Format("Can not create module '{0}'.", moduleType.FullName));
|
||||
}
|
||||
|
||||
_moduleMaps[moduleType] = moduleImp;
|
||||
|
||||
LinkedListNode<ModuleImp> current = _modules.First;
|
||||
while (current != null)
|
||||
{
|
||||
if (moduleImp.Priority > current.Value.Priority)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
current = current.Next;
|
||||
}
|
||||
|
||||
if (current != null)
|
||||
{
|
||||
_modules.AddBefore(current, moduleImp);
|
||||
}
|
||||
else
|
||||
{
|
||||
_modules.AddLast(moduleImp);
|
||||
}
|
||||
|
||||
if (Attribute.GetCustomAttribute(moduleType, typeof(UpdateModuleAttribute)) is UpdateModuleAttribute updateModuleAttribute)
|
||||
{
|
||||
LinkedListNode<ModuleImp> currentUpdate = _updateModules.First;
|
||||
while (currentUpdate != null)
|
||||
{
|
||||
if (moduleImp.Priority > currentUpdate.Value.Priority)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
currentUpdate = currentUpdate.Next;
|
||||
}
|
||||
|
||||
if (currentUpdate != null)
|
||||
{
|
||||
_updateModules.AddBefore(currentUpdate, moduleImp);
|
||||
}
|
||||
else
|
||||
{
|
||||
_updateModules.AddLast(moduleImp);
|
||||
}
|
||||
|
||||
_updateExecuteList.Clear();
|
||||
_updateExecuteList.AddRange(_updateModules);
|
||||
}
|
||||
|
||||
return moduleImp;
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: eb600bcb941e4094a006a6780098c241
|
||||
timeCreated: 1694796997
|
@@ -0,0 +1,139 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEngine.SceneManagement;
|
||||
|
||||
namespace SHFrame
|
||||
{
|
||||
/// <summary>
|
||||
/// 游戏框架模块管理系统。
|
||||
/// </summary>
|
||||
public static class ModuleSystem
|
||||
{
|
||||
private static readonly GameFrameworkLinkedList<Module> _modules = new GameFrameworkLinkedList<Module>();
|
||||
|
||||
/// <summary>
|
||||
/// 游戏框架所在的场景编号。
|
||||
/// </summary>
|
||||
internal const int GameFrameworkSceneId = 0;
|
||||
|
||||
/// <summary>
|
||||
/// 获取游戏框架模块。
|
||||
/// </summary>
|
||||
/// <typeparam name="T">要获取的游戏框架模块类型。</typeparam>
|
||||
/// <returns>要获取的游戏框架模块。</returns>
|
||||
public static T GetModule<T>() where T : Module
|
||||
{
|
||||
return (T)GetModule(typeof(T));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取游戏框架模块。
|
||||
/// </summary>
|
||||
/// <param name="type">要获取的游戏框架模块类型。</param>
|
||||
/// <returns>要获取的游戏框架模块。</returns>
|
||||
public static Module GetModule(Type type)
|
||||
{
|
||||
LinkedListNode<Module> current = _modules.First;
|
||||
while (current != null)
|
||||
{
|
||||
if (current.Value.GetType() == type)
|
||||
{
|
||||
return current.Value;
|
||||
}
|
||||
|
||||
current = current.Next;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取游戏框架模块。
|
||||
/// </summary>
|
||||
/// <param name="typeName">要获取的游戏框架模块类型名称。</param>
|
||||
/// <returns>要获取的游戏框架模块。</returns>
|
||||
public static Module GetModule(string typeName)
|
||||
{
|
||||
LinkedListNode<Module> current = _modules.First;
|
||||
while (current != null)
|
||||
{
|
||||
Type type = current.Value.GetType();
|
||||
if (type.FullName == typeName || type.Name == typeName)
|
||||
{
|
||||
return current.Value;
|
||||
}
|
||||
|
||||
current = current.Next;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 关闭游戏框架。
|
||||
/// </summary>
|
||||
/// <param name="shutdownType">关闭游戏框架类型。</param>
|
||||
public static void Shutdown(ShutdownType shutdownType)
|
||||
{
|
||||
Log.Info("Shutdown Game Framework ({0})...", shutdownType);
|
||||
RootModule rootModule = GetModule<RootModule>();
|
||||
if (rootModule != null)
|
||||
{
|
||||
rootModule.Shutdown();
|
||||
rootModule = null;
|
||||
}
|
||||
_modules.Clear();
|
||||
|
||||
GameModule.Shutdown(shutdownType);
|
||||
|
||||
if (shutdownType == ShutdownType.None)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (shutdownType == ShutdownType.Restart)
|
||||
{
|
||||
SceneManager.LoadScene(GameFrameworkSceneId);
|
||||
return;
|
||||
}
|
||||
|
||||
if (shutdownType == ShutdownType.Quit)
|
||||
{
|
||||
Application.Quit();
|
||||
#if UNITY_EDITOR
|
||||
UnityEditor.EditorApplication.isPlaying = false;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 注册游戏框架模块。
|
||||
/// </summary>
|
||||
/// <param name="module">要注册的游戏框架模块。</param>
|
||||
internal static void RegisterModule(Module module)
|
||||
{
|
||||
if (module == null)
|
||||
{
|
||||
Log.Error("Module is invalid.");
|
||||
return;
|
||||
}
|
||||
|
||||
Type type = module.GetType();
|
||||
|
||||
LinkedListNode<Module> current = _modules.First;
|
||||
while (current != null)
|
||||
{
|
||||
if (current.Value.GetType() == type)
|
||||
{
|
||||
Log.Error("Game Framework component type '{0}' is already exist.", type.FullName);
|
||||
return;
|
||||
}
|
||||
|
||||
current = current.Next;
|
||||
}
|
||||
|
||||
_modules.AddLast(module);
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d3f0059418a84d0d8aaebdbc005bb1f5
|
||||
timeCreated: 1694839938
|
@@ -0,0 +1,23 @@
|
||||
namespace SHFrame
|
||||
{
|
||||
/// <summary>
|
||||
/// 关闭游戏框架类型。
|
||||
/// </summary>
|
||||
public enum ShutdownType : byte
|
||||
{
|
||||
/// <summary>
|
||||
/// 仅关闭游戏框架。
|
||||
/// </summary>
|
||||
None = 0,
|
||||
|
||||
/// <summary>
|
||||
/// 关闭游戏框架并重启游戏。
|
||||
/// </summary>
|
||||
Restart,
|
||||
|
||||
/// <summary>
|
||||
/// 关闭游戏框架并退出游戏。
|
||||
/// </summary>
|
||||
Quit,
|
||||
}
|
||||
}
|
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e004d71ac8074d1ab0021efcf433f34d
|
||||
timeCreated: 1694840037
|
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 52214ae888604bf7a3dc4b6b1241adff
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,218 @@
|
||||
//------------------------------------------------------------
|
||||
// Game Framework
|
||||
// Copyright © 2013-2021 Jiang Yin. All rights reserved.
|
||||
// Homepage: https://gameframework.cn/
|
||||
// Feedback: mailto:ellan@gameframework.cn
|
||||
//------------------------------------------------------------
|
||||
|
||||
using System;
|
||||
|
||||
namespace SHFrame
|
||||
{
|
||||
/// <summary>
|
||||
/// 对象池接口。
|
||||
/// </summary>
|
||||
/// <typeparam name="T">对象类型。</typeparam>
|
||||
public interface IObjectPool<T> where T : ObjectBase
|
||||
{
|
||||
/// <summary>
|
||||
/// 获取对象池名称。
|
||||
/// </summary>
|
||||
string Name
|
||||
{
|
||||
get;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取对象池完整名称。
|
||||
/// </summary>
|
||||
string FullName
|
||||
{
|
||||
get;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取对象池对象类型。
|
||||
/// </summary>
|
||||
Type ObjectType
|
||||
{
|
||||
get;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取对象池中对象的数量。
|
||||
/// </summary>
|
||||
int Count
|
||||
{
|
||||
get;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取对象池中能被释放的对象的数量。
|
||||
/// </summary>
|
||||
int CanReleaseCount
|
||||
{
|
||||
get;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取是否允许对象被多次获取。
|
||||
/// </summary>
|
||||
bool AllowMultiSpawn
|
||||
{
|
||||
get;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取或设置对象池自动释放可释放对象的间隔秒数。
|
||||
/// </summary>
|
||||
float AutoReleaseInterval
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取或设置对象池的容量。
|
||||
/// </summary>
|
||||
int Capacity
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取或设置对象池对象过期秒数。
|
||||
/// </summary>
|
||||
float ExpireTime
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取或设置对象池的优先级。
|
||||
/// </summary>
|
||||
int Priority
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 创建对象。
|
||||
/// </summary>
|
||||
/// <param name="obj">对象。</param>
|
||||
/// <param name="spawned">对象是否已被获取。</param>
|
||||
void Register(T obj, bool spawned);
|
||||
|
||||
/// <summary>
|
||||
/// 检查对象。
|
||||
/// </summary>
|
||||
/// <returns>要检查的对象是否存在。</returns>
|
||||
bool CanSpawn();
|
||||
|
||||
/// <summary>
|
||||
/// 检查对象。
|
||||
/// </summary>
|
||||
/// <param name="name">对象名称。</param>
|
||||
/// <returns>要检查的对象是否存在。</returns>
|
||||
bool CanSpawn(string name);
|
||||
|
||||
/// <summary>
|
||||
/// 获取对象。
|
||||
/// </summary>
|
||||
/// <returns>要获取的对象。</returns>
|
||||
T Spawn();
|
||||
|
||||
/// <summary>
|
||||
/// 获取对象。
|
||||
/// </summary>
|
||||
/// <param name="name">对象名称。</param>
|
||||
/// <returns>要获取的对象。</returns>
|
||||
T Spawn(string name);
|
||||
|
||||
/// <summary>
|
||||
/// 回收对象。
|
||||
/// </summary>
|
||||
/// <param name="obj">要回收的对象。</param>
|
||||
void Unspawn(T obj);
|
||||
|
||||
/// <summary>
|
||||
/// 回收对象。
|
||||
/// </summary>
|
||||
/// <param name="target">要回收的对象。</param>
|
||||
void Unspawn(object target);
|
||||
|
||||
/// <summary>
|
||||
/// 设置对象是否被加锁。
|
||||
/// </summary>
|
||||
/// <param name="obj">要设置被加锁的对象。</param>
|
||||
/// <param name="locked">是否被加锁。</param>
|
||||
void SetLocked(T obj, bool locked);
|
||||
|
||||
/// <summary>
|
||||
/// 设置对象是否被加锁。
|
||||
/// </summary>
|
||||
/// <param name="target">要设置被加锁的对象。</param>
|
||||
/// <param name="locked">是否被加锁。</param>
|
||||
void SetLocked(object target, bool locked);
|
||||
|
||||
/// <summary>
|
||||
/// 设置对象的优先级。
|
||||
/// </summary>
|
||||
/// <param name="obj">要设置优先级的对象。</param>
|
||||
/// <param name="priority">优先级。</param>
|
||||
void SetPriority(T obj, int priority);
|
||||
|
||||
/// <summary>
|
||||
/// 设置对象的优先级。
|
||||
/// </summary>
|
||||
/// <param name="target">要设置优先级的对象。</param>
|
||||
/// <param name="priority">优先级。</param>
|
||||
void SetPriority(object target, int priority);
|
||||
|
||||
/// <summary>
|
||||
/// 释放对象。
|
||||
/// </summary>
|
||||
/// <param name="obj">要释放的对象。</param>
|
||||
/// <returns>释放对象是否成功。</returns>
|
||||
bool ReleaseObject(T obj);
|
||||
|
||||
/// <summary>
|
||||
/// 释放对象。
|
||||
/// </summary>
|
||||
/// <param name="target">要释放的对象。</param>
|
||||
/// <returns>释放对象是否成功。</returns>
|
||||
bool ReleaseObject(object target);
|
||||
|
||||
/// <summary>
|
||||
/// 释放对象池中的可释放对象。
|
||||
/// </summary>
|
||||
void Release();
|
||||
|
||||
/// <summary>
|
||||
/// 释放对象池中的可释放对象。
|
||||
/// </summary>
|
||||
/// <param name="toReleaseCount">尝试释放对象数量。</param>
|
||||
void Release(int toReleaseCount);
|
||||
|
||||
/// <summary>
|
||||
/// 释放对象池中的可释放对象。
|
||||
/// </summary>
|
||||
/// <param name="releaseObjectFilterCallback">释放对象筛选函数。</param>
|
||||
void Release(ReleaseObjectFilterCallback<T> releaseObjectFilterCallback);
|
||||
|
||||
/// <summary>
|
||||
/// 释放对象池中的可释放对象。
|
||||
/// </summary>
|
||||
/// <param name="toReleaseCount">尝试释放对象数量。</param>
|
||||
/// <param name="releaseObjectFilterCallback">释放对象筛选函数。</param>
|
||||
void Release(int toReleaseCount, ReleaseObjectFilterCallback<T> releaseObjectFilterCallback);
|
||||
|
||||
/// <summary>
|
||||
/// 释放对象池中的所有未使用对象。
|
||||
/// </summary>
|
||||
void ReleaseAllUnused();
|
||||
}
|
||||
}
|
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4d548f22ce18454a806f5f61ee71c75d
|
||||
timeCreated: 1708673686
|
@@ -0,0 +1,751 @@
|
||||
//------------------------------------------------------------
|
||||
// Game Framework
|
||||
// Copyright © 2013-2021 Jiang Yin. All rights reserved.
|
||||
// Homepage: https://gameframework.cn/
|
||||
// Feedback: mailto:ellan@gameframework.cn
|
||||
//------------------------------------------------------------
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace SHFrame
|
||||
{
|
||||
/// <summary>
|
||||
/// 对象池管理器。
|
||||
/// </summary>
|
||||
public interface IObjectPoolManager
|
||||
{
|
||||
/// <summary>
|
||||
/// 获取对象池数量。
|
||||
/// </summary>
|
||||
int Count
|
||||
{
|
||||
get;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 检查是否存在对象池。
|
||||
/// </summary>
|
||||
/// <typeparam name="T">对象类型。</typeparam>
|
||||
/// <returns>是否存在对象池。</returns>
|
||||
bool HasObjectPool<T>() where T : ObjectBase;
|
||||
|
||||
/// <summary>
|
||||
/// 检查是否存在对象池。
|
||||
/// </summary>
|
||||
/// <param name="objectType">对象类型。</param>
|
||||
/// <returns>是否存在对象池。</returns>
|
||||
bool HasObjectPool(Type objectType);
|
||||
|
||||
/// <summary>
|
||||
/// 检查是否存在对象池。
|
||||
/// </summary>
|
||||
/// <typeparam name="T">对象类型。</typeparam>
|
||||
/// <param name="name">对象池名称。</param>
|
||||
/// <returns>是否存在对象池。</returns>
|
||||
bool HasObjectPool<T>(string name) where T : ObjectBase;
|
||||
|
||||
/// <summary>
|
||||
/// 检查是否存在对象池。
|
||||
/// </summary>
|
||||
/// <param name="objectType">对象类型。</param>
|
||||
/// <param name="name">对象池名称。</param>
|
||||
/// <returns>是否存在对象池。</returns>
|
||||
bool HasObjectPool(Type objectType, string name);
|
||||
|
||||
/// <summary>
|
||||
/// 检查是否存在对象池。
|
||||
/// </summary>
|
||||
/// <param name="condition">要检查的条件。</param>
|
||||
/// <returns>是否存在对象池。</returns>
|
||||
bool HasObjectPool(Predicate<ObjectPoolBase> condition);
|
||||
|
||||
/// <summary>
|
||||
/// 获取对象池。
|
||||
/// </summary>
|
||||
/// <typeparam name="T">对象类型。</typeparam>
|
||||
/// <returns>要获取的对象池。</returns>
|
||||
IObjectPool<T> GetObjectPool<T>() where T : ObjectBase;
|
||||
|
||||
/// <summary>
|
||||
/// 获取对象池。
|
||||
/// </summary>
|
||||
/// <param name="objectType">对象类型。</param>
|
||||
/// <returns>要获取的对象池。</returns>
|
||||
ObjectPoolBase GetObjectPool(Type objectType);
|
||||
|
||||
/// <summary>
|
||||
/// 获取对象池。
|
||||
/// </summary>
|
||||
/// <typeparam name="T">对象类型。</typeparam>
|
||||
/// <param name="name">对象池名称。</param>
|
||||
/// <returns>要获取的对象池。</returns>
|
||||
IObjectPool<T> GetObjectPool<T>(string name) where T : ObjectBase;
|
||||
|
||||
/// <summary>
|
||||
/// 获取对象池。
|
||||
/// </summary>
|
||||
/// <param name="objectType">对象类型。</param>
|
||||
/// <param name="name">对象池名称。</param>
|
||||
/// <returns>要获取的对象池。</returns>
|
||||
ObjectPoolBase GetObjectPool(Type objectType, string name);
|
||||
|
||||
/// <summary>
|
||||
/// 获取对象池。
|
||||
/// </summary>
|
||||
/// <param name="condition">要检查的条件。</param>
|
||||
/// <returns>要获取的对象池。</returns>
|
||||
ObjectPoolBase GetObjectPool(Predicate<ObjectPoolBase> condition);
|
||||
|
||||
/// <summary>
|
||||
/// 获取对象池。
|
||||
/// </summary>
|
||||
/// <param name="condition">要检查的条件。</param>
|
||||
/// <returns>要获取的对象池。</returns>
|
||||
ObjectPoolBase[] GetObjectPools(Predicate<ObjectPoolBase> condition);
|
||||
|
||||
/// <summary>
|
||||
/// 获取对象池。
|
||||
/// </summary>
|
||||
/// <param name="condition">要检查的条件。</param>
|
||||
/// <param name="results">要获取的对象池。</param>
|
||||
void GetObjectPools(Predicate<ObjectPoolBase> condition, List<ObjectPoolBase> results);
|
||||
|
||||
/// <summary>
|
||||
/// 获取所有对象池。
|
||||
/// </summary>
|
||||
/// <returns>所有对象池。</returns>
|
||||
ObjectPoolBase[] GetAllObjectPools();
|
||||
|
||||
/// <summary>
|
||||
/// 获取所有对象池。
|
||||
/// </summary>
|
||||
/// <param name="results">所有对象池。</param>
|
||||
void GetAllObjectPools(List<ObjectPoolBase> results);
|
||||
|
||||
/// <summary>
|
||||
/// 获取所有对象池。
|
||||
/// </summary>
|
||||
/// <param name="sort">是否根据对象池的优先级排序。</param>
|
||||
/// <returns>所有对象池。</returns>
|
||||
ObjectPoolBase[] GetAllObjectPools(bool sort);
|
||||
|
||||
/// <summary>
|
||||
/// 获取所有对象池。
|
||||
/// </summary>
|
||||
/// <param name="sort">是否根据对象池的优先级排序。</param>
|
||||
/// <param name="results">所有对象池。</param>
|
||||
void GetAllObjectPools(bool sort, List<ObjectPoolBase> results);
|
||||
|
||||
/// <summary>
|
||||
/// 创建允许单次获取的对象池。
|
||||
/// </summary>
|
||||
/// <typeparam name="T">对象类型。</typeparam>
|
||||
/// <returns>要创建的允许单次获取的对象池。</returns>
|
||||
IObjectPool<T> CreateSingleSpawnObjectPool<T>() where T : ObjectBase;
|
||||
|
||||
/// <summary>
|
||||
/// 创建允许单次获取的对象池。
|
||||
/// </summary>
|
||||
/// <param name="objectType">对象类型。</param>
|
||||
/// <returns>要创建的允许单次获取的对象池。</returns>
|
||||
ObjectPoolBase CreateSingleSpawnObjectPool(Type objectType);
|
||||
|
||||
/// <summary>
|
||||
/// 创建允许单次获取的对象池。
|
||||
/// </summary>
|
||||
/// <typeparam name="T">对象类型。</typeparam>
|
||||
/// <param name="name">对象池名称。</param>
|
||||
/// <returns>要创建的允许单次获取的对象池。</returns>
|
||||
IObjectPool<T> CreateSingleSpawnObjectPool<T>(string name) where T : ObjectBase;
|
||||
|
||||
/// <summary>
|
||||
/// 创建允许单次获取的对象池。
|
||||
/// </summary>
|
||||
/// <param name="objectType">对象类型。</param>
|
||||
/// <param name="name">对象池名称。</param>
|
||||
/// <returns>要创建的允许单次获取的对象池。</returns>
|
||||
ObjectPoolBase CreateSingleSpawnObjectPool(Type objectType, string name);
|
||||
|
||||
/// <summary>
|
||||
/// 创建允许单次获取的对象池。
|
||||
/// </summary>
|
||||
/// <typeparam name="T">对象类型。</typeparam>
|
||||
/// <param name="capacity">对象池的容量。</param>
|
||||
/// <returns>要创建的允许单次获取的对象池。</returns>
|
||||
IObjectPool<T> CreateSingleSpawnObjectPool<T>(int capacity) where T : ObjectBase;
|
||||
|
||||
/// <summary>
|
||||
/// 创建允许单次获取的对象池。
|
||||
/// </summary>
|
||||
/// <param name="objectType">对象类型。</param>
|
||||
/// <param name="capacity">对象池的容量。</param>
|
||||
/// <returns>要创建的允许单次获取的对象池。</returns>
|
||||
ObjectPoolBase CreateSingleSpawnObjectPool(Type objectType, int capacity);
|
||||
|
||||
/// <summary>
|
||||
/// 创建允许单次获取的对象池。
|
||||
/// </summary>
|
||||
/// <typeparam name="T">对象类型。</typeparam>
|
||||
/// <param name="expireTime">对象池对象过期秒数。</param>
|
||||
/// <returns>要创建的允许单次获取的对象池。</returns>
|
||||
IObjectPool<T> CreateSingleSpawnObjectPool<T>(float expireTime) where T : ObjectBase;
|
||||
|
||||
/// <summary>
|
||||
/// 创建允许单次获取的对象池。
|
||||
/// </summary>
|
||||
/// <param name="objectType">对象类型。</param>
|
||||
/// <param name="expireTime">对象池对象过期秒数。</param>
|
||||
/// <returns>要创建的允许单次获取的对象池。</returns>
|
||||
ObjectPoolBase CreateSingleSpawnObjectPool(Type objectType, float expireTime);
|
||||
|
||||
/// <summary>
|
||||
/// 创建允许单次获取的对象池。
|
||||
/// </summary>
|
||||
/// <typeparam name="T">对象类型。</typeparam>
|
||||
/// <param name="name">对象池名称。</param>
|
||||
/// <param name="capacity">对象池的容量。</param>
|
||||
/// <returns>要创建的允许单次获取的对象池。</returns>
|
||||
IObjectPool<T> CreateSingleSpawnObjectPool<T>(string name, int capacity) where T : ObjectBase;
|
||||
|
||||
/// <summary>
|
||||
/// 创建允许单次获取的对象池。
|
||||
/// </summary>
|
||||
/// <param name="objectType">对象类型。</param>
|
||||
/// <param name="name">对象池名称。</param>
|
||||
/// <param name="capacity">对象池的容量。</param>
|
||||
/// <returns>要创建的允许单次获取的对象池。</returns>
|
||||
ObjectPoolBase CreateSingleSpawnObjectPool(Type objectType, string name, int capacity);
|
||||
|
||||
/// <summary>
|
||||
/// 创建允许单次获取的对象池。
|
||||
/// </summary>
|
||||
/// <typeparam name="T">对象类型。</typeparam>
|
||||
/// <param name="name">对象池名称。</param>
|
||||
/// <param name="expireTime">对象池对象过期秒数。</param>
|
||||
/// <returns>要创建的允许单次获取的对象池。</returns>
|
||||
IObjectPool<T> CreateSingleSpawnObjectPool<T>(string name, float expireTime) where T : ObjectBase;
|
||||
|
||||
/// <summary>
|
||||
/// 创建允许单次获取的对象池。
|
||||
/// </summary>
|
||||
/// <param name="objectType">对象类型。</param>
|
||||
/// <param name="name">对象池名称。</param>
|
||||
/// <param name="expireTime">对象池对象过期秒数。</param>
|
||||
/// <returns>要创建的允许单次获取的对象池。</returns>
|
||||
ObjectPoolBase CreateSingleSpawnObjectPool(Type objectType, string name, float expireTime);
|
||||
|
||||
/// <summary>
|
||||
/// 创建允许单次获取的对象池。
|
||||
/// </summary>
|
||||
/// <typeparam name="T">对象类型。</typeparam>
|
||||
/// <param name="capacity">对象池的容量。</param>
|
||||
/// <param name="expireTime">对象池对象过期秒数。</param>
|
||||
/// <returns>要创建的允许单次获取的对象池。</returns>
|
||||
IObjectPool<T> CreateSingleSpawnObjectPool<T>(int capacity, float expireTime) where T : ObjectBase;
|
||||
|
||||
/// <summary>
|
||||
/// 创建允许单次获取的对象池。
|
||||
/// </summary>
|
||||
/// <param name="objectType">对象类型。</param>
|
||||
/// <param name="capacity">对象池的容量。</param>
|
||||
/// <param name="expireTime">对象池对象过期秒数。</param>
|
||||
/// <returns>要创建的允许单次获取的对象池。</returns>
|
||||
ObjectPoolBase CreateSingleSpawnObjectPool(Type objectType, int capacity, float expireTime);
|
||||
|
||||
/// <summary>
|
||||
/// 创建允许单次获取的对象池。
|
||||
/// </summary>
|
||||
/// <typeparam name="T">对象类型。</typeparam>
|
||||
/// <param name="capacity">对象池的容量。</param>
|
||||
/// <param name="priority">对象池的优先级。</param>
|
||||
/// <returns>要创建的允许单次获取的对象池。</returns>
|
||||
IObjectPool<T> CreateSingleSpawnObjectPool<T>(int capacity, int priority) where T : ObjectBase;
|
||||
|
||||
/// <summary>
|
||||
/// 创建允许单次获取的对象池。
|
||||
/// </summary>
|
||||
/// <param name="objectType">对象类型。</param>
|
||||
/// <param name="capacity">对象池的容量。</param>
|
||||
/// <param name="priority">对象池的优先级。</param>
|
||||
/// <returns>要创建的允许单次获取的对象池。</returns>
|
||||
ObjectPoolBase CreateSingleSpawnObjectPool(Type objectType, int capacity, int priority);
|
||||
|
||||
/// <summary>
|
||||
/// 创建允许单次获取的对象池。
|
||||
/// </summary>
|
||||
/// <typeparam name="T">对象类型。</typeparam>
|
||||
/// <param name="expireTime">对象池对象过期秒数。</param>
|
||||
/// <param name="priority">对象池的优先级。</param>
|
||||
/// <returns>要创建的允许单次获取的对象池。</returns>
|
||||
IObjectPool<T> CreateSingleSpawnObjectPool<T>(float expireTime, int priority) where T : ObjectBase;
|
||||
|
||||
/// <summary>
|
||||
/// 创建允许单次获取的对象池。
|
||||
/// </summary>
|
||||
/// <param name="objectType">对象类型。</param>
|
||||
/// <param name="expireTime">对象池对象过期秒数。</param>
|
||||
/// <param name="priority">对象池的优先级。</param>
|
||||
/// <returns>要创建的允许单次获取的对象池。</returns>
|
||||
ObjectPoolBase CreateSingleSpawnObjectPool(Type objectType, float expireTime, int priority);
|
||||
|
||||
/// <summary>
|
||||
/// 创建允许单次获取的对象池。
|
||||
/// </summary>
|
||||
/// <typeparam name="T">对象类型。</typeparam>
|
||||
/// <param name="name">对象池名称。</param>
|
||||
/// <param name="capacity">对象池的容量。</param>
|
||||
/// <param name="expireTime">对象池对象过期秒数。</param>
|
||||
/// <returns>要创建的允许单次获取的对象池。</returns>
|
||||
IObjectPool<T> CreateSingleSpawnObjectPool<T>(string name, int capacity, float expireTime) where T : ObjectBase;
|
||||
|
||||
/// <summary>
|
||||
/// 创建允许单次获取的对象池。
|
||||
/// </summary>
|
||||
/// <param name="objectType">对象类型。</param>
|
||||
/// <param name="name">对象池名称。</param>
|
||||
/// <param name="capacity">对象池的容量。</param>
|
||||
/// <param name="expireTime">对象池对象过期秒数。</param>
|
||||
/// <returns>要创建的允许单次获取的对象池。</returns>
|
||||
ObjectPoolBase CreateSingleSpawnObjectPool(Type objectType, string name, int capacity, float expireTime);
|
||||
|
||||
/// <summary>
|
||||
/// 创建允许单次获取的对象池。
|
||||
/// </summary>
|
||||
/// <typeparam name="T">对象类型。</typeparam>
|
||||
/// <param name="name">对象池名称。</param>
|
||||
/// <param name="capacity">对象池的容量。</param>
|
||||
/// <param name="priority">对象池的优先级。</param>
|
||||
/// <returns>要创建的允许单次获取的对象池。</returns>
|
||||
IObjectPool<T> CreateSingleSpawnObjectPool<T>(string name, int capacity, int priority) where T : ObjectBase;
|
||||
|
||||
/// <summary>
|
||||
/// 创建允许单次获取的对象池。
|
||||
/// </summary>
|
||||
/// <param name="objectType">对象类型。</param>
|
||||
/// <param name="name">对象池名称。</param>
|
||||
/// <param name="capacity">对象池的容量。</param>
|
||||
/// <param name="priority">对象池的优先级。</param>
|
||||
/// <returns>要创建的允许单次获取的对象池。</returns>
|
||||
ObjectPoolBase CreateSingleSpawnObjectPool(Type objectType, string name, int capacity, int priority);
|
||||
|
||||
/// <summary>
|
||||
/// 创建允许单次获取的对象池。
|
||||
/// </summary>
|
||||
/// <typeparam name="T">对象类型。</typeparam>
|
||||
/// <param name="name">对象池名称。</param>
|
||||
/// <param name="expireTime">对象池对象过期秒数。</param>
|
||||
/// <param name="priority">对象池的优先级。</param>
|
||||
/// <returns>要创建的允许单次获取的对象池。</returns>
|
||||
IObjectPool<T> CreateSingleSpawnObjectPool<T>(string name, float expireTime, int priority) where T : ObjectBase;
|
||||
|
||||
/// <summary>
|
||||
/// 创建允许单次获取的对象池。
|
||||
/// </summary>
|
||||
/// <param name="objectType">对象类型。</param>
|
||||
/// <param name="name">对象池名称。</param>
|
||||
/// <param name="expireTime">对象池对象过期秒数。</param>
|
||||
/// <param name="priority">对象池的优先级。</param>
|
||||
/// <returns>要创建的允许单次获取的对象池。</returns>
|
||||
ObjectPoolBase CreateSingleSpawnObjectPool(Type objectType, string name, float expireTime, int priority);
|
||||
|
||||
/// <summary>
|
||||
/// 创建允许单次获取的对象池。
|
||||
/// </summary>
|
||||
/// <typeparam name="T">对象类型。</typeparam>
|
||||
/// <param name="capacity">对象池的容量。</param>
|
||||
/// <param name="expireTime">对象池对象过期秒数。</param>
|
||||
/// <param name="priority">对象池的优先级。</param>
|
||||
/// <returns>要创建的允许单次获取的对象池。</returns>
|
||||
IObjectPool<T> CreateSingleSpawnObjectPool<T>(int capacity, float expireTime, int priority) where T : ObjectBase;
|
||||
|
||||
/// <summary>
|
||||
/// 创建允许单次获取的对象池。
|
||||
/// </summary>
|
||||
/// <param name="objectType">对象类型。</param>
|
||||
/// <param name="capacity">对象池的容量。</param>
|
||||
/// <param name="expireTime">对象池对象过期秒数。</param>
|
||||
/// <param name="priority">对象池的优先级。</param>
|
||||
/// <returns>要创建的允许单次获取的对象池。</returns>
|
||||
ObjectPoolBase CreateSingleSpawnObjectPool(Type objectType, int capacity, float expireTime, int priority);
|
||||
|
||||
/// <summary>
|
||||
/// 创建允许单次获取的对象池。
|
||||
/// </summary>
|
||||
/// <typeparam name="T">对象类型。</typeparam>
|
||||
/// <param name="name">对象池名称。</param>
|
||||
/// <param name="capacity">对象池的容量。</param>
|
||||
/// <param name="expireTime">对象池对象过期秒数。</param>
|
||||
/// <param name="priority">对象池的优先级。</param>
|
||||
/// <returns>要创建的允许单次获取的对象池。</returns>
|
||||
IObjectPool<T> CreateSingleSpawnObjectPool<T>(string name, int capacity, float expireTime, int priority) where T : ObjectBase;
|
||||
|
||||
/// <summary>
|
||||
/// 创建允许单次获取的对象池。
|
||||
/// </summary>
|
||||
/// <param name="objectType">对象类型。</param>
|
||||
/// <param name="name">对象池名称。</param>
|
||||
/// <param name="capacity">对象池的容量。</param>
|
||||
/// <param name="expireTime">对象池对象过期秒数。</param>
|
||||
/// <param name="priority">对象池的优先级。</param>
|
||||
/// <returns>要创建的允许单次获取的对象池。</returns>
|
||||
ObjectPoolBase CreateSingleSpawnObjectPool(Type objectType, string name, int capacity, float expireTime, int priority);
|
||||
|
||||
/// <summary>
|
||||
/// 创建允许单次获取的对象池。
|
||||
/// </summary>
|
||||
/// <typeparam name="T">对象类型。</typeparam>
|
||||
/// <param name="name">对象池名称。</param>
|
||||
/// <param name="autoReleaseInterval">对象池自动释放可释放对象的间隔秒数。</param>
|
||||
/// <param name="capacity">对象池的容量。</param>
|
||||
/// <param name="expireTime">对象池对象过期秒数。</param>
|
||||
/// <param name="priority">对象池的优先级。</param>
|
||||
/// <returns>要创建的允许单次获取的对象池。</returns>
|
||||
IObjectPool<T> CreateSingleSpawnObjectPool<T>(string name, float autoReleaseInterval, int capacity, float expireTime, int priority) where T : ObjectBase;
|
||||
|
||||
/// <summary>
|
||||
/// 创建允许单次获取的对象池。
|
||||
/// </summary>
|
||||
/// <param name="objectType">对象类型。</param>
|
||||
/// <param name="name">对象池名称。</param>
|
||||
/// <param name="autoReleaseInterval">对象池自动释放可释放对象的间隔秒数。</param>
|
||||
/// <param name="capacity">对象池的容量。</param>
|
||||
/// <param name="expireTime">对象池对象过期秒数。</param>
|
||||
/// <param name="priority">对象池的优先级。</param>
|
||||
/// <returns>要创建的允许单次获取的对象池。</returns>
|
||||
ObjectPoolBase CreateSingleSpawnObjectPool(Type objectType, string name, float autoReleaseInterval, int capacity, float expireTime, int priority);
|
||||
|
||||
/// <summary>
|
||||
/// 创建允许多次获取的对象池。
|
||||
/// </summary>
|
||||
/// <typeparam name="T">对象类型。</typeparam>
|
||||
/// <returns>要创建的允许多次获取的对象池。</returns>
|
||||
IObjectPool<T> CreateMultiSpawnObjectPool<T>() where T : ObjectBase;
|
||||
|
||||
/// <summary>
|
||||
/// 创建允许多次获取的对象池。
|
||||
/// </summary>
|
||||
/// <param name="objectType">对象类型。</param>
|
||||
/// <returns>要创建的允许多次获取的对象池。</returns>
|
||||
ObjectPoolBase CreateMultiSpawnObjectPool(Type objectType);
|
||||
|
||||
/// <summary>
|
||||
/// 创建允许多次获取的对象池。
|
||||
/// </summary>
|
||||
/// <typeparam name="T">对象类型。</typeparam>
|
||||
/// <param name="name">对象池名称。</param>
|
||||
/// <returns>要创建的允许多次获取的对象池。</returns>
|
||||
IObjectPool<T> CreateMultiSpawnObjectPool<T>(string name) where T : ObjectBase;
|
||||
|
||||
/// <summary>
|
||||
/// 创建允许多次获取的对象池。
|
||||
/// </summary>
|
||||
/// <param name="objectType">对象类型。</param>
|
||||
/// <param name="name">对象池名称。</param>
|
||||
/// <returns>要创建的允许多次获取的对象池。</returns>
|
||||
ObjectPoolBase CreateMultiSpawnObjectPool(Type objectType, string name);
|
||||
|
||||
/// <summary>
|
||||
/// 创建允许多次获取的对象池。
|
||||
/// </summary>
|
||||
/// <typeparam name="T">对象类型。</typeparam>
|
||||
/// <param name="capacity">对象池的容量。</param>
|
||||
/// <returns>要创建的允许多次获取的对象池。</returns>
|
||||
IObjectPool<T> CreateMultiSpawnObjectPool<T>(int capacity) where T : ObjectBase;
|
||||
|
||||
/// <summary>
|
||||
/// 创建允许多次获取的对象池。
|
||||
/// </summary>
|
||||
/// <param name="objectType">对象类型。</param>
|
||||
/// <param name="capacity">对象池的容量。</param>
|
||||
/// <returns>要创建的允许多次获取的对象池。</returns>
|
||||
ObjectPoolBase CreateMultiSpawnObjectPool(Type objectType, int capacity);
|
||||
|
||||
/// <summary>
|
||||
/// 创建允许多次获取的对象池。
|
||||
/// </summary>
|
||||
/// <typeparam name="T">对象类型。</typeparam>
|
||||
/// <param name="expireTime">对象池对象过期秒数。</param>
|
||||
/// <returns>要创建的允许多次获取的对象池。</returns>
|
||||
IObjectPool<T> CreateMultiSpawnObjectPool<T>(float expireTime) where T : ObjectBase;
|
||||
|
||||
/// <summary>
|
||||
/// 创建允许多次获取的对象池。
|
||||
/// </summary>
|
||||
/// <param name="objectType">对象类型。</param>
|
||||
/// <param name="expireTime">对象池对象过期秒数。</param>
|
||||
/// <returns>要创建的允许多次获取的对象池。</returns>
|
||||
ObjectPoolBase CreateMultiSpawnObjectPool(Type objectType, float expireTime);
|
||||
|
||||
/// <summary>
|
||||
/// 创建允许多次获取的对象池。
|
||||
/// </summary>
|
||||
/// <typeparam name="T">对象类型。</typeparam>
|
||||
/// <param name="name">对象池名称。</param>
|
||||
/// <param name="capacity">对象池的容量。</param>
|
||||
/// <returns>要创建的允许多次获取的对象池。</returns>
|
||||
IObjectPool<T> CreateMultiSpawnObjectPool<T>(string name, int capacity) where T : ObjectBase;
|
||||
|
||||
/// <summary>
|
||||
/// 创建允许多次获取的对象池。
|
||||
/// </summary>
|
||||
/// <param name="objectType">对象类型。</param>
|
||||
/// <param name="name">对象池名称。</param>
|
||||
/// <param name="capacity">对象池的容量。</param>
|
||||
/// <returns>要创建的允许多次获取的对象池。</returns>
|
||||
ObjectPoolBase CreateMultiSpawnObjectPool(Type objectType, string name, int capacity);
|
||||
|
||||
/// <summary>
|
||||
/// 创建允许多次获取的对象池。
|
||||
/// </summary>
|
||||
/// <typeparam name="T">对象类型。</typeparam>
|
||||
/// <param name="name">对象池名称。</param>
|
||||
/// <param name="expireTime">对象池对象过期秒数。</param>
|
||||
/// <returns>要创建的允许多次获取的对象池。</returns>
|
||||
IObjectPool<T> CreateMultiSpawnObjectPool<T>(string name, float expireTime) where T : ObjectBase;
|
||||
|
||||
/// <summary>
|
||||
/// 创建允许多次获取的对象池。
|
||||
/// </summary>
|
||||
/// <param name="objectType">对象类型。</param>
|
||||
/// <param name="name">对象池名称。</param>
|
||||
/// <param name="expireTime">对象池对象过期秒数。</param>
|
||||
/// <returns>要创建的允许多次获取的对象池。</returns>
|
||||
ObjectPoolBase CreateMultiSpawnObjectPool(Type objectType, string name, float expireTime);
|
||||
|
||||
/// <summary>
|
||||
/// 创建允许多次获取的对象池。
|
||||
/// </summary>
|
||||
/// <typeparam name="T">对象类型。</typeparam>
|
||||
/// <param name="capacity">对象池的容量。</param>
|
||||
/// <param name="expireTime">对象池对象过期秒数。</param>
|
||||
/// <returns>要创建的允许多次获取的对象池。</returns>
|
||||
IObjectPool<T> CreateMultiSpawnObjectPool<T>(int capacity, float expireTime) where T : ObjectBase;
|
||||
|
||||
/// <summary>
|
||||
/// 创建允许多次获取的对象池。
|
||||
/// </summary>
|
||||
/// <param name="objectType">对象类型。</param>
|
||||
/// <param name="capacity">对象池的容量。</param>
|
||||
/// <param name="expireTime">对象池对象过期秒数。</param>
|
||||
/// <returns>要创建的允许多次获取的对象池。</returns>
|
||||
ObjectPoolBase CreateMultiSpawnObjectPool(Type objectType, int capacity, float expireTime);
|
||||
|
||||
/// <summary>
|
||||
/// 创建允许多次获取的对象池。
|
||||
/// </summary>
|
||||
/// <typeparam name="T">对象类型。</typeparam>
|
||||
/// <param name="capacity">对象池的容量。</param>
|
||||
/// <param name="priority">对象池的优先级。</param>
|
||||
/// <returns>要创建的允许多次获取的对象池。</returns>
|
||||
IObjectPool<T> CreateMultiSpawnObjectPool<T>(int capacity, int priority) where T : ObjectBase;
|
||||
|
||||
/// <summary>
|
||||
/// 创建允许多次获取的对象池。
|
||||
/// </summary>
|
||||
/// <param name="objectType">对象类型。</param>
|
||||
/// <param name="capacity">对象池的容量。</param>
|
||||
/// <param name="priority">对象池的优先级。</param>
|
||||
/// <returns>要创建的允许多次获取的对象池。</returns>
|
||||
ObjectPoolBase CreateMultiSpawnObjectPool(Type objectType, int capacity, int priority);
|
||||
|
||||
/// <summary>
|
||||
/// 创建允许多次获取的对象池。
|
||||
/// </summary>
|
||||
/// <typeparam name="T">对象类型。</typeparam>
|
||||
/// <param name="expireTime">对象池对象过期秒数。</param>
|
||||
/// <param name="priority">对象池的优先级。</param>
|
||||
/// <returns>要创建的允许多次获取的对象池。</returns>
|
||||
IObjectPool<T> CreateMultiSpawnObjectPool<T>(float expireTime, int priority) where T : ObjectBase;
|
||||
|
||||
/// <summary>
|
||||
/// 创建允许多次获取的对象池。
|
||||
/// </summary>
|
||||
/// <param name="objectType">对象类型。</param>
|
||||
/// <param name="expireTime">对象池对象过期秒数。</param>
|
||||
/// <param name="priority">对象池的优先级。</param>
|
||||
/// <returns>要创建的允许多次获取的对象池。</returns>
|
||||
ObjectPoolBase CreateMultiSpawnObjectPool(Type objectType, float expireTime, int priority);
|
||||
|
||||
/// <summary>
|
||||
/// 创建允许多次获取的对象池。
|
||||
/// </summary>
|
||||
/// <typeparam name="T">对象类型。</typeparam>
|
||||
/// <param name="name">对象池名称。</param>
|
||||
/// <param name="capacity">对象池的容量。</param>
|
||||
/// <param name="expireTime">对象池对象过期秒数。</param>
|
||||
/// <returns>要创建的允许多次获取的对象池。</returns>
|
||||
IObjectPool<T> CreateMultiSpawnObjectPool<T>(string name, int capacity, float expireTime) where T : ObjectBase;
|
||||
|
||||
/// <summary>
|
||||
/// 创建允许多次获取的对象池。
|
||||
/// </summary>
|
||||
/// <param name="objectType">对象类型。</param>
|
||||
/// <param name="name">对象池名称。</param>
|
||||
/// <param name="capacity">对象池的容量。</param>
|
||||
/// <param name="expireTime">对象池对象过期秒数。</param>
|
||||
/// <returns>要创建的允许多次获取的对象池。</returns>
|
||||
ObjectPoolBase CreateMultiSpawnObjectPool(Type objectType, string name, int capacity, float expireTime);
|
||||
|
||||
/// <summary>
|
||||
/// 创建允许多次获取的对象池。
|
||||
/// </summary>
|
||||
/// <typeparam name="T">对象类型。</typeparam>
|
||||
/// <param name="name">对象池名称。</param>
|
||||
/// <param name="capacity">对象池的容量。</param>
|
||||
/// <param name="priority">对象池的优先级。</param>
|
||||
/// <returns>要创建的允许多次获取的对象池。</returns>
|
||||
IObjectPool<T> CreateMultiSpawnObjectPool<T>(string name, int capacity, int priority) where T : ObjectBase;
|
||||
|
||||
/// <summary>
|
||||
/// 创建允许多次获取的对象池。
|
||||
/// </summary>
|
||||
/// <param name="objectType">对象类型。</param>
|
||||
/// <param name="name">对象池名称。</param>
|
||||
/// <param name="capacity">对象池的容量。</param>
|
||||
/// <param name="priority">对象池的优先级。</param>
|
||||
/// <returns>要创建的允许多次获取的对象池。</returns>
|
||||
ObjectPoolBase CreateMultiSpawnObjectPool(Type objectType, string name, int capacity, int priority);
|
||||
|
||||
/// <summary>
|
||||
/// 创建允许多次获取的对象池。
|
||||
/// </summary>
|
||||
/// <typeparam name="T">对象类型。</typeparam>
|
||||
/// <param name="name">对象池名称。</param>
|
||||
/// <param name="expireTime">对象池对象过期秒数。</param>
|
||||
/// <param name="priority">对象池的优先级。</param>
|
||||
/// <returns>要创建的允许多次获取的对象池。</returns>
|
||||
IObjectPool<T> CreateMultiSpawnObjectPool<T>(string name, float expireTime, int priority) where T : ObjectBase;
|
||||
|
||||
/// <summary>
|
||||
/// 创建允许多次获取的对象池。
|
||||
/// </summary>
|
||||
/// <param name="objectType">对象类型。</param>
|
||||
/// <param name="name">对象池名称。</param>
|
||||
/// <param name="expireTime">对象池对象过期秒数。</param>
|
||||
/// <param name="priority">对象池的优先级。</param>
|
||||
/// <returns>要创建的允许多次获取的对象池。</returns>
|
||||
ObjectPoolBase CreateMultiSpawnObjectPool(Type objectType, string name, float expireTime, int priority);
|
||||
|
||||
/// <summary>
|
||||
/// 创建允许多次获取的对象池。
|
||||
/// </summary>
|
||||
/// <typeparam name="T">对象类型。</typeparam>
|
||||
/// <param name="capacity">对象池的容量。</param>
|
||||
/// <param name="expireTime">对象池对象过期秒数。</param>
|
||||
/// <param name="priority">对象池的优先级。</param>
|
||||
/// <returns>要创建的允许多次获取的对象池。</returns>
|
||||
IObjectPool<T> CreateMultiSpawnObjectPool<T>(int capacity, float expireTime, int priority) where T : ObjectBase;
|
||||
|
||||
/// <summary>
|
||||
/// 创建允许多次获取的对象池。
|
||||
/// </summary>
|
||||
/// <param name="objectType">对象类型。</param>
|
||||
/// <param name="capacity">对象池的容量。</param>
|
||||
/// <param name="expireTime">对象池对象过期秒数。</param>
|
||||
/// <param name="priority">对象池的优先级。</param>
|
||||
/// <returns>要创建的允许多次获取的对象池。</returns>
|
||||
ObjectPoolBase CreateMultiSpawnObjectPool(Type objectType, int capacity, float expireTime, int priority);
|
||||
|
||||
/// <summary>
|
||||
/// 创建允许多次获取的对象池。
|
||||
/// </summary>
|
||||
/// <typeparam name="T">对象类型。</typeparam>
|
||||
/// <param name="name">对象池名称。</param>
|
||||
/// <param name="capacity">对象池的容量。</param>
|
||||
/// <param name="expireTime">对象池对象过期秒数。</param>
|
||||
/// <param name="priority">对象池的优先级。</param>
|
||||
/// <returns>要创建的允许多次获取的对象池。</returns>
|
||||
IObjectPool<T> CreateMultiSpawnObjectPool<T>(string name, int capacity, float expireTime, int priority) where T : ObjectBase;
|
||||
|
||||
/// <summary>
|
||||
/// 创建允许多次获取的对象池。
|
||||
/// </summary>
|
||||
/// <param name="objectType">对象类型。</param>
|
||||
/// <param name="name">对象池名称。</param>
|
||||
/// <param name="capacity">对象池的容量。</param>
|
||||
/// <param name="expireTime">对象池对象过期秒数。</param>
|
||||
/// <param name="priority">对象池的优先级。</param>
|
||||
/// <returns>要创建的允许多次获取的对象池。</returns>
|
||||
ObjectPoolBase CreateMultiSpawnObjectPool(Type objectType, string name, int capacity, float expireTime, int priority);
|
||||
|
||||
/// <summary>
|
||||
/// 创建允许多次获取的对象池。
|
||||
/// </summary>
|
||||
/// <typeparam name="T">对象类型。</typeparam>
|
||||
/// <param name="name">对象池名称。</param>
|
||||
/// <param name="autoReleaseInterval">对象池自动释放可释放对象的间隔秒数。</param>
|
||||
/// <param name="capacity">对象池的容量。</param>
|
||||
/// <param name="expireTime">对象池对象过期秒数。</param>
|
||||
/// <param name="priority">对象池的优先级。</param>
|
||||
/// <returns>要创建的允许多次获取的对象池。</returns>
|
||||
IObjectPool<T> CreateMultiSpawnObjectPool<T>(string name, float autoReleaseInterval, int capacity, float expireTime, int priority) where T : ObjectBase;
|
||||
|
||||
/// <summary>
|
||||
/// 创建允许多次获取的对象池。
|
||||
/// </summary>
|
||||
/// <param name="objectType">对象类型。</param>
|
||||
/// <param name="name">对象池名称。</param>
|
||||
/// <param name="autoReleaseInterval">对象池自动释放可释放对象的间隔秒数。</param>
|
||||
/// <param name="capacity">对象池的容量。</param>
|
||||
/// <param name="expireTime">对象池对象过期秒数。</param>
|
||||
/// <param name="priority">对象池的优先级。</param>
|
||||
/// <returns>要创建的允许多次获取的对象池。</returns>
|
||||
ObjectPoolBase CreateMultiSpawnObjectPool(Type objectType, string name, float autoReleaseInterval, int capacity, float expireTime, int priority);
|
||||
|
||||
/// <summary>
|
||||
/// 销毁对象池。
|
||||
/// </summary>
|
||||
/// <typeparam name="T">对象类型。</typeparam>
|
||||
/// <returns>是否销毁对象池成功。</returns>
|
||||
bool DestroyObjectPool<T>() where T : ObjectBase;
|
||||
|
||||
/// <summary>
|
||||
/// 销毁对象池。
|
||||
/// </summary>
|
||||
/// <param name="objectType">对象类型。</param>
|
||||
/// <returns>是否销毁对象池成功。</returns>
|
||||
bool DestroyObjectPool(Type objectType);
|
||||
|
||||
/// <summary>
|
||||
/// 销毁对象池。
|
||||
/// </summary>
|
||||
/// <typeparam name="T">对象类型。</typeparam>
|
||||
/// <param name="name">要销毁的对象池名称。</param>
|
||||
/// <returns>是否销毁对象池成功。</returns>
|
||||
bool DestroyObjectPool<T>(string name) where T : ObjectBase;
|
||||
|
||||
/// <summary>
|
||||
/// 销毁对象池。
|
||||
/// </summary>
|
||||
/// <param name="objectType">对象类型。</param>
|
||||
/// <param name="name">要销毁的对象池名称。</param>
|
||||
/// <returns>是否销毁对象池成功。</returns>
|
||||
bool DestroyObjectPool(Type objectType, string name);
|
||||
|
||||
/// <summary>
|
||||
/// 销毁对象池。
|
||||
/// </summary>
|
||||
/// <typeparam name="T">对象类型。</typeparam>
|
||||
/// <param name="objectPool">要销毁的对象池。</param>
|
||||
/// <returns>是否销毁对象池成功。</returns>
|
||||
bool DestroyObjectPool<T>(IObjectPool<T> objectPool) where T : ObjectBase;
|
||||
|
||||
/// <summary>
|
||||
/// 销毁对象池。
|
||||
/// </summary>
|
||||
/// <param name="objectPool">要销毁的对象池。</param>
|
||||
/// <returns>是否销毁对象池成功。</returns>
|
||||
bool DestroyObjectPool(ObjectPoolBase objectPool);
|
||||
|
||||
/// <summary>
|
||||
/// 释放对象池中的可释放对象。
|
||||
/// </summary>
|
||||
void Release();
|
||||
|
||||
/// <summary>
|
||||
/// 释放对象池中的所有未使用对象。
|
||||
/// </summary>
|
||||
void ReleaseAllUnused();
|
||||
}
|
||||
}
|
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4e06b511ecf14c3e8a183ed7492f70dc
|
||||
timeCreated: 1708673686
|
@@ -0,0 +1,207 @@
|
||||
//------------------------------------------------------------
|
||||
// Game Framework
|
||||
// Copyright © 2013-2021 Jiang Yin. All rights reserved.
|
||||
// Homepage: https://gameframework.cn/
|
||||
// Feedback: mailto:ellan@gameframework.cn
|
||||
//------------------------------------------------------------
|
||||
|
||||
using System;
|
||||
|
||||
namespace SHFrame
|
||||
{
|
||||
/// <summary>
|
||||
/// 对象基类。
|
||||
/// </summary>
|
||||
public abstract class ObjectBase : IReference
|
||||
{
|
||||
private string m_Name;
|
||||
private object m_Target;
|
||||
private bool m_Locked;
|
||||
private int m_Priority;
|
||||
private DateTime m_LastUseTime;
|
||||
|
||||
/// <summary>
|
||||
/// 初始化对象基类的新实例。
|
||||
/// </summary>
|
||||
public ObjectBase()
|
||||
{
|
||||
m_Name = null;
|
||||
m_Target = null;
|
||||
m_Locked = false;
|
||||
m_Priority = 0;
|
||||
m_LastUseTime = default(DateTime);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取对象名称。
|
||||
/// </summary>
|
||||
public string Name
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_Name;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取对象。
|
||||
/// </summary>
|
||||
public object Target
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_Target;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取或设置对象是否被加锁。
|
||||
/// </summary>
|
||||
public bool Locked
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_Locked;
|
||||
}
|
||||
set
|
||||
{
|
||||
m_Locked = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取或设置对象的优先级。
|
||||
/// </summary>
|
||||
public int Priority
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_Priority;
|
||||
}
|
||||
set
|
||||
{
|
||||
m_Priority = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取自定义释放检查标记。
|
||||
/// </summary>
|
||||
public virtual bool CustomCanReleaseFlag
|
||||
{
|
||||
get
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取对象上次使用时间。
|
||||
/// </summary>
|
||||
public DateTime LastUseTime
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_LastUseTime;
|
||||
}
|
||||
internal set
|
||||
{
|
||||
m_LastUseTime = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 初始化对象基类。
|
||||
/// </summary>
|
||||
/// <param name="target">对象。</param>
|
||||
protected void Initialize(object target)
|
||||
{
|
||||
Initialize(null, target, false, 0);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 初始化对象基类。
|
||||
/// </summary>
|
||||
/// <param name="name">对象名称。</param>
|
||||
/// <param name="target">对象。</param>
|
||||
protected void Initialize(string name, object target)
|
||||
{
|
||||
Initialize(name, target, false, 0);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 初始化对象基类。
|
||||
/// </summary>
|
||||
/// <param name="name">对象名称。</param>
|
||||
/// <param name="target">对象。</param>
|
||||
/// <param name="locked">对象是否被加锁。</param>
|
||||
protected void Initialize(string name, object target, bool locked)
|
||||
{
|
||||
Initialize(name, target, locked, 0);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 初始化对象基类。
|
||||
/// </summary>
|
||||
/// <param name="name">对象名称。</param>
|
||||
/// <param name="target">对象。</param>
|
||||
/// <param name="priority">对象的优先级。</param>
|
||||
protected void Initialize(string name, object target, int priority)
|
||||
{
|
||||
Initialize(name, target, false, priority);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 初始化对象基类。
|
||||
/// </summary>
|
||||
/// <param name="name">对象名称。</param>
|
||||
/// <param name="target">对象。</param>
|
||||
/// <param name="locked">对象是否被加锁。</param>
|
||||
/// <param name="priority">对象的优先级。</param>
|
||||
protected void Initialize(string name, object target, bool locked, int priority)
|
||||
{
|
||||
if (target == null)
|
||||
{
|
||||
throw new GameFrameworkException(Utility.Text.Format("Target '{0}' is invalid.", name));
|
||||
}
|
||||
|
||||
m_Name = name ?? string.Empty;
|
||||
m_Target = target;
|
||||
m_Locked = locked;
|
||||
m_Priority = priority;
|
||||
m_LastUseTime = DateTime.UtcNow;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 清理对象基类。
|
||||
/// </summary>
|
||||
public virtual void Clear()
|
||||
{
|
||||
m_Name = null;
|
||||
m_Target = null;
|
||||
m_Locked = false;
|
||||
m_Priority = 0;
|
||||
m_LastUseTime = default(DateTime);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取对象时的事件。
|
||||
/// </summary>
|
||||
protected internal virtual void OnSpawn()
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 回收对象时的事件。
|
||||
/// </summary>
|
||||
protected internal virtual void OnUnspawn()
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 释放对象。
|
||||
/// </summary>
|
||||
/// <param name="isShutdown">是否是关闭对象池时触发。</param>
|
||||
protected internal abstract void Release(bool isShutdown);
|
||||
}
|
||||
}
|
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1aa534825636481e87032c12e5faa895
|
||||
timeCreated: 1708673686
|
@@ -0,0 +1,122 @@
|
||||
//------------------------------------------------------------
|
||||
// Game Framework
|
||||
// Copyright © 2013-2021 Jiang Yin. All rights reserved.
|
||||
// Homepage: https://gameframework.cn/
|
||||
// Feedback: mailto:ellan@gameframework.cn
|
||||
//------------------------------------------------------------
|
||||
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace SHFrame
|
||||
{
|
||||
/// <summary>
|
||||
/// 对象信息。
|
||||
/// </summary>
|
||||
[StructLayout(LayoutKind.Auto)]
|
||||
public struct ObjectInfo
|
||||
{
|
||||
private readonly string m_Name;
|
||||
private readonly bool m_Locked;
|
||||
private readonly bool m_CustomCanReleaseFlag;
|
||||
private readonly int m_Priority;
|
||||
private readonly DateTime m_LastUseTime;
|
||||
private readonly int m_SpawnCount;
|
||||
|
||||
/// <summary>
|
||||
/// 初始化对象信息的新实例。
|
||||
/// </summary>
|
||||
/// <param name="name">对象名称。</param>
|
||||
/// <param name="locked">对象是否被加锁。</param>
|
||||
/// <param name="customCanReleaseFlag">对象自定义释放检查标记。</param>
|
||||
/// <param name="priority">对象的优先级。</param>
|
||||
/// <param name="lastUseTime">对象上次使用时间。</param>
|
||||
/// <param name="spawnCount">对象的获取计数。</param>
|
||||
public ObjectInfo(string name, bool locked, bool customCanReleaseFlag, int priority, DateTime lastUseTime, int spawnCount)
|
||||
{
|
||||
m_Name = name;
|
||||
m_Locked = locked;
|
||||
m_CustomCanReleaseFlag = customCanReleaseFlag;
|
||||
m_Priority = priority;
|
||||
m_LastUseTime = lastUseTime;
|
||||
m_SpawnCount = spawnCount;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取对象名称。
|
||||
/// </summary>
|
||||
public string Name
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_Name;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取对象是否被加锁。
|
||||
/// </summary>
|
||||
public bool Locked
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_Locked;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取对象自定义释放检查标记。
|
||||
/// </summary>
|
||||
public bool CustomCanReleaseFlag
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_CustomCanReleaseFlag;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取对象的优先级。
|
||||
/// </summary>
|
||||
public int Priority
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_Priority;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取对象上次使用时间。
|
||||
/// </summary>
|
||||
public DateTime LastUseTime
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_LastUseTime;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取对象是否正在使用。
|
||||
/// </summary>
|
||||
public bool IsInUse
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_SpawnCount > 0;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取对象的获取计数。
|
||||
/// </summary>
|
||||
public int SpawnCount
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_SpawnCount;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 383ecd9134c14f8b89494e4e49b9c42c
|
||||
timeCreated: 1708673686
|
@@ -0,0 +1,152 @@
|
||||
//------------------------------------------------------------
|
||||
// Game Framework
|
||||
// Copyright © 2013-2021 Jiang Yin. All rights reserved.
|
||||
// Homepage: https://gameframework.cn/
|
||||
// Feedback: mailto:ellan@gameframework.cn
|
||||
//------------------------------------------------------------
|
||||
|
||||
using System;
|
||||
|
||||
namespace SHFrame
|
||||
{
|
||||
/// <summary>
|
||||
/// 对象池基类。
|
||||
/// </summary>
|
||||
public abstract class ObjectPoolBase
|
||||
{
|
||||
private readonly string m_Name;
|
||||
|
||||
/// <summary>
|
||||
/// 初始化对象池基类的新实例。
|
||||
/// </summary>
|
||||
public ObjectPoolBase()
|
||||
: this(null)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 初始化对象池基类的新实例。
|
||||
/// </summary>
|
||||
/// <param name="name">对象池名称。</param>
|
||||
public ObjectPoolBase(string name)
|
||||
{
|
||||
m_Name = name ?? string.Empty;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取对象池名称。
|
||||
/// </summary>
|
||||
public string Name
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_Name;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取对象池完整名称。
|
||||
/// </summary>
|
||||
public string FullName
|
||||
{
|
||||
get
|
||||
{
|
||||
return new TypeNamePair(ObjectType, m_Name).ToString();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取对象池对象类型。
|
||||
/// </summary>
|
||||
public abstract Type ObjectType
|
||||
{
|
||||
get;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取对象池中对象的数量。
|
||||
/// </summary>
|
||||
public abstract int Count
|
||||
{
|
||||
get;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取对象池中能被释放的对象的数量。
|
||||
/// </summary>
|
||||
public abstract int CanReleaseCount
|
||||
{
|
||||
get;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取是否允许对象被多次获取。
|
||||
/// </summary>
|
||||
public abstract bool AllowMultiSpawn
|
||||
{
|
||||
get;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取或设置对象池自动释放可释放对象的间隔秒数。
|
||||
/// </summary>
|
||||
public abstract float AutoReleaseInterval
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取或设置对象池的容量。
|
||||
/// </summary>
|
||||
public abstract int Capacity
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取或设置对象池对象过期秒数。
|
||||
/// </summary>
|
||||
public abstract float ExpireTime
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取或设置对象池的优先级。
|
||||
/// </summary>
|
||||
public abstract int Priority
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 释放对象池中的可释放对象。
|
||||
/// </summary>
|
||||
public abstract void Release();
|
||||
|
||||
/// <summary>
|
||||
/// 释放对象池中的可释放对象。
|
||||
/// </summary>
|
||||
/// <param name="toReleaseCount">尝试释放对象数量。</param>
|
||||
public abstract void Release(int toReleaseCount);
|
||||
|
||||
/// <summary>
|
||||
/// 释放对象池中的所有未使用对象。
|
||||
/// </summary>
|
||||
public abstract void ReleaseAllUnused();
|
||||
|
||||
/// <summary>
|
||||
/// 获取所有对象信息。
|
||||
/// </summary>
|
||||
/// <returns>所有对象信息。</returns>
|
||||
public abstract ObjectInfo[] GetAllObjectInfos();
|
||||
|
||||
internal abstract void Update(float elapseSeconds, float realElapseSeconds);
|
||||
|
||||
internal abstract void Shutdown();
|
||||
}
|
||||
}
|
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7feeaa70df6e49e8ac5f289d63942c70
|
||||
timeCreated: 1708673686
|
@@ -0,0 +1,200 @@
|
||||
//------------------------------------------------------------
|
||||
// Game Framework
|
||||
// Copyright © 2013-2021 Jiang Yin. All rights reserved.
|
||||
// Homepage: https://gameframework.cn/
|
||||
// Feedback: mailto:ellan@gameframework.cn
|
||||
//------------------------------------------------------------
|
||||
|
||||
using System;
|
||||
|
||||
namespace SHFrame
|
||||
{
|
||||
internal sealed partial class ObjectPoolManager : ModuleImp, IObjectPoolManager
|
||||
{
|
||||
/// <summary>
|
||||
/// 内部对象。
|
||||
/// </summary>
|
||||
/// <typeparam name="T">对象类型。</typeparam>
|
||||
private sealed class Object<T> : IReference where T : ObjectBase
|
||||
{
|
||||
private T m_Object;
|
||||
private int m_SpawnCount;
|
||||
|
||||
/// <summary>
|
||||
/// 初始化内部对象的新实例。
|
||||
/// </summary>
|
||||
public Object()
|
||||
{
|
||||
m_Object = null;
|
||||
m_SpawnCount = 0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取对象名称。
|
||||
/// </summary>
|
||||
public string Name
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_Object.Name;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取对象是否被加锁。
|
||||
/// </summary>
|
||||
public bool Locked
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_Object.Locked;
|
||||
}
|
||||
internal set
|
||||
{
|
||||
m_Object.Locked = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取对象的优先级。
|
||||
/// </summary>
|
||||
public int Priority
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_Object.Priority;
|
||||
}
|
||||
internal set
|
||||
{
|
||||
m_Object.Priority = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取自定义释放检查标记。
|
||||
/// </summary>
|
||||
public bool CustomCanReleaseFlag
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_Object.CustomCanReleaseFlag;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取对象上次使用时间。
|
||||
/// </summary>
|
||||
public DateTime LastUseTime
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_Object.LastUseTime;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取对象是否正在使用。
|
||||
/// </summary>
|
||||
public bool IsInUse
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_SpawnCount > 0;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取对象的获取计数。
|
||||
/// </summary>
|
||||
public int SpawnCount
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_SpawnCount;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 创建内部对象。
|
||||
/// </summary>
|
||||
/// <param name="obj">对象。</param>
|
||||
/// <param name="spawned">对象是否已被获取。</param>
|
||||
/// <returns>创建的内部对象。</returns>
|
||||
public static Object<T> Create(T obj, bool spawned)
|
||||
{
|
||||
if (obj == null)
|
||||
{
|
||||
throw new GameFrameworkException("Object is invalid.");
|
||||
}
|
||||
|
||||
Object<T> internalObject = ReferencePool.Acquire<Object<T>>();
|
||||
internalObject.m_Object = obj;
|
||||
internalObject.m_SpawnCount = spawned ? 1 : 0;
|
||||
if (spawned)
|
||||
{
|
||||
obj.OnSpawn();
|
||||
}
|
||||
|
||||
return internalObject;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 清理内部对象。
|
||||
/// </summary>
|
||||
public void Clear()
|
||||
{
|
||||
m_Object = null;
|
||||
m_SpawnCount = 0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查看对象。
|
||||
/// </summary>
|
||||
/// <returns>对象。</returns>
|
||||
public T Peek()
|
||||
{
|
||||
return m_Object;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取对象。
|
||||
/// </summary>
|
||||
/// <returns>对象。</returns>
|
||||
public T Spawn()
|
||||
{
|
||||
m_SpawnCount++;
|
||||
m_Object.LastUseTime = DateTime.UtcNow;
|
||||
m_Object.OnSpawn();
|
||||
return m_Object;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 回收对象。
|
||||
/// </summary>
|
||||
public void Unspawn()
|
||||
{
|
||||
if(m_SpawnCount == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
m_Object.OnUnspawn();
|
||||
m_Object.LastUseTime = DateTime.UtcNow;
|
||||
m_SpawnCount--;
|
||||
if (m_SpawnCount < 0)
|
||||
{
|
||||
throw new GameFrameworkException(Utility.Text.Format("Object '{0}' spawn count is less than 0.", Name));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 释放对象。
|
||||
/// </summary>
|
||||
/// <param name="isShutdown">是否是关闭对象池时触发。</param>
|
||||
public void Release(bool isShutdown)
|
||||
{
|
||||
m_Object.Release(isShutdown);
|
||||
ReferencePool.Release(m_Object);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ad6098a006474f6f8ad774fff96556ce
|
||||
timeCreated: 1708673686
|
@@ -0,0 +1,637 @@
|
||||
//------------------------------------------------------------
|
||||
// Game Framework
|
||||
// Copyright © 2013-2021 Jiang Yin. All rights reserved.
|
||||
// Homepage: https://gameframework.cn/
|
||||
// Feedback: mailto:ellan@gameframework.cn
|
||||
//------------------------------------------------------------
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace SHFrame
|
||||
{
|
||||
internal sealed partial class ObjectPoolManager : ModuleImp, IObjectPoolManager
|
||||
{
|
||||
/// <summary>
|
||||
/// 对象池。
|
||||
/// </summary>
|
||||
/// <typeparam name="T">对象类型。</typeparam>
|
||||
private sealed class ObjectPool<T> : ObjectPoolBase, IObjectPool<T> where T : ObjectBase
|
||||
{
|
||||
private readonly GameFrameworkMultiDictionary<string, Object<T>> m_Objects;
|
||||
private readonly Dictionary<object, Object<T>> m_ObjectMap;
|
||||
private readonly ReleaseObjectFilterCallback<T> m_DefaultReleaseObjectFilterCallback;
|
||||
private readonly List<T> m_CachedCanReleaseObjects;
|
||||
private readonly List<T> m_CachedToReleaseObjects;
|
||||
private readonly bool m_AllowMultiSpawn;
|
||||
private float m_AutoReleaseInterval;
|
||||
private int m_Capacity;
|
||||
private float m_ExpireTime;
|
||||
private int m_Priority;
|
||||
private float m_AutoReleaseTime;
|
||||
|
||||
/// <summary>
|
||||
/// 初始化对象池的新实例。
|
||||
/// </summary>
|
||||
/// <param name="name">对象池名称。</param>
|
||||
/// <param name="allowMultiSpawn">是否允许对象被多次获取。</param>
|
||||
/// <param name="autoReleaseInterval">对象池自动释放可释放对象的间隔秒数。</param>
|
||||
/// <param name="capacity">对象池的容量。</param>
|
||||
/// <param name="expireTime">对象池对象过期秒数。</param>
|
||||
/// <param name="priority">对象池的优先级。</param>
|
||||
public ObjectPool(string name, bool allowMultiSpawn, float autoReleaseInterval, int capacity, float expireTime, int priority)
|
||||
: base(name)
|
||||
{
|
||||
m_Objects = new GameFrameworkMultiDictionary<string, Object<T>>();
|
||||
m_ObjectMap = new Dictionary<object, Object<T>>();
|
||||
m_DefaultReleaseObjectFilterCallback = DefaultReleaseObjectFilterCallback;
|
||||
m_CachedCanReleaseObjects = new List<T>();
|
||||
m_CachedToReleaseObjects = new List<T>();
|
||||
m_AllowMultiSpawn = allowMultiSpawn;
|
||||
m_AutoReleaseInterval = autoReleaseInterval;
|
||||
Capacity = capacity;
|
||||
ExpireTime = expireTime;
|
||||
m_Priority = priority;
|
||||
m_AutoReleaseTime = 0f;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取对象池对象类型。
|
||||
/// </summary>
|
||||
public override Type ObjectType
|
||||
{
|
||||
get
|
||||
{
|
||||
return typeof(T);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取对象池中对象的数量。
|
||||
/// </summary>
|
||||
public override int Count
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_ObjectMap.Count;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取对象池中能被释放的对象的数量。
|
||||
/// </summary>
|
||||
public override int CanReleaseCount
|
||||
{
|
||||
get
|
||||
{
|
||||
GetCanReleaseObjects(m_CachedCanReleaseObjects);
|
||||
return m_CachedCanReleaseObjects.Count;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取是否允许对象被多次获取。
|
||||
/// </summary>
|
||||
public override bool AllowMultiSpawn
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_AllowMultiSpawn;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取或设置对象池自动释放可释放对象的间隔秒数。
|
||||
/// </summary>
|
||||
public override float AutoReleaseInterval
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_AutoReleaseInterval;
|
||||
}
|
||||
set
|
||||
{
|
||||
m_AutoReleaseInterval = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取或设置对象池的容量。
|
||||
/// </summary>
|
||||
public override int Capacity
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_Capacity;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (value < 0)
|
||||
{
|
||||
throw new GameFrameworkException("Capacity is invalid.");
|
||||
}
|
||||
|
||||
if (m_Capacity == value)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
m_Capacity = value;
|
||||
Release();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取或设置对象池对象过期秒数。
|
||||
/// </summary>
|
||||
public override float ExpireTime
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_ExpireTime;
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
if (value < 0f)
|
||||
{
|
||||
throw new GameFrameworkException("ExpireTime is invalid.");
|
||||
}
|
||||
|
||||
if (ExpireTime == value)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
m_ExpireTime = value;
|
||||
Release();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取或设置对象池的优先级。
|
||||
/// </summary>
|
||||
public override int Priority
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_Priority;
|
||||
}
|
||||
set
|
||||
{
|
||||
m_Priority = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 创建对象。
|
||||
/// </summary>
|
||||
/// <param name="obj">对象。</param>
|
||||
/// <param name="spawned">对象是否已被获取。</param>
|
||||
public void Register(T obj, bool spawned)
|
||||
{
|
||||
if (obj == null)
|
||||
{
|
||||
throw new GameFrameworkException("Object is invalid.");
|
||||
}
|
||||
|
||||
Object<T> internalObject = Object<T>.Create(obj, spawned);
|
||||
m_Objects.Add(obj.Name, internalObject);
|
||||
m_ObjectMap.Add(obj.Target, internalObject);
|
||||
|
||||
if (Count > m_Capacity)
|
||||
{
|
||||
Release();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 检查对象。
|
||||
/// </summary>
|
||||
/// <returns>要检查的对象是否存在。</returns>
|
||||
public bool CanSpawn()
|
||||
{
|
||||
return CanSpawn(string.Empty);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 检查对象。
|
||||
/// </summary>
|
||||
/// <param name="name">对象名称。</param>
|
||||
/// <returns>要检查的对象是否存在。</returns>
|
||||
public bool CanSpawn(string name)
|
||||
{
|
||||
if (name == null)
|
||||
{
|
||||
throw new GameFrameworkException("Name is invalid.");
|
||||
}
|
||||
|
||||
GameFrameworkLinkedListRange<Object<T>> objectRange = default(GameFrameworkLinkedListRange<Object<T>>);
|
||||
if (m_Objects.TryGetValue(name, out objectRange))
|
||||
{
|
||||
foreach (Object<T> internalObject in objectRange)
|
||||
{
|
||||
if (m_AllowMultiSpawn || !internalObject.IsInUse)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取对象。
|
||||
/// </summary>
|
||||
/// <returns>要获取的对象。</returns>
|
||||
public T Spawn()
|
||||
{
|
||||
return Spawn(string.Empty);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取对象。
|
||||
/// </summary>
|
||||
/// <param name="name">对象名称。</param>
|
||||
/// <returns>要获取的对象。</returns>
|
||||
public T Spawn(string name)
|
||||
{
|
||||
if (name == null)
|
||||
{
|
||||
throw new GameFrameworkException("Name is invalid.");
|
||||
}
|
||||
|
||||
GameFrameworkLinkedListRange<Object<T>> objectRange = default(GameFrameworkLinkedListRange<Object<T>>);
|
||||
if (m_Objects.TryGetValue(name, out objectRange))
|
||||
{
|
||||
foreach (Object<T> internalObject in objectRange)
|
||||
{
|
||||
if (m_AllowMultiSpawn || !internalObject.IsInUse)
|
||||
{
|
||||
return internalObject.Spawn();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 回收对象。
|
||||
/// </summary>
|
||||
/// <param name="obj">要回收的对象。</param>
|
||||
public void Unspawn(T obj)
|
||||
{
|
||||
if (obj == null)
|
||||
{
|
||||
throw new GameFrameworkException("Object is invalid.");
|
||||
}
|
||||
|
||||
Unspawn(obj.Target);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 回收对象。
|
||||
/// </summary>
|
||||
/// <param name="target">要回收的对象。</param>
|
||||
public void Unspawn(object target)
|
||||
{
|
||||
if (target == null)
|
||||
{
|
||||
throw new GameFrameworkException("Target is invalid.");
|
||||
}
|
||||
|
||||
Object<T> internalObject = GetObject(target);
|
||||
if (internalObject != null)
|
||||
{
|
||||
internalObject.Unspawn();
|
||||
if (Count > m_Capacity && internalObject.SpawnCount <= 0)
|
||||
{
|
||||
Release();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new GameFrameworkException(Utility.Text.Format("Can not find target in object pool '{0}', target type is '{1}', target value is '{2}'.", new TypeNamePair(typeof(T), Name), target.GetType().FullName, target));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 设置对象是否被加锁。
|
||||
/// </summary>
|
||||
/// <param name="obj">要设置被加锁的对象。</param>
|
||||
/// <param name="locked">是否被加锁。</param>
|
||||
public void SetLocked(T obj, bool locked)
|
||||
{
|
||||
if (obj == null)
|
||||
{
|
||||
throw new GameFrameworkException("Object is invalid.");
|
||||
}
|
||||
|
||||
SetLocked(obj.Target, locked);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 设置对象是否被加锁。
|
||||
/// </summary>
|
||||
/// <param name="target">要设置被加锁的对象。</param>
|
||||
/// <param name="locked">是否被加锁。</param>
|
||||
public void SetLocked(object target, bool locked)
|
||||
{
|
||||
if (target == null)
|
||||
{
|
||||
throw new GameFrameworkException("Target is invalid.");
|
||||
}
|
||||
|
||||
Object<T> internalObject = GetObject(target);
|
||||
if (internalObject != null)
|
||||
{
|
||||
internalObject.Locked = locked;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new GameFrameworkException(Utility.Text.Format("Can not find target in object pool '{0}', target type is '{1}', target value is '{2}'.", new TypeNamePair(typeof(T), Name), target.GetType().FullName, target));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 设置对象的优先级。
|
||||
/// </summary>
|
||||
/// <param name="obj">要设置优先级的对象。</param>
|
||||
/// <param name="priority">优先级。</param>
|
||||
public void SetPriority(T obj, int priority)
|
||||
{
|
||||
if (obj == null)
|
||||
{
|
||||
throw new GameFrameworkException("Object is invalid.");
|
||||
}
|
||||
|
||||
SetPriority(obj.Target, priority);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 设置对象的优先级。
|
||||
/// </summary>
|
||||
/// <param name="target">要设置优先级的对象。</param>
|
||||
/// <param name="priority">优先级。</param>
|
||||
public void SetPriority(object target, int priority)
|
||||
{
|
||||
if (target == null)
|
||||
{
|
||||
throw new GameFrameworkException("Target is invalid.");
|
||||
}
|
||||
|
||||
Object<T> internalObject = GetObject(target);
|
||||
if (internalObject != null)
|
||||
{
|
||||
internalObject.Priority = priority;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new GameFrameworkException(Utility.Text.Format("Can not find target in object pool '{0}', target type is '{1}', target value is '{2}'.", new TypeNamePair(typeof(T), Name), target.GetType().FullName, target));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 释放对象。
|
||||
/// </summary>
|
||||
/// <param name="obj">要释放的对象。</param>
|
||||
/// <returns>释放对象是否成功。</returns>
|
||||
public bool ReleaseObject(T obj)
|
||||
{
|
||||
if (obj == null)
|
||||
{
|
||||
throw new GameFrameworkException("Object is invalid.");
|
||||
}
|
||||
|
||||
return ReleaseObject(obj.Target);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 释放对象。
|
||||
/// </summary>
|
||||
/// <param name="target">要释放的对象。</param>
|
||||
/// <returns>释放对象是否成功。</returns>
|
||||
public bool ReleaseObject(object target)
|
||||
{
|
||||
if (target == null)
|
||||
{
|
||||
throw new GameFrameworkException("Target is invalid.");
|
||||
}
|
||||
|
||||
Object<T> internalObject = GetObject(target);
|
||||
if (internalObject == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (internalObject.IsInUse || internalObject.Locked || !internalObject.CustomCanReleaseFlag)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
m_Objects.Remove(internalObject.Name, internalObject);
|
||||
m_ObjectMap.Remove(internalObject.Peek().Target);
|
||||
|
||||
internalObject.Release(false);
|
||||
ReferencePool.Release(internalObject);
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 释放对象池中的可释放对象。
|
||||
/// </summary>
|
||||
public override void Release()
|
||||
{
|
||||
Release(Count - m_Capacity, m_DefaultReleaseObjectFilterCallback);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 释放对象池中的可释放对象。
|
||||
/// </summary>
|
||||
/// <param name="toReleaseCount">尝试释放对象数量。</param>
|
||||
public override void Release(int toReleaseCount)
|
||||
{
|
||||
Release(toReleaseCount, m_DefaultReleaseObjectFilterCallback);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 释放对象池中的可释放对象。
|
||||
/// </summary>
|
||||
/// <param name="releaseObjectFilterCallback">释放对象筛选函数。</param>
|
||||
public void Release(ReleaseObjectFilterCallback<T> releaseObjectFilterCallback)
|
||||
{
|
||||
Release(Count - m_Capacity, releaseObjectFilterCallback);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 释放对象池中的可释放对象。
|
||||
/// </summary>
|
||||
/// <param name="toReleaseCount">尝试释放对象数量。</param>
|
||||
/// <param name="releaseObjectFilterCallback">释放对象筛选函数。</param>
|
||||
public void Release(int toReleaseCount, ReleaseObjectFilterCallback<T> releaseObjectFilterCallback)
|
||||
{
|
||||
if (releaseObjectFilterCallback == null)
|
||||
{
|
||||
throw new GameFrameworkException("Release object filter callback is invalid.");
|
||||
}
|
||||
|
||||
if (toReleaseCount < 0)
|
||||
{
|
||||
toReleaseCount = 0;
|
||||
}
|
||||
|
||||
DateTime expireTime = DateTime.MinValue;
|
||||
if (m_ExpireTime < float.MaxValue)
|
||||
{
|
||||
expireTime = DateTime.UtcNow.AddSeconds(-m_ExpireTime);
|
||||
}
|
||||
|
||||
m_AutoReleaseTime = 0f;
|
||||
GetCanReleaseObjects(m_CachedCanReleaseObjects);
|
||||
List<T> toReleaseObjects = releaseObjectFilterCallback(m_CachedCanReleaseObjects, toReleaseCount, expireTime);
|
||||
if (toReleaseObjects == null || toReleaseObjects.Count <= 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
foreach (T toReleaseObject in toReleaseObjects)
|
||||
{
|
||||
ReleaseObject(toReleaseObject);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 释放对象池中的所有未使用对象。
|
||||
/// </summary>
|
||||
public override void ReleaseAllUnused()
|
||||
{
|
||||
m_AutoReleaseTime = 0f;
|
||||
GetCanReleaseObjects(m_CachedCanReleaseObjects);
|
||||
foreach (T toReleaseObject in m_CachedCanReleaseObjects)
|
||||
{
|
||||
ReleaseObject(toReleaseObject);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取所有对象信息。
|
||||
/// </summary>
|
||||
/// <returns>所有对象信息。</returns>
|
||||
public override ObjectInfo[] GetAllObjectInfos()
|
||||
{
|
||||
List<ObjectInfo> results = new List<ObjectInfo>();
|
||||
foreach (KeyValuePair<string, GameFrameworkLinkedListRange<Object<T>>> objectRanges in m_Objects)
|
||||
{
|
||||
foreach (Object<T> internalObject in objectRanges.Value)
|
||||
{
|
||||
results.Add(new ObjectInfo(internalObject.Name, internalObject.Locked, internalObject.CustomCanReleaseFlag, internalObject.Priority, internalObject.LastUseTime, internalObject.SpawnCount));
|
||||
}
|
||||
}
|
||||
|
||||
return results.ToArray();
|
||||
}
|
||||
|
||||
internal override void Update(float elapseSeconds, float realElapseSeconds)
|
||||
{
|
||||
m_AutoReleaseTime += realElapseSeconds;
|
||||
if (m_AutoReleaseTime < m_AutoReleaseInterval)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Release();
|
||||
}
|
||||
|
||||
internal override void Shutdown()
|
||||
{
|
||||
foreach (KeyValuePair<object, Object<T>> objectInMap in m_ObjectMap)
|
||||
{
|
||||
objectInMap.Value.Release(true);
|
||||
ReferencePool.Release(objectInMap.Value);
|
||||
}
|
||||
|
||||
m_Objects.Clear();
|
||||
m_ObjectMap.Clear();
|
||||
m_CachedCanReleaseObjects.Clear();
|
||||
m_CachedToReleaseObjects.Clear();
|
||||
}
|
||||
|
||||
private Object<T> GetObject(object target)
|
||||
{
|
||||
if (target == null)
|
||||
{
|
||||
throw new GameFrameworkException("Target is invalid.");
|
||||
}
|
||||
|
||||
Object<T> internalObject = null;
|
||||
if (m_ObjectMap.TryGetValue(target, out internalObject))
|
||||
{
|
||||
return internalObject;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private void GetCanReleaseObjects(List<T> results)
|
||||
{
|
||||
if (results == null)
|
||||
{
|
||||
throw new GameFrameworkException("Results is invalid.");
|
||||
}
|
||||
|
||||
results.Clear();
|
||||
foreach (KeyValuePair<object, Object<T>> objectInMap in m_ObjectMap)
|
||||
{
|
||||
Object<T> internalObject = objectInMap.Value;
|
||||
if (internalObject.IsInUse || internalObject.Locked || !internalObject.CustomCanReleaseFlag)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
results.Add(internalObject.Peek());
|
||||
}
|
||||
}
|
||||
|
||||
private List<T> DefaultReleaseObjectFilterCallback(List<T> candidateObjects, int toReleaseCount, DateTime expireTime)
|
||||
{
|
||||
m_CachedToReleaseObjects.Clear();
|
||||
|
||||
if (expireTime > DateTime.MinValue)
|
||||
{
|
||||
for (int i = candidateObjects.Count - 1; i >= 0; i--)
|
||||
{
|
||||
if (candidateObjects[i].LastUseTime <= expireTime)
|
||||
{
|
||||
m_CachedToReleaseObjects.Add(candidateObjects[i]);
|
||||
candidateObjects.RemoveAt(i);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
toReleaseCount -= m_CachedToReleaseObjects.Count;
|
||||
}
|
||||
|
||||
for (int i = 0; toReleaseCount > 0 && i < candidateObjects.Count; i++)
|
||||
{
|
||||
for (int j = i + 1; j < candidateObjects.Count; j++)
|
||||
{
|
||||
if (candidateObjects[i].Priority > candidateObjects[j].Priority
|
||||
|| candidateObjects[i].Priority == candidateObjects[j].Priority && candidateObjects[i].LastUseTime > candidateObjects[j].LastUseTime)
|
||||
{
|
||||
T temp = candidateObjects[i];
|
||||
candidateObjects[i] = candidateObjects[j];
|
||||
candidateObjects[j] = temp;
|
||||
}
|
||||
}
|
||||
|
||||
m_CachedToReleaseObjects.Add(candidateObjects[i]);
|
||||
toReleaseCount--;
|
||||
}
|
||||
|
||||
return m_CachedToReleaseObjects;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 47555abda225429bba3f1d33e7cf408a
|
||||
timeCreated: 1708673686
|
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 72eae18b8c9a41d5bc970c2d702061b9
|
||||
timeCreated: 1708673686
|
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: af4a69a729384044b97f0ca31b16412a
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,22 @@
|
||||
//------------------------------------------------------------
|
||||
// Game Framework
|
||||
// Copyright © 2013-2021 Jiang Yin. All rights reserved.
|
||||
// Homepage: https://gameframework.cn/
|
||||
// Feedback: mailto:ellan@gameframework.cn
|
||||
//------------------------------------------------------------
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace SHFrame
|
||||
{
|
||||
/// <summary>
|
||||
/// 释放对象筛选函数。
|
||||
/// </summary>
|
||||
/// <typeparam name="T">对象类型。</typeparam>
|
||||
/// <param name="candidateObjects">要筛选的对象集合。</param>
|
||||
/// <param name="toReleaseCount">需要释放的对象数量。</param>
|
||||
/// <param name="expireTime">对象过期参考时间。</param>
|
||||
/// <returns>经筛选需要释放的对象集合。</returns>
|
||||
public delegate List<T> ReleaseObjectFilterCallback<T>(List<T> candidateObjects, int toReleaseCount, DateTime expireTime) where T : ObjectBase;
|
||||
}
|
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6a256ddf090e4ed58402f4db83117f79
|
||||
timeCreated: 1708673686
|
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c0bf55d98c52af64fb78899141efc94f
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,74 @@
|
||||
|
||||
using System;
|
||||
|
||||
namespace SHFrame
|
||||
{
|
||||
/// <summary>
|
||||
/// 流程管理器接口。
|
||||
/// </summary>
|
||||
public interface IProcedureManager
|
||||
{
|
||||
/// <summary>
|
||||
/// 获取当前流程。
|
||||
/// </summary>
|
||||
ProcedureBase CurrentProcedure
|
||||
{
|
||||
get;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取当前流程持续时间。
|
||||
/// </summary>
|
||||
float CurrentProcedureTime
|
||||
{
|
||||
get;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 初始化流程管理器。
|
||||
/// </summary>
|
||||
/// <param name="fsmManager">有限状态机管理器。</param>
|
||||
/// <param name="procedures">流程管理器包含的流程。</param>
|
||||
void Initialize(FSM.IFsmManager fsmManager, params ProcedureBase[] procedures);
|
||||
|
||||
/// <summary>
|
||||
/// 开始流程。
|
||||
/// </summary>
|
||||
/// <typeparam name="T">要开始的流程类型。</typeparam>
|
||||
void StartProcedure<T>() where T : ProcedureBase;
|
||||
|
||||
/// <summary>
|
||||
/// 开始流程。
|
||||
/// </summary>
|
||||
/// <param name="procedureType">要开始的流程类型。</param>
|
||||
void StartProcedure(Type procedureType);
|
||||
|
||||
/// <summary>
|
||||
/// 是否存在流程。
|
||||
/// </summary>
|
||||
/// <typeparam name="T">要检查的流程类型。</typeparam>
|
||||
/// <returns>是否存在流程。</returns>
|
||||
bool HasProcedure<T>() where T : ProcedureBase;
|
||||
|
||||
/// <summary>
|
||||
/// 是否存在流程。
|
||||
/// </summary>
|
||||
/// <param name="procedureType">要检查的流程类型。</param>
|
||||
/// <returns>是否存在流程。</returns>
|
||||
bool HasProcedure(Type procedureType);
|
||||
|
||||
/// <summary>
|
||||
/// 获取流程。
|
||||
/// </summary>
|
||||
/// <typeparam name="T">要获取的流程类型。</typeparam>
|
||||
/// <returns>要获取的流程。</returns>
|
||||
ProcedureBase GetProcedure<T>() where T : ProcedureBase;
|
||||
|
||||
/// <summary>
|
||||
/// 获取流程。
|
||||
/// </summary>
|
||||
/// <param name="procedureType">要获取的流程类型。</param>
|
||||
/// <returns>要获取的流程。</returns>
|
||||
ProcedureBase GetProcedure(Type procedureType);
|
||||
}
|
||||
}
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c821b1d0ed655664ca0e31707b63d7cb
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,59 @@
|
||||
|
||||
using ProcedureOwner = SHFrame.FSM.IFsm<SHFrame.IProcedureManager>;
|
||||
|
||||
namespace SHFrame
|
||||
{
|
||||
/// <summary>
|
||||
/// 流程基类。
|
||||
/// </summary>
|
||||
public abstract class ProcedureBase : FSM.FsmState<IProcedureManager>
|
||||
{
|
||||
/// <summary>
|
||||
/// 状态初始化时调用。
|
||||
/// </summary>
|
||||
/// <param name="procedureOwner">流程持有者。</param>
|
||||
protected internal override void OnInit(ProcedureOwner procedureOwner)
|
||||
{
|
||||
base.OnInit(procedureOwner);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 进入状态时调用。
|
||||
/// </summary>
|
||||
/// <param name="procedureOwner">流程持有者。</param>
|
||||
protected internal override void OnEnter(ProcedureOwner procedureOwner)
|
||||
{
|
||||
base.OnEnter(procedureOwner);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 状态轮询时调用。
|
||||
/// </summary>
|
||||
/// <param name="procedureOwner">流程持有者。</param>
|
||||
/// <param name="elapseSeconds">逻辑流逝时间,以秒为单位。</param>
|
||||
/// <param name="realElapseSeconds">真实流逝时间,以秒为单位。</param>
|
||||
protected internal override void OnUpdate(ProcedureOwner procedureOwner, float elapseSeconds, float realElapseSeconds)
|
||||
{
|
||||
base.OnUpdate(procedureOwner, elapseSeconds, realElapseSeconds);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 离开状态时调用。
|
||||
/// </summary>
|
||||
/// <param name="procedureOwner">流程持有者。</param>
|
||||
/// <param name="isShutdown">是否是关闭状态机时触发。</param>
|
||||
protected internal override void OnLeave(ProcedureOwner procedureOwner, bool isShutdown)
|
||||
{
|
||||
base.OnLeave(procedureOwner, isShutdown);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 状态销毁时调用。
|
||||
/// </summary>
|
||||
/// <param name="procedureOwner">流程持有者。</param>
|
||||
protected internal override void OnDestroy(ProcedureOwner procedureOwner)
|
||||
{
|
||||
base.OnDestroy(procedureOwner);
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8be720b5d94706e4a9b09f7260887bff
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,197 @@
|
||||
|
||||
using System;
|
||||
|
||||
namespace SHFrame
|
||||
{
|
||||
/// <summary>
|
||||
/// 流程管理器。
|
||||
/// </summary>
|
||||
internal sealed class ProcedureManager : ModuleImp, IProcedureManager
|
||||
{
|
||||
private FSM.IFsmManager m_FsmManager;
|
||||
private FSM.IFsm<IProcedureManager> m_ProcedureFsm;
|
||||
|
||||
/// <summary>
|
||||
/// 初始化流程管理器的新实例。
|
||||
/// </summary>
|
||||
public ProcedureManager()
|
||||
{
|
||||
m_FsmManager = null;
|
||||
m_ProcedureFsm = null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取游戏框架模块优先级。
|
||||
/// </summary>
|
||||
/// <remarks>优先级较高的模块会优先轮询,并且关闭操作会后进行。</remarks>
|
||||
internal override int Priority
|
||||
{
|
||||
get
|
||||
{
|
||||
return -2;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取当前流程。
|
||||
/// </summary>
|
||||
public ProcedureBase CurrentProcedure
|
||||
{
|
||||
get
|
||||
{
|
||||
if (m_ProcedureFsm == null)
|
||||
{
|
||||
throw new GameFrameworkException("You must initialize procedure first.");
|
||||
}
|
||||
|
||||
return (ProcedureBase)m_ProcedureFsm.CurrentState;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取当前流程持续时间。
|
||||
/// </summary>
|
||||
public float CurrentProcedureTime
|
||||
{
|
||||
get
|
||||
{
|
||||
if (m_ProcedureFsm == null)
|
||||
{
|
||||
throw new GameFrameworkException("You must initialize procedure first.");
|
||||
}
|
||||
|
||||
return m_ProcedureFsm.CurrentStateTime;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 流程管理器轮询。
|
||||
/// </summary>
|
||||
/// <param name="elapseSeconds">逻辑流逝时间,以秒为单位。</param>
|
||||
/// <param name="realElapseSeconds">真实流逝时间,以秒为单位。</param>
|
||||
internal override void Update(float elapseSeconds, float realElapseSeconds)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 关闭并清理流程管理器。
|
||||
/// </summary>
|
||||
internal override void Shutdown()
|
||||
{
|
||||
if (m_FsmManager != null)
|
||||
{
|
||||
if (m_ProcedureFsm != null)
|
||||
{
|
||||
m_FsmManager.DestroyFsm(m_ProcedureFsm);
|
||||
m_ProcedureFsm = null;
|
||||
}
|
||||
|
||||
m_FsmManager = null;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 初始化流程管理器。
|
||||
/// </summary>
|
||||
/// <param name="fsmManager">有限状态机管理器。</param>
|
||||
/// <param name="procedures">流程管理器包含的流程。</param>
|
||||
public void Initialize(FSM.IFsmManager fsmManager, params ProcedureBase[] procedures)
|
||||
{
|
||||
if (fsmManager == null)
|
||||
{
|
||||
throw new GameFrameworkException("FSM manager is invalid.");
|
||||
}
|
||||
|
||||
m_FsmManager = fsmManager;
|
||||
m_ProcedureFsm = m_FsmManager.CreateFsm(this, procedures);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 开始流程。
|
||||
/// </summary>
|
||||
/// <typeparam name="T">要开始的流程类型。</typeparam>
|
||||
public void StartProcedure<T>() where T : ProcedureBase
|
||||
{
|
||||
if (m_ProcedureFsm == null)
|
||||
{
|
||||
throw new GameFrameworkException("You must initialize procedure first.");
|
||||
}
|
||||
|
||||
m_ProcedureFsm.Start<T>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 开始流程。
|
||||
/// </summary>
|
||||
/// <param name="procedureType">要开始的流程类型。</param>
|
||||
public void StartProcedure(Type procedureType)
|
||||
{
|
||||
if (m_ProcedureFsm == null)
|
||||
{
|
||||
throw new GameFrameworkException("You must initialize procedure first.");
|
||||
}
|
||||
|
||||
m_ProcedureFsm.Start(procedureType);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 是否存在流程。
|
||||
/// </summary>
|
||||
/// <typeparam name="T">要检查的流程类型。</typeparam>
|
||||
/// <returns>是否存在流程。</returns>
|
||||
public bool HasProcedure<T>() where T : ProcedureBase
|
||||
{
|
||||
if (m_ProcedureFsm == null)
|
||||
{
|
||||
throw new GameFrameworkException("You must initialize procedure first.");
|
||||
}
|
||||
|
||||
return m_ProcedureFsm.HasState<T>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 是否存在流程。
|
||||
/// </summary>
|
||||
/// <param name="procedureType">要检查的流程类型。</param>
|
||||
/// <returns>是否存在流程。</returns>
|
||||
public bool HasProcedure(Type procedureType)
|
||||
{
|
||||
if (m_ProcedureFsm == null)
|
||||
{
|
||||
throw new GameFrameworkException("You must initialize procedure first.");
|
||||
}
|
||||
|
||||
return m_ProcedureFsm.HasState(procedureType);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取流程。
|
||||
/// </summary>
|
||||
/// <typeparam name="T">要获取的流程类型。</typeparam>
|
||||
/// <returns>要获取的流程。</returns>
|
||||
public ProcedureBase GetProcedure<T>() where T : ProcedureBase
|
||||
{
|
||||
if (m_ProcedureFsm == null)
|
||||
{
|
||||
throw new GameFrameworkException("You must initialize procedure first.");
|
||||
}
|
||||
|
||||
return m_ProcedureFsm.GetState<T>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取流程。
|
||||
/// </summary>
|
||||
/// <param name="procedureType">要获取的流程类型。</param>
|
||||
/// <returns>要获取的流程。</returns>
|
||||
public ProcedureBase GetProcedure(Type procedureType)
|
||||
{
|
||||
if (m_ProcedureFsm == null)
|
||||
{
|
||||
throw new GameFrameworkException("You must initialize procedure first.");
|
||||
}
|
||||
|
||||
return (ProcedureBase)m_ProcedureFsm.GetState(procedureType);
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 001bd8b56e2fb744ebbabc52d38c0488
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,153 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using UnityEngine;
|
||||
|
||||
namespace SHFrame
|
||||
{
|
||||
[DisallowMultipleComponent]
|
||||
public sealed class ProcedureModule : Module
|
||||
{
|
||||
private IProcedureManager m_ProcedureManager = null;
|
||||
private ProcedureBase m_EntranceProcedure = null;
|
||||
|
||||
[SerializeField] private string[] m_AvailableProcedureTypeNames = null;
|
||||
|
||||
[SerializeField] private string m_EntranceProcedureTypeName = null;
|
||||
|
||||
/// <summary>
|
||||
/// 获取当前流程。
|
||||
/// </summary>
|
||||
public ProcedureBase CurrentProcedure
|
||||
{
|
||||
get { return m_ProcedureManager.CurrentProcedure; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取当前流程持续时间。
|
||||
/// </summary>
|
||||
public float CurrentProcedureTime
|
||||
{
|
||||
get { return m_ProcedureManager.CurrentProcedureTime; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 游戏框架组件初始化。
|
||||
/// </summary>
|
||||
protected override void Awake()
|
||||
{
|
||||
base.Awake();
|
||||
|
||||
m_ProcedureManager = ModuleImpSystem.GetModule<IProcedureManager>();
|
||||
if (m_ProcedureManager == null)
|
||||
{
|
||||
Log.Fatal("Procedure manager is invalid.");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
private IEnumerator Start()
|
||||
{
|
||||
ProcedureBase[] procedures = new ProcedureBase[m_AvailableProcedureTypeNames.Length];
|
||||
for (int i = 0; i < m_AvailableProcedureTypeNames.Length; i++)
|
||||
{
|
||||
Type procedureType = Utility.Assembly.GetType(m_AvailableProcedureTypeNames[i]);
|
||||
if (procedureType == null)
|
||||
{
|
||||
Log.Error("Can not find procedure type '{0}'.", m_AvailableProcedureTypeNames[i]);
|
||||
yield break;
|
||||
}
|
||||
|
||||
procedures[i] = (ProcedureBase)Activator.CreateInstance(procedureType);
|
||||
if (procedures[i] == null)
|
||||
{
|
||||
Log.Error("Can not create procedure instance '{0}'.", m_AvailableProcedureTypeNames[i]);
|
||||
yield break;
|
||||
}
|
||||
|
||||
if (m_EntranceProcedureTypeName == m_AvailableProcedureTypeNames[i])
|
||||
{
|
||||
m_EntranceProcedure = procedures[i];
|
||||
}
|
||||
}
|
||||
|
||||
if (m_EntranceProcedure == null)
|
||||
{
|
||||
Log.Error("Entrance procedure is invalid.");
|
||||
yield break;
|
||||
}
|
||||
|
||||
m_ProcedureManager.Initialize(ModuleImpSystem.GetModule<FSM.IFsmManager>(), procedures);
|
||||
yield return new WaitForEndOfFrame();
|
||||
m_ProcedureManager.StartProcedure(m_EntranceProcedure.GetType());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 是否存在流程。
|
||||
/// </summary>
|
||||
/// <typeparam name="T">要检查的流程类型。</typeparam>
|
||||
/// <returns>是否存在流程。</returns>
|
||||
public bool HasProcedure<T>() where T : ProcedureBase
|
||||
{
|
||||
return m_ProcedureManager.HasProcedure<T>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 是否存在流程。
|
||||
/// </summary>
|
||||
/// <param name="procedureType">要检查的流程类型。</param>
|
||||
/// <returns>是否存在流程。</returns>
|
||||
public bool HasProcedure(Type procedureType)
|
||||
{
|
||||
return m_ProcedureManager.HasProcedure(procedureType);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取流程。
|
||||
/// </summary>
|
||||
/// <typeparam name="T">要获取的流程类型。</typeparam>
|
||||
/// <returns>要获取的流程。</returns>
|
||||
public ProcedureBase GetProcedure<T>() where T : ProcedureBase
|
||||
{
|
||||
return m_ProcedureManager.GetProcedure<T>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取流程。
|
||||
/// </summary>
|
||||
/// <param name="procedureType">要获取的流程类型。</param>
|
||||
/// <returns>要获取的流程。</returns>
|
||||
public ProcedureBase GetProcedure(Type procedureType)
|
||||
{
|
||||
return m_ProcedureManager.GetProcedure(procedureType);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 重启流程。
|
||||
/// <remarks>默认使用第一个流程作为启动流程。</remarks>
|
||||
/// </summary>
|
||||
/// <param name="defaultIndex"></param>
|
||||
/// <param name="procedures">新的的流程。</param>
|
||||
/// <returns>是否重启成功。</returns>
|
||||
/// <exception cref="GameFrameworkException">重启异常。</exception>
|
||||
public bool RestartProcedure(int defaultIndex, params ProcedureBase[] procedures)
|
||||
{
|
||||
if (procedures == null || procedures.Length <= 0)
|
||||
{
|
||||
throw new GameFrameworkException("RestartProcedure Failed procedures is invalid.");
|
||||
}
|
||||
|
||||
FSM.IFsmManager fsmManager = ModuleImpSystem.GetModule<FSM.IFsmManager>();
|
||||
|
||||
if (!fsmManager.DestroyFsm<IProcedureManager>())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
m_ProcedureManager = null;
|
||||
m_ProcedureManager = ModuleImpSystem.GetModule<IProcedureManager>();
|
||||
m_ProcedureManager.Initialize(fsmManager, procedures);
|
||||
m_ProcedureManager.StartProcedure(procedures[defaultIndex].GetType());
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f8594aafa061b684a936aed29f6be663
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
314
JNFrame2/Assets/UsePlugins/SHFrame/Runtime/Modules/RootModule.cs
Normal file
314
JNFrame2/Assets/UsePlugins/SHFrame/Runtime/Modules/RootModule.cs
Normal file
@@ -0,0 +1,314 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
namespace SHFrame
|
||||
{
|
||||
/// <summary>
|
||||
/// 基础模块。
|
||||
/// </summary>
|
||||
[DisallowMultipleComponent]
|
||||
public sealed class RootModule : Module
|
||||
{
|
||||
private const int DefaultDpi = 96; // default windows dpi
|
||||
|
||||
private float m_GameSpeedBeforePause = 1f;
|
||||
|
||||
// [SerializeField]
|
||||
// private Language m_EditorLanguage = Language.Unspecified;
|
||||
|
||||
[SerializeField]
|
||||
private string m_TextHelperTypeName = "SHFrame.DefaultTextHelper";
|
||||
|
||||
[SerializeField]
|
||||
private string m_VersionHelperTypeName = "SHFrame.DefaultVersionHelper";
|
||||
|
||||
[SerializeField]
|
||||
private string m_LogHelperTypeName = "SHFrame.DefaultLogHelper";
|
||||
|
||||
[SerializeField]
|
||||
private string m_JsonHelperTypeName = "SHFrame.DefaultJsonHelper";
|
||||
|
||||
[SerializeField]
|
||||
private int m_FrameRate = 120;
|
||||
|
||||
[SerializeField]
|
||||
private float m_GameSpeed = 1f;
|
||||
|
||||
[SerializeField]
|
||||
private bool m_RunInBackground = true;
|
||||
|
||||
[SerializeField]
|
||||
private bool m_NeverSleep = true;
|
||||
|
||||
// /// <summary>
|
||||
// /// 获取或设置编辑器语言(仅编辑器内有效)。
|
||||
// /// </summary>
|
||||
// public Language EditorLanguage
|
||||
// {
|
||||
// get => m_EditorLanguage;
|
||||
// set => m_EditorLanguage = value;
|
||||
// }
|
||||
|
||||
/// <summary>
|
||||
/// 获取或设置游戏帧率。
|
||||
/// </summary>
|
||||
public int FrameRate
|
||||
{
|
||||
get => m_FrameRate;
|
||||
set => Application.targetFrameRate = m_FrameRate = value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取或设置游戏速度。
|
||||
/// </summary>
|
||||
public float GameSpeed
|
||||
{
|
||||
get => m_GameSpeed;
|
||||
set => Time.timeScale = m_GameSpeed = value >= 0f ? value : 0f;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取游戏是否暂停。
|
||||
/// </summary>
|
||||
public bool IsGamePaused => m_GameSpeed <= 0f;
|
||||
|
||||
/// <summary>
|
||||
/// 获取是否正常游戏速度。
|
||||
/// </summary>
|
||||
public bool IsNormalGameSpeed => Math.Abs(m_GameSpeed - 1f) < 0.01f;
|
||||
|
||||
/// <summary>
|
||||
/// 获取或设置是否允许后台运行。
|
||||
/// </summary>
|
||||
public bool RunInBackground
|
||||
{
|
||||
get => m_RunInBackground;
|
||||
set => Application.runInBackground = m_RunInBackground = value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取或设置是否禁止休眠。
|
||||
/// </summary>
|
||||
public bool NeverSleep
|
||||
{
|
||||
get => m_NeverSleep;
|
||||
set
|
||||
{
|
||||
m_NeverSleep = value;
|
||||
Screen.sleepTimeout = value ? SleepTimeout.NeverSleep : SleepTimeout.SystemSetting;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 游戏框架模块初始化。
|
||||
/// </summary>
|
||||
protected override void Awake()
|
||||
{
|
||||
base.Awake();
|
||||
|
||||
InitTextHelper();
|
||||
InitVersionHelper();
|
||||
InitLogHelper();
|
||||
Log.Info("Version: {0}", Version.GameFrameworkVersion);
|
||||
Log.Info("Game Version: {0} ({1})", Version.GameVersion, Version.InternalGameVersion);
|
||||
Log.Info("Unity Version: {0}", Application.unityVersion);
|
||||
|
||||
InitJsonHelper();
|
||||
|
||||
Utility.Converter.ScreenDpi = Screen.dpi;
|
||||
if (Utility.Converter.ScreenDpi <= 0)
|
||||
{
|
||||
Utility.Converter.ScreenDpi = DefaultDpi;
|
||||
}
|
||||
|
||||
Time.timeScale = m_GameSpeed;
|
||||
Application.runInBackground = m_RunInBackground;
|
||||
Screen.sleepTimeout = m_NeverSleep ? SleepTimeout.NeverSleep : SleepTimeout.SystemSetting;
|
||||
|
||||
Application.lowMemory += OnLowMemory;
|
||||
GameTime.StartFrame();
|
||||
}
|
||||
|
||||
private void Update()
|
||||
{
|
||||
GameTime.StartFrame();
|
||||
ModuleImpSystem.Update(GameTime.deltaTime, GameTime.unscaledDeltaTime);
|
||||
}
|
||||
|
||||
private void FixedUpdate()
|
||||
{
|
||||
GameTime.StartFrame();
|
||||
}
|
||||
|
||||
private void LateUpdate()
|
||||
{
|
||||
GameTime.StartFrame();
|
||||
}
|
||||
|
||||
private void OnApplicationQuit()
|
||||
{
|
||||
Application.lowMemory -= OnLowMemory;
|
||||
StopAllCoroutines();
|
||||
}
|
||||
|
||||
private void OnDestroy()
|
||||
{
|
||||
ModuleImpSystem.Shutdown();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 暂停游戏。
|
||||
/// </summary>
|
||||
public void PauseGame()
|
||||
{
|
||||
if (IsGamePaused)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
m_GameSpeedBeforePause = GameSpeed;
|
||||
GameSpeed = 0f;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 恢复游戏。
|
||||
/// </summary>
|
||||
public void ResumeGame()
|
||||
{
|
||||
if (!IsGamePaused)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
GameSpeed = m_GameSpeedBeforePause;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 重置为正常游戏速度。
|
||||
/// </summary>
|
||||
public void ResetNormalGameSpeed()
|
||||
{
|
||||
if (IsNormalGameSpeed)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
GameSpeed = 1f;
|
||||
}
|
||||
|
||||
internal void Shutdown()
|
||||
{
|
||||
Destroy(gameObject);
|
||||
}
|
||||
|
||||
private void InitTextHelper()
|
||||
{
|
||||
if (string.IsNullOrEmpty(m_TextHelperTypeName))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Type textHelperType = Utility.Assembly.GetType(m_TextHelperTypeName);
|
||||
if (textHelperType == null)
|
||||
{
|
||||
Log.Error("Can not find text helper type '{0}'.", m_TextHelperTypeName);
|
||||
return;
|
||||
}
|
||||
|
||||
Utility.Text.ITextHelper textHelper = (Utility.Text.ITextHelper)Activator.CreateInstance(textHelperType);
|
||||
if (textHelper == null)
|
||||
{
|
||||
Log.Error("Can not create text helper instance '{0}'.", m_TextHelperTypeName);
|
||||
return;
|
||||
}
|
||||
|
||||
Utility.Text.SetTextHelper(textHelper);
|
||||
}
|
||||
|
||||
private void InitVersionHelper()
|
||||
{
|
||||
if (string.IsNullOrEmpty(m_VersionHelperTypeName))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Type versionHelperType = Utility.Assembly.GetType(m_VersionHelperTypeName);
|
||||
if (versionHelperType == null)
|
||||
{
|
||||
throw new GameFrameworkException(Utility.Text.Format("Can not find version helper type '{0}'.", m_VersionHelperTypeName));
|
||||
}
|
||||
|
||||
Version.IVersionHelper versionHelper = (Version.IVersionHelper)Activator.CreateInstance(versionHelperType);
|
||||
if (versionHelper == null)
|
||||
{
|
||||
throw new GameFrameworkException(Utility.Text.Format("Can not create version helper instance '{0}'.", m_VersionHelperTypeName));
|
||||
}
|
||||
|
||||
Version.SetVersionHelper(versionHelper);
|
||||
}
|
||||
|
||||
private void InitLogHelper()
|
||||
{
|
||||
if (string.IsNullOrEmpty(m_LogHelperTypeName))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Type logHelperType = Utility.Assembly.GetType(m_LogHelperTypeName);
|
||||
if (logHelperType == null)
|
||||
{
|
||||
throw new GameFrameworkException(Utility.Text.Format("Can not find log helper type '{0}'.", m_LogHelperTypeName));
|
||||
}
|
||||
|
||||
GameFrameworkLog.ILogHelper logHelper = (GameFrameworkLog.ILogHelper)Activator.CreateInstance(logHelperType);
|
||||
if (logHelper == null)
|
||||
{
|
||||
throw new GameFrameworkException(Utility.Text.Format("Can not create log helper instance '{0}'.", m_LogHelperTypeName));
|
||||
}
|
||||
|
||||
GameFrameworkLog.SetLogHelper(logHelper);
|
||||
}
|
||||
|
||||
private void InitJsonHelper()
|
||||
{
|
||||
if (string.IsNullOrEmpty(m_JsonHelperTypeName))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Type jsonHelperType = Utility.Assembly.GetType(m_JsonHelperTypeName);
|
||||
if (jsonHelperType == null)
|
||||
{
|
||||
Log.Error("Can not find JSON helper type '{0}'.", m_JsonHelperTypeName);
|
||||
return;
|
||||
}
|
||||
|
||||
Utility.Json.IJsonHelper jsonHelper = (Utility.Json.IJsonHelper)Activator.CreateInstance(jsonHelperType);
|
||||
if (jsonHelper == null)
|
||||
{
|
||||
Log.Error("Can not create JSON helper instance '{0}'.", m_JsonHelperTypeName);
|
||||
return;
|
||||
}
|
||||
|
||||
Utility.Json.SetJsonHelper(jsonHelper);
|
||||
}
|
||||
|
||||
private void OnLowMemory()
|
||||
{
|
||||
Log.Warning("Low memory reported...");
|
||||
|
||||
ObjectPoolModule objectPoolModule = ModuleSystem.GetModule<ObjectPoolModule>();
|
||||
if (objectPoolModule != null)
|
||||
{
|
||||
objectPoolModule.ReleaseAllUnused();
|
||||
}
|
||||
|
||||
// 卸载所有不在使用的资源
|
||||
// ResourceModule resourceModule = ModuleSystem.GetModule<ResourceModule>();
|
||||
// if (resourceModule != null)
|
||||
// {
|
||||
// resourceModule.ForceUnloadUnusedAssets(true);
|
||||
// }
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 627ac88ed6da4735b476619bb8a91951
|
||||
timeCreated: 1727610588
|
Reference in New Issue
Block a user