【m】框架大更新

This commit is contained in:
2025-10-31 11:18:23 +08:00
parent ae6e7c804b
commit 8e1d52ddbf
1883 changed files with 213934 additions and 640 deletions

View File

@@ -0,0 +1,234 @@
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UniFramework.Event;
using UniFramework.Utility;
using YooAsset;
using Random = UnityEngine.Random;
[Serializable]
public class RoomBoundary
{
public float xMin, xMax, zMin, zMax;
}
/// <summary>
/// 战斗房间
/// </summary>
public class BattleRoom
{
private enum ESteps
{
None,
Ready,
SpawnEnemy,
WaitSpawn,
WaitWave,
GameOver,
}
private readonly EventGroup _eventGroup = new EventGroup();
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 readonly UniTimer _startWaitTimer = UniTimer.CreateOnceTimer(1f);
private readonly UniTimer _spawnWaitTimer = UniTimer.CreateOnceTimer(0.75f);
private readonly UniTimer _waveWaitTimer = UniTimer.CreateOnceTimer(4f);
private readonly List<AssetHandle> _handles = new List<AssetHandle>(1000);
/// <summary>
/// 初始化房间
/// </summary>
public void IntRoom()
{
// 创建房间根对象
_roomRoot = new GameObject("BattleRoom");
// 监听游戏事件
_eventGroup.AddListener<BattleEventDefine.PlayerDead>(OnHandleEventMessage);
_eventGroup.AddListener<BattleEventDefine.EnemyDead>(OnHandleEventMessage);
_eventGroup.AddListener<BattleEventDefine.AsteroidExplosion>(OnHandleEventMessage);
_eventGroup.AddListener<BattleEventDefine.PlayerFireBullet>(OnHandleEventMessage);
_eventGroup.AddListener<BattleEventDefine.EnemyFireBullet>(OnHandleEventMessage);
_steps = ESteps.Ready;
}
/// <summary>
/// 销毁房间
/// </summary>
public void DestroyRoom()
{
if (_eventGroup != null)
_eventGroup.RemoveAllListener();
if (_roomRoot != null)
GameObject.Destroy(_roomRoot);
foreach(var handle in _handles)
{
handle.Release();
}
_handles.Clear();
}
/// <summary>
/// 更新房间
/// </summary>
public void UpdateRoom()
{
if (_steps == ESteps.None || _steps == ESteps.GameOver)
return;
if (_steps == ESteps.Ready)
{
if (_startWaitTimer.Update(Time.deltaTime))
{
// 生成实体
var assetHandle = YooAssets.LoadAssetAsync<GameObject>("player_ship");
assetHandle.Completed += (AssetHandle handle) =>
{
handle.InstantiateSync(_roomRoot.transform);
};
_handles.Add(assetHandle);
_steps = ESteps.SpawnEnemy;
}
}
if (_steps == ESteps.SpawnEnemy)
{
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;
// 生成实体
var assetHandle = YooAssets.LoadAssetAsync<GameObject>(enemyLocation);
assetHandle.Completed += (AssetHandle handle) =>
{
handle.InstantiateSync(spawnPosition, spawnRotation, _roomRoot.transform);
};
_handles.Add(assetHandle);
_waveSpawnCount++;
if (_waveSpawnCount >= EnemyCount)
{
_steps = ESteps.WaitWave;
}
else
{
_steps = ESteps.WaitSpawn;
}
}
if (_steps == ESteps.WaitSpawn)
{
if (_spawnWaitTimer.Update(Time.deltaTime))
{
_spawnWaitTimer.Reset();
_steps = ESteps.SpawnEnemy;
}
}
if (_steps == ESteps.WaitWave)
{
if (_waveWaitTimer.Update(Time.deltaTime))
{
_waveWaitTimer.Reset();
_waveSpawnCount = 0;
_steps = ESteps.SpawnEnemy;
}
}
}
/// <summary>
/// 接收事件
/// </summary>
/// <param name="message"></param>
private void OnHandleEventMessage(IEventMessage message)
{
if (message is BattleEventDefine.PlayerDead)
{
var msg = message as BattleEventDefine.PlayerDead;
// 创建爆炸效果
var assetHandle = YooAssets.LoadAssetAsync<GameObject>("explosion_player");
assetHandle.Completed += (AssetHandle handle) =>
{
handle.InstantiateSync(msg.Position, msg.Rotation, _roomRoot.transform);
};
_handles.Add(assetHandle);
_steps = ESteps.GameOver;
BattleEventDefine.GameOver.SendEventMessage();
}
else if (message is BattleEventDefine.EnemyDead)
{
var msg = message as BattleEventDefine.EnemyDead;
// 创建爆炸效果
var assetHandle = YooAssets.LoadAssetAsync<GameObject>("explosion_enemy");
assetHandle.Completed += (AssetHandle handle) =>
{
handle.InstantiateSync(msg.Position, msg.Rotation, _roomRoot.transform);
};
_handles.Add(assetHandle);
_totalScore += EnemyScore;
BattleEventDefine.ScoreChange.SendEventMessage(_totalScore);
}
else if (message is BattleEventDefine.AsteroidExplosion)
{
var msg = message as BattleEventDefine.AsteroidExplosion;
// 创建爆炸效果
var assetHandle = YooAssets.LoadAssetAsync<GameObject>("explosion_asteroid");
assetHandle.Completed += (AssetHandle handle) =>
{
handle.InstantiateSync(msg.Position, msg.Rotation, _roomRoot.transform);
};
_handles.Add(assetHandle);
_totalScore += AsteroidScore;
BattleEventDefine.ScoreChange.SendEventMessage(_totalScore);
}
else if (message is BattleEventDefine.PlayerFireBullet)
{
var msg = message as BattleEventDefine.PlayerFireBullet;
// 创建子弹实体
var assetHandle = YooAssets.LoadAssetAsync<GameObject>("player_bullet");
assetHandle.Completed += (AssetHandle handle) =>
{
handle.InstantiateSync(msg.Position, msg.Rotation, _roomRoot.transform);
};
_handles.Add(assetHandle);
}
else if (message is BattleEventDefine.EnemyFireBullet)
{
var msg = message as BattleEventDefine.EnemyFireBullet;
// 创建子弹实体
var assetHandle = YooAssets.LoadAssetAsync<GameObject>("enemy_bullet");
assetHandle.Completed += (AssetHandle handle) =>
{
handle.InstantiateSync(msg.Position, msg.Rotation, _roomRoot.transform);
};
_handles.Add(assetHandle);
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: d4dfc5f1cace4e8469e496d83b254ac7
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,35 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class EntityAsteroid : MonoBehaviour
{
public float MoveSpeed = -5f;
public float Tumble = 5f;
private Rigidbody _rigidbody;
void Awake()
{
_rigidbody = this.transform.GetComponent<Rigidbody>();
_rigidbody.velocity = this.transform.forward * MoveSpeed;
_rigidbody.angularVelocity = Random.insideUnitSphere * Tumble;
}
void OnTriggerEnter(Collider other)
{
var name = other.gameObject.name;
if (name.StartsWith("player"))
{
BattleEventDefine.AsteroidExplosion.SendEventMessage(this.transform.position, this.transform.rotation);
GameObject.Destroy(this.gameObject);
}
}
void OnTriggerExit(Collider other)
{
var name = other.gameObject.name;
if (name.StartsWith("Boundary"))
{
GameObject.Destroy(this.gameObject);
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: ffef5a382eef32d46b1d6175c85f644e
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,48 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class EntityBullet : MonoBehaviour
{
public float MoveSpeed = 20f;
public float DelayDestroyTime = 5f;
private Rigidbody _rigidbody;
void Awake()
{
_rigidbody = this.transform.GetComponent<Rigidbody>();
_rigidbody.velocity = this.transform.forward * MoveSpeed;
}
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)
{
GameObject.Destroy(this.gameObject);
}
}
if (goName.StartsWith("player_bullet"))
{
if (name.StartsWith("player") == false)
{
GameObject.Destroy(this.gameObject);
}
}
}
void OnTriggerExit(Collider other)
{
var name = other.gameObject.name;
if (name.StartsWith("Boundary"))
{
GameObject.Destroy(this.gameObject);
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 1a9d4ddd3c4e60245b6bc4f9f1435291
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,16 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class EntityEffect : MonoBehaviour
{
public float DelayDestroyTime = 1f;
private void Awake()
{
Invoke(nameof(DelayDestroy), DelayDestroyTime);
}
private void DelayDestroy()
{
GameObject.Destroy(this.gameObject);
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 014c1f9b87e247446bd7d558f8bf143e
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,92 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
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 Transform _shotSpawn;
private Rigidbody _rigidbody;
private AudioSource _audioSource;
private float _lastFireTime = 0f;
private float _currentSpeed;
private float _targetManeuver;
void Awake()
{
_rigidbody = this.gameObject.GetComponent<Rigidbody>();
_audioSource = this.gameObject.GetComponent<AudioSource>();
_shotSpawn = this.transform.Find("shot_spawn");
_rigidbody.velocity = this.transform.forward * -5f;
_lastFireTime = Time.time;
_currentSpeed = _rigidbody.velocity.z;
_targetManeuver = 0f;
StartCoroutine(Evade());
}
void Update()
{
if (Time.time - _lastFireTime >= FireInterval)
{
_lastFireTime = Time.time;
_audioSource.Play();
BattleEventDefine.EnemyFireBullet.SendEventMessage(_shotSpawn.position, _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"))
{
BattleEventDefine.EnemyDead.SendEventMessage(this.transform.position, this.transform.rotation);
GameObject.Destroy(this.gameObject);
}
}
void OnTriggerExit(Collider other)
{
var name = other.gameObject.name;
if (name.StartsWith("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));
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: a613426c4968b3149b8bf9bf88fe41c7
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,57 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class EntityPlayer : MonoBehaviour
{
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;
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();
BattleEventDefine.PlayerFireBullet.SendEventMessage(_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"))
{
BattleEventDefine.PlayerDead.SendEventMessage(this.transform.position, this.transform.rotation);
GameObject.Destroy(this.gameObject);
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: d3933af4e188ec44683e3c52784eadb0
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant: