备份CatanBuilding瘦身独立工程
This commit is contained in:
@@ -0,0 +1,415 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using UnityEngine;
|
||||
using asap.core;
|
||||
using Cinemachine;
|
||||
using DataCenter;
|
||||
using UniRx;
|
||||
using Random = UnityEngine.Random;
|
||||
|
||||
namespace UI.PartnerGather.Mining
|
||||
{
|
||||
/// <summary>
|
||||
/// 事件合作伙伴挖矿场景控制器
|
||||
/// 负责管理整个挖矿场景的逻辑,包括角色移动、挖矿动画、相机跟随等
|
||||
/// 建议挂载在:挖矿场景的根对象上
|
||||
/// </summary>
|
||||
public class EventPartnerMiningSceneController : MonoBehaviour
|
||||
{
|
||||
#region 组件引用配置
|
||||
[Header("=== 核心组件引用 ===")]
|
||||
[Tooltip("角色控制器 - 建议挂载在角色GameObject上")]
|
||||
public EventPartnerMiningCharacterController character;
|
||||
|
||||
[Header("第二主角")]
|
||||
public EventPartnerMiningCharacterController Character2; // 好友的
|
||||
|
||||
[Tooltip("挖矿点管理器 - 建议挂载在MiningPoints容器对象上")]
|
||||
public EventPartnerMiningPointManager miningPoints;
|
||||
|
||||
[Tooltip("火车控制器 - 建议挂载在Train容器对象上")]
|
||||
public EventPartnerTrainController trainController;
|
||||
|
||||
[Header("=== 资源配置 ===")]
|
||||
[Tooltip("矿石资源预制体数组 - 从Project窗口拖拽矿石Prefab到这里")]
|
||||
public GameObject[] miningResourcePrefabs; // P_miningresource_01~05
|
||||
|
||||
|
||||
// [Header("=== 相机跟随设置 ===")]
|
||||
// [Tooltip("跟随相机Transform - 通常是Main Camera")]
|
||||
// public Transform followCamera;
|
||||
// [Range(-10f, 10f)]
|
||||
// public float cameraOffsetX = 2f;
|
||||
// [Range(0f, 20f)]
|
||||
// public float cameraY = 5f;
|
||||
// [Range(-50f, 0f)]
|
||||
// public float cameraZ = -10f;
|
||||
// [Range(1f, 20f)]
|
||||
// public float cameraSmooth = 8f;
|
||||
|
||||
[Header("=== 动画与移动配置 ===")]
|
||||
[Range(0.5f, 10f)]
|
||||
[Tooltip("角色移动速度")]
|
||||
public float characterMoveSpeed = 2f;
|
||||
[Range(0.5f, 5f)]
|
||||
[Tooltip("挖矿动画持续时间")]
|
||||
public float miningDuration = 2f;
|
||||
[Range(0.01f, 1f)]
|
||||
[Tooltip("矿石生成间隔")]
|
||||
public float oreGenerateDelay = 0.5f;
|
||||
#endregion
|
||||
|
||||
|
||||
#region 运行时数据
|
||||
private CinemachineVirtualCameraBase _targetVcam;
|
||||
// 动态生成的矿石对象缓存
|
||||
private readonly List<GameObject> _activeMiningResources = new();
|
||||
// 管理矿石堆,一个一个的场景可能更好
|
||||
private readonly List<Transform> _listOre = new();
|
||||
|
||||
// 数据管理与事件订阅
|
||||
private EventPartnerGatherManager _manager;
|
||||
|
||||
//
|
||||
private CompositeDisposable _disposables = new();
|
||||
// UI面板引用
|
||||
private EventPartnerDrawMiningPanel _drawMiningPanel;
|
||||
|
||||
// 数据同步缓存(用于检测变化)
|
||||
private int _lastMiningProgress = -1;
|
||||
private int _lastTrainProgress = -1;
|
||||
private int _lastPoints = -1;
|
||||
#endregion
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
// 获取数据管理器
|
||||
_manager = GContext.container.Resolve<EventPartnerGatherManager>();
|
||||
// 自动查找子组件
|
||||
InitializeComponents();
|
||||
Log("EventPartnerMiningSceneController 初始化完成");
|
||||
// 第二主角
|
||||
Log(Character2);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 自动查找和初始化子组件
|
||||
/// 如果Inspector中未手动分配组件,会尝试在子对象中查找
|
||||
/// </summary>
|
||||
private void InitializeComponents()
|
||||
{
|
||||
Log("开始初始化挖矿场景组件...");
|
||||
|
||||
// 查找挖矿点管理器
|
||||
if (!miningPoints)
|
||||
{
|
||||
miningPoints = GetComponentInChildren<EventPartnerMiningPointManager>();
|
||||
Log(miningPoints != null
|
||||
? $"✓ 自动找到挖矿点管理器: {miningPoints.name}"
|
||||
: "⚠ 警告:未找到EventPartnerMiningPointManager组件");
|
||||
}
|
||||
|
||||
// 查找角色控制器
|
||||
if (!character)
|
||||
{
|
||||
character = GetComponentInChildren<EventPartnerMiningCharacterController>();
|
||||
Log(character ? $"✓ 自动找到角色控制器: {character.name}" : "⚠ 警告:未找到EventPartnerMiningCharacterController组件");
|
||||
}
|
||||
|
||||
|
||||
|
||||
// 查找火车控制器
|
||||
if (!trainController)
|
||||
{
|
||||
trainController = GetComponentInChildren<EventPartnerTrainController>();
|
||||
Log(trainController ? $"✓ 自动找到火车控制器: {trainController.name}" : "⚠ 警告:未找到EventPartnerTrainController组件");
|
||||
}
|
||||
|
||||
// // 查找跟随相机(如果未设置)
|
||||
// if (followCamera == null)
|
||||
// {
|
||||
// var mainCamera = Camera.main;
|
||||
// if (mainCamera != null)
|
||||
// {
|
||||
// followCamera = mainCamera.transform;
|
||||
// Log($"✓ 自动设置跟随相机: {followCamera.name}");
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// Log("⚠ 警告:未找到主相机,相机跟随功能将不可用");
|
||||
// }
|
||||
// }
|
||||
|
||||
// _vCam = transform.Find("CameraRoot/Camera").GetComponent<CinemachineVirtualCamera>();
|
||||
_targetVcam = transform.Find("CameraRoot/CameraSwitch").GetComponent<CinemachineVirtualCamera>();
|
||||
|
||||
// 验证矿石资源预制体
|
||||
if (miningResourcePrefabs == null || miningResourcePrefabs.Length == 0)
|
||||
{
|
||||
Log("⚠ 警告:未设置矿石资源预制体,矿石生成功能将不可用");
|
||||
}
|
||||
else
|
||||
{
|
||||
Log($"✓ 矿石资源预制体数量: {miningResourcePrefabs.Length}");
|
||||
}
|
||||
|
||||
Log("挖矿场景组件初始化完成");
|
||||
}
|
||||
|
||||
private void OnEnable()
|
||||
{
|
||||
GContext.OnEvent<EventPartnerGatherPointsUpdate>().Subscribe(_ => OnPointsUpdate()).AddTo(_disposables);
|
||||
GContext.OnEvent<EventPartnerGatherMiningProgressUpdate>().Subscribe(evt => OnMiningProgressUpdate(evt)).AddTo(_disposables);
|
||||
GContext.OnEvent<EventPartnerGatherTrainProgressUpdate>().Subscribe(evt => OnTrainProgressUpdate(evt)).AddTo(_disposables);
|
||||
}
|
||||
|
||||
private void Start()
|
||||
{
|
||||
_listOre.Add(transform.Find("ore01"));
|
||||
_listOre.Add(transform.Find("ore02"));
|
||||
_listOre.Add(transform.Find("ore03"));
|
||||
_listOre.Add(transform.Find("ore04"));
|
||||
_listOre.Add(transform.Find("ore05"));
|
||||
|
||||
SyncAllData();
|
||||
}
|
||||
|
||||
private void Update()
|
||||
{
|
||||
// UpdateCameraFollow();
|
||||
PollDataChanges();
|
||||
}
|
||||
|
||||
#region 相机跟随 (来自EventPartnerMiningController)
|
||||
// private void UpdateCameraFollow()
|
||||
// {
|
||||
// if (followCamera == null || character == null) return;
|
||||
// var pos = followCamera.position;
|
||||
// pos.x = Mathf.Lerp(pos.x, character.transform.position.x + cameraOffsetX, Time.deltaTime * cameraSmooth);
|
||||
// pos.y = cameraY;
|
||||
// pos.z = cameraZ;
|
||||
// followCamera.position = pos;
|
||||
// }
|
||||
#endregion
|
||||
|
||||
#region 数据同步监听 (来自EventPartnerMiningController)
|
||||
private void PollDataChanges()
|
||||
{
|
||||
if (_manager?.GatherData == null) return;
|
||||
|
||||
if (_lastPoints != _manager.GatherData.CurrentPoints)
|
||||
{
|
||||
_lastPoints = _manager.GatherData.CurrentPoints;
|
||||
}
|
||||
|
||||
if (_lastMiningProgress != _manager.GatherData.CurrentMiningProgress)
|
||||
{
|
||||
int delta = _manager.GatherData.CurrentMiningProgress - _lastMiningProgress;
|
||||
_lastMiningProgress = _manager.GatherData.CurrentMiningProgress;
|
||||
for (int i = 0; i < Mathf.Max(0, delta); i++)
|
||||
{
|
||||
DoAutoMiningStep();
|
||||
}
|
||||
}
|
||||
|
||||
if (_lastTrainProgress != _manager.GatherData.TrainProgress)
|
||||
{
|
||||
_lastTrainProgress = _manager.GatherData.TrainProgress;
|
||||
UpdateUIPanel();
|
||||
}
|
||||
}
|
||||
|
||||
private void OnPointsUpdate()
|
||||
{
|
||||
UpdateUIPanel();
|
||||
}
|
||||
|
||||
private void OnMiningProgressUpdate(EventPartnerGatherMiningProgressUpdate evt)
|
||||
{
|
||||
Log($"接收到挖矿进度更新事件: {evt.Progress}");
|
||||
// 触发自动挖矿动画(如果进度增加)
|
||||
int delta = evt.Progress - _lastMiningProgress;
|
||||
if (delta > 0)
|
||||
{
|
||||
_lastMiningProgress = evt.Progress;
|
||||
for (int i = 0; i < delta; i++)
|
||||
{
|
||||
DoAutoMiningStep();
|
||||
}
|
||||
}
|
||||
UpdateUIPanel();
|
||||
}
|
||||
|
||||
private void OnTrainProgressUpdate(EventPartnerGatherTrainProgressUpdate evt)
|
||||
{
|
||||
Log($"接收到火车进度更新事件: {evt.Progress}/{evt.MaxNodes}");
|
||||
_lastTrainProgress = evt.Progress;
|
||||
UpdateUIPanel();
|
||||
}
|
||||
|
||||
private void SyncAllData()
|
||||
{
|
||||
if (_manager?.GatherData == null) return;
|
||||
_lastPoints = _manager.GatherData.CurrentPoints;
|
||||
_lastMiningProgress = _manager.GatherData.CurrentMiningProgress;
|
||||
_lastTrainProgress = _manager.GatherData.TrainProgress;
|
||||
UpdateUIPanel();
|
||||
}
|
||||
|
||||
// ReSharper disable Unity.PerformanceAnalysis
|
||||
private async void DoAutoMiningStep()
|
||||
{
|
||||
if (miningPoints == null || character == null) return;
|
||||
var target = miningPoints.GetNextPoint();
|
||||
if (target == null) return;
|
||||
await character.MoveToPosition(target.position, characterMoveSpeed);
|
||||
await character.PlayMining(miningDuration);
|
||||
UpdateUIPanel();
|
||||
}
|
||||
|
||||
private void UpdateUIPanel()
|
||||
{
|
||||
if (_drawMiningPanel == null || _manager?.GatherData == null) return;
|
||||
_drawMiningPanel.SetPoints(_manager.GatherData.CurrentPoints);
|
||||
_drawMiningPanel.SetMiningProgress(_manager.GatherData.CurrentMiningProgress);
|
||||
_drawMiningPanel.SetTrainProgress(_manager.GatherData.TrainProgress, _manager.MaxTrainNodes);
|
||||
}
|
||||
|
||||
public void SetUIPanel(EventPartnerDrawMiningPanel panel)
|
||||
{
|
||||
_drawMiningPanel = panel;
|
||||
}
|
||||
#endregion
|
||||
|
||||
private Transform _transPoint;
|
||||
#region 手动采集流程 (原MiningSceneController功能)
|
||||
public async Task StartMiningSequence(int point)
|
||||
{
|
||||
// 获取下一个挖矿点
|
||||
var targetPoint = miningPoints.GetNextPoint();
|
||||
if (targetPoint == null) return;
|
||||
UpdateActive();
|
||||
|
||||
var userPoint = targetPoint.Find("user_point");
|
||||
var trainPoint = targetPoint.Find("train_point");
|
||||
|
||||
await character.MoveToPosition(userPoint.position, characterMoveSpeed);
|
||||
trainController.StartMoveTo(trainPoint.position);
|
||||
|
||||
await OnEnterMining(point,targetPoint);
|
||||
}
|
||||
|
||||
// 进入阶段,需要积分,计算挖矿到什么阶段
|
||||
private async Task OnEnterMining(int points,Transform targetPoints)
|
||||
{
|
||||
await character.PlayMining(miningDuration);
|
||||
await GenerateAndCollectOres(points);
|
||||
}
|
||||
|
||||
// 更新当前激活对象
|
||||
private void UpdateActive()
|
||||
{
|
||||
// _activeOri =
|
||||
}
|
||||
|
||||
private async Task GenerateAndCollectOres(int points)
|
||||
{
|
||||
Log($"GenerateAndCollectOres-> {points}");
|
||||
// 根据点数生成对应数量的矿石
|
||||
var oreCount = CalculateOreCount(points);
|
||||
var oreList = new List<GameObject>();
|
||||
var listOrePos = CalculateOrePos(points);
|
||||
|
||||
// for (var i = 0; i < oreCount; ++i)
|
||||
// {
|
||||
// var pos = listOrePos[i % listOrePos.Count];
|
||||
// oreList.Add(CreateOre(pos));
|
||||
// }
|
||||
// foreach (var ore in oreList)
|
||||
// {
|
||||
// await Awaiters.Seconds(oreGenerateDelay);
|
||||
// _ = trainController.CollectOre(ore, points);
|
||||
// }
|
||||
for (int i = 0; i < oreCount; i++)
|
||||
{
|
||||
// await Task.Delay((int)(oreGenerateDelay * 1000));
|
||||
await Awaiters.Seconds(oreGenerateDelay);
|
||||
var pos = listOrePos[i % listOrePos.Count];
|
||||
// 生成矿石
|
||||
var ore = CreateOre(pos);
|
||||
if (ore != null)
|
||||
{
|
||||
// 矿石飞入对应车厢
|
||||
_ = trainController.CollectOre(ore, points);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private int CalculateOreCount(int points)
|
||||
{
|
||||
return points switch
|
||||
{
|
||||
// return points;
|
||||
// 根据点数计算矿石数量
|
||||
// if (points >= 50) return 5;
|
||||
// if (points >= 30) return 3;
|
||||
// if (points >= 20) return 2;
|
||||
// return 1;
|
||||
< 100 => 8,
|
||||
< 200 => 16,
|
||||
_ => 1
|
||||
};
|
||||
}
|
||||
|
||||
private List<Vector3> CalculateOrePos(int points)
|
||||
{
|
||||
var ore = _listOre.First();
|
||||
return (from Transform child in ore select child.position).ToList();
|
||||
}
|
||||
private GameObject CreateOre(Vector3 position)
|
||||
{
|
||||
if (miningResourcePrefabs == null || miningResourcePrefabs.Length == 0) return null;
|
||||
// 随机选择一个矿石预制体
|
||||
|
||||
var orePos = new Vector3(position.x, position.y + 2, position.z);
|
||||
|
||||
var prefab = miningResourcePrefabs[Random.Range(0, miningResourcePrefabs.Length)];
|
||||
var ore = Instantiate(prefab, orePos, Quaternion.identity);
|
||||
_activeMiningResources.Add(ore);
|
||||
return ore;
|
||||
}
|
||||
#endregion
|
||||
|
||||
public void ResetScene()
|
||||
{
|
||||
// 清理场景中的矿石
|
||||
foreach (var ore in _activeMiningResources)
|
||||
{
|
||||
if (ore != null) DestroyImmediate(ore);
|
||||
}
|
||||
_activeMiningResources.Clear();
|
||||
|
||||
// 重置挖矿点
|
||||
miningPoints?.ResetPoints();
|
||||
|
||||
// 重置火车状态
|
||||
trainController?.ResetTrain();
|
||||
}
|
||||
|
||||
private void OnDisable()
|
||||
{
|
||||
_disposables.Dispose();
|
||||
_disposables = new CompositeDisposable();
|
||||
if (_targetVcam == null) return;
|
||||
// 方法1:将该相机移动到当前优先级子队列顶部,通常会成为Live或在混合后成为Live
|
||||
_targetVcam.MoveToTopOfPrioritySubqueue();
|
||||
}
|
||||
|
||||
private void Log(object t)
|
||||
{
|
||||
Debug.Log($"<Color=cyan> EventPartnerMiningSceneController {t} </color>");
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user