mirror of
https://github.com/Alex-Rachel/TEngine.git
synced 2025-08-14 16:51:28 +00:00
Demo
Demo
This commit is contained in:
8
Assets/GameScripts/HotFix/GameLogic/Demo.meta
Normal file
8
Assets/GameScripts/HotFix/GameLogic/Demo.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8689b5a2e84e72e47a4387c0d25b4c5c
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
8
Assets/GameScripts/HotFix/GameLogic/Demo/Actor.meta
Normal file
8
Assets/GameScripts/HotFix/GameLogic/Demo/Actor.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6eccec3101ad0714697d394a14c2ec65
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,15 @@
|
||||
using TEngine;
|
||||
|
||||
namespace GameLogic
|
||||
{
|
||||
public static class ActorEventDefine
|
||||
{
|
||||
public static readonly int ScoreChange = StringId.StringToHash("ActorEventDefine.ScoreChange");
|
||||
public static readonly int GameOver = StringId.StringToHash("ActorEventDefine.GameOver");
|
||||
public static readonly int EnemyDead = StringId.StringToHash("ActorEventDefine.EnemyDead");
|
||||
public static readonly int PlayerDead = StringId.StringToHash("ActorEventDefine.PlayerDead");
|
||||
public static readonly int AsteroidExplosion = StringId.StringToHash("ActorEventDefine.AsteroidExplosion");
|
||||
public static readonly int EnemyFireBullet = StringId.StringToHash("ActorEventDefine.EnemyFireBullet");
|
||||
public static readonly int PlayerFireBullet = StringId.StringToHash("ActorEventDefine.PlayerFireBullet");
|
||||
}
|
||||
}
|
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: de011fa2ea744cfe94ddb63030ebf031
|
||||
timeCreated: 1683946273
|
@@ -0,0 +1,45 @@
|
||||
using GameLogic;
|
||||
using TEngine;
|
||||
using UnityEngine;
|
||||
using UniFramework.Pooling;
|
||||
|
||||
public class EntityAsteroid : MonoBehaviour
|
||||
{
|
||||
public float MoveSpeed = -5f;
|
||||
public float Tumble = 5f;
|
||||
|
||||
private SpawnHandle _handle;
|
||||
private Rigidbody _rigidbody;
|
||||
|
||||
public void InitEntity(SpawnHandle handle)
|
||||
{
|
||||
_handle = handle;
|
||||
|
||||
_rigidbody.velocity = this.transform.forward * MoveSpeed;
|
||||
_rigidbody.angularVelocity = Random.insideUnitSphere * Tumble;
|
||||
}
|
||||
|
||||
void Awake()
|
||||
{
|
||||
_rigidbody = this.transform.GetComponent<Rigidbody>();
|
||||
}
|
||||
void OnTriggerEnter(Collider other)
|
||||
{
|
||||
var name = other.gameObject.name;
|
||||
if (name.StartsWith("player"))
|
||||
{
|
||||
GameEvent.Send(ActorEventDefine.AsteroidExplosion,this.transform.position, this.transform.rotation);
|
||||
_handle.Restore();
|
||||
_handle = null;
|
||||
}
|
||||
}
|
||||
void OnTriggerExit(Collider other)
|
||||
{
|
||||
var name = other.gameObject.name;
|
||||
if (name.StartsWith("Boundary"))
|
||||
{
|
||||
_handle.Restore();
|
||||
_handle = null;
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ffef5a382eef32d46b1d6175c85f644e
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,56 @@
|
||||
using UnityEngine;
|
||||
using UniFramework.Pooling;
|
||||
|
||||
public class EntityBullet : MonoBehaviour
|
||||
{
|
||||
public float MoveSpeed = 20f;
|
||||
public float DelayDestroyTime = 5f;
|
||||
|
||||
private SpawnHandle _handle;
|
||||
private Rigidbody _rigidbody;
|
||||
|
||||
public void InitEntity(SpawnHandle handle)
|
||||
{
|
||||
_handle = handle;
|
||||
_rigidbody.velocity = this.transform.forward * MoveSpeed;
|
||||
}
|
||||
|
||||
void Awake()
|
||||
{
|
||||
_rigidbody = this.transform.GetComponent<Rigidbody>();
|
||||
}
|
||||
void OnTriggerEnter(Collider other)
|
||||
{
|
||||
var name = other.gameObject.name;
|
||||
if (name.StartsWith("Boundary"))
|
||||
return;
|
||||
|
||||
var goName = this.gameObject.name;
|
||||
if (goName.StartsWith("enemy_bullet"))
|
||||
{
|
||||
if (name.StartsWith("enemy") == false)
|
||||
{
|
||||
_handle.Restore();
|
||||
_handle = null;
|
||||
}
|
||||
}
|
||||
|
||||
if (goName.StartsWith("player_bullet"))
|
||||
{
|
||||
if (name.StartsWith("player") == false)
|
||||
{
|
||||
_handle.Restore();
|
||||
_handle = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
void OnTriggerExit(Collider other)
|
||||
{
|
||||
var name = other.gameObject.name;
|
||||
if (name.StartsWith("Boundary"))
|
||||
{
|
||||
_handle.Restore();
|
||||
_handle = null;
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1a9d4ddd3c4e60245b6bc4f9f1435291
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,21 @@
|
||||
using UnityEngine;
|
||||
using UniFramework.Pooling;
|
||||
|
||||
public class EntityEffect : MonoBehaviour
|
||||
{
|
||||
public float DelayDestroyTime = 1f;
|
||||
|
||||
private SpawnHandle _handle;
|
||||
|
||||
public void InitEntity(SpawnHandle handle)
|
||||
{
|
||||
_handle = handle;
|
||||
|
||||
Invoke(nameof(DelayDestroy), DelayDestroyTime);
|
||||
}
|
||||
private void DelayDestroy()
|
||||
{
|
||||
_handle.Restore();
|
||||
_handle = null;
|
||||
}
|
||||
}
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 014c1f9b87e247446bd7d558f8bf143e
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
101
Assets/GameScripts/HotFix/GameLogic/Demo/Actor/EntityEnemy.cs
Normal file
101
Assets/GameScripts/HotFix/GameLogic/Demo/Actor/EntityEnemy.cs
Normal file
@@ -0,0 +1,101 @@
|
||||
using System.Collections;
|
||||
using GameLogic;
|
||||
using TEngine;
|
||||
using UnityEngine;
|
||||
using UniFramework.Pooling;
|
||||
using Random = UnityEngine.Random;
|
||||
|
||||
public class EntityEnemy : MonoBehaviour
|
||||
{
|
||||
private const float Dodge = 5f;
|
||||
private const float Smoothing = 7.5f;
|
||||
|
||||
public RoomBoundary Boundary;
|
||||
public float MoveSpeed = 20f;
|
||||
public float FireInterval = 2f;
|
||||
|
||||
public Vector2 StartWait = new Vector2(0.5f, 1f);
|
||||
public Vector2 ManeuverTime = new Vector2(1, 2);
|
||||
public Vector2 ManeuverWait = new Vector2(1, 2);
|
||||
|
||||
private SpawnHandle _handle;
|
||||
private Transform _shotSpawn;
|
||||
private Rigidbody _rigidbody;
|
||||
private AudioSource _audioSource;
|
||||
private float _lastFireTime = 0f;
|
||||
private float _currentSpeed;
|
||||
private float _targetManeuver;
|
||||
|
||||
|
||||
public void InitEntity(SpawnHandle handle)
|
||||
{
|
||||
_handle = handle;
|
||||
|
||||
_rigidbody.velocity = this.transform.forward * -5f;
|
||||
_lastFireTime = Time.time;
|
||||
_currentSpeed = _rigidbody.velocity.z;
|
||||
_targetManeuver = 0f;
|
||||
StartCoroutine(Evade());
|
||||
}
|
||||
|
||||
void Awake()
|
||||
{
|
||||
_rigidbody = this.gameObject.GetComponent<Rigidbody>();
|
||||
_audioSource = this.gameObject.GetComponent<AudioSource>();
|
||||
_shotSpawn = this.transform.Find("shot_spawn");
|
||||
}
|
||||
void Update()
|
||||
{
|
||||
if (Time.time - _lastFireTime >= FireInterval)
|
||||
{
|
||||
_lastFireTime = Time.time;
|
||||
_audioSource.Play();
|
||||
GameEvent.Send(ActorEventDefine.EnemyFireBullet,this._shotSpawn.position, this._shotSpawn.rotation);
|
||||
}
|
||||
}
|
||||
void FixedUpdate()
|
||||
{
|
||||
float newManeuver = Mathf.MoveTowards(_rigidbody.velocity.x, _targetManeuver, Smoothing * Time.deltaTime);
|
||||
_rigidbody.velocity = new Vector3(newManeuver, 0.0f, _currentSpeed);
|
||||
_rigidbody.position = new Vector3
|
||||
(
|
||||
Mathf.Clamp(_rigidbody.position.x, Boundary.xMin, Boundary.xMax),
|
||||
0.0f,
|
||||
Mathf.Clamp(_rigidbody.position.z, Boundary.zMin, Boundary.zMax)
|
||||
);
|
||||
|
||||
float tilt = 10f;
|
||||
_rigidbody.rotation = Quaternion.Euler(0, 0, _rigidbody.velocity.x * -tilt);
|
||||
}
|
||||
void OnTriggerEnter(Collider other)
|
||||
{
|
||||
var name = other.gameObject.name;
|
||||
if (name.StartsWith("player"))
|
||||
{
|
||||
GameEvent.Send(ActorEventDefine.EnemyDead,this.transform.position, this.transform.rotation);
|
||||
_handle.Restore();
|
||||
_handle = null;
|
||||
}
|
||||
}
|
||||
void OnTriggerExit(Collider other)
|
||||
{
|
||||
var name = other.gameObject.name;
|
||||
if (name.StartsWith("Boundary"))
|
||||
{
|
||||
_handle.Restore();
|
||||
_handle = null;
|
||||
}
|
||||
}
|
||||
|
||||
IEnumerator Evade()
|
||||
{
|
||||
yield return new WaitForSeconds(Random.Range(StartWait.x, StartWait.y));
|
||||
while (true)
|
||||
{
|
||||
_targetManeuver = Random.Range(1, Dodge) * -Mathf.Sign(transform.position.x);
|
||||
yield return new WaitForSeconds(Random.Range(ManeuverTime.x, ManeuverTime.y));
|
||||
_targetManeuver = 0;
|
||||
yield return new WaitForSeconds(Random.Range(ManeuverWait.x, ManeuverWait.y));
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a613426c4968b3149b8bf9bf88fe41c7
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,65 @@
|
||||
using GameLogic;
|
||||
using TEngine;
|
||||
using UnityEngine;
|
||||
using UniFramework.Pooling;
|
||||
|
||||
public class EntityPlayer : MonoBehaviour
|
||||
{
|
||||
public RoomBoundary Boundary;
|
||||
public float MoveSpeed = 10f;
|
||||
public float FireRate = 0.25f;
|
||||
|
||||
private SpawnHandle _handle;
|
||||
private float _nextFireTime = 0f;
|
||||
private Transform _shotSpawn;
|
||||
private Rigidbody _rigidbody;
|
||||
private AudioSource _audioSource;
|
||||
|
||||
public void InitEntity(SpawnHandle handle)
|
||||
{
|
||||
_handle = handle;
|
||||
}
|
||||
|
||||
void Awake()
|
||||
{
|
||||
_rigidbody = this.gameObject.GetComponent<Rigidbody>();
|
||||
_audioSource = this.gameObject.GetComponent<AudioSource>();
|
||||
_shotSpawn = this.transform.Find("shot_spawn");
|
||||
}
|
||||
void Update()
|
||||
{
|
||||
if (Input.GetButton("Fire1") && Time.time > _nextFireTime)
|
||||
{
|
||||
_nextFireTime = Time.time + FireRate;
|
||||
_audioSource.Play();
|
||||
GameEvent.Send(ActorEventDefine.PlayerFireBullet,_shotSpawn.position, _shotSpawn.rotation);
|
||||
}
|
||||
}
|
||||
void FixedUpdate()
|
||||
{
|
||||
float moveHorizontal = Input.GetAxis("Horizontal");
|
||||
float moveVertical = Input.GetAxis("Vertical");
|
||||
|
||||
Vector3 movement = new Vector3(moveHorizontal, 0.0f, moveVertical);
|
||||
_rigidbody.velocity = movement * MoveSpeed;
|
||||
_rigidbody.position = new Vector3
|
||||
(
|
||||
Mathf.Clamp(GetComponent<Rigidbody>().position.x, Boundary.xMin, Boundary.xMax),
|
||||
0.0f,
|
||||
Mathf.Clamp(GetComponent<Rigidbody>().position.z, Boundary.zMin, Boundary.zMax)
|
||||
);
|
||||
|
||||
float tilt = 5f;
|
||||
_rigidbody.rotation = Quaternion.Euler(0.0f, 0.0f, _rigidbody.velocity.x * -tilt);
|
||||
}
|
||||
void OnTriggerEnter(Collider other)
|
||||
{
|
||||
var name = other.gameObject.name;
|
||||
if (name.StartsWith("enemy") || name.StartsWith("asteroid"))
|
||||
{
|
||||
GameEvent.Send(ActorEventDefine.PlayerDead,transform.position, transform.rotation);
|
||||
_handle.Restore();
|
||||
_handle = null;
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d3933af4e188ec44683e3c52784eadb0
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,10 @@
|
||||
using System;
|
||||
|
||||
namespace GameLogic
|
||||
{
|
||||
[Serializable]
|
||||
public class RoomBoundary
|
||||
{
|
||||
public float xMin, xMax, zMin, zMax;
|
||||
}
|
||||
}
|
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 871ee1492e44425da07021fdc3100325
|
||||
timeCreated: 1683946064
|
239
Assets/GameScripts/HotFix/GameLogic/Demo/BattleSystem.cs
Normal file
239
Assets/GameScripts/HotFix/GameLogic/Demo/BattleSystem.cs
Normal file
@@ -0,0 +1,239 @@
|
||||
using System.Collections;
|
||||
using GameLogic;
|
||||
using TEngine;
|
||||
using UnityEngine;
|
||||
using UniFramework.Pooling;
|
||||
using UniFramework.Utility;
|
||||
using AudioType = TEngine.AudioType;
|
||||
using Object = UnityEngine.Object;
|
||||
using Random = UnityEngine.Random;
|
||||
|
||||
/// <summary>
|
||||
/// 战斗房间
|
||||
/// </summary>
|
||||
public class BattleRoom
|
||||
{
|
||||
private enum ESteps
|
||||
{
|
||||
None,
|
||||
Ready,
|
||||
Spawn,
|
||||
WaitSpawn,
|
||||
WaitWave,
|
||||
GameOver,
|
||||
}
|
||||
|
||||
private Spawner _entitySpawner;
|
||||
private GameObject _roomRoot;
|
||||
|
||||
// 关卡参数
|
||||
private const int EnemyCount = 10;
|
||||
private const int EnemyScore = 10;
|
||||
private const int AsteroidScore = 1;
|
||||
private readonly Vector3 _spawnValues = new Vector3(6, 0, 20);
|
||||
private readonly string[] _entityLocations = new string[]
|
||||
{
|
||||
"asteroid01", "asteroid02", "asteroid03", "enemy_ship"
|
||||
};
|
||||
|
||||
private ESteps _steps = ESteps.None;
|
||||
private int _totalScore = 0;
|
||||
private int _waveSpawnCount = 0;
|
||||
|
||||
private UniTimer _startWaitTimer = UniTimer.CreateOnceTimer(1f);
|
||||
private UniTimer _spawnWaitTimer = UniTimer.CreateOnceTimer(0.75f);
|
||||
private UniTimer _waveWaitTimer = UniTimer.CreateOnceTimer(4f);
|
||||
|
||||
public BattleRoom()
|
||||
{
|
||||
Utility.Unity.AddUpdateListener(UpdateRoom);
|
||||
}
|
||||
|
||||
~BattleRoom()
|
||||
{
|
||||
Utility.Unity.RemoveUpdateListener(UpdateRoom);
|
||||
DestroyRoom();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 销毁房间
|
||||
/// </summary>
|
||||
public void DestroyRoom()
|
||||
{
|
||||
// 加载背景音乐
|
||||
GameModule.Audio.Stop(AudioType.Music, true);
|
||||
|
||||
if (_entitySpawner != null)
|
||||
_entitySpawner.DestroyAll(true);
|
||||
|
||||
if (_roomRoot != null)
|
||||
Object.Destroy(_roomRoot);
|
||||
|
||||
GameModule.UI.CloseWindow<UIBattleWindow>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 更新房间
|
||||
/// </summary>
|
||||
public void UpdateRoom()
|
||||
{
|
||||
if (_steps == ESteps.None || _steps == ESteps.GameOver)
|
||||
return;
|
||||
|
||||
if (_steps == ESteps.Ready)
|
||||
{
|
||||
if (_startWaitTimer.Update(Time.deltaTime))
|
||||
{
|
||||
_steps = ESteps.Spawn;
|
||||
}
|
||||
}
|
||||
|
||||
if (_steps == ESteps.Spawn)
|
||||
{
|
||||
var enemyLocation = _entityLocations[Random.Range(0, 4)];
|
||||
Vector3 spawnPosition = new Vector3(Random.Range(-_spawnValues.x, _spawnValues.x), _spawnValues.y, _spawnValues.z);
|
||||
Quaternion spawnRotation = Quaternion.identity;
|
||||
|
||||
if (enemyLocation == "enemy_ship")
|
||||
{
|
||||
// 生成敌人实体
|
||||
var handle = _entitySpawner.SpawnSync(enemyLocation, _roomRoot.transform, spawnPosition, spawnRotation);
|
||||
var entity = handle.GameObj.GetComponent<EntityEnemy>();
|
||||
entity.InitEntity(handle);
|
||||
}
|
||||
else
|
||||
{
|
||||
// 生成小行星实体
|
||||
var handle = _entitySpawner.SpawnSync(enemyLocation, _roomRoot.transform, spawnPosition, spawnRotation);
|
||||
var entity = handle.GameObj.GetComponent<EntityAsteroid>();
|
||||
entity.InitEntity(handle);
|
||||
}
|
||||
|
||||
_waveSpawnCount++;
|
||||
if (_waveSpawnCount >= EnemyCount)
|
||||
{
|
||||
_steps = ESteps.WaitWave;
|
||||
}
|
||||
else
|
||||
{
|
||||
_steps = ESteps.WaitSpawn;
|
||||
}
|
||||
}
|
||||
|
||||
if (_steps == ESteps.WaitSpawn)
|
||||
{
|
||||
if (_spawnWaitTimer.Update(Time.deltaTime))
|
||||
{
|
||||
_spawnWaitTimer.Reset();
|
||||
_steps = ESteps.Spawn;
|
||||
}
|
||||
}
|
||||
|
||||
if (_steps == ESteps.WaitWave)
|
||||
{
|
||||
if (_waveWaitTimer.Update(Time.deltaTime))
|
||||
{
|
||||
_waveWaitTimer.Reset();
|
||||
_waveSpawnCount = 0;
|
||||
_steps = ESteps.Spawn;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 加载房间
|
||||
/// </summary>
|
||||
public IEnumerator LoadRoom()
|
||||
{
|
||||
// 创建房间根对象
|
||||
_roomRoot = new GameObject("BattleRoom");
|
||||
|
||||
// 加载背景音乐
|
||||
GameModule.Audio.Play(AudioType.Music, "music_background", true);
|
||||
|
||||
// 创建游戏对象发生器
|
||||
_entitySpawner = UniPooling.CreateSpawner("DefaultPackage");
|
||||
|
||||
// 创建游戏对象池
|
||||
yield return _entitySpawner.CreateGameObjectPoolAsync("player_ship");
|
||||
yield return _entitySpawner.CreateGameObjectPoolAsync("player_bullet");
|
||||
yield return _entitySpawner.CreateGameObjectPoolAsync("enemy_ship");
|
||||
yield return _entitySpawner.CreateGameObjectPoolAsync("enemy_bullet");
|
||||
yield return _entitySpawner.CreateGameObjectPoolAsync("asteroid01");
|
||||
yield return _entitySpawner.CreateGameObjectPoolAsync("asteroid02");
|
||||
yield return _entitySpawner.CreateGameObjectPoolAsync("asteroid03");
|
||||
yield return _entitySpawner.CreateGameObjectPoolAsync("explosion_asteroid");
|
||||
yield return _entitySpawner.CreateGameObjectPoolAsync("explosion_enemy");
|
||||
yield return _entitySpawner.CreateGameObjectPoolAsync("explosion_player");
|
||||
|
||||
// 创建玩家实体对象
|
||||
var handle = _entitySpawner.SpawnSync("player_ship", _roomRoot.transform);
|
||||
var entity = handle.GameObj.GetComponent<EntityPlayer>();
|
||||
entity.InitEntity(handle);
|
||||
|
||||
// 显示战斗界面
|
||||
yield return GameModule.UI.ShowUIAsync<UIBattleWindow>();
|
||||
|
||||
// 监听游戏事件
|
||||
GameEvent.AddEventListener<Vector3,Quaternion>(ActorEventDefine.PlayerDead,OnPlayerDead);
|
||||
GameEvent.AddEventListener<Vector3,Quaternion>(ActorEventDefine.EnemyDead,OnEnemyDead);
|
||||
GameEvent.AddEventListener<Vector3,Quaternion>(ActorEventDefine.AsteroidExplosion,OnAsteroidExplosion);
|
||||
GameEvent.AddEventListener<Vector3,Quaternion>(ActorEventDefine.PlayerFireBullet,OnPlayerFireBullet);
|
||||
GameEvent.AddEventListener<Vector3,Quaternion>(ActorEventDefine.EnemyFireBullet,OnEnemyFireBullet);
|
||||
|
||||
_steps = ESteps.Ready;
|
||||
}
|
||||
|
||||
#region 接收事件
|
||||
|
||||
private void OnPlayerDead(Vector3 position,Quaternion rotation)
|
||||
{
|
||||
// 创建爆炸效果
|
||||
var handle = _entitySpawner.SpawnSync("explosion_player", _roomRoot.transform, position, rotation);
|
||||
var entity = handle.GameObj.GetComponent<EntityEffect>();
|
||||
entity.InitEntity(handle);
|
||||
|
||||
_steps = ESteps.GameOver;
|
||||
GameEvent.Send(ActorEventDefine.GameOver);
|
||||
}
|
||||
|
||||
private void OnEnemyDead(Vector3 position,Quaternion rotation)
|
||||
{
|
||||
// 创建爆炸效果
|
||||
var handle = _entitySpawner.SpawnSync("explosion_enemy", _roomRoot.transform, position, rotation);
|
||||
var entity = handle.GameObj.GetComponent<EntityEffect>();
|
||||
entity.InitEntity(handle);
|
||||
|
||||
_totalScore += EnemyScore;
|
||||
GameEvent.Send(ActorEventDefine.ScoreChange,_totalScore);
|
||||
}
|
||||
|
||||
private void OnAsteroidExplosion(Vector3 position,Quaternion rotation)
|
||||
{
|
||||
// 创建爆炸效果
|
||||
var handle = _entitySpawner.SpawnSync("explosion_asteroid", _roomRoot.transform, position, rotation);
|
||||
var entity = handle.GameObj.GetComponent<EntityEffect>();
|
||||
entity.InitEntity(handle);
|
||||
|
||||
_totalScore += AsteroidScore;
|
||||
GameEvent.Send(ActorEventDefine.ScoreChange,_totalScore);
|
||||
}
|
||||
|
||||
private void OnPlayerFireBullet(Vector3 position,Quaternion rotation)
|
||||
{
|
||||
// 创建子弹实体
|
||||
var handle = _entitySpawner.SpawnSync("player_bullet", _roomRoot.transform, position, rotation);
|
||||
var entity = handle.GameObj.GetComponent<EntityBullet>();
|
||||
entity.InitEntity(handle);
|
||||
}
|
||||
|
||||
private void OnEnemyFireBullet(Vector3 position,Quaternion rotation)
|
||||
{
|
||||
// 创建子弹实体
|
||||
var handle = _entitySpawner.SpawnSync("enemy_bullet", _roomRoot.transform,position,rotation);
|
||||
var entity = handle.GameObj.GetComponent<EntityBullet>();
|
||||
entity.InitEntity(handle);
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f4289f2d6df7432ca3f04870400571df
|
||||
timeCreated: 1683946643
|
8
Assets/GameScripts/HotFix/GameLogic/Demo/Behaviour.meta
Normal file
8
Assets/GameScripts/HotFix/GameLogic/Demo/Behaviour.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 41a3231c52df1c14baa2d77e6d3a3b0e
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,15 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
using YooAsset;
|
||||
|
||||
public class BhvApplicationQuit : MonoBehaviour
|
||||
{
|
||||
private void Awake()
|
||||
{
|
||||
DontDestroyOnLoad(this.gameObject);
|
||||
}
|
||||
private void OnApplicationQuit()
|
||||
{
|
||||
YooAssets.Destroy();
|
||||
}
|
||||
}
|
@@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3cbcea01819f3d94ba5162624ad9c75f
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,21 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
public class BhvBackgroundScroller : MonoBehaviour
|
||||
{
|
||||
public float ScrollSpeed;
|
||||
public float TileSizeZ;
|
||||
|
||||
private Vector3 _startPosition;
|
||||
|
||||
void Start ()
|
||||
{
|
||||
_startPosition = transform.position;
|
||||
}
|
||||
|
||||
void Update ()
|
||||
{
|
||||
float newPosition = Mathf.Repeat(Time.time * ScrollSpeed, TileSizeZ);
|
||||
this.transform.position = _startPosition + Vector3.forward * newPosition;
|
||||
}
|
||||
}
|
@@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 814f6a7e3ec8a40aaa3a2057e2695924
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
3
Assets/GameScripts/HotFix/GameLogic/Demo/UI.meta
Normal file
3
Assets/GameScripts/HotFix/GameLogic/Demo/UI.meta
Normal file
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5119c9cc1ae24e3e8272dc88a33b8ede
|
||||
timeCreated: 1683947325
|
@@ -0,0 +1,79 @@
|
||||
using Cysharp.Threading.Tasks;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
using TEngine;
|
||||
|
||||
namespace GameLogic
|
||||
{
|
||||
[Window(UILayer.UI)]
|
||||
class UIBattleWindow : UIWindow
|
||||
{
|
||||
#region 脚本工具生成的代码
|
||||
|
||||
private Text m_textScore;
|
||||
private GameObject m_goOverView;
|
||||
private Button m_btnRestart;
|
||||
private Button m_btnHome;
|
||||
|
||||
public override void ScriptGenerator()
|
||||
{
|
||||
m_textScore = FindChildComponent<Text>("ScoreView/m_textScore");
|
||||
m_goOverView = FindChild("m_goOverView").gameObject;
|
||||
m_btnRestart = FindChildComponent<Button>("m_goOverView/m_btnRestart");
|
||||
m_btnHome = FindChildComponent<Button>("m_goOverView/m_btnHome");
|
||||
m_btnRestart.onClick.AddListener(UniTask.UnityAction(OnClickRestartBtn));
|
||||
m_btnHome.onClick.AddListener(UniTask.UnityAction(OnClickHomeBtn));
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
public override void RegisterEvent()
|
||||
{
|
||||
AddUIEvent<int>(ActorEventDefine.ScoreChange, OnScoreChange);
|
||||
AddUIEvent(ActorEventDefine.GameOver, OnGameOver);
|
||||
}
|
||||
|
||||
public override void OnRefresh()
|
||||
{
|
||||
m_goOverView.SetActive(false);
|
||||
}
|
||||
|
||||
#region 事件
|
||||
|
||||
private async UniTaskVoid OnClickRestartBtn()
|
||||
{
|
||||
await UniTask.Yield();
|
||||
// yield return YooAssets.LoadSceneAsync("scene_battle");
|
||||
//
|
||||
// _battleRoom = new BattleRoom();
|
||||
// yield return _battleRoom.LoadRoom();
|
||||
//
|
||||
// // 释放资源
|
||||
// var package = YooAssets.GetPackage("DefaultPackage");
|
||||
// package.UnloadUnusedAssets();
|
||||
}
|
||||
|
||||
private async UniTaskVoid OnClickHomeBtn()
|
||||
{
|
||||
await UniTask.Yield();
|
||||
// yield return YooAssets.LoadSceneAsync("scene_home");
|
||||
// yield return UniWindow.OpenWindowAsync<UIHomeWindow>("UIHome");
|
||||
//
|
||||
// // 释放资源
|
||||
// var package = YooAssets.GetPackage("DefaultPackage");
|
||||
// package.UnloadUnusedAssets();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private void OnScoreChange(int currentScores)
|
||||
{
|
||||
m_textScore.text = $"Score : {currentScores}";
|
||||
}
|
||||
|
||||
private void OnGameOver()
|
||||
{
|
||||
m_goOverView.SetActive(true);
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 15d6c65ac046403185b3dd833e6e2a7e
|
||||
timeCreated: 1683947329
|
8
Assets/GameScripts/HotFix/GameLogic/Demo/Uni.meta
Normal file
8
Assets/GameScripts/HotFix/GameLogic/Demo/Uni.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 22e854424b81c9d49b36e6aa8b1cc9ba
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
36
Assets/GameScripts/HotFix/GameLogic/Demo/Uni/README.md
Normal file
36
Assets/GameScripts/HotFix/GameLogic/Demo/Uni/README.md
Normal file
@@ -0,0 +1,36 @@
|
||||
# UniFramework.Pooling
|
||||
|
||||
一个功能强大的游戏对象池系统。
|
||||
|
||||
该系统依赖于YooAsset资源系统,支持各类异步编程,支持同步接口和异步接口。
|
||||
|
||||
```c#
|
||||
using UnityEngine;
|
||||
using YooAsset;
|
||||
using UniFramework.Pooling;
|
||||
|
||||
IEnumerator Start()
|
||||
{
|
||||
// 初始化游戏对象池系统
|
||||
UniPooling.Initalize();
|
||||
|
||||
// 创建孵化器
|
||||
var spawner = UniPooling.CreateSpawner("DefaultPackage");
|
||||
|
||||
// 创建Cube预制体的对象池
|
||||
var operation = spawner.CreateGameObjectPoolAsync("Cube.prefab");
|
||||
yield return operation;
|
||||
|
||||
// 孵化Cube游戏对象
|
||||
SpawnHandle handle = spawner.SpawnAsync("Cube.prefab");
|
||||
yield return handle;
|
||||
Debug.Log(handle.GameObj.name);
|
||||
|
||||
// 回收游戏对象
|
||||
handle.Restore();
|
||||
|
||||
// 丢弃游戏对象
|
||||
handle.Discard();
|
||||
}
|
||||
```
|
||||
|
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7976cbcaa4dcfcc4b932fb01d6c0499a
|
||||
TextScriptImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5904699460a22064182a5cf9129fc09e
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,70 @@
|
||||
using YooAsset;
|
||||
|
||||
namespace UniFramework.Pooling
|
||||
{
|
||||
public class CreatePoolOperation : GameAsyncOperation
|
||||
{
|
||||
private enum ESteps
|
||||
{
|
||||
None,
|
||||
Waiting,
|
||||
Done,
|
||||
}
|
||||
|
||||
private readonly AssetOperationHandle _handle;
|
||||
private ESteps _steps = ESteps.None;
|
||||
|
||||
internal CreatePoolOperation(AssetOperationHandle handle)
|
||||
{
|
||||
_handle = handle;
|
||||
}
|
||||
protected override void OnStart()
|
||||
{
|
||||
_steps = ESteps.Waiting;
|
||||
}
|
||||
protected override void OnUpdate()
|
||||
{
|
||||
if (_steps == ESteps.None || _steps == ESteps.Done)
|
||||
return;
|
||||
|
||||
if (_steps == ESteps.Waiting)
|
||||
{
|
||||
if (_handle.IsValid == false)
|
||||
{
|
||||
_steps = ESteps.Done;
|
||||
Status = EOperationStatus.Failed;
|
||||
Error = $"{nameof(AssetOperationHandle)} is invalid.";
|
||||
return;
|
||||
}
|
||||
|
||||
if (_handle.IsDone == false)
|
||||
return;
|
||||
|
||||
if (_handle.AssetObject == null)
|
||||
{
|
||||
_steps = ESteps.Done;
|
||||
Status = EOperationStatus.Failed;
|
||||
Error = $"{nameof(AssetOperationHandle.AssetObject)} is null.";
|
||||
return;
|
||||
}
|
||||
|
||||
_steps = ESteps.Done;
|
||||
Status = EOperationStatus.Succeed;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 等待异步实例化结束
|
||||
/// </summary>
|
||||
public void WaitForAsyncComplete()
|
||||
{
|
||||
if (_handle != null)
|
||||
{
|
||||
if (_steps == ESteps.Done)
|
||||
return;
|
||||
_handle.WaitForAsyncComplete();
|
||||
OnUpdate();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a5687620a17f42e4085a0e2243be7561
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,215 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using YooAsset;
|
||||
|
||||
namespace UniFramework.Pooling
|
||||
{
|
||||
internal class GameObjectPool
|
||||
{
|
||||
private readonly Transform _poolRoot;
|
||||
private readonly Queue<InstantiateOperation> _cacheOperations;
|
||||
private readonly bool _dontDestroy;
|
||||
private readonly int _initCapacity;
|
||||
private readonly int _maxCapacity;
|
||||
private readonly float _destroyTime;
|
||||
private float _lastRestoreRealTime = -1f;
|
||||
|
||||
/// <summary>
|
||||
/// 资源句柄
|
||||
/// </summary>
|
||||
public AssetOperationHandle AssetHandle { private set; get; }
|
||||
|
||||
/// <summary>
|
||||
/// 资源定位地址
|
||||
/// </summary>
|
||||
public string Location { private set; get; }
|
||||
|
||||
/// <summary>
|
||||
/// 内部缓存总数
|
||||
/// </summary>
|
||||
public int CacheCount
|
||||
{
|
||||
get { return _cacheOperations.Count; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 外部使用总数
|
||||
/// </summary>
|
||||
public int SpawnCount { private set; get; } = 0;
|
||||
|
||||
/// <summary>
|
||||
/// 是否常驻不销毁
|
||||
/// </summary>
|
||||
public bool DontDestroy
|
||||
{
|
||||
get { return _dontDestroy; }
|
||||
}
|
||||
|
||||
|
||||
public GameObjectPool(GameObject poolRoot, string location, bool dontDestroy, int initCapacity, int maxCapacity, float destroyTime)
|
||||
{
|
||||
_poolRoot = poolRoot.transform;
|
||||
Location = location;
|
||||
|
||||
_dontDestroy = dontDestroy;
|
||||
_initCapacity = initCapacity;
|
||||
_maxCapacity = maxCapacity;
|
||||
_destroyTime = destroyTime;
|
||||
|
||||
// 创建缓存池
|
||||
_cacheOperations = new Queue<InstantiateOperation>(initCapacity);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 创建对象池
|
||||
/// </summary>
|
||||
public void CreatePool(ResourcePackage package)
|
||||
{
|
||||
// 加载游戏对象
|
||||
AssetHandle = package.LoadAssetAsync<GameObject>(Location);
|
||||
|
||||
// 创建初始对象
|
||||
for (int i = 0; i < _initCapacity; i++)
|
||||
{
|
||||
var operation = AssetHandle.InstantiateAsync(_poolRoot);
|
||||
_cacheOperations.Enqueue(operation);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 销毁游戏对象池
|
||||
/// </summary>
|
||||
public void DestroyPool()
|
||||
{
|
||||
// 卸载资源对象
|
||||
AssetHandle.Release();
|
||||
AssetHandle = null;
|
||||
|
||||
// 销毁游戏对象
|
||||
foreach (var operation in _cacheOperations)
|
||||
{
|
||||
if (operation.Result != null)
|
||||
GameObject.Destroy(operation.Result);
|
||||
}
|
||||
_cacheOperations.Clear();
|
||||
|
||||
SpawnCount = 0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查询静默时间内是否可以销毁
|
||||
/// </summary>
|
||||
public bool CanAutoDestroy()
|
||||
{
|
||||
if (_dontDestroy)
|
||||
return false;
|
||||
if (_destroyTime < 0)
|
||||
return false;
|
||||
|
||||
if (_lastRestoreRealTime > 0 && SpawnCount <= 0)
|
||||
return (Time.realtimeSinceStartup - _lastRestoreRealTime) > _destroyTime;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 游戏对象池是否已经销毁
|
||||
/// </summary>
|
||||
public bool IsDestroyed()
|
||||
{
|
||||
return AssetHandle == null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 回收
|
||||
/// </summary>
|
||||
public void Restore(InstantiateOperation operation)
|
||||
{
|
||||
if (IsDestroyed())
|
||||
{
|
||||
DestroyInstantiateOperation(operation);
|
||||
return;
|
||||
}
|
||||
|
||||
SpawnCount--;
|
||||
if (SpawnCount <= 0)
|
||||
_lastRestoreRealTime = Time.realtimeSinceStartup;
|
||||
|
||||
// 如果外部逻辑销毁了游戏对象
|
||||
if (operation.Status == EOperationStatus.Succeed)
|
||||
{
|
||||
if (operation.Result == null)
|
||||
return;
|
||||
}
|
||||
|
||||
// 如果缓存池还未满员
|
||||
if (_cacheOperations.Count < _maxCapacity)
|
||||
{
|
||||
SetRestoreGameObject(operation.Result);
|
||||
_cacheOperations.Enqueue(operation);
|
||||
}
|
||||
else
|
||||
{
|
||||
DestroyInstantiateOperation(operation);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 丢弃
|
||||
/// </summary>
|
||||
public void Discard(InstantiateOperation operation)
|
||||
{
|
||||
if (IsDestroyed())
|
||||
{
|
||||
DestroyInstantiateOperation(operation);
|
||||
return;
|
||||
}
|
||||
|
||||
SpawnCount--;
|
||||
if (SpawnCount <= 0)
|
||||
_lastRestoreRealTime = Time.realtimeSinceStartup;
|
||||
|
||||
DestroyInstantiateOperation(operation);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取一个游戏对象
|
||||
/// </summary>
|
||||
public SpawnHandle Spawn(Transform parent, Vector3 position, Quaternion rotation, bool forceClone, params System.Object[] userDatas)
|
||||
{
|
||||
InstantiateOperation operation;
|
||||
if (forceClone == false && _cacheOperations.Count > 0)
|
||||
operation = _cacheOperations.Dequeue();
|
||||
else
|
||||
operation = AssetHandle.InstantiateAsync();
|
||||
|
||||
SpawnCount++;
|
||||
SpawnHandle handle = new SpawnHandle(this, operation, parent, position, rotation, userDatas);
|
||||
YooAssets.StartOperation(handle);
|
||||
return handle;
|
||||
}
|
||||
|
||||
private void DestroyInstantiateOperation(InstantiateOperation operation)
|
||||
{
|
||||
// 取消异步操作
|
||||
operation.Cancel();
|
||||
|
||||
// 销毁游戏对象
|
||||
if (operation.Result != null)
|
||||
{
|
||||
GameObject.Destroy(operation.Result);
|
||||
}
|
||||
}
|
||||
private void SetRestoreGameObject(GameObject gameObj)
|
||||
{
|
||||
if (gameObj != null)
|
||||
{
|
||||
gameObj.SetActive(false);
|
||||
gameObj.transform.SetParent(_poolRoot);
|
||||
gameObj.transform.SetPositionAndRotation(Vector3.zero, Quaternion.identity);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1dd976626eb4ca645b4ec80921f4e8fd
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,148 @@
|
||||
using UnityEngine;
|
||||
using YooAsset;
|
||||
|
||||
namespace UniFramework.Pooling
|
||||
{
|
||||
public sealed class SpawnHandle : GameAsyncOperation
|
||||
{
|
||||
private enum ESteps
|
||||
{
|
||||
None,
|
||||
Waiting,
|
||||
Done,
|
||||
}
|
||||
|
||||
private readonly GameObjectPool _pool;
|
||||
private InstantiateOperation _operation;
|
||||
private readonly Transform _parent;
|
||||
private readonly Vector3 _position;
|
||||
private readonly Quaternion _rotation;
|
||||
private ESteps _steps = ESteps.None;
|
||||
|
||||
/// <summary>
|
||||
/// 实例化的游戏对象
|
||||
/// </summary>
|
||||
public GameObject GameObj
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_operation == null)
|
||||
{
|
||||
UniLogger.Warning("The spawn handle is invalid !");
|
||||
return null;
|
||||
}
|
||||
|
||||
return _operation.Result;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 用户自定义数据集
|
||||
/// </summary>
|
||||
public System.Object[] UserDatas { private set; get; }
|
||||
|
||||
private SpawnHandle()
|
||||
{
|
||||
}
|
||||
internal SpawnHandle(GameObjectPool pool, InstantiateOperation operation, Transform parent, Vector3 position, Quaternion rotation, params System.Object[] userDatas)
|
||||
{
|
||||
_pool = pool;
|
||||
_operation = operation;
|
||||
_parent = parent;
|
||||
_position = position;
|
||||
_rotation = rotation;
|
||||
UserDatas = userDatas;
|
||||
}
|
||||
protected override void OnStart()
|
||||
{
|
||||
_steps = ESteps.Waiting;
|
||||
}
|
||||
protected override void OnUpdate()
|
||||
{
|
||||
if (_steps == ESteps.None || _steps == ESteps.Done)
|
||||
return;
|
||||
|
||||
if (_steps == ESteps.Waiting)
|
||||
{
|
||||
if (_operation.IsDone == false)
|
||||
return;
|
||||
|
||||
if (_operation.Status != EOperationStatus.Succeed)
|
||||
{
|
||||
_steps = ESteps.Done;
|
||||
Status = EOperationStatus.Failed;
|
||||
Error = _operation.Error;
|
||||
return;
|
||||
}
|
||||
|
||||
if (_operation.Result == null)
|
||||
{
|
||||
_steps = ESteps.Done;
|
||||
Status = EOperationStatus.Failed;
|
||||
Error = $"Clone game object is null.";
|
||||
return;
|
||||
}
|
||||
|
||||
// 设置参数
|
||||
_operation.Result.transform.SetParent(_parent);
|
||||
_operation.Result.transform.SetPositionAndRotation(_position, _rotation);
|
||||
_operation.Result.SetActive(true);
|
||||
|
||||
_steps = ESteps.Done;
|
||||
Status = EOperationStatus.Succeed;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 回收
|
||||
/// </summary>
|
||||
public void Restore()
|
||||
{
|
||||
if (_operation != null)
|
||||
{
|
||||
ClearCompletedCallback();
|
||||
CancelHandle();
|
||||
_pool.Restore(_operation);
|
||||
_operation = null;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 丢弃
|
||||
/// </summary>
|
||||
public void Discard()
|
||||
{
|
||||
if (_operation != null)
|
||||
{
|
||||
ClearCompletedCallback();
|
||||
CancelHandle();
|
||||
_pool.Discard(_operation);
|
||||
_operation = null;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 等待异步实例化结束
|
||||
/// </summary>
|
||||
public void WaitForAsyncComplete()
|
||||
{
|
||||
if (_operation != null)
|
||||
{
|
||||
if (_steps == ESteps.Done)
|
||||
return;
|
||||
_operation.WaitForAsyncComplete();
|
||||
OnUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
private void CancelHandle()
|
||||
{
|
||||
if (IsDone == false)
|
||||
{
|
||||
_steps = ESteps.Done;
|
||||
Status = EOperationStatus.Failed;
|
||||
Error = $"User cancelled !";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6350d2984a149b349b9cec658d21b12a
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
259
Assets/GameScripts/HotFix/GameLogic/Demo/Uni/Runtime/Spawner.cs
Normal file
259
Assets/GameScripts/HotFix/GameLogic/Demo/Uni/Runtime/Spawner.cs
Normal file
@@ -0,0 +1,259 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using YooAsset;
|
||||
|
||||
namespace UniFramework.Pooling
|
||||
{
|
||||
public class Spawner
|
||||
{
|
||||
private readonly List<GameObjectPool> _gameObjectPools = new List<GameObjectPool>(100);
|
||||
private readonly List<GameObjectPool> _removeList = new List<GameObjectPool>(100);
|
||||
private readonly GameObject _spawnerRoot;
|
||||
private readonly ResourcePackage _package;
|
||||
|
||||
public string PackageName
|
||||
{
|
||||
get
|
||||
{
|
||||
return _package.PackageName;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private Spawner()
|
||||
{
|
||||
}
|
||||
internal Spawner(GameObject poolingRoot, ResourcePackage package)
|
||||
{
|
||||
_spawnerRoot = new GameObject($"{package.PackageName}");
|
||||
_spawnerRoot.transform.SetParent(poolingRoot.transform);
|
||||
_package = package;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 更新游戏对象池系统
|
||||
/// </summary>
|
||||
internal void Update()
|
||||
{
|
||||
_removeList.Clear();
|
||||
foreach (var pool in _gameObjectPools)
|
||||
{
|
||||
if (pool.CanAutoDestroy())
|
||||
_removeList.Add(pool);
|
||||
}
|
||||
|
||||
foreach (var pool in _removeList)
|
||||
{
|
||||
_gameObjectPools.Remove(pool);
|
||||
pool.DestroyPool();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 销毁游戏对象池系统
|
||||
/// </summary>
|
||||
internal void Destroy()
|
||||
{
|
||||
DestroyAll(true);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 销毁所有对象池及其资源
|
||||
/// </summary>
|
||||
/// <param name="includeAll">销毁所有对象池,包括常驻对象池</param>
|
||||
public void DestroyAll(bool includeAll)
|
||||
{
|
||||
if (includeAll)
|
||||
{
|
||||
foreach (var pool in _gameObjectPools)
|
||||
{
|
||||
pool.DestroyPool();
|
||||
}
|
||||
_gameObjectPools.Clear();
|
||||
}
|
||||
else
|
||||
{
|
||||
List<GameObjectPool> removeList = new List<GameObjectPool>();
|
||||
foreach (var pool in _gameObjectPools)
|
||||
{
|
||||
if (pool.DontDestroy == false)
|
||||
removeList.Add(pool);
|
||||
}
|
||||
foreach (var pool in removeList)
|
||||
{
|
||||
_gameObjectPools.Remove(pool);
|
||||
pool.DestroyPool();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 异步创建指定资源的游戏对象池
|
||||
/// </summary>
|
||||
/// <param name="location">资源定位地址</param>
|
||||
/// <param name="dontDestroy">资源常驻不销毁</param>
|
||||
/// <param name="initCapacity">对象池的初始容量</param>
|
||||
/// <param name="maxCapacity">对象池的最大容量</param>
|
||||
/// <param name="destroyTime">静默销毁时间(注意:小于零代表不主动销毁)</param>
|
||||
public CreatePoolOperation CreateGameObjectPoolAsync(string location, bool dontDestroy = false, int initCapacity = 0, int maxCapacity = int.MaxValue, float destroyTime = -1f)
|
||||
{
|
||||
return CreateGameObjectPoolInternal(location, dontDestroy, initCapacity, maxCapacity, destroyTime);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 同步创建指定资源的游戏对象池
|
||||
/// </summary>
|
||||
/// <param name="location">资源定位地址</param>
|
||||
/// <param name="dontDestroy">资源常驻不销毁</param>
|
||||
/// <param name="initCapacity">对象池的初始容量</param>
|
||||
/// <param name="maxCapacity">对象池的最大容量</param>
|
||||
/// <param name="destroyTime">静默销毁时间(注意:小于零代表不主动销毁)</param>
|
||||
public CreatePoolOperation CreateGameObjectPoolSync(string location, bool dontDestroy = false, int initCapacity = 0, int maxCapacity = int.MaxValue, float destroyTime = -1f)
|
||||
{
|
||||
var operation = CreateGameObjectPoolInternal(location, dontDestroy, initCapacity, maxCapacity, destroyTime);
|
||||
operation.WaitForAsyncComplete();
|
||||
return operation;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 创建指定资源的游戏对象池
|
||||
/// </summary>
|
||||
private CreatePoolOperation CreateGameObjectPoolInternal(string location, bool dontDestroy = false, int initCapacity = 0, int maxCapacity = int.MaxValue, float destroyTime = -1f)
|
||||
{
|
||||
if (maxCapacity < initCapacity)
|
||||
throw new Exception("The max capacity value must be greater the init capacity value.");
|
||||
|
||||
GameObjectPool pool = TryGetGameObjectPool(location);
|
||||
if (pool != null)
|
||||
{
|
||||
UniLogger.Warning($"GameObject pool is already existed : {location}");
|
||||
var operation = new CreatePoolOperation(pool.AssetHandle);
|
||||
YooAssets.StartOperation(operation);
|
||||
return operation;
|
||||
}
|
||||
else
|
||||
{
|
||||
pool = new GameObjectPool(_spawnerRoot, location, dontDestroy, initCapacity, maxCapacity, destroyTime);
|
||||
pool.CreatePool(_package);
|
||||
_gameObjectPools.Add(pool);
|
||||
|
||||
var operation = new CreatePoolOperation(pool.AssetHandle);
|
||||
YooAssets.StartOperation(operation);
|
||||
return operation;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 异步实例化一个游戏对象
|
||||
/// </summary>
|
||||
/// <param name="location">资源定位地址</param>
|
||||
/// <param name="forceClone">强制克隆游戏对象,忽略缓存池里的对象</param>
|
||||
/// <param name="userDatas">用户自定义数据</param>
|
||||
public SpawnHandle SpawnAsync(string location, bool forceClone = false, params System.Object[] userDatas)
|
||||
{
|
||||
return SpawnInternal(location, null, Vector3.zero, Quaternion.identity, forceClone, userDatas);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 异步实例化一个游戏对象
|
||||
/// </summary>
|
||||
/// <param name="location">资源定位地址</param>
|
||||
/// <param name="parent">父物体</param>
|
||||
/// <param name="forceClone">强制克隆游戏对象,忽略缓存池里的对象</param>
|
||||
/// <param name="userDatas">用户自定义数据</param>
|
||||
public SpawnHandle SpawnAsync(string location, Transform parent, bool forceClone = false, params System.Object[] userDatas)
|
||||
{
|
||||
return SpawnInternal(location, parent, Vector3.zero, Quaternion.identity, forceClone, userDatas);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 异步实例化一个游戏对象
|
||||
/// </summary>
|
||||
/// <param name="location">资源定位地址</param>
|
||||
/// <param name="parent">父物体</param>
|
||||
/// <param name="position">世界坐标</param>
|
||||
/// <param name="rotation">世界角度</param>
|
||||
/// <param name="forceClone">强制克隆游戏对象,忽略缓存池里的对象</param>
|
||||
/// <param name="userDatas">用户自定义数据</param>
|
||||
public SpawnHandle SpawnAsync(string location, Transform parent, Vector3 position, Quaternion rotation, bool forceClone = false, params System.Object[] userDatas)
|
||||
{
|
||||
return SpawnInternal(location, parent, position, rotation, forceClone, userDatas);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 同步实例化一个游戏对象
|
||||
/// </summary>
|
||||
/// <param name="location">资源定位地址</param>
|
||||
/// <param name="forceClone">强制克隆游戏对象,忽略缓存池里的对象</param>
|
||||
/// <param name="userDatas">用户自定义数据</param>
|
||||
public SpawnHandle SpawnSync(string location, bool forceClone = false, params System.Object[] userDatas)
|
||||
{
|
||||
SpawnHandle handle = SpawnInternal(location, null, Vector3.zero, Quaternion.identity, forceClone, userDatas);
|
||||
handle.WaitForAsyncComplete();
|
||||
return handle;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 同步实例化一个游戏对象
|
||||
/// </summary>
|
||||
/// <param name="location">资源定位地址</param>
|
||||
/// <param name="parent">父物体</param>
|
||||
/// <param name="forceClone">强制克隆游戏对象,忽略缓存池里的对象</param>
|
||||
/// <param name="userDatas">用户自定义数据</param>
|
||||
public SpawnHandle SpawnSync(string location, Transform parent, bool forceClone = false, params System.Object[] userDatas)
|
||||
{
|
||||
SpawnHandle handle = SpawnInternal(location, parent, Vector3.zero, Quaternion.identity, forceClone, userDatas);
|
||||
handle.WaitForAsyncComplete();
|
||||
return handle;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 同步实例化一个游戏对象
|
||||
/// </summary>
|
||||
/// <param name="location">资源定位地址</param>
|
||||
/// <param name="parent">父物体</param>
|
||||
/// <param name="position">世界坐标</param>
|
||||
/// <param name="rotation">世界角度</param>
|
||||
/// <param name="forceClone">强制克隆游戏对象,忽略缓存池里的对象</param>
|
||||
/// <param name="userDatas">用户自定义数据</param>
|
||||
public SpawnHandle SpawnSync(string location, Transform parent, Vector3 position, Quaternion rotation, bool forceClone = false, params System.Object[] userDatas)
|
||||
{
|
||||
SpawnHandle handle = SpawnInternal(location, parent, position, rotation, forceClone, userDatas);
|
||||
handle.WaitForAsyncComplete();
|
||||
return handle;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 实例化一个游戏对象
|
||||
/// </summary>
|
||||
private SpawnHandle SpawnInternal(string location, Transform parent, Vector3 position, Quaternion rotation, bool forceClone, params System.Object[] userDatas)
|
||||
{
|
||||
var pool = TryGetGameObjectPool(location);
|
||||
if (pool != null)
|
||||
{
|
||||
return pool.Spawn(parent, position, rotation, forceClone, userDatas);
|
||||
}
|
||||
|
||||
// 如果不存在创建游戏对象池
|
||||
pool = new GameObjectPool(_spawnerRoot, location, false, 0, int.MaxValue, -1f);
|
||||
pool.CreatePool(_package);
|
||||
_gameObjectPools.Add(pool);
|
||||
return pool.Spawn(parent, position, rotation, forceClone, userDatas);
|
||||
}
|
||||
|
||||
|
||||
private GameObjectPool TryGetGameObjectPool(string location)
|
||||
{
|
||||
foreach (var pool in _gameObjectPools)
|
||||
{
|
||||
if (pool.Location == location)
|
||||
return pool;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6c0b7912d44674d47a5b7240670dcc87
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,21 @@
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace UniFramework.Pooling
|
||||
{
|
||||
internal static class UniLogger
|
||||
{
|
||||
[Conditional("DEBUG")]
|
||||
public static void Log(string info)
|
||||
{
|
||||
UnityEngine.Debug.Log(info);
|
||||
}
|
||||
public static void Warning(string info)
|
||||
{
|
||||
UnityEngine.Debug.LogWarning(info);
|
||||
}
|
||||
public static void Error(string info)
|
||||
{
|
||||
UnityEngine.Debug.LogError(info);
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 50142a5596fb6c1439dced35faef4d4c
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,127 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using YooAsset;
|
||||
|
||||
namespace UniFramework.Pooling
|
||||
{
|
||||
/// <summary>
|
||||
/// 游戏对象池系统
|
||||
/// </summary>
|
||||
public static class UniPooling
|
||||
{
|
||||
private static bool _isInitialize = false;
|
||||
private static GameObject _driver = null;
|
||||
private static readonly List<Spawner> _spawners = new List<Spawner>();
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 初始化游戏对象池系统
|
||||
/// </summary>
|
||||
public static void Initalize()
|
||||
{
|
||||
if (_isInitialize)
|
||||
throw new Exception($"{nameof(UniPooling)} is initialized !");
|
||||
|
||||
if (_isInitialize == false)
|
||||
{
|
||||
// 创建驱动器
|
||||
_isInitialize = true;
|
||||
_driver = new UnityEngine.GameObject($"[{nameof(UniPooling)}]");
|
||||
_driver.AddComponent<UniPoolingDriver>();
|
||||
UnityEngine.Object.DontDestroyOnLoad(_driver);
|
||||
UniLogger.Log($"{nameof(UniPooling)} initalize !");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 销毁游戏对象池系统
|
||||
/// </summary>
|
||||
public static void Destroy()
|
||||
{
|
||||
if (_isInitialize)
|
||||
{
|
||||
foreach (var spawner in _spawners)
|
||||
{
|
||||
spawner.Destroy();
|
||||
}
|
||||
_spawners.Clear();
|
||||
|
||||
_isInitialize = false;
|
||||
if (_driver != null)
|
||||
GameObject.Destroy(_driver);
|
||||
UniLogger.Log($"{nameof(UniPooling)} destroy all !");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 更新游戏对象池系统
|
||||
/// </summary>
|
||||
internal static void Update()
|
||||
{
|
||||
if (_isInitialize)
|
||||
{
|
||||
foreach (var spawner in _spawners)
|
||||
{
|
||||
spawner.Update();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 创建游戏对象生成器
|
||||
/// </summary>
|
||||
/// <param name="packageName">资源包名称</param>
|
||||
public static Spawner CreateSpawner(string packageName)
|
||||
{
|
||||
// 获取资源包
|
||||
var assetPackage = YooAssets.GetPackage(packageName);
|
||||
if (assetPackage == null)
|
||||
throw new Exception($"Not found asset package : {packageName}");
|
||||
|
||||
// 检测资源包初始化状态
|
||||
if (assetPackage.InitializeStatus == EOperationStatus.None)
|
||||
throw new Exception($"Asset package {packageName} not initialize !");
|
||||
if (assetPackage.InitializeStatus == EOperationStatus.Failed)
|
||||
throw new Exception($"Asset package {packageName} initialize failed !");
|
||||
|
||||
if (HasSpawner(packageName))
|
||||
return GetSpawner(packageName);
|
||||
|
||||
Spawner spawner = new Spawner(_driver, assetPackage);
|
||||
_spawners.Add(spawner);
|
||||
return spawner;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取游戏对象生成器
|
||||
/// </summary>
|
||||
/// <param name="packageName">资源包名称</param>
|
||||
public static Spawner GetSpawner(string packageName)
|
||||
{
|
||||
foreach (var spawner in _spawners)
|
||||
{
|
||||
if (spawner.PackageName == packageName)
|
||||
return spawner;
|
||||
}
|
||||
|
||||
UniLogger.Warning($"Not found spawner : {packageName}");
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 检测游戏对象生成器是否存在
|
||||
/// </summary>
|
||||
/// <param name="packageName">资源包名称</param>
|
||||
public static bool HasSpawner(string packageName)
|
||||
{
|
||||
foreach (var spawner in _spawners)
|
||||
{
|
||||
if (spawner.PackageName == packageName)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 04fd1800aa2e61644893fa7893d93db8
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,12 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace UniFramework.Pooling
|
||||
{
|
||||
internal class UniPoolingDriver : MonoBehaviour
|
||||
{
|
||||
void Update()
|
||||
{
|
||||
UniPooling.Update();
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f4112e0723ed46c45927cc3498d62e5a
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
199
Assets/GameScripts/HotFix/GameLogic/Demo/Uni/UniTimer.cs
Normal file
199
Assets/GameScripts/HotFix/GameLogic/Demo/Uni/UniTimer.cs
Normal file
@@ -0,0 +1,199 @@
|
||||
|
||||
namespace UniFramework.Utility
|
||||
{
|
||||
public sealed class UniTimer
|
||||
{
|
||||
/// <summary>
|
||||
/// 延迟后,触发一次
|
||||
/// </summary>
|
||||
public static UniTimer CreateOnceTimer(float delay)
|
||||
{
|
||||
return new UniTimer(delay, -1, -1, 1);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 延迟后,永久性的间隔触发
|
||||
/// </summary>
|
||||
/// <param name="delay">延迟时间</param>
|
||||
/// <param name="interval">间隔时间</param>
|
||||
public static UniTimer CreatePepeatTimer(float delay, float interval)
|
||||
{
|
||||
return new UniTimer(delay, interval, -1, -1);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 延迟后,在一段时间内间隔触发
|
||||
/// </summary>
|
||||
/// <param name="delay">延迟时间</param>
|
||||
/// <param name="interval">间隔时间</param>
|
||||
/// <param name="duration">触发周期</param>
|
||||
public static UniTimer CreatePepeatTimer(float delay, float interval, float duration)
|
||||
{
|
||||
return new UniTimer(delay, interval, duration, -1);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 延迟后,间隔触发一定次数
|
||||
/// </summary>
|
||||
/// <param name="delay">延迟时间</param>
|
||||
/// <param name="interval">间隔时间</param>
|
||||
/// <param name="maxTriggerCount">最大触发次数</param>
|
||||
public static UniTimer CreatePepeatTimer(float delay, float interval, long maxTriggerCount)
|
||||
{
|
||||
return new UniTimer(delay, interval, -1, maxTriggerCount);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 延迟后,在一段时间内触发
|
||||
/// </summary>
|
||||
/// <param name="delay">延迟时间</param>
|
||||
/// <param name="duration">触发周期</param>
|
||||
public static UniTimer CreateDurationTimer(float delay, float duration)
|
||||
{
|
||||
return new UniTimer(delay, -1, duration, -1);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 延迟后,永久触发
|
||||
/// </summary>
|
||||
public static UniTimer CreateForeverTimer(float delay)
|
||||
{
|
||||
return new UniTimer(delay, -1, -1, -1);
|
||||
}
|
||||
|
||||
|
||||
private readonly float _intervalTime;
|
||||
private readonly float _durationTime;
|
||||
private readonly long _maxTriggerCount;
|
||||
|
||||
// 需要重置的变量
|
||||
private float _delayTimer = 0;
|
||||
private float _durationTimer = 0;
|
||||
private float _intervalTimer = 0;
|
||||
private long _triggerCount = 0;
|
||||
|
||||
/// <summary>
|
||||
/// 延迟时间
|
||||
/// </summary>
|
||||
public float DelayTime { private set; get; }
|
||||
|
||||
/// <summary>
|
||||
/// 是否已经结束
|
||||
/// </summary>
|
||||
public bool IsOver { private set; get; }
|
||||
|
||||
/// <summary>
|
||||
/// 是否已经暂停
|
||||
/// </summary>
|
||||
public bool IsPause { private set; get; }
|
||||
|
||||
/// <summary>
|
||||
/// 延迟剩余时间
|
||||
/// </summary>
|
||||
public float Remaining
|
||||
{
|
||||
get
|
||||
{
|
||||
if (IsOver)
|
||||
return 0f;
|
||||
else
|
||||
return System.Math.Max(0f, DelayTime - _delayTimer);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 计时器
|
||||
/// </summary>
|
||||
/// <param name="delay">延迟时间</param>
|
||||
/// <param name="interval">间隔时间</param>
|
||||
/// <param name="duration">运行时间</param>
|
||||
/// <param name="maxTriggerTimes">最大触发次数</param>
|
||||
public UniTimer(float delay, float interval, float duration, long maxTriggerCount)
|
||||
{
|
||||
DelayTime = delay;
|
||||
_intervalTime = interval;
|
||||
_durationTime = duration;
|
||||
_maxTriggerCount = maxTriggerCount;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 暂停计时器
|
||||
/// </summary>
|
||||
public void Pause()
|
||||
{
|
||||
IsPause = true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 恢复计时器
|
||||
/// </summary>
|
||||
public void Resume()
|
||||
{
|
||||
IsPause = false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 结束计时器
|
||||
/// </summary>
|
||||
public void Kill()
|
||||
{
|
||||
IsOver = true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 重置计时器
|
||||
/// </summary>
|
||||
public void Reset()
|
||||
{
|
||||
_delayTimer = 0;
|
||||
_durationTimer = 0;
|
||||
_intervalTimer = 0;
|
||||
_triggerCount = 0;
|
||||
IsOver = false;
|
||||
IsPause = false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 更新计时器
|
||||
/// </summary>
|
||||
public bool Update(float deltaTime)
|
||||
{
|
||||
if (IsOver || IsPause)
|
||||
return false;
|
||||
|
||||
_delayTimer += deltaTime;
|
||||
if (_delayTimer < DelayTime)
|
||||
return false;
|
||||
|
||||
if(_intervalTime > 0)
|
||||
_intervalTimer += deltaTime;
|
||||
if (_durationTime > 0)
|
||||
_durationTimer += deltaTime;
|
||||
|
||||
// 检测间隔执行
|
||||
if (_intervalTime > 0)
|
||||
{
|
||||
if (_intervalTimer < _intervalTime)
|
||||
return false;
|
||||
_intervalTimer = 0;
|
||||
}
|
||||
|
||||
// 检测结束条件
|
||||
if (_durationTime > 0)
|
||||
{
|
||||
if (_durationTimer >= _durationTime)
|
||||
Kill();
|
||||
}
|
||||
|
||||
// 检测结束条件
|
||||
if (_maxTriggerCount > 0)
|
||||
{
|
||||
_triggerCount++;
|
||||
if (_triggerCount >= _maxTriggerCount)
|
||||
Kill();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a9ba1e57e76e1c3498c1e678e2737ab2
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
8
Assets/GameScripts/HotFix/GameLogic/Demo/UniPooling.meta
Normal file
8
Assets/GameScripts/HotFix/GameLogic/Demo/UniPooling.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ca2e7b4bdd8611b4ca9a21408a8a20a1
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -1,3 +1,5 @@
|
||||
using System.Collections;
|
||||
using Cysharp.Threading.Tasks;
|
||||
using GameBase;
|
||||
using TEngine;
|
||||
|
||||
@@ -28,7 +30,15 @@ public partial class GameApp:Singleton<GameApp>
|
||||
/// </summary>
|
||||
private void StartGameLogic()
|
||||
{
|
||||
|
||||
StartBattleRoom().Forget();
|
||||
}
|
||||
|
||||
private async UniTaskVoid StartBattleRoom()
|
||||
{
|
||||
await GameModule.Resource.LoadSceneAsync("scene_battle").ToUniTask(Utility.Unity.Behaviour);
|
||||
|
||||
BattleRoom battleRoom = new BattleRoom();
|
||||
await battleRoom.LoadRoom().ToUniTask(Utility.Unity.Behaviour);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@@ -1,5 +1,6 @@
|
||||
using System.Collections.Generic;
|
||||
using TEngine;
|
||||
using UniFramework.Pooling;
|
||||
|
||||
public partial class GameApp
|
||||
{
|
||||
@@ -17,7 +18,8 @@ public partial class GameApp
|
||||
/// </summary>
|
||||
private void InitSystemSetting()
|
||||
{
|
||||
|
||||
// 初始化对象池系统
|
||||
UniPooling.Initalize();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
Reference in New Issue
Block a user