Update space shooter
This commit is contained in:
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 62f3c214d7670b44ebbee7153636c648
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,65 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using YooAsset;
|
||||
|
||||
public class EncryptionNone : IEncryptionServices
|
||||
{
|
||||
public EncryptResult Encrypt(EncryptFileInfo fileInfo)
|
||||
{
|
||||
EncryptResult result = new EncryptResult();
|
||||
result.LoadMethod = EBundleLoadMethod.Normal;
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
public class FileOffsetEncryption : IEncryptionServices
|
||||
{
|
||||
public EncryptResult Encrypt(EncryptFileInfo fileInfo)
|
||||
{
|
||||
if(fileInfo.BundleName.Contains("gameres_music"))
|
||||
{
|
||||
int offset = 32;
|
||||
byte[] fileData = File.ReadAllBytes(fileInfo.FilePath);
|
||||
var encryptedData = new byte[fileData.Length + offset];
|
||||
Buffer.BlockCopy(fileData, 0, encryptedData, offset, fileData.Length);
|
||||
|
||||
EncryptResult result = new EncryptResult();
|
||||
result.LoadMethod = EBundleLoadMethod.LoadFromFileOffset;
|
||||
result.EncryptedData = encryptedData;
|
||||
return result;
|
||||
}
|
||||
else
|
||||
{
|
||||
EncryptResult result = new EncryptResult();
|
||||
result.LoadMethod = EBundleLoadMethod.Normal;
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class FileStreamEncryption : IEncryptionServices
|
||||
{
|
||||
public EncryptResult Encrypt(EncryptFileInfo fileInfo)
|
||||
{
|
||||
if (fileInfo.BundleName.Contains("gameres_music"))
|
||||
{
|
||||
var fileData = File.ReadAllBytes(fileInfo.FilePath);
|
||||
for (int i = 0; i < fileData.Length; i++)
|
||||
{
|
||||
fileData[i] ^= BundleStream.KEY;
|
||||
}
|
||||
|
||||
EncryptResult result = new EncryptResult();
|
||||
result.LoadMethod = EBundleLoadMethod.LoadFromStream;
|
||||
result.EncryptedData = fileData;
|
||||
return result;
|
||||
}
|
||||
else
|
||||
{
|
||||
EncryptResult result = new EncryptResult();
|
||||
result.LoadMethod = EBundleLoadMethod.Normal;
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 339682333f36d014e942a790dea6b1f7
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 631e5633e0d02ff49b08cb300f7139a6
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: cae7dcd2cee351e4390eebef0851486e
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
public class BackgroundScroller : 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;
|
||||
}
|
||||
}
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 814f6a7e3ec8a40aaa3a2057e2695924
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
public class BattleEventDefine
|
||||
{
|
||||
public class ScoreChange : IEventMessage
|
||||
{
|
||||
public int CurrentScores;
|
||||
}
|
||||
|
||||
public class GameOver : IEventMessage
|
||||
{
|
||||
}
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 523858f19dde4204aad79345f342b0ce
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
public static class BattleEventDispatcher
|
||||
{
|
||||
public static void SendScoreChangeMsg(int currentScores)
|
||||
{
|
||||
BattleEventDefine.ScoreChange msg = new BattleEventDefine.ScoreChange();
|
||||
msg.CurrentScores = currentScores;
|
||||
EventManager.SendMessage(msg);
|
||||
}
|
||||
|
||||
public static void SendGameOverMsg()
|
||||
{
|
||||
BattleEventDefine.GameOver msg = new BattleEventDefine.GameOver();
|
||||
EventManager.SendMessage(msg);
|
||||
}
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5915c7b5006a8384dbefdf32da34a3e6
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,97 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System;
|
||||
using UnityEngine;
|
||||
using YooAsset;
|
||||
using Random = UnityEngine.Random;
|
||||
|
||||
[Serializable]
|
||||
public class RoomBoundary
|
||||
{
|
||||
public float xMin, xMax, zMin, zMax;
|
||||
}
|
||||
|
||||
public class BattleRoom : MonoBehaviour
|
||||
{
|
||||
public static BattleRoom Instance;
|
||||
|
||||
public Vector3 SpawnValues;
|
||||
public int EnemyCount = 10;
|
||||
public float SpawnWait = 0.75f;
|
||||
public float StartWait = 1f;
|
||||
public float WaveWait = 4f;
|
||||
|
||||
private int _totalScore = 0;
|
||||
private bool _gameOver = false;
|
||||
private string[] _enemyLocations = new string[]
|
||||
{
|
||||
"asteroid01", "asteroid02", "asteroid03", "enemy_ship"
|
||||
};
|
||||
|
||||
void Awake()
|
||||
{
|
||||
Instance = this;
|
||||
}
|
||||
void Start()
|
||||
{
|
||||
var handle = YooAssets.LoadAssetSync<GameObject>("player_ship");
|
||||
var go = handle.InstantiateSync();
|
||||
var bhv = go.GetComponent<EntityPlayer>();
|
||||
bhv.InitEntity(handle);
|
||||
|
||||
StartCoroutine(SpawnWaves());
|
||||
}
|
||||
void OnDestroy()
|
||||
{
|
||||
Instance = null;
|
||||
}
|
||||
|
||||
IEnumerator SpawnWaves()
|
||||
{
|
||||
yield return new WaitForSeconds(StartWait);
|
||||
while (true)
|
||||
{
|
||||
for (int i = 0; i < EnemyCount; i++)
|
||||
{
|
||||
var enemyLocation= _enemyLocations[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 = YooAssets.LoadAssetSync<GameObject>(enemyLocation);
|
||||
var go = handle.InstantiateSync(spawnPosition, spawnRotation);
|
||||
var bhv = go.GetComponent<EntityEnemy>();
|
||||
bhv.InitEntity(handle);
|
||||
}
|
||||
else
|
||||
{
|
||||
var handle = YooAssets.LoadAssetSync<GameObject>(enemyLocation);
|
||||
var go = handle.InstantiateSync(spawnPosition, spawnRotation);
|
||||
var bhv = go.GetComponent<EntityAsteroid>();
|
||||
bhv.InitEntity(handle);
|
||||
}
|
||||
|
||||
yield return new WaitForSeconds(SpawnWait);
|
||||
}
|
||||
yield return new WaitForSeconds(WaveWait);
|
||||
|
||||
if (_gameOver)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void GameOver()
|
||||
{
|
||||
_gameOver = true;
|
||||
BattleEventDispatcher.SendGameOverMsg();
|
||||
}
|
||||
|
||||
public void AddScore(int score)
|
||||
{
|
||||
_totalScore += score;
|
||||
BattleEventDispatcher.SendScoreChangeMsg(_totalScore);
|
||||
}
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 43ab5a1b8ae5c2b4a8995952e7e01f3f
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
+52
@@ -0,0 +1,52 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using YooAsset;
|
||||
|
||||
public class EntityAsteroid : MonoBehaviour
|
||||
{
|
||||
private AssetOperationHandle _ownerHandle;
|
||||
|
||||
public float MoveSpeed = -5f;
|
||||
public float Tumble = 5f;
|
||||
|
||||
public void InitEntity(AssetOperationHandle ownerHandle)
|
||||
{
|
||||
_ownerHandle = ownerHandle;
|
||||
}
|
||||
|
||||
void Awake()
|
||||
{
|
||||
var rigidBody = this.transform.GetComponent<Rigidbody>();
|
||||
rigidBody.velocity = this.transform.forward * MoveSpeed;
|
||||
rigidBody.angularVelocity = Random.insideUnitSphere * Tumble;
|
||||
}
|
||||
void OnDestroy()
|
||||
{
|
||||
if (_ownerHandle != null)
|
||||
{
|
||||
_ownerHandle.Release();
|
||||
_ownerHandle = null;
|
||||
}
|
||||
}
|
||||
void OnTriggerEnter(Collider other)
|
||||
{
|
||||
if (other.CompareTag("PlayerBullet"))
|
||||
{
|
||||
var handle = YooAssets.LoadAssetSync<GameObject>("explosion_asteroid");
|
||||
var go = handle.InstantiateSync(other.transform.position, Quaternion.identity);
|
||||
var bhv = go.GetComponent<EntityEffect>();
|
||||
bhv.InitEntity(handle);
|
||||
|
||||
BattleRoom.Instance.AddScore(1);
|
||||
GameObject.Destroy(this.gameObject);
|
||||
}
|
||||
}
|
||||
void OnTriggerExit(Collider other)
|
||||
{
|
||||
if (other.CompareTag("Boundary"))
|
||||
{
|
||||
GameObject.Destroy(this.gameObject);
|
||||
}
|
||||
}
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ffef5a382eef32d46b1d6175c85f644e
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,55 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using YooAsset;
|
||||
|
||||
public class EntityBullet : MonoBehaviour
|
||||
{
|
||||
private AssetOperationHandle _ownerHandle;
|
||||
|
||||
public float MoveSpeed = 20f;
|
||||
public float DelayDestroyTime = 5f;
|
||||
|
||||
public void InitEntity(AssetOperationHandle ownerHandle)
|
||||
{
|
||||
_ownerHandle = ownerHandle;
|
||||
}
|
||||
|
||||
void Awake()
|
||||
{
|
||||
var rigidBody = this.transform.GetComponent<Rigidbody>();
|
||||
rigidBody.velocity = this.transform.forward * MoveSpeed;
|
||||
}
|
||||
void OnDestroy()
|
||||
{
|
||||
if (_ownerHandle != null)
|
||||
{
|
||||
_ownerHandle.Release();
|
||||
_ownerHandle = null;
|
||||
}
|
||||
}
|
||||
void OnTriggerEnter(Collider other)
|
||||
{
|
||||
if (other.CompareTag("Boundary"))
|
||||
return;
|
||||
|
||||
if (this.gameObject.CompareTag("EnemyBullet"))
|
||||
{
|
||||
if (other.CompareTag("Enemy") == false)
|
||||
GameObject.Destroy(this.gameObject);
|
||||
}
|
||||
|
||||
if (this.gameObject.CompareTag("PlayerBullet"))
|
||||
{
|
||||
if (other.CompareTag("Player") == false)
|
||||
GameObject.Destroy(this.gameObject);
|
||||
}
|
||||
}
|
||||
void OnTriggerExit(Collider other)
|
||||
{
|
||||
if (other.CompareTag("Boundary"))
|
||||
{
|
||||
GameObject.Destroy(this.gameObject);
|
||||
}
|
||||
}
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1a9d4ddd3c4e60245b6bc4f9f1435291
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,34 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using YooAsset;
|
||||
|
||||
public class EntityEffect : MonoBehaviour
|
||||
{
|
||||
private AssetOperationHandle _ownerHandle;
|
||||
|
||||
public float DelayDestroyTime = 1f;
|
||||
|
||||
public void InitEntity(AssetOperationHandle ownerHandle)
|
||||
{
|
||||
_ownerHandle = ownerHandle;
|
||||
}
|
||||
|
||||
void Awake()
|
||||
{
|
||||
Invoke(nameof(DelayDestroy), DelayDestroyTime);
|
||||
}
|
||||
void OnDestroy()
|
||||
{
|
||||
if (_ownerHandle != null)
|
||||
{
|
||||
_ownerHandle.Release();
|
||||
_ownerHandle = null;
|
||||
}
|
||||
}
|
||||
|
||||
private void DelayDestroy()
|
||||
{
|
||||
GameObject.Destroy(this.gameObject);
|
||||
}
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 014c1f9b87e247446bd7d558f8bf143e
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,117 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using YooAsset;
|
||||
using Random = UnityEngine.Random;
|
||||
|
||||
public class EntityEnemy : MonoBehaviour
|
||||
{
|
||||
private const float Dodge = 5f;
|
||||
private const float Smoothing = 7.5f;
|
||||
|
||||
private AssetOperationHandle _ownerHandle;
|
||||
|
||||
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 Transform _shotSpawn;
|
||||
private Rigidbody _rigidbody;
|
||||
private AudioSource _audioSource;
|
||||
private float _lastFireTime = 0f;
|
||||
|
||||
float _currentSpeed;
|
||||
float targetManeuver;
|
||||
|
||||
public void InitEntity(AssetOperationHandle ownerHandle)
|
||||
{
|
||||
_ownerHandle = ownerHandle;
|
||||
}
|
||||
|
||||
void Awake()
|
||||
{
|
||||
_rigidbody = this.gameObject.GetComponent<Rigidbody>();
|
||||
_audioSource = this.gameObject.GetComponent<AudioSource>();
|
||||
_shotSpawn = this.transform.Find("shot_spawn");
|
||||
|
||||
_rigidbody.velocity = this.transform.forward * -5f;
|
||||
_currentSpeed = _rigidbody.velocity.z;
|
||||
StartCoroutine(Evade());
|
||||
}
|
||||
void Start()
|
||||
{
|
||||
_lastFireTime = Time.time;
|
||||
}
|
||||
void OnDestroy()
|
||||
{
|
||||
if (_ownerHandle != null)
|
||||
{
|
||||
_ownerHandle.Release();
|
||||
_ownerHandle = null;
|
||||
}
|
||||
}
|
||||
void Update()
|
||||
{
|
||||
if (Time.time - _lastFireTime >= FireInterval)
|
||||
{
|
||||
_lastFireTime = Time.time;
|
||||
|
||||
var handle = YooAssets.LoadAssetSync<GameObject>("enemy_bullet");
|
||||
var go = handle.InstantiateSync(_shotSpawn.position, _shotSpawn.rotation);
|
||||
var bhv = go.GetComponent<EntityBullet>();
|
||||
bhv.InitEntity(handle);
|
||||
|
||||
_audioSource.Play();
|
||||
}
|
||||
}
|
||||
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)
|
||||
{
|
||||
if (other.CompareTag("PlayerBullet"))
|
||||
{
|
||||
var handle = YooAssets.LoadAssetSync<GameObject>("explosion_enemy");
|
||||
var go = handle.InstantiateSync(this.transform.position, this.transform.rotation);
|
||||
var bhv = go.GetComponent<EntityEffect>();
|
||||
bhv.InitEntity(handle);
|
||||
|
||||
BattleRoom.Instance.AddScore(10);
|
||||
GameObject.Destroy(this.gameObject);
|
||||
}
|
||||
}
|
||||
void OnTriggerExit(Collider other)
|
||||
{
|
||||
if (other.CompareTag("Boundary"))
|
||||
{
|
||||
GameObject.Destroy(this.gameObject);
|
||||
}
|
||||
}
|
||||
|
||||
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));
|
||||
}
|
||||
}
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a613426c4968b3149b8bf9bf88fe41c7
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,83 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using YooAsset;
|
||||
|
||||
public class EntityPlayer : MonoBehaviour
|
||||
{
|
||||
private AssetOperationHandle _ownerHandle;
|
||||
|
||||
public RoomBoundary Boundary;
|
||||
public float MoveSpeed = 10f;
|
||||
public float FireRate = 0.25f;
|
||||
|
||||
private float _nextFireTime = 0f;
|
||||
private Transform _shotSpawn;
|
||||
private Rigidbody _rigidbody;
|
||||
private AudioSource _audioSource;
|
||||
|
||||
public void InitEntity(AssetOperationHandle ownerHandle)
|
||||
{
|
||||
_ownerHandle = ownerHandle;
|
||||
}
|
||||
|
||||
void Awake()
|
||||
{
|
||||
_rigidbody = this.gameObject.GetComponent<Rigidbody>();
|
||||
_audioSource = this.gameObject.GetComponent<AudioSource>();
|
||||
_shotSpawn = this.transform.Find("shot_spawn");
|
||||
}
|
||||
void OnDestroy()
|
||||
{
|
||||
if (_ownerHandle != null)
|
||||
{
|
||||
_ownerHandle.Release();
|
||||
_ownerHandle = null;
|
||||
}
|
||||
}
|
||||
void Update()
|
||||
{
|
||||
if (Input.GetButton("Fire1") && Time.time > _nextFireTime)
|
||||
{
|
||||
_nextFireTime = Time.time + FireRate;
|
||||
|
||||
var handle = YooAssets.LoadAssetSync<GameObject>("player_bullet");
|
||||
var go = handle.InstantiateSync(_shotSpawn.position, _shotSpawn.rotation);
|
||||
var bhv = go.GetComponent<EntityBullet>();
|
||||
bhv.InitEntity(handle);
|
||||
|
||||
_audioSource.Play();
|
||||
}
|
||||
}
|
||||
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)
|
||||
{
|
||||
if (other.CompareTag("Enemy") || other.CompareTag("EnemyBullet") || other.CompareTag("Asteroid"))
|
||||
{
|
||||
var explosionHandle = YooAssets.LoadAssetSync<GameObject>("explosion_player");
|
||||
var go = explosionHandle.InstantiateSync(this.transform.position, this.transform.rotation);
|
||||
var bhv = go.GetComponent<EntityEffect>();
|
||||
bhv.InitEntity(explosionHandle);
|
||||
|
||||
BattleRoom.Instance.GameOver();
|
||||
GameObject.Destroy(this.gameObject);
|
||||
}
|
||||
}
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d3933af4e188ec44683e3c52784eadb0
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,138 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using UnityEngine;
|
||||
using YooAsset;
|
||||
using Better.StreamingAssets;
|
||||
using System.IO;
|
||||
|
||||
public class BootScene : MonoBehaviour
|
||||
{
|
||||
public static BootScene Instance { private set; get; }
|
||||
public static EPlayMode GamePlayMode;
|
||||
|
||||
public EPlayMode PlayMode = EPlayMode.EditorSimulateMode;
|
||||
|
||||
void Awake()
|
||||
{
|
||||
Instance = this;
|
||||
|
||||
Application.targetFrameRate = 60;
|
||||
Application.runInBackground = true;
|
||||
}
|
||||
void OnDestroy()
|
||||
{
|
||||
Instance = null;
|
||||
}
|
||||
void Update()
|
||||
{
|
||||
EventManager.Update();
|
||||
FsmManager.Update();
|
||||
}
|
||||
|
||||
IEnumerator Start()
|
||||
{
|
||||
GamePlayMode = PlayMode;
|
||||
Debug.Log($"资源系统运行模式:{PlayMode}");
|
||||
|
||||
// 初始化BetterStreaming
|
||||
BetterStreamingAssets.Initialize();
|
||||
|
||||
// 初始化资源系统
|
||||
YooAssets.Initialize();
|
||||
|
||||
// 创建默认的资源包
|
||||
var defaultPackage = YooAssets.CreateAssetsPackage("DefaultPackage");
|
||||
|
||||
// 设置该资源包为默认的资源包
|
||||
YooAssets.SetDefaultAssetsPackage(defaultPackage);
|
||||
|
||||
// 编辑器下的模拟模式
|
||||
if (PlayMode == EPlayMode.EditorSimulateMode)
|
||||
{
|
||||
var createParameters = new EditorSimulateModeParameters();
|
||||
createParameters.SimulatePatchManifestPath = EditorSimulateModeHelper.SimulateBuild("DefaultPackage");
|
||||
yield return defaultPackage.InitializeAsync(createParameters);
|
||||
}
|
||||
|
||||
// 单机运行模式
|
||||
if (PlayMode == EPlayMode.OfflinePlayMode)
|
||||
{
|
||||
var createParameters = new OfflinePlayModeParameters();
|
||||
createParameters.DecryptionServices = new BundleDecryptionServices();
|
||||
yield return defaultPackage.InitializeAsync(createParameters);
|
||||
}
|
||||
|
||||
// 联机运行模式
|
||||
if (PlayMode == EPlayMode.HostPlayMode)
|
||||
{
|
||||
var createParameters = new HostPlayModeParameters();
|
||||
createParameters.DecryptionServices = new BundleDecryptionServices();
|
||||
createParameters.QueryServices = new QueryStreamingAssetsFileServices();
|
||||
createParameters.DefaultHostServer = GetHostServerURL();
|
||||
createParameters.FallbackHostServer = GetHostServerURL();
|
||||
yield return defaultPackage.InitializeAsync(createParameters);
|
||||
}
|
||||
|
||||
// 运行补丁流程
|
||||
PatchManager.Run();
|
||||
}
|
||||
|
||||
private string GetHostServerURL()
|
||||
{
|
||||
//string hostServerIP = "http://10.0.2.2"; //安卓模拟器地址
|
||||
string hostServerIP = "http://127.0.0.1";
|
||||
string gameVersion = "v1.0";
|
||||
|
||||
#if UNITY_EDITOR
|
||||
if (UnityEditor.EditorUserBuildSettings.activeBuildTarget == UnityEditor.BuildTarget.Android)
|
||||
return $"{hostServerIP}/CDN/Android/{gameVersion}";
|
||||
else if (UnityEditor.EditorUserBuildSettings.activeBuildTarget == UnityEditor.BuildTarget.iOS)
|
||||
return $"{hostServerIP}/CDN/IPhone/{gameVersion}";
|
||||
else if (UnityEditor.EditorUserBuildSettings.activeBuildTarget == UnityEditor.BuildTarget.WebGL)
|
||||
return $"{hostServerIP}/CDN/WebGL/{gameVersion}";
|
||||
else
|
||||
return $"{hostServerIP}/CDN/PC/{gameVersion}";
|
||||
#else
|
||||
if (Application.platform == RuntimePlatform.Android)
|
||||
return $"{hostServerIP}/CDN/Android/{gameVersion}";
|
||||
else if (Application.platform == RuntimePlatform.IPhonePlayer)
|
||||
return $"{hostServerIP}/CDN/IPhone/{gameVersion}";
|
||||
else if (Application.platform == RuntimePlatform.WebGLPlayer)
|
||||
return $"{hostServerIP}/CDN/WebGL/{gameVersion}";
|
||||
else
|
||||
return $"{hostServerIP}/CDN/PC/{gameVersion}";
|
||||
#endif
|
||||
}
|
||||
private class QueryStreamingAssetsFileServices : IQueryServices
|
||||
{
|
||||
public bool QueryStreamingAssets(string fileName)
|
||||
{
|
||||
// 注意:使用了BetterStreamingAssets插件,使用前需要初始化该插件!
|
||||
string buildinFolderName = YooAssets.GetStreamingAssetBuildinFolderName();
|
||||
return BetterStreamingAssets.FileExists($"{buildinFolderName}/{fileName}");
|
||||
}
|
||||
}
|
||||
private class BundleDecryptionServices : IDecryptionServices
|
||||
{
|
||||
public ulong LoadFromFileOffset(DecryptFileInfo fileInfo)
|
||||
{
|
||||
return 32;
|
||||
}
|
||||
|
||||
public byte[] LoadFromMemory(DecryptFileInfo fileInfo)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public FileStream LoadFromStream(DecryptFileInfo fileInfo)
|
||||
{
|
||||
BundleStream bundleStream = new BundleStream(fileInfo.FilePath, FileMode.Open);
|
||||
return bundleStream;
|
||||
}
|
||||
|
||||
public uint GetManagedReadBufferSize()
|
||||
{
|
||||
return 1024;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 41fef9a778e4e254b939e9dc3e553bf0
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,27 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using UnityEngine;
|
||||
|
||||
public class BundleStream : FileStream
|
||||
{
|
||||
public const byte KEY = 64;
|
||||
|
||||
public BundleStream(string path, FileMode mode, FileAccess access, FileShare share, int bufferSize, bool useAsync) : base(path, mode, access, share, bufferSize, useAsync)
|
||||
{
|
||||
}
|
||||
public BundleStream(string path, FileMode mode) : base(path, mode)
|
||||
{
|
||||
}
|
||||
|
||||
public override int Read(byte[] array, int offset, int count)
|
||||
{
|
||||
var index = base.Read(array, offset, count);
|
||||
for (int i = 0; i < array.Length; i++)
|
||||
{
|
||||
array[i] ^= KEY;
|
||||
}
|
||||
return index;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7da6bc93686626a4cb248691891073ac
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c64420b3b1ae37943b4565f458c10b7d
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1a79eedc3fa88c8429b085954a7e9093
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
+45
@@ -0,0 +1,45 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
|
||||
public class EventGroup
|
||||
{
|
||||
private readonly Dictionary<System.Type, List<Action<IEventMessage>>> _cachedListener = new Dictionary<System.Type, List<Action<IEventMessage>>>();
|
||||
|
||||
/// <summary>
|
||||
/// 添加一个监听
|
||||
/// </summary>
|
||||
public void AddListener<TEvent>(System.Action<IEventMessage> listener) where TEvent : IEventMessage
|
||||
{
|
||||
System.Type eventType = typeof(TEvent);
|
||||
if (_cachedListener.ContainsKey(eventType) == false)
|
||||
_cachedListener.Add(eventType, new List<Action<IEventMessage>>());
|
||||
|
||||
if (_cachedListener[eventType].Contains(listener) == false)
|
||||
{
|
||||
_cachedListener[eventType].Add(listener);
|
||||
EventManager.AddListener(eventType, listener);
|
||||
}
|
||||
else
|
||||
{
|
||||
UnityEngine.Debug.LogWarning($"Event listener is exist : {eventType}");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 移除所有缓存的监听
|
||||
/// </summary>
|
||||
public void RemoveAllListener()
|
||||
{
|
||||
foreach (var pair in _cachedListener)
|
||||
{
|
||||
System.Type eventType = pair.Key;
|
||||
for (int i = 0; i < pair.Value.Count; i++)
|
||||
{
|
||||
EventManager.RemoveListener(eventType, pair.Value[i]);
|
||||
}
|
||||
pair.Value.Clear();
|
||||
}
|
||||
_cachedListener.Clear();
|
||||
}
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1e0ee5b75a4bc4b49b08f174399b9f01
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
+171
@@ -0,0 +1,171 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
|
||||
/// <summary>
|
||||
/// 事件管理器
|
||||
/// </summary>
|
||||
public static class EventManager
|
||||
{
|
||||
private class PostWrapper
|
||||
{
|
||||
public int PostFrame;
|
||||
public int EventID;
|
||||
public IEventMessage Message;
|
||||
|
||||
public void OnRelease()
|
||||
{
|
||||
PostFrame = 0;
|
||||
EventID = 0;
|
||||
Message = null;
|
||||
}
|
||||
}
|
||||
|
||||
private static readonly Dictionary<int, List<Action<IEventMessage>>> _listeners = new Dictionary<int, List<Action<IEventMessage>>>(1000);
|
||||
private static readonly List<PostWrapper> _postWrappers = new List<PostWrapper>(1000);
|
||||
|
||||
|
||||
public static void Update()
|
||||
{
|
||||
for (int i = _postWrappers.Count - 1; i >= 0; i--)
|
||||
{
|
||||
var wrapper = _postWrappers[i];
|
||||
if (UnityEngine.Time.frameCount > wrapper.PostFrame)
|
||||
{
|
||||
SendMessage(wrapper.EventID, wrapper.Message);
|
||||
_postWrappers.RemoveAt(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 添加监听
|
||||
/// </summary>
|
||||
public static void AddListener<TEvent>(System.Action<IEventMessage> listener) where TEvent : IEventMessage
|
||||
{
|
||||
AddListener(typeof(TEvent), listener);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 添加监听
|
||||
/// </summary>
|
||||
public static void AddListener(System.Type eventType, System.Action<IEventMessage> listener)
|
||||
{
|
||||
int eventId = eventType.GetHashCode();
|
||||
AddListener(eventId, listener);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 添加监听
|
||||
/// </summary>
|
||||
public static void AddListener(int eventId, System.Action<IEventMessage> listener)
|
||||
{
|
||||
if (_listeners.ContainsKey(eventId) == false)
|
||||
_listeners.Add(eventId, new List<Action<IEventMessage>>());
|
||||
if (_listeners[eventId].Contains(listener) == false)
|
||||
_listeners[eventId].Add(listener);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 移除监听
|
||||
/// </summary>
|
||||
public static void RemoveListener<TEvent>(System.Action<IEventMessage> listener) where TEvent : IEventMessage
|
||||
{
|
||||
RemoveListener(typeof(TEvent), listener);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 移除监听
|
||||
/// </summary>
|
||||
public static void RemoveListener(System.Type eventType, System.Action<IEventMessage> listener)
|
||||
{
|
||||
int eventId = eventType.GetHashCode();
|
||||
RemoveListener(eventId, listener);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 移除监听
|
||||
/// </summary>
|
||||
public static void RemoveListener(int eventId, System.Action<IEventMessage> listener)
|
||||
{
|
||||
if (_listeners.ContainsKey(eventId))
|
||||
{
|
||||
if (_listeners[eventId].Contains(listener))
|
||||
_listeners[eventId].Remove(listener);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 实时广播事件
|
||||
/// </summary>
|
||||
public static void SendMessage(IEventMessage message)
|
||||
{
|
||||
int eventId = message.GetType().GetHashCode();
|
||||
SendMessage(eventId, message);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 实时广播事件
|
||||
/// </summary>
|
||||
public static void SendMessage(int eventId, IEventMessage message)
|
||||
{
|
||||
if (_listeners.ContainsKey(eventId) == false)
|
||||
return;
|
||||
|
||||
List<Action<IEventMessage>> listeners = _listeners[eventId];
|
||||
for (int i = listeners.Count - 1; i >= 0; i--)
|
||||
{
|
||||
listeners[i].Invoke(message);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 延迟广播事件
|
||||
/// </summary>
|
||||
public static void PostMessage(IEventMessage message)
|
||||
{
|
||||
int eventId = message.GetType().GetHashCode();
|
||||
PostMessage(eventId, message);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 延迟广播事件
|
||||
/// </summary>
|
||||
public static void PostMessage(int eventId, IEventMessage message)
|
||||
{
|
||||
var wrapper = new PostWrapper();
|
||||
wrapper.PostFrame = UnityEngine.Time.frameCount;
|
||||
wrapper.EventID = eventId;
|
||||
wrapper.Message = message;
|
||||
_postWrappers.Add(wrapper);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 清空所有监听
|
||||
/// </summary>
|
||||
public static void ClearListeners()
|
||||
{
|
||||
foreach (int eventId in _listeners.Keys)
|
||||
{
|
||||
_listeners[eventId].Clear();
|
||||
}
|
||||
_listeners.Clear();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取监听者总数
|
||||
/// </summary>
|
||||
private static int GetAllListenerCount()
|
||||
{
|
||||
int count = 0;
|
||||
foreach (var list in _listeners)
|
||||
{
|
||||
count += list.Value.Count;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 195a0b4317373b44d9289d7b0529eb7c
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
+4
@@ -0,0 +1,4 @@
|
||||
|
||||
public interface IEventMessage
|
||||
{
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9f3747f3c9166b74f946fcdfde7f7827
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: cb1f2313c4b23304f9257ac58c1024f8
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
+121
@@ -0,0 +1,121 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
|
||||
/// <summary>
|
||||
/// 有限状态机
|
||||
/// </summary>
|
||||
public static class FsmManager
|
||||
{
|
||||
private static readonly List<IFsmNode> _nodes = new List<IFsmNode>();
|
||||
private static IFsmNode _curNode;
|
||||
private static IFsmNode _preNode;
|
||||
|
||||
/// <summary>
|
||||
/// 当前运行的节点名称
|
||||
/// </summary>
|
||||
public static string CurrentNodeName
|
||||
{
|
||||
get { return _curNode != null ? _curNode.Name : string.Empty; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 之前运行的节点名称
|
||||
/// </summary>
|
||||
public static string PreviousNodeName
|
||||
{
|
||||
get { return _preNode != null ? _preNode.Name : string.Empty; }
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 启动状态机
|
||||
/// </summary>
|
||||
/// <param name="entryNode">入口节点</param>
|
||||
public static void Run(string entryNode)
|
||||
{
|
||||
_curNode = GetNode(entryNode);
|
||||
_preNode = GetNode(entryNode);
|
||||
|
||||
if (_curNode != null)
|
||||
_curNode.OnEnter();
|
||||
else
|
||||
UnityEngine.Debug.LogError($"Not found entry node : {entryNode}");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 更新状态机
|
||||
/// </summary>
|
||||
public static void Update()
|
||||
{
|
||||
if (_curNode != null)
|
||||
_curNode.OnUpdate();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 加入一个节点
|
||||
/// </summary>
|
||||
public static void AddNode(IFsmNode node)
|
||||
{
|
||||
if (node == null)
|
||||
throw new ArgumentNullException();
|
||||
|
||||
if (_nodes.Contains(node) == false)
|
||||
{
|
||||
_nodes.Add(node);
|
||||
}
|
||||
else
|
||||
{
|
||||
UnityEngine.Debug.LogWarning($"Node {node.Name} already existed");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 转换节点
|
||||
/// </summary>
|
||||
public static void Transition(string nodeName)
|
||||
{
|
||||
if (string.IsNullOrEmpty(nodeName))
|
||||
throw new ArgumentNullException();
|
||||
|
||||
IFsmNode node = GetNode(nodeName);
|
||||
if (node == null)
|
||||
{
|
||||
UnityEngine.Debug.LogError($"Can not found node {nodeName}");
|
||||
return;
|
||||
}
|
||||
|
||||
UnityEngine.Debug.Log($"FSM change {_curNode.Name} to {node.Name}");
|
||||
_preNode = _curNode;
|
||||
_curNode.OnExit();
|
||||
_curNode = node;
|
||||
_curNode.OnEnter();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 返回到之前的节点
|
||||
/// </summary>
|
||||
public static void RevertToPreviousNode()
|
||||
{
|
||||
Transition(PreviousNodeName);
|
||||
}
|
||||
|
||||
private static bool IsContains(string nodeName)
|
||||
{
|
||||
for (int i = 0; i < _nodes.Count; i++)
|
||||
{
|
||||
if (_nodes[i].Name == nodeName)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
private static IFsmNode GetNode(string nodeName)
|
||||
{
|
||||
for (int i = 0; i < _nodes.Count; i++)
|
||||
{
|
||||
if (_nodes[i].Name == nodeName)
|
||||
return _nodes[i];
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: bcbf86a86eb115a41b6aa61fb0945d43
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
|
||||
public interface IFsmNode
|
||||
{
|
||||
/// <summary>
|
||||
/// 节点名称
|
||||
/// </summary>
|
||||
string Name { get; }
|
||||
|
||||
void OnEnter();
|
||||
void OnUpdate();
|
||||
void OnExit();
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 40fe73297598be84fb8dadedd4dd17e6
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0806ae86bd95bad4ca04d04b9084170f
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
+26
@@ -0,0 +1,26 @@
|
||||
|
||||
/// <summary>
|
||||
/// 用户层反馈的操作方式
|
||||
/// </summary>
|
||||
public enum EPatchOperation
|
||||
{
|
||||
/// <summary>
|
||||
/// 开始下载网络文件
|
||||
/// </summary>
|
||||
BeginDownloadWebFiles,
|
||||
|
||||
/// <summary>
|
||||
/// 尝试再次更新静态版本
|
||||
/// </summary>
|
||||
TryUpdateStaticVersion,
|
||||
|
||||
/// <summary>
|
||||
/// 尝试再次更新补丁清单
|
||||
/// </summary>
|
||||
TryUpdatePatchManifest,
|
||||
|
||||
/// <summary>
|
||||
/// 尝试再次下载网络文件
|
||||
/// </summary>
|
||||
TryDownloadWebFiles,
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 219b7f0e5d04432429b5fcb2207fa23b
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
+31
@@ -0,0 +1,31 @@
|
||||
|
||||
/// <summary>
|
||||
/// 补丁系统更新状态
|
||||
/// </summary>
|
||||
public enum EPatchStates
|
||||
{
|
||||
/// <summary>
|
||||
/// 更新静态的资源版本
|
||||
/// </summary>
|
||||
UpdateStaticVersion,
|
||||
|
||||
/// <summary>
|
||||
/// 更新补丁清单
|
||||
/// </summary>
|
||||
UpdateManifest,
|
||||
|
||||
/// <summary>
|
||||
/// 创建下载器
|
||||
/// </summary>
|
||||
CreateDownloader,
|
||||
|
||||
/// <summary>
|
||||
/// 下载远端文件
|
||||
/// </summary>
|
||||
DownloadWebFiles,
|
||||
|
||||
/// <summary>
|
||||
/// 补丁流程完毕
|
||||
/// </summary>
|
||||
PatchDone,
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6f1f35b77d2285045b35f588be8f7236
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 22a43ec58b9da1743bfa629be08ef1ac
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
+28
@@ -0,0 +1,28 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
internal class FsmClearCache : IFsmNode
|
||||
{
|
||||
public string Name { private set; get; } = nameof(FsmClearCache);
|
||||
|
||||
void IFsmNode.OnEnter()
|
||||
{
|
||||
Debug.Log("清理未使用的缓存文件!");
|
||||
var package = YooAsset.YooAssets.GetAssetsPackage("DefaultPackage");
|
||||
var operation = package.ClearPackageUnusedCacheFilesAsync();
|
||||
operation.Completed += Operation_Completed;
|
||||
}
|
||||
|
||||
private void Operation_Completed(YooAsset.AsyncOperationBase obj)
|
||||
{
|
||||
FsmManager.Transition(nameof(FsmStartGame));
|
||||
}
|
||||
|
||||
void IFsmNode.OnUpdate()
|
||||
{
|
||||
}
|
||||
void IFsmNode.OnExit()
|
||||
{
|
||||
}
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1d83ce785f1442a40a1ad0f837073b69
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
+46
@@ -0,0 +1,46 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using YooAsset;
|
||||
|
||||
public class FsmCreateDownloader : IFsmNode
|
||||
{
|
||||
public string Name { private set; get; } = nameof(FsmCreateDownloader);
|
||||
|
||||
void IFsmNode.OnEnter()
|
||||
{
|
||||
PatchEventDispatcher.SendPatchStepsChangeMsg(EPatchStates.CreateDownloader);
|
||||
BootScene.Instance.StartCoroutine(CreateDownloader());
|
||||
}
|
||||
void IFsmNode.OnUpdate()
|
||||
{
|
||||
}
|
||||
void IFsmNode.OnExit()
|
||||
{
|
||||
}
|
||||
|
||||
IEnumerator CreateDownloader()
|
||||
{
|
||||
yield return new WaitForSecondsRealtime(0.5f);
|
||||
|
||||
Debug.Log("创建补丁下载器.");
|
||||
int downloadingMaxNum = 10;
|
||||
int failedTryAgain = 3;
|
||||
PatchManager.Downloader = YooAssets.CreatePatchDownloader(downloadingMaxNum, failedTryAgain);
|
||||
if (PatchManager.Downloader.TotalDownloadCount == 0)
|
||||
{
|
||||
Debug.Log("没有发现需要下载的资源");
|
||||
FsmManager.Transition(nameof(FsmPatchDone));
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.Log($"一共发现了{PatchManager.Downloader.TotalDownloadCount}个资源需要更新下载。");
|
||||
|
||||
// 发现新更新文件后,挂起流程系统
|
||||
// 注意:开发者需要在下载前检测磁盘空间不足
|
||||
int totalDownloadCount = PatchManager.Downloader.TotalDownloadCount;
|
||||
long totalDownloadBytes = PatchManager.Downloader.TotalDownloadBytes;
|
||||
PatchEventDispatcher.SendFoundUpdateFilesMsg(totalDownloadCount, totalDownloadBytes);
|
||||
}
|
||||
}
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8b104741ebcb72946abe282c1da73360
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
+36
@@ -0,0 +1,36 @@
|
||||
using System.Collections;
|
||||
using YooAsset;
|
||||
|
||||
public class FsmDownloadFiles : IFsmNode
|
||||
{
|
||||
public string Name { private set; get; } = nameof(FsmDownloadFiles);
|
||||
|
||||
void IFsmNode.OnEnter()
|
||||
{
|
||||
PatchEventDispatcher.SendPatchStepsChangeMsg(EPatchStates.DownloadWebFiles);
|
||||
BootScene.Instance.StartCoroutine(BeginDownload());
|
||||
}
|
||||
void IFsmNode.OnUpdate()
|
||||
{
|
||||
}
|
||||
void IFsmNode.OnExit()
|
||||
{
|
||||
}
|
||||
|
||||
private IEnumerator BeginDownload()
|
||||
{
|
||||
var downloader = PatchManager.Downloader;
|
||||
|
||||
// 注册下载回调
|
||||
downloader.OnDownloadErrorCallback = PatchEventDispatcher.SendWebFileDownloadFailedMsg;
|
||||
downloader.OnDownloadProgressCallback = PatchEventDispatcher.SendDownloadProgressUpdateMsg;
|
||||
downloader.BeginDownload();
|
||||
yield return downloader;
|
||||
|
||||
// 检测下载结果
|
||||
if (downloader.Status != EOperationStatus.Succeed)
|
||||
yield break;
|
||||
|
||||
FsmManager.Transition(nameof(FsmPatchDone));
|
||||
}
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a3fae22040fe2d541ab4582c7c1c71fb
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
internal class FsmPatchDone : IFsmNode
|
||||
{
|
||||
public string Name { private set; get; } = nameof(FsmPatchDone);
|
||||
|
||||
void IFsmNode.OnEnter()
|
||||
{
|
||||
PatchEventDispatcher.SendPatchStepsChangeMsg(EPatchStates.PatchDone);
|
||||
Debug.Log("补丁流程更新完毕!");
|
||||
|
||||
FsmManager.Transition(nameof(FsmClearCache));
|
||||
}
|
||||
void IFsmNode.OnUpdate()
|
||||
{
|
||||
}
|
||||
void IFsmNode.OnExit()
|
||||
{
|
||||
}
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6cf80cfbed474c34b892eaeda7fcb054
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
+30
@@ -0,0 +1,30 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
internal class FsmPatchInit : IFsmNode
|
||||
{
|
||||
public string Name { private set; get; } = nameof(FsmPatchInit);
|
||||
|
||||
void IFsmNode.OnEnter()
|
||||
{
|
||||
// 加载更新面板
|
||||
var go = Resources.Load<GameObject>("PatchWindow");
|
||||
GameObject.Instantiate(go);
|
||||
|
||||
BootScene.Instance.StartCoroutine(Begin());
|
||||
}
|
||||
void IFsmNode.OnUpdate()
|
||||
{
|
||||
}
|
||||
void IFsmNode.OnExit()
|
||||
{
|
||||
}
|
||||
|
||||
private IEnumerator Begin()
|
||||
{
|
||||
yield return new WaitForSecondsRealtime(0.5f);
|
||||
|
||||
FsmManager.Transition(nameof(FsmUpdateVersion));
|
||||
}
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8998f67b4187d404eb26190f5cd5ac86
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
internal class FsmStartGame : IFsmNode
|
||||
{
|
||||
public string Name { private set; get; } = nameof(FsmStartGame);
|
||||
|
||||
void IFsmNode.OnEnter()
|
||||
{
|
||||
Debug.Log("开始游戏!");
|
||||
YooAsset.YooAssets.LoadSceneAsync("scene_home");
|
||||
}
|
||||
void IFsmNode.OnUpdate()
|
||||
{
|
||||
}
|
||||
void IFsmNode.OnExit()
|
||||
{
|
||||
}
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1c01a6c3b0dbdaf43ad5e31634eef386
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
+41
@@ -0,0 +1,41 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using YooAsset;
|
||||
|
||||
public class FsmUpdateManifest : IFsmNode
|
||||
{
|
||||
public string Name { private set; get; } = nameof(FsmUpdateManifest);
|
||||
|
||||
void IFsmNode.OnEnter()
|
||||
{
|
||||
PatchEventDispatcher.SendPatchStepsChangeMsg(EPatchStates.UpdateManifest);
|
||||
BootScene.Instance.StartCoroutine(UpdateManifest());
|
||||
}
|
||||
void IFsmNode.OnUpdate()
|
||||
{
|
||||
}
|
||||
void IFsmNode.OnExit()
|
||||
{
|
||||
}
|
||||
|
||||
private IEnumerator UpdateManifest()
|
||||
{
|
||||
yield return new WaitForSecondsRealtime(0.5f);
|
||||
|
||||
// 更新补丁清单
|
||||
var package = YooAssets.GetAssetsPackage("DefaultPackage");
|
||||
var operation = package.UpdatePackageManifestAsync(PatchManager.PackageVersion, 30);
|
||||
yield return operation;
|
||||
|
||||
if(operation.Status == EOperationStatus.Succeed)
|
||||
{
|
||||
FsmManager.Transition(nameof(FsmCreateDownloader));
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogWarning(operation.Error);
|
||||
PatchEventDispatcher.SendPatchManifestUpdateFailedMsg();
|
||||
}
|
||||
}
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b4b6ef49759dcf14d80c5aa2d360f597
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
+42
@@ -0,0 +1,42 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using YooAsset;
|
||||
|
||||
internal class FsmUpdateVersion : IFsmNode
|
||||
{
|
||||
public string Name { private set; get; } = nameof(FsmUpdateVersion);
|
||||
|
||||
void IFsmNode.OnEnter()
|
||||
{
|
||||
PatchEventDispatcher.SendPatchStepsChangeMsg(EPatchStates.UpdateStaticVersion);
|
||||
BootScene.Instance.StartCoroutine(GetStaticVersion());
|
||||
}
|
||||
void IFsmNode.OnUpdate()
|
||||
{
|
||||
}
|
||||
void IFsmNode.OnExit()
|
||||
{
|
||||
}
|
||||
|
||||
private IEnumerator GetStaticVersion()
|
||||
{
|
||||
yield return new WaitForSecondsRealtime(0.5f);
|
||||
|
||||
// 更新资源版本号
|
||||
var package = YooAssets.GetAssetsPackage("DefaultPackage");
|
||||
var operation = package.UpdatePackageVersionAsync(30);
|
||||
yield return operation;
|
||||
|
||||
if (operation.Status == EOperationStatus.Succeed)
|
||||
{
|
||||
PatchManager.PackageVersion = operation.PackageVersion;
|
||||
FsmManager.Transition(nameof(FsmUpdateManifest));
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogWarning(operation.Error);
|
||||
PatchEventDispatcher.SendStaticVersionUpdateFailedMsg();
|
||||
}
|
||||
}
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f5ea76dfe0fc52b47a00a3bf68a54d09
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
+54
@@ -0,0 +1,54 @@
|
||||
|
||||
public class PatchEventDefine
|
||||
{
|
||||
/// <summary>
|
||||
/// 补丁流程步骤改变
|
||||
/// </summary>
|
||||
public class PatchStatesChange : IEventMessage
|
||||
{
|
||||
public EPatchStates CurrentStates;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 发现更新文件
|
||||
/// </summary>
|
||||
public class FoundUpdateFiles : IEventMessage
|
||||
{
|
||||
public int TotalCount;
|
||||
public long TotalSizeBytes;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 下载进度更新
|
||||
/// </summary>
|
||||
public class DownloadProgressUpdate : IEventMessage
|
||||
{
|
||||
public int TotalDownloadCount;
|
||||
public int CurrentDownloadCount;
|
||||
public long TotalDownloadSizeBytes;
|
||||
public long CurrentDownloadSizeBytes;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 资源版本号更新失败
|
||||
/// </summary>
|
||||
public class StaticVersionUpdateFailed : IEventMessage
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 补丁清单更新失败
|
||||
/// </summary>
|
||||
public class PatchManifestUpdateFailed : IEventMessage
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 网络文件下载失败
|
||||
/// </summary>
|
||||
public class WebFileDownloadFailed : IEventMessage
|
||||
{
|
||||
public string FileName;
|
||||
public string Error;
|
||||
}
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7bb954fb42c50874b8897756e8b5dae5
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
+43
@@ -0,0 +1,43 @@
|
||||
|
||||
public static class PatchEventDispatcher
|
||||
{
|
||||
public static void SendPatchStepsChangeMsg(EPatchStates currentStates)
|
||||
{
|
||||
PatchEventDefine.PatchStatesChange msg = new PatchEventDefine.PatchStatesChange();
|
||||
msg.CurrentStates = currentStates;
|
||||
EventManager.SendMessage(msg);
|
||||
}
|
||||
public static void SendFoundUpdateFilesMsg(int totalCount, long totalSizeBytes)
|
||||
{
|
||||
PatchEventDefine.FoundUpdateFiles msg = new PatchEventDefine.FoundUpdateFiles();
|
||||
msg.TotalCount = totalCount;
|
||||
msg.TotalSizeBytes = totalSizeBytes;
|
||||
EventManager.SendMessage(msg);
|
||||
}
|
||||
public static void SendDownloadProgressUpdateMsg(int totalDownloadCount, int currentDownloadCount, long totalDownloadSizeBytes, long currentDownloadSizeBytes)
|
||||
{
|
||||
PatchEventDefine.DownloadProgressUpdate msg = new PatchEventDefine.DownloadProgressUpdate();
|
||||
msg.TotalDownloadCount = totalDownloadCount;
|
||||
msg.CurrentDownloadCount = currentDownloadCount;
|
||||
msg.TotalDownloadSizeBytes = totalDownloadSizeBytes;
|
||||
msg.CurrentDownloadSizeBytes = currentDownloadSizeBytes;
|
||||
EventManager.SendMessage(msg);
|
||||
}
|
||||
public static void SendStaticVersionUpdateFailedMsg()
|
||||
{
|
||||
PatchEventDefine.StaticVersionUpdateFailed msg = new PatchEventDefine.StaticVersionUpdateFailed();
|
||||
EventManager.SendMessage(msg);
|
||||
}
|
||||
public static void SendPatchManifestUpdateFailedMsg()
|
||||
{
|
||||
PatchEventDefine.PatchManifestUpdateFailed msg = new PatchEventDefine.PatchManifestUpdateFailed();
|
||||
EventManager.SendMessage(msg);
|
||||
}
|
||||
public static void SendWebFileDownloadFailedMsg(string fileName, string error)
|
||||
{
|
||||
PatchEventDefine.WebFileDownloadFailed msg = new PatchEventDefine.WebFileDownloadFailed();
|
||||
msg.FileName = fileName;
|
||||
msg.Error = error;
|
||||
EventManager.SendMessage(msg);
|
||||
}
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: fe1971e74e4881641b59485f977219dc
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
+75
@@ -0,0 +1,75 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using YooAsset;
|
||||
|
||||
public static class PatchManager
|
||||
{
|
||||
private static bool _isRun = false;
|
||||
|
||||
/// <summary>
|
||||
/// 下载器
|
||||
/// </summary>
|
||||
public static PatchDownloaderOperation Downloader { set; get; }
|
||||
|
||||
/// <summary>
|
||||
/// 包裹的版本信息
|
||||
/// </summary>
|
||||
public static string PackageVersion { set; get; }
|
||||
|
||||
/// <summary>
|
||||
/// 开启初始化流程
|
||||
/// </summary>
|
||||
public static void Run()
|
||||
{
|
||||
if (_isRun == false)
|
||||
{
|
||||
_isRun = true;
|
||||
|
||||
Debug.Log("开始补丁更新...");
|
||||
|
||||
// 注意:按照先后顺序添加流程节点
|
||||
FsmManager.AddNode(new FsmPatchInit());
|
||||
FsmManager.AddNode(new FsmUpdateVersion());
|
||||
FsmManager.AddNode(new FsmUpdateManifest());
|
||||
FsmManager.AddNode(new FsmCreateDownloader());
|
||||
FsmManager.AddNode(new FsmDownloadFiles());
|
||||
FsmManager.AddNode(new FsmPatchDone());
|
||||
FsmManager.AddNode(new FsmClearCache());
|
||||
FsmManager.AddNode(new FsmStartGame());
|
||||
FsmManager.Run(nameof(FsmPatchInit));
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogWarning("补丁更新已经正在进行中!");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 处理请求操作
|
||||
/// </summary>
|
||||
public static void HandleOperation(EPatchOperation operation)
|
||||
{
|
||||
if (operation == EPatchOperation.BeginDownloadWebFiles)
|
||||
{
|
||||
FsmManager.Transition(nameof(FsmDownloadFiles));
|
||||
}
|
||||
else if(operation == EPatchOperation.TryUpdateStaticVersion)
|
||||
{
|
||||
FsmManager.Transition(nameof(FsmUpdateVersion));
|
||||
}
|
||||
else if (operation == EPatchOperation.TryUpdatePatchManifest)
|
||||
{
|
||||
FsmManager.Transition(nameof(FsmUpdateManifest));
|
||||
}
|
||||
else if (operation == EPatchOperation.TryDownloadWebFiles)
|
||||
{
|
||||
FsmManager.Transition(nameof(FsmCreateDownloader));
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new NotImplementedException($"{operation}");
|
||||
}
|
||||
}
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4c1b4cadd806a1a409db720564a44a83
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
+185
@@ -0,0 +1,185 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
public class PatchWindow : MonoBehaviour
|
||||
{
|
||||
/// <summary>
|
||||
/// 对话框封装类
|
||||
/// </summary>
|
||||
private class MessageBox
|
||||
{
|
||||
private GameObject _cloneObject;
|
||||
private Text _content;
|
||||
private Button _btnOK;
|
||||
private System.Action _clickOK;
|
||||
|
||||
public bool ActiveSelf
|
||||
{
|
||||
get
|
||||
{
|
||||
return _cloneObject.activeSelf;
|
||||
}
|
||||
}
|
||||
|
||||
public void Create(GameObject cloneObject)
|
||||
{
|
||||
_cloneObject = cloneObject;
|
||||
_content = cloneObject.transform.Find("txt_content").GetComponent<Text>();
|
||||
_btnOK = cloneObject.transform.Find("btn_ok").GetComponent<Button>();
|
||||
_btnOK.onClick.AddListener(OnClickYes);
|
||||
}
|
||||
public void Show(string content, System.Action clickOK)
|
||||
{
|
||||
_content.text = content;
|
||||
_clickOK = clickOK;
|
||||
_cloneObject.SetActive(true);
|
||||
_cloneObject.transform.SetAsLastSibling();
|
||||
}
|
||||
public void Hide()
|
||||
{
|
||||
_content.text = string.Empty;
|
||||
_clickOK = null;
|
||||
_cloneObject.SetActive(false);
|
||||
}
|
||||
private void OnClickYes()
|
||||
{
|
||||
_clickOK?.Invoke();
|
||||
Hide();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private readonly EventGroup _eventGroup = new EventGroup();
|
||||
private readonly List<MessageBox> _msgBoxList = new List<MessageBox>();
|
||||
|
||||
// UGUI相关
|
||||
private GameObject _messageBoxObj;
|
||||
private Slider _slider;
|
||||
private Text _tips;
|
||||
|
||||
|
||||
void Awake()
|
||||
{
|
||||
_slider = transform.Find("UIWindow/Slider").GetComponent<Slider>();
|
||||
_tips = transform.Find("UIWindow/Slider/txt_tips").GetComponent<Text>();
|
||||
_tips.text = "Initializing the game world !";
|
||||
_messageBoxObj = transform.Find("UIWindow/MessgeBox").gameObject;
|
||||
_messageBoxObj.SetActive(false);
|
||||
|
||||
_eventGroup.AddListener<PatchEventDefine.PatchStatesChange>(OnHandleEvent);
|
||||
_eventGroup.AddListener<PatchEventDefine.FoundUpdateFiles>(OnHandleEvent);
|
||||
_eventGroup.AddListener<PatchEventDefine.DownloadProgressUpdate>(OnHandleEvent);
|
||||
_eventGroup.AddListener<PatchEventDefine.StaticVersionUpdateFailed>(OnHandleEvent);
|
||||
_eventGroup.AddListener<PatchEventDefine.PatchManifestUpdateFailed>(OnHandleEvent);
|
||||
_eventGroup.AddListener<PatchEventDefine.WebFileDownloadFailed>(OnHandleEvent);
|
||||
}
|
||||
void OnDestroy()
|
||||
{
|
||||
_eventGroup.RemoveAllListener();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 接收事件
|
||||
/// </summary>
|
||||
private void OnHandleEvent(IEventMessage msg)
|
||||
{
|
||||
if (msg is PatchEventDefine.PatchStatesChange)
|
||||
{
|
||||
var message = msg as PatchEventDefine.PatchStatesChange;
|
||||
if (message.CurrentStates == EPatchStates.UpdateStaticVersion)
|
||||
_tips.text = "Update static version.";
|
||||
else if (message.CurrentStates == EPatchStates.UpdateManifest)
|
||||
_tips.text = "Update patch manifest.";
|
||||
else if (message.CurrentStates == EPatchStates.CreateDownloader)
|
||||
_tips.text = "Check download contents.";
|
||||
else if (message.CurrentStates == EPatchStates.DownloadWebFiles)
|
||||
_tips.text = "Downloading patch files.";
|
||||
else if (message.CurrentStates == EPatchStates.PatchDone)
|
||||
_tips.text = "Welcome to game world !";
|
||||
else
|
||||
throw new NotImplementedException(message.CurrentStates.ToString());
|
||||
}
|
||||
else if (msg is PatchEventDefine.FoundUpdateFiles)
|
||||
{
|
||||
var message = msg as PatchEventDefine.FoundUpdateFiles;
|
||||
System.Action callback = () =>
|
||||
{
|
||||
PatchManager.HandleOperation(EPatchOperation.BeginDownloadWebFiles);
|
||||
};
|
||||
float sizeMB = message.TotalSizeBytes / 1048576f;
|
||||
sizeMB = Mathf.Clamp(sizeMB, 0.1f, float.MaxValue);
|
||||
string totalSizeMB = sizeMB.ToString("f1");
|
||||
ShowMessageBox($"Found update patch files, Total count {message.TotalCount} Total szie {totalSizeMB}MB", callback);
|
||||
}
|
||||
else if (msg is PatchEventDefine.DownloadProgressUpdate)
|
||||
{
|
||||
var message = msg as PatchEventDefine.DownloadProgressUpdate;
|
||||
_slider.value = (float)message.CurrentDownloadCount / message.TotalDownloadCount;
|
||||
string currentSizeMB = (message.CurrentDownloadSizeBytes / 1048576f).ToString("f1");
|
||||
string totalSizeMB = (message.TotalDownloadSizeBytes / 1048576f).ToString("f1");
|
||||
_tips.text = $"{message.CurrentDownloadCount}/{message.TotalDownloadCount} {currentSizeMB}MB/{totalSizeMB}MB";
|
||||
}
|
||||
else if (msg is PatchEventDefine.StaticVersionUpdateFailed)
|
||||
{
|
||||
System.Action callback = () =>
|
||||
{
|
||||
PatchManager.HandleOperation(EPatchOperation.TryUpdateStaticVersion);
|
||||
};
|
||||
ShowMessageBox($"Failed to update static version, please check the network status.", callback);
|
||||
}
|
||||
else if (msg is PatchEventDefine.PatchManifestUpdateFailed)
|
||||
{
|
||||
System.Action callback = () =>
|
||||
{
|
||||
PatchManager.HandleOperation(EPatchOperation.TryUpdatePatchManifest);
|
||||
};
|
||||
ShowMessageBox($"Failed to update patch manifest, please check the network status.", callback);
|
||||
}
|
||||
else if (msg is PatchEventDefine.WebFileDownloadFailed)
|
||||
{
|
||||
var message = msg as PatchEventDefine.WebFileDownloadFailed;
|
||||
System.Action callback = () =>
|
||||
{
|
||||
PatchManager.HandleOperation(EPatchOperation.TryDownloadWebFiles);
|
||||
};
|
||||
ShowMessageBox($"Failed to download file : {message.FileName}", callback);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new System.NotImplementedException($"{msg.GetType()}");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 显示对话框
|
||||
/// </summary>
|
||||
private void ShowMessageBox(string content, System.Action ok)
|
||||
{
|
||||
// 尝试获取一个可用的对话框
|
||||
MessageBox msgBox = null;
|
||||
for (int i = 0; i < _msgBoxList.Count; i++)
|
||||
{
|
||||
var item = _msgBoxList[i];
|
||||
if (item.ActiveSelf == false)
|
||||
{
|
||||
msgBox = item;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// 如果没有可用的对话框,则创建一个新的对话框
|
||||
if (msgBox == null)
|
||||
{
|
||||
msgBox = new MessageBox();
|
||||
var cloneObject = GameObject.Instantiate(_messageBoxObj, _messageBoxObj.transform.parent);
|
||||
msgBox.Create(cloneObject);
|
||||
_msgBoxList.Add(msgBox);
|
||||
}
|
||||
|
||||
// 显示对话框
|
||||
msgBox.Show(content, ok);
|
||||
}
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c569e2dd13155914aa41a50e0e588b6d
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: fadb6c5775042624595410d325420148
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,55 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
using YooAsset;
|
||||
|
||||
public class UIBattleWindow : MonoBehaviour
|
||||
{
|
||||
private Text _scoreLabel;
|
||||
private GameObject _overView;
|
||||
|
||||
void Awake()
|
||||
{
|
||||
_scoreLabel = this.transform.Find("ScoreView/Score").GetComponent<Text>();
|
||||
_scoreLabel.text = "Score : 0";
|
||||
|
||||
var restartBtn = this.transform.Find("OverView/Restart").GetComponent<Button>();
|
||||
restartBtn.onClick.AddListener(OnClickLoginBtn);
|
||||
|
||||
var homeBtn = this.transform.Find("OverView/Home").GetComponent<Button>();
|
||||
homeBtn.onClick.AddListener(OnClickHomeBtn);
|
||||
|
||||
_overView = this.transform.Find("OverView").gameObject;
|
||||
_overView.gameObject.SetActive(false);
|
||||
|
||||
EventManager.AddListener<BattleEventDefine.ScoreChange>(OnHandleEventMessage);
|
||||
EventManager.AddListener<BattleEventDefine.GameOver>(OnHandleEventMessage);
|
||||
}
|
||||
void OnDestroy()
|
||||
{
|
||||
EventManager.RemoveListener<BattleEventDefine.ScoreChange > (OnHandleEventMessage);
|
||||
EventManager.RemoveListener<BattleEventDefine.GameOver>(OnHandleEventMessage);
|
||||
}
|
||||
|
||||
private void OnClickLoginBtn()
|
||||
{
|
||||
YooAssets.LoadSceneAsync("scene_game");
|
||||
}
|
||||
private void OnClickHomeBtn()
|
||||
{
|
||||
YooAssets.LoadSceneAsync("scene_home");
|
||||
}
|
||||
private void OnHandleEventMessage(IEventMessage message)
|
||||
{
|
||||
if(message is BattleEventDefine.ScoreChange)
|
||||
{
|
||||
var msg = message as BattleEventDefine.ScoreChange;
|
||||
_scoreLabel.text = $"Score : {msg.CurrentScores}";
|
||||
}
|
||||
else if(message is BattleEventDefine.GameOver)
|
||||
{
|
||||
_overView.SetActive(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9776c197a7f86e94c9484946495616bb
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,19 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
using YooAsset;
|
||||
|
||||
public class UILoginWindow : MonoBehaviour
|
||||
{
|
||||
void Awake()
|
||||
{
|
||||
var loginBtn = this.transform.Find("Start").GetComponent<Button>();
|
||||
loginBtn.onClick.AddListener(OnClickLoginBtn);
|
||||
}
|
||||
|
||||
private void OnClickLoginBtn()
|
||||
{
|
||||
YooAssets.LoadSceneAsync("scene_game");
|
||||
}
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4792d7c57be85c845bc50d7215160853
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Reference in New Issue
Block a user