1707 lines
64 KiB
C#
1707 lines
64 KiB
C#
using System.Collections.Generic;
|
||
using System.Linq;
|
||
using System.Threading.Tasks;
|
||
using UnityEngine;
|
||
using asap.core;
|
||
using Cinemachine;
|
||
using DataCenter;
|
||
using EventPartnerGather;
|
||
using EventPartnerGather.Mining;
|
||
using game;
|
||
using UniRx;
|
||
using UnityEngine.Serialization;
|
||
using Random = UnityEngine.Random;
|
||
|
||
public class EnterTrophyEvent { }
|
||
|
||
namespace UI.PartnerGather.Mining
|
||
{
|
||
|
||
/// <summary>
|
||
/// 事件合作伙伴挖矿场景控制器
|
||
/// 负责管理整个挖矿场景的逻辑,包括角色移动、挖矿动画、相机跟随等
|
||
/// 建议挂载在:挖矿场景的根对象上
|
||
/// </summary>
|
||
public class EventPartnerMiningSceneController : MonoBehaviour
|
||
{
|
||
private const bool EnableTraceLogs = false;
|
||
private const int FlowLogSampleInterval = 5;
|
||
#region 组件引用配置
|
||
[FormerlySerializedAs("character")]
|
||
[Header("=== 核心组件引用 ===")]
|
||
[Tooltip("角色控制器 - 建议挂载在角色GameObject上")]
|
||
public EventPartnerMiningCharacterController character1;
|
||
|
||
[Header("第二主角")]
|
||
public EventPartnerMiningCharacterController character2; // 好友的
|
||
[Header("第二主角的偏移")]
|
||
public Vector3 secondOffsetVector3 = Vector3.zero;
|
||
|
||
|
||
[Header("奖杯摄像机")]
|
||
public CinemachineVirtualCamera vcamArea;
|
||
|
||
[Tooltip("挖矿点管理器 - 建议挂载在MiningPoints容器对象上")]
|
||
public EventPartnerMiningPointManager miningPoints;
|
||
|
||
[Tooltip("火车控制器 - 建议挂载在Train容器对象上")]
|
||
public EventPartnerTrainController trainController;
|
||
|
||
[Header("=== 资源配置 ===")]
|
||
[Tooltip("矿石资源预制体数组 - 从Project窗口拖拽矿石Prefab到这里")]
|
||
public GameObject[] miningFlyResourcePrefabs;
|
||
|
||
// 每一组矿石
|
||
[Tooltip("矿石资源预制体数组")]
|
||
public GameObject[] miningResourcePrefabs;
|
||
|
||
[Tooltip("挖矿几次算一个周期")]
|
||
public int gatherNumPerDuration = 3;
|
||
|
||
|
||
[Header("=== 动画与移动配置 ===")]
|
||
[Range(0.5f, 10f)]
|
||
[Tooltip("角色移动速度")]
|
||
public float characterMoveSpeed = 2f;
|
||
|
||
[Tooltip("用户落点偏移")]
|
||
[Range(-10f, 10f)] public List<float> userPointDelta = new();
|
||
|
||
[Range(0.5f, 5f)]
|
||
[Tooltip("挖矿动画持续时间")]
|
||
public float miningDuration = 2f;
|
||
[Range(0.01f, 1f)]
|
||
[Tooltip("矿石生成间隔")]
|
||
public float oreGenerateDelay = 0.5f;
|
||
[Tooltip("矿石飞行周期")]
|
||
public float oreFlightDuration = 1.0f;
|
||
|
||
// [SerializeField]
|
||
// [Tooltip("矿石距离")]
|
||
private float _columnDistance = 1.12f;
|
||
|
||
#endregion
|
||
|
||
|
||
private IConfig _config;
|
||
|
||
#region 运行时数据
|
||
private CinemachineVirtualCameraBase _vCamSwitch;
|
||
|
||
// 用户摄像机,负责跟随用户
|
||
private CinemachineVirtualCamera _vCamCharacter;
|
||
|
||
//
|
||
public int activePriority = 20;
|
||
// 低级
|
||
private int areaBasePriority = 5;
|
||
|
||
private int zeroPriority = 0;
|
||
|
||
private int chaBasePriority = 10;
|
||
|
||
|
||
// 动态生成的矿石对象缓存
|
||
private readonly List<GameObject> _activeMiningResources = new();
|
||
|
||
// 数据管理与事件订阅
|
||
private EventPartnerGatherManager _manager;
|
||
//
|
||
private CompositeDisposable _disposables = new();
|
||
// UI面板引用
|
||
private EventPartnerDrawMiningPanel _drawMiningPanel;
|
||
|
||
// 数据同步缓存(用于检测变化)
|
||
private int _lastMiningProgress = -1;
|
||
|
||
private int _lastPoints = -1;
|
||
|
||
// private int _lastPartnerPoint = -1;
|
||
// 当前step 剩余的点数
|
||
private int _lastLeftPoint = -1;
|
||
|
||
private int _usedPoints = 0; // 当前已经挖去的矿石数
|
||
|
||
// 当前移动了的Column
|
||
private int _moveColumn = 0;
|
||
// 当前组需要挖掉的矿石
|
||
private readonly List<Transform> _miningOres = new();
|
||
// 可能剩多出的哪一个
|
||
private Transform _lastOre;
|
||
|
||
private int _miningPoint = 0;
|
||
private int _flowLogCounter = 0;
|
||
|
||
//-
|
||
private bool _isStageRewardLogic = false;
|
||
// private bool _isFinalRewardLogic = false;
|
||
|
||
|
||
private readonly IUserService _userService = GContext.container.Resolve<IUserService>();
|
||
|
||
// 当前建造过程
|
||
private BuildPartner _buildPartner;
|
||
//
|
||
private EventPartnerMiningCharacterController mainCharacter;
|
||
private EventPartnerMiningCharacterController otherCharacter;
|
||
|
||
//
|
||
private Vector3 _bornPos1;
|
||
private Vector3 _bornPos2;
|
||
private Vector3 _trainBornPos;
|
||
|
||
|
||
|
||
#endregion
|
||
|
||
private void Awake()
|
||
{
|
||
_config = GContext.container.Resolve<IConfig>();
|
||
// 获取数据管理器
|
||
_manager = GContext.container.Resolve<EventPartnerGatherManager>();
|
||
// 自动查找子组件
|
||
InitializeComponents();
|
||
Trace("SceneControllerInitialized");
|
||
// 第二主角
|
||
// Log(Character2);
|
||
|
||
|
||
|
||
|
||
GContext.OnEvent<EventPartnerGatherPartnerAddScore>().Subscribe(OnAddScore).AddTo(_disposables);
|
||
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);
|
||
GContext.OnEvent<EventMiningOre>().Subscribe(OnMiningOre).AddTo(_disposables);;
|
||
GContext.OnEvent<FishingChallengeContinueEvent>().Subscribe(OnStageLogicContinue).AddTo(_disposables);
|
||
GContext.OnEvent<EnterTrophyEvent>().Subscribe(OnEnterTrophyRegion).AddTo(_disposables);
|
||
GContext.OnEvent<EventPartnerGatherSceneStart>().Subscribe(OnMiningStart).AddTo(_disposables);
|
||
|
||
}
|
||
|
||
private void OnEnable()
|
||
{
|
||
// var outplaySound = GetComponent<OutPlaySound>();
|
||
// if(outplaySound)
|
||
// outplaySound.enabled = true;
|
||
|
||
if (_vCamSwitch)
|
||
{
|
||
_vCamSwitch.Priority = zeroPriority;
|
||
}
|
||
|
||
if (_vCamCharacter)
|
||
{
|
||
_vCamCharacter.Priority = chaBasePriority;
|
||
}
|
||
|
||
if (vcamArea)
|
||
{
|
||
vcamArea.Priority = areaBasePriority;
|
||
}
|
||
}
|
||
|
||
private void Start()
|
||
{
|
||
_columnDistance = miningPoints.cubeWidthZ;
|
||
_buildPartner = _manager.CurrentBuildPartner;
|
||
Physics.IgnoreCollision(character1.GetComponent<CharacterController>(),
|
||
character2.GetComponent<CharacterController>(), true);
|
||
|
||
|
||
}
|
||
|
||
|
||
// #if UNITY_EDITOR
|
||
private void Update()
|
||
{
|
||
// UpdateBonus()
|
||
// UpdateCameraFollow();
|
||
// PollDataChanges();
|
||
|
||
if (_config != null && _config.Get("GM", "0") == "1")
|
||
{
|
||
OnGM();
|
||
}
|
||
}
|
||
|
||
bool isShow;
|
||
private string _spinIdStr;
|
||
|
||
private string _startTime;
|
||
private string _deltaTime;
|
||
|
||
// private bool isChecked = false;
|
||
private void OnGM()
|
||
{
|
||
if (Input.GetKeyDown(KeyCode.K))
|
||
{
|
||
isShow = !isShow;
|
||
}
|
||
// if(Input.GetTouch())
|
||
}
|
||
private void OnGUI()
|
||
{
|
||
if (!isShow)
|
||
{
|
||
return;
|
||
}
|
||
float buttonWidth = 300; // Replace with your desired width
|
||
float buttonHeight = 70; // Replace with your desired height
|
||
var fontSize = 40; // Replace with your desired font size
|
||
GUI.skin.textField.fontSize = fontSize;
|
||
GUI.skin.button.fontSize = fontSize;
|
||
GUI.skin.label.fontSize = fontSize;
|
||
GUI.skin.toggle.fontSize = fontSize;
|
||
// GUILayout.Label($"当前阶段: {_lastMiningProgress}");
|
||
|
||
GUILayout.Label("SpinId:");
|
||
_spinIdStr = GUILayout.TextField(_spinIdStr, GUILayout.Width(buttonWidth), GUILayout.Height(buttonHeight));
|
||
int.TryParse(_spinIdStr, out var spinId);
|
||
_manager.GmSetSpinId(spinId);
|
||
if(GUILayout.Button("关闭作弊",GUILayout.Width(buttonWidth), GUILayout.Height(buttonHeight)))
|
||
{
|
||
_manager.CloseGM();
|
||
_spinIdStr = "";
|
||
}
|
||
|
||
if (GUILayout.Button("清理挖矿数字", GUILayout.Width(buttonWidth), GUILayout.Height(buttonHeight)))
|
||
{
|
||
// var ret = await _manager.BuildWorks(score * _multipleValue,cost);
|
||
CleanMyScore();
|
||
}
|
||
|
||
|
||
GUILayout.Label("作弊时间");
|
||
_startTime = GUILayout.TextField(_startTime, GUILayout.Width(buttonWidth), GUILayout.Height(buttonHeight));
|
||
int.TryParse(_startTime, out var timeSeconds);
|
||
|
||
|
||
_deltaTime = GUILayout.TextField(_deltaTime, GUILayout.Width(buttonWidth), GUILayout.Height(buttonHeight));
|
||
_manager.GMRobotStartTIme(timeSeconds);
|
||
int.TryParse(_deltaTime, out var deltaSeconds);
|
||
|
||
_manager.GMRobotDelta(deltaSeconds);
|
||
|
||
}
|
||
|
||
public async void CleanMyScore()
|
||
{
|
||
await _manager.BuildWorks( _buildPartner.ScoreSelfActual * -1 ,0);
|
||
}
|
||
|
||
// #endif
|
||
public void ShowDebugView()
|
||
{
|
||
if (_config.Get("GM", "0") == "1")
|
||
{
|
||
isShow = !isShow;
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 自动查找和初始化子组件
|
||
/// 如果Inspector中未手动分配组件,会尝试在子对象中查找
|
||
/// </summary>
|
||
private void InitializeComponents()
|
||
{
|
||
Trace("InitSceneComponentsStart");
|
||
// 查找挖矿点管理器
|
||
if (!miningPoints)
|
||
{
|
||
miningPoints = GetComponentInChildren<EventPartnerMiningPointManager>();
|
||
if (miningPoints)
|
||
Trace($"ComponentAutoFound component=MiningPointManager name={miningPoints.name}");
|
||
else
|
||
LogWarning("MissingComponent component=EventPartnerMiningPointManager");
|
||
}
|
||
// 查找角色控制器
|
||
if (!character1)
|
||
{
|
||
character1 = GetComponentInChildren<EventPartnerMiningCharacterController>();
|
||
if (character1)
|
||
Trace($"ComponentAutoFound component=MiningCharacterController name={character1.name}");
|
||
else
|
||
LogWarning("MissingComponent component=EventPartnerMiningCharacterController");
|
||
}
|
||
|
||
if (character1)
|
||
{
|
||
character1.GatherNumPerDuration = gatherNumPerDuration;
|
||
_bornPos1 = character1.transform.position;
|
||
}
|
||
|
||
if (!character2)
|
||
{
|
||
character2 = transform.Find("playerNode/player2").GetComponent<EventPartnerMiningCharacterController>();
|
||
}
|
||
|
||
if (character2)
|
||
{
|
||
character2.GatherNumPerDuration = gatherNumPerDuration;
|
||
_bornPos2 = character2.transform.position;
|
||
}
|
||
|
||
// 查找火车控制器
|
||
if (!trainController)
|
||
{
|
||
trainController = GetComponentInChildren<EventPartnerTrainController>();
|
||
if (trainController)
|
||
Trace($"ComponentAutoFound component=TrainController name={trainController.name}");
|
||
else
|
||
LogWarning("MissingComponent component=EventPartnerTrainController");
|
||
|
||
_trainBornPos = trainController.transform.position;
|
||
}
|
||
|
||
_vCamSwitch = transform.Find("CameraRoot/CameraSwitch").GetComponent<CinemachineVirtualCamera>();
|
||
_vCamCharacter = transform.Find("CameraRoot/Camera").GetComponent<CinemachineVirtualCamera>();
|
||
|
||
|
||
// 验证矿石资源预制体
|
||
if (miningFlyResourcePrefabs == null || miningFlyResourcePrefabs.Length == 0)
|
||
{
|
||
LogWarning("MissingConfig key=MiningResourcePrefabs impact=OreGenerationUnavailable");
|
||
}
|
||
else
|
||
{
|
||
Trace($"MiningResourcePrefabCount count={miningFlyResourcePrefabs.Length}");
|
||
}
|
||
|
||
Trace("InitSceneComponentsComplete");
|
||
}
|
||
|
||
#region 数据同步监听 (来自EventPartnerMiningController)
|
||
|
||
|
||
// rock1 rock2 rock3
|
||
// private void MiningOreProgress(Transform ore, int progress)
|
||
// {
|
||
// // Log($"MiningOreProgress-> {ore} {progress}");
|
||
// foreach (var child in ore.Cast<Transform>())
|
||
// {
|
||
// var childName = child.gameObject.name;
|
||
// child.gameObject.SetActive(childName.EndsWith(progress.ToString()));
|
||
// }
|
||
// }
|
||
private void OnMiningOre(EventMiningOre evt)
|
||
{
|
||
// Log($"OnMiningOre -> {evt.Num} {_miningOres.Count}");
|
||
// var index = evt.Num + 1;
|
||
var index = evt.Num;
|
||
if (_miningOres is { Count: > 0 })
|
||
{
|
||
foreach (var ore in _miningOres)
|
||
{
|
||
// MiningOreProgress(ore, index);
|
||
MiningOreWithScore(ore, index);
|
||
}
|
||
}
|
||
|
||
if (_lastOre)
|
||
{
|
||
MiningOreWithScore(_lastOre,index);
|
||
}
|
||
|
||
// var (leftScore,oreLast,progress) = _lastFinalOre;
|
||
// if (leftScore > 0 && oreLast)
|
||
// {
|
||
// MiningOreWithScore(oreLast,progress);
|
||
// }
|
||
//
|
||
// var (first, oreFirst) = _firstBrokenOre;
|
||
// if (first > 0 && oreFirst)
|
||
// {
|
||
// MiningOreWithScore(oreFirst, index, first);
|
||
// }
|
||
}
|
||
|
||
// private int
|
||
private void MiningOreWithScore(Transform ore, int progress)
|
||
{
|
||
var oreController = ore.GetComponent<OreController>();
|
||
oreController?.OnMining(progress);
|
||
}
|
||
|
||
//-
|
||
public async void OnAddScore(EventPartnerGatherPartnerAddScore evt)
|
||
{
|
||
Trace($"PartnerScoreAdd partnerId={evt.partnerId} score={evt.score}");
|
||
// _lastPartnerPoint += evt.score;
|
||
//
|
||
// _manager.AddPoints(evt.score);
|
||
//
|
||
// character2.SetSpinPointText(_lastPartnerPoint);
|
||
// SetupMainCharacter(true);
|
||
// await StartMining(evt.score);
|
||
}
|
||
|
||
private async void OnMiningStart(EventPartnerGatherSceneStart evt)
|
||
{
|
||
Trace($"SceneStartEventReceived event={evt?.GetType().Name}");
|
||
await RunPartnerMining();
|
||
await CheckForStepCompletion();
|
||
// _manager.SyncFromPartnerInfo(_buildPartner.SlotId);
|
||
Log("SceneEnterNormalFlow");
|
||
_drawMiningPanel.SetInteractable(true);
|
||
}
|
||
|
||
|
||
private void OnEnterTrophyRegion(EnterTrophyEvent evt)
|
||
{
|
||
Trace("EnterTrophyRegion");
|
||
if (vcamArea)
|
||
vcamArea.Priority = activePriority;
|
||
|
||
}
|
||
private void OnStageLogicContinue(FishingChallengeContinueEvent evt)
|
||
{
|
||
Trace("StageLogicContinue");
|
||
_isStageRewardLogic = false;
|
||
// _isFinalRewardLogic = false;
|
||
}
|
||
|
||
private void OnPointsUpdate()
|
||
{
|
||
Trace("PointsUpdate");
|
||
|
||
UpdateUIPanel();
|
||
}
|
||
|
||
private void OnMiningProgressUpdate(EventPartnerGatherMiningProgressUpdate evt)
|
||
{
|
||
Trace($"MiningProgressUpdate progress={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();
|
||
}
|
||
|
||
public void OnEnter()
|
||
{
|
||
Trace("OnEnter");
|
||
// if (true) // 作弊
|
||
// {
|
||
// _manager.GatherData.CurrentPoints = 2100;
|
||
// _manager.GatherData.CurrentMiningProgress = 4;
|
||
// _manager.GatherData.CompletedNodes.Clear();
|
||
// }
|
||
|
||
ResetScene();
|
||
|
||
SyncAllData();
|
||
UpdateTrainData();
|
||
SyncSceneElement();
|
||
// 同步,后续优化
|
||
_drawMiningPanel.OnEnter();
|
||
}
|
||
public void OnLeave()
|
||
{
|
||
Trace("OnLeave");
|
||
|
||
_vCamCharacter.Priority = chaBasePriority;
|
||
vcamArea.Priority = areaBasePriority;
|
||
|
||
ResetScene();
|
||
}
|
||
|
||
private void SyncAllData()
|
||
{
|
||
Trace("SyncAllData");
|
||
if (_manager?.GatherData == null) return;
|
||
_buildPartner = _manager.CurrentBuildPartner;
|
||
|
||
//
|
||
// if (true)
|
||
// {
|
||
// var slotId = _manager.CurrentBuildPartner.SlotId;
|
||
// var completedNodes = _manager.GatherData.CompletedNodesList[slotId];
|
||
// completedNodes.Remove(4);
|
||
// completedNodes.Remove(3);
|
||
// _manager.SaveData();
|
||
// _buildPartner.ScoreSelfActual = 962;
|
||
// _buildPartner.ScorePartnerDisplay = 1998;
|
||
// }
|
||
|
||
_lastPoints = _buildPartner.ScoreSelfActual;
|
||
_usedPoints = _lastPoints + _buildPartner.ScorePartnerDisplay;
|
||
_lastMiningProgress = _manager.CalcMiningProgressOld(_usedPoints);
|
||
_lastLeftPoint = _manager.GetLeftPoint(_usedPoints,_lastMiningProgress);
|
||
|
||
if (_manager.IsStepFinished(_buildPartner.SlotId,_lastMiningProgress) && _lastLeftPoint == 0) // 结束,进入下一阶段
|
||
{
|
||
_lastMiningProgress = _manager.CalcMiningProgressNew(_usedPoints);
|
||
_lastLeftPoint = _manager.GetLeftPoint(_usedPoints,_lastMiningProgress);
|
||
}
|
||
CheckCompleteNodes(_lastLeftPoint <= 0 && _lastMiningProgress == _manager.MaxSteps) ;
|
||
}
|
||
|
||
private void CheckCompleteNodes(bool hasLast)
|
||
{
|
||
int finalIdx;// = _lastMiningProgress;
|
||
if (hasLast)
|
||
finalIdx = _lastMiningProgress + 1;
|
||
else
|
||
finalIdx = _lastMiningProgress;
|
||
|
||
|
||
for (var i = 0; i < finalIdx; ++i)
|
||
{
|
||
if (!_manager.IsStepFinished(_buildPartner.SlotId, i))
|
||
{
|
||
_manager.CompleteStage(i);
|
||
}
|
||
}
|
||
|
||
}
|
||
|
||
private void SyncSceneElement()
|
||
{
|
||
Trace($"SyncSceneElement lastPoints={_lastPoints} lastMiningProgress={_lastMiningProgress}");
|
||
// 设置用户的位置
|
||
|
||
var nameSelf = _userService.DisplayName;
|
||
var partnerName = _buildPartner.DisplayName;
|
||
|
||
// var info = _userService.GetPlayInfo(_buildPartner.PartnerId);
|
||
// Log($"info.name = {info.name} partnerName = {partnerName}");
|
||
|
||
character1.SetHeadImage(_userService.AvatarUrl);
|
||
character1.SetPlayerName(nameSelf);
|
||
character1.SetSpinPointText(_buildPartner.ScoreSelfActual);
|
||
character2.SetPlayerName(partnerName);
|
||
character2.SetSpinPointText(_buildPartner.ScorePartnerActual);
|
||
character2.SetHeadImage(_buildPartner.AvatarUrl);
|
||
SetupMainCharacter();
|
||
|
||
|
||
if (_usedPoints > 0)
|
||
{
|
||
var step = _lastMiningProgress;
|
||
var waPoint = _usedPoints - _manager.GetCumulativeStepPoint(step - 1);
|
||
_moveColumn = _manager.GetGoColumn(waPoint,step);
|
||
Log($"CalcWaPoint waPoint={waPoint}");
|
||
|
||
if (step == _manager.MaxSteps && _moveColumn > 24)
|
||
{
|
||
_moveColumn = 24;
|
||
}
|
||
|
||
SetPlayerPos(step, _moveColumn);
|
||
SetTrainPos(step, _moveColumn);
|
||
// 破坏的数据
|
||
for(var i = 0;i < step;i++)
|
||
{
|
||
DestroyOres(i,-1);
|
||
trainController.SetTrainCarCollectPoints(i);
|
||
}
|
||
DestroyOres(step,waPoint);
|
||
trainController.SetTrainCarCollectPoints(step,waPoint);
|
||
//
|
||
}
|
||
UpdateUIPanel();
|
||
}
|
||
// 执行 好友挖矿流程
|
||
private async Task RunPartnerMining()
|
||
{
|
||
ELog($"RunPartnerMining moveColumn={_moveColumn}");
|
||
|
||
if (_buildPartner.ScorePartnerActual > _buildPartner.ScorePartnerDisplay)
|
||
{
|
||
SetupMainCharacter(true);
|
||
await Awaiters.Seconds(1.0f);
|
||
var curStep = _manager.CalcMiningProgressNew(_usedPoints);
|
||
|
||
var slotId = _manager.CurrentBuildPartner.SlotId;
|
||
var completedNodes = _manager.GatherData.CompletedNodesList[slotId];
|
||
ELog(completedNodes.Count);
|
||
completedNodes.RemoveAll(x => x >= curStep);
|
||
var score = (_buildPartner.ScorePartnerActual - _buildPartner.ScorePartnerDisplay);
|
||
if (character2.IsMainCharacter)
|
||
{
|
||
ELog($"CharacterPositionSnapshot character1={character1.transform.position} character2={character2.transform.position}");
|
||
|
||
// Physics.IgnoreCollision(character1.GetComponent<CharacterController>(), character2.GetComponent<CharacterController>(), true);
|
||
var character1Pos = character1.body.position;
|
||
var character2Pos = character2.body.position;
|
||
|
||
var tasks = new List<Task>();
|
||
|
||
async Task ExecuteCharacter1Movement()
|
||
{
|
||
await character1.MoveToPosition(character2Pos, characterMoveSpeed);
|
||
character1.FinishMove();
|
||
}
|
||
async Task ExecuteCharacter2Movement()
|
||
{
|
||
await character2.MoveToPosition(character1Pos, characterMoveSpeed);
|
||
character2.FinishMove();
|
||
}
|
||
tasks.Add(ExecuteCharacter1Movement());
|
||
tasks.Add(ExecuteCharacter2Movement());
|
||
|
||
await Task.WhenAll(tasks);
|
||
await Awaiters.NextFrame;
|
||
|
||
// character1.SetSpinPointText(_buildPartner.ScoreSelfActual);
|
||
character2.SetSpinPointText(_buildPartner.ScorePartnerActual);
|
||
}
|
||
_drawMiningPanel.SetInteractable(false);
|
||
await StartMining(score);
|
||
_manager.SavePartnerInfo(slotId);
|
||
}
|
||
}
|
||
private void SetTrainPos(int step, int col)
|
||
{
|
||
ELog($"SetTrainPos step={step} col={col}");
|
||
var train = trainController.transform;
|
||
var targetPoint = miningPoints.GetPoint(step);
|
||
var trainPoint = targetPoint.Find("train_point");
|
||
var targetPosition = new Vector3(trainPoint.position.x + col * _columnDistance, train.position.y, train.position.z);
|
||
train.position = targetPosition;
|
||
}
|
||
|
||
|
||
public Vector3 GetPlayerBasePos(EventPartnerMiningCharacterController character, bool isSecondary = false)
|
||
{
|
||
var step = character.step;
|
||
var col = character.col;
|
||
var animType = character.GetAnimatorShowType();
|
||
return GetPlayerBasePos(step, col, animType,isSecondary);
|
||
}
|
||
public Vector3 GetPlayerBasePos (int step,int col,int animType, bool isSecondary = false)
|
||
{
|
||
//
|
||
if (step == -1)
|
||
{
|
||
return isSecondary ?_bornPos2 :_bornPos1;
|
||
}
|
||
|
||
var targetPoint = miningPoints.GetPoint(step);
|
||
var userPoint = targetPoint.Find("user_point");
|
||
var position = userPoint.position;
|
||
var newDelta = userPointDelta?[animType] ?? 0;
|
||
var userPosX = position.x + col * _columnDistance;
|
||
userPosX += newDelta;
|
||
|
||
var playerPos = new Vector3(userPosX, position.y, position.z);
|
||
if (isSecondary)
|
||
{
|
||
playerPos += secondOffsetVector3;
|
||
}
|
||
ELog($"GetPlayerPos step={step} col={col} isSecondary={isSecondary} playerPos={playerPos}");
|
||
// return new Vector3(userPosX, position.y, position.z);
|
||
return playerPos;
|
||
}
|
||
// 获取偏移
|
||
private float GetPositionDelta(int animType)
|
||
{
|
||
var newDelta = userPointDelta?[animType] ?? 0;
|
||
return newDelta;
|
||
}
|
||
private void SetPlayerPos(int step, int col)
|
||
{
|
||
ELog($"SetPlayerPos step={step} col={col}");
|
||
var targetPoint = miningPoints.GetPoint(step);
|
||
var userPoint = targetPoint.Find("user_point");
|
||
// var position = GetUserPoint(character1, userPoint.position);
|
||
// Log($"position- >{position} : userPoint.position: {userPoint.position}");
|
||
// var userPosX = position.x + col * _columnDistance;
|
||
SetPlayerStepAndCol(step, col);
|
||
var position = this.GetPlayerBasePos(step, col,0);
|
||
character1.transform.position = position;
|
||
// character1.transform.position = new Vector3(userPosX, character1.transform.position.y, userPoint.position.z);
|
||
// character1.LastTargetPosition = position;
|
||
|
||
var playerPos1 = character1.transform.position;
|
||
character2.transform.position = playerPos1 + secondOffsetVector3;
|
||
|
||
}
|
||
private void UpdateTrainData()
|
||
{
|
||
trainController.OreFlightDuration = oreFlightDuration;
|
||
trainController?.UpdateData(_manager);
|
||
}
|
||
private void UpdateUIPanel()
|
||
{
|
||
if (!_drawMiningPanel || _manager?.GatherData == null) return;
|
||
_drawMiningPanel.SetMiningProgress(_lastMiningProgress);
|
||
_drawMiningPanel.SetMiningPoints(_usedPoints);
|
||
}
|
||
public void SetUIPanel(EventPartnerDrawMiningPanel panel)
|
||
{
|
||
_drawMiningPanel = panel;
|
||
}
|
||
#endregion
|
||
|
||
// private Transform _transPoint;
|
||
#region 手动采集流程 (原MiningSceneController功能)
|
||
public async Task StartMining(int point ,string showType = "Basic")
|
||
{
|
||
ELog($"StartMining point={point}");
|
||
|
||
if (mainCharacter)
|
||
{
|
||
await MoveNext(point,showType);
|
||
}
|
||
ELog($"StartMiningFinished point={point}");
|
||
}
|
||
|
||
// private async Task MoveNextProgress()
|
||
private async Task MoveNext(int point,string showType)
|
||
{
|
||
ELog($"MoveNextStart point={point}");
|
||
if (point < 0)
|
||
{
|
||
return;
|
||
}
|
||
var leftPoint = _lastLeftPoint;
|
||
var curStep = _lastMiningProgress;
|
||
var stepPoints = _manager.GetStepPoints(curStep);
|
||
FlowELog($"MoveNextState curStep={curStep} leftPoint={leftPoint} stepPoints={stepPoints}");
|
||
|
||
if (leftPoint > 0)
|
||
{
|
||
if (stepPoints == leftPoint) // 还没挖过矿,移动到当前
|
||
{
|
||
_moveColumn = 0;
|
||
SetPlayerStepAndCol(curStep,_moveColumn);
|
||
await UpdatePlayerShowType(showType);
|
||
await MoveToMiningPoint(curStep);
|
||
if (point <= 0)
|
||
{
|
||
await FinishMiningStep();
|
||
return;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
FlowELog($"MoveNextBranch111 curStep={curStep} leftPoint={leftPoint} stepPoints={stepPoints}");
|
||
if (point <= 0)
|
||
{
|
||
await FinishMiningStep();
|
||
return;
|
||
}
|
||
|
||
var consumePoints = stepPoints - leftPoint;
|
||
var column = _manager.GetGoColumn(consumePoints,curStep);
|
||
// TODO:LF 逻辑再修改,先挖矿再移动还是直接移动,以及移动的 范围
|
||
FlowELog($"MoveNextBranch122 consumePoints={consumePoints} column={column} moveColumn={_moveColumn}");
|
||
SetPlayerStepAndCol(curStep,column);
|
||
if (consumePoints > 0)
|
||
{
|
||
await MoveToPlayerMiningPos(showType);
|
||
await UpdatePlayerShowType(showType);
|
||
}
|
||
|
||
if (_moveColumn != column)
|
||
{
|
||
// var disColumn = column - _moveColumn;
|
||
// await MoveCol(disColumn);
|
||
_moveColumn = column;
|
||
// await UpdatePlayerShowType(showType);
|
||
await MoveToCol(curStep,_moveColumn);
|
||
}
|
||
}
|
||
int consumePoint;
|
||
(point,leftPoint,consumePoint )= await ConsumePoint(point, leftPoint);
|
||
FlowELog($"MoveNextBranch133 consumePoint={consumePoint} point={point}");
|
||
_lastLeftPoint = leftPoint;
|
||
}
|
||
else
|
||
{
|
||
var hasNextStep = OnNextMiningStep();
|
||
if (!hasNextStep)
|
||
{
|
||
ELog($"MoveNextFinished curStep={curStep}");
|
||
await FinishMiningStep();
|
||
return;
|
||
}
|
||
}
|
||
await MoveNext(point,showType);
|
||
}
|
||
|
||
private async Task MoveToPlayerMiningPos(string newShowType)
|
||
{
|
||
var step = mainCharacter.step;
|
||
var col = mainCharacter.col;
|
||
|
||
var oldAnimType = mainCharacter.GetAnimatorShowType();
|
||
var newAnimType = GetAniIndexByShowType(newShowType);
|
||
if (oldAnimType == newAnimType)
|
||
{
|
||
return;
|
||
}
|
||
var pos = GetPlayerBasePos(step,col,newAnimType);
|
||
await mainCharacter.MoveToPosition(pos,characterMoveSpeed);
|
||
mainCharacter.FinishMove();
|
||
}
|
||
|
||
|
||
private void SetPlayerStepAndCol(int step,int col)
|
||
{
|
||
character1.step = step;
|
||
character1.col = col;
|
||
character2.step = step;
|
||
character2.step = col;
|
||
}
|
||
|
||
|
||
// private async Task CompleteStepFinished(int step)
|
||
// {
|
||
// Log($"CompleteStepFinished -> {step}");
|
||
// if (step > -1)
|
||
// {
|
||
// if (_manager.CompleteStage(step))
|
||
// {
|
||
// await Awaiters.Seconds(1.0f);
|
||
// }
|
||
// }
|
||
// }
|
||
|
||
private async Task FinishMiningStep()
|
||
{
|
||
Log($"FinishMiningStep miningProgress={_lastMiningProgress}");
|
||
mainCharacter.FinishMove();
|
||
await Awaiters.NextFrame;
|
||
|
||
// var pos = GetPlayerBasePos(mainCharacter);
|
||
await mainCharacter.WaitIdleSpecialFinish();
|
||
}
|
||
private bool OnNextMiningStep()
|
||
{
|
||
Log($"NextMiningStep from={_lastMiningProgress} to={_lastMiningProgress + 1}");
|
||
_moveColumn = 0;
|
||
if (_lastMiningProgress <= _manager.MaxSteps)
|
||
{
|
||
// GContext.Publish(new EventUISound("audio_ui_partnermining_target_finish"));
|
||
_manager.CompleteStage(_lastMiningProgress);
|
||
_lastMiningProgress += 1;
|
||
_lastLeftPoint = _manager.GetStepPoints(_lastMiningProgress);
|
||
if (_drawMiningPanel)
|
||
{
|
||
// _drawMiningPanel.SetMiningProgress(_lastMiningProgress);
|
||
_drawMiningPanel.FinishStep(_lastMiningProgress);
|
||
}
|
||
return true;
|
||
}
|
||
return false;
|
||
}
|
||
// private async Task MoveCol(int column)
|
||
// {
|
||
// Log($"MoveCol->{column}");
|
||
// if (column > 0)
|
||
// {
|
||
// var step = _lastMiningProgress;
|
||
// var targetPoint = miningPoints.GetPoint(step);
|
||
// var userPoint = targetPoint.Find("user_point");
|
||
// // 传入变身后的 userPoint 点,根据自身的位置,再次移动
|
||
// var currentPoint = GetUserPoint(mainCharacter, userPoint.position);
|
||
// await mainCharacter.MoveCol(column ,currentPoint,_columnDistance,characterMoveSpeed);
|
||
// var train = trainController.transform;
|
||
// // _ = character2.FollowCol(column,GetUserPoint(character2, userPoint.position,true),_columnDistance);
|
||
// var characterPos = GetUserPoint(otherCharacter,mainCharacter.transform.position, true);
|
||
// _ = otherCharacter.FollowToPosition(characterPos);
|
||
// var targetPosition = new Vector3(train.position.x + column * _columnDistance, train.position.y, train.position.z);
|
||
// trainController.StartMoveTo(targetPosition);
|
||
// }
|
||
// }
|
||
|
||
private async Task MoveToCol(int step, int column)
|
||
{
|
||
var targetPoint = miningPoints.GetPoint(step);
|
||
var trainPoint = targetPoint.Find("train_point");
|
||
var animType = mainCharacter.GetAnimatorShowType();
|
||
var userPosition = GetPlayerBasePos(step,column,animType);
|
||
var otherUserPosition = GetPlayerBasePos(step, column,animType,true);
|
||
await mainCharacter.MoveToPosition(userPosition, characterMoveSpeed);
|
||
_ = otherCharacter.FollowToPosition(otherUserPosition,characterMoveSpeed);
|
||
var trainPos = trainPoint.position.x + column * _columnDistance;
|
||
trainController.StartMoveTo(new Vector3(trainPos,trainController.transform.position.y,trainController.transform.position.z));
|
||
// var targetPosition = new Vector3(train.position.x + column * _columnDistance, train.position.y, train.position.z);
|
||
// trainController.StartMoveTo(targetPosition);
|
||
// trainController.StartMoveTo(new Vector3(trainPoint.position.x,trainController.transform.position.y,trainController.transform.position.z));
|
||
}
|
||
private async Task MoveToMiningPoint(int miningProgress)
|
||
{
|
||
ELog($"MoveToMiningPoint miningProgress={miningProgress}");
|
||
var targetPoint = miningPoints.GetPoint(miningProgress);
|
||
var trainPoint = targetPoint.Find("train_point");
|
||
// var userPoint = targetPoint.Find("user_point");
|
||
// Log($"MoveToMiningPoint -> {miningProgress} {userPoint.position}");
|
||
// await mainCharacter.MoveToPosition(GetUserPoint(mainCharacter,userPoint.position), characterMoveSpeed);
|
||
// _ = otherCharacter.FollowToPosition(GetUserPoint(otherCharacter, userPoint.position,true ));
|
||
// trainController.StartMoveTo(new Vector3(trainPoint.position.x,trainController.transform.position.y,trainController.transform.position.z));
|
||
|
||
|
||
var animType = mainCharacter.GetAnimatorShowType();
|
||
// var deltaPos = GetPositionDelta(animType);
|
||
var userPosition = GetPlayerBasePos(miningProgress,0,animType);
|
||
// 修正
|
||
userPosition = new Vector3(userPosition.x, userPosition.y,userPosition.z);
|
||
var otherUserPosition = GetPlayerBasePos(miningProgress, 0,animType,true);
|
||
otherUserPosition = new Vector3(otherUserPosition.x, otherUserPosition.y, otherUserPosition.z);
|
||
|
||
ELog($"MoveToMiningPointResolved userPosition={userPosition}");
|
||
|
||
await mainCharacter.MoveToPosition(userPosition, characterMoveSpeed);
|
||
_ = otherCharacter.FollowToPosition(otherUserPosition,characterMoveSpeed);
|
||
trainController.StartMoveTo(new Vector3(trainPoint.position.x,trainController.transform.position.y,trainController.transform.position.z));
|
||
|
||
}
|
||
|
||
// private Vector3 GetUserPoint(EventPartnerMiningCharacterController characterController, Vector3 position,bool isSecondary = false)
|
||
// {
|
||
// var idx = characterController.GetAnimatorShowType();
|
||
// var delta = userPointDelta?[idx] ?? 0;
|
||
// Log($"GetUserPoint -> {idx}");
|
||
// position.x += delta;
|
||
// position.y = characterController.transform.position.y;
|
||
// if (isSecondary)
|
||
// {
|
||
// position += secondOffsetVector3;
|
||
// }
|
||
// return position;
|
||
// }
|
||
|
||
// 消耗之后还剩余多少
|
||
private async Task<(int myPoints,int levelPoints,int counsumePoint)> ConsumePoint(int waPoints, int leftPoint)
|
||
{
|
||
if (waPoints <= 0)
|
||
{
|
||
return (0, leftPoint,0);
|
||
}
|
||
var consumePoints = _manager.GetConsumePoint(_lastMiningProgress);
|
||
var realConsumePoint = Mathf.Min(consumePoints, waPoints,leftPoint);
|
||
FlowELog($"ConsumePointPhase11 waPoints={waPoints} leftPoint={leftPoint} consumePoints={consumePoints} realConsumePoint={realConsumePoint}");
|
||
|
||
UpdateUsedPoints(realConsumePoint);
|
||
|
||
GetMiningOres(realConsumePoint);
|
||
|
||
var gatherNum = gatherNumPerDuration;
|
||
if (_miningOres.Count <= 0)
|
||
{
|
||
gatherNum = GetGatherNum(realConsumePoint);
|
||
}
|
||
FlowELog($"GatherNumResolved gatherNum={gatherNum}");
|
||
|
||
await PlayMining(gatherNum);
|
||
await GenerateAndCollectOres(realConsumePoint);
|
||
leftPoint -= realConsumePoint;
|
||
waPoints -= realConsumePoint;
|
||
FlowELog($"ConsumePointPhase12 waPoints={waPoints} leftPoint={leftPoint}");
|
||
return (waPoints,leftPoint,realConsumePoint);
|
||
}
|
||
|
||
private void UpdateUsedPoints(int realConsumePoint)
|
||
{
|
||
_usedPoints += realConsumePoint; // 更新 挖了的数值
|
||
}
|
||
|
||
private async Task PlayMining(int gatherNum = 3)
|
||
{
|
||
mainCharacter.GatherNumPerDuration = gatherNum;
|
||
await mainCharacter.PlayMining();
|
||
}
|
||
|
||
private int GetGatherNum(int point)
|
||
{
|
||
var num = gatherNumPerDuration;
|
||
// if (_miningOres is { Count: > 0 })
|
||
// return num;
|
||
|
||
var perPoint = _manager.EventPartnerMineMainData.MinePoint / num;
|
||
if (point < _manager.EventPartnerMineMainData.MinePoint)
|
||
{
|
||
for (var i = 1; i <= num; ++i)
|
||
{
|
||
if (point <= perPoint * i)
|
||
{
|
||
return i;
|
||
}
|
||
}
|
||
}
|
||
return num;
|
||
}
|
||
private void GetMiningOres(int consumePoint)
|
||
{
|
||
|
||
var step = _lastMiningProgress;
|
||
var collectedPointsTo = _manager.CollectPointAndCalcValid(step,_usedPoints);
|
||
var num = _manager.CalcWaNum(collectedPointsTo,out var leftPoint);
|
||
FlowELog($"CollectPointCalc step={step} collectTo={collectedPointsTo} num={num} lastPoints={_lastPoints} usedPoints={_usedPoints}");
|
||
var pointTrans = miningPoints.GetPoint(step);
|
||
var oresRoot = pointTrans.Find("ores");
|
||
var allChildren = oresRoot.Cast<Transform>().ToList();
|
||
num = Mathf.Min(num, allChildren.Count);
|
||
_miningOres.Clear();
|
||
|
||
for (var i = 0; i < num; ++i)
|
||
{
|
||
var child = allChildren[i];
|
||
if (child.gameObject.activeSelf)
|
||
{
|
||
_miningOres.Add(child); // 记录生成的石头
|
||
}
|
||
|
||
var saver = child.gameObject.GetComponent<OreController>();
|
||
if (!saver)
|
||
{
|
||
saver = child.gameObject.AddComponent<OreController>();
|
||
}
|
||
if (saver)
|
||
{
|
||
saver.InQueue = true;
|
||
saver.validTimes = gatherNumPerDuration;
|
||
}
|
||
}
|
||
|
||
// 只有一个的时候,放入单独处理中
|
||
if(_miningOres.Count == 1 && leftPoint <= 0)
|
||
{
|
||
_miningOres.Clear();
|
||
leftPoint = _manager.EventPartnerMineMainData.MinePoint;
|
||
num -= 1;
|
||
}
|
||
|
||
if (leftPoint > 0)
|
||
{
|
||
if (num < allChildren.Count)
|
||
{
|
||
var trans = allChildren[num];
|
||
var saver = trans.gameObject.GetComponent<OreController>();
|
||
if (!saver)
|
||
{
|
||
saver = trans.gameObject.AddComponent<OreController>();
|
||
saver.miningTimes = 0;
|
||
}
|
||
saver.InQueue = false;
|
||
saver.maxTimes = gatherNumPerDuration;
|
||
saver.validTimes = gatherNumPerDuration;
|
||
_lastOre = trans;
|
||
if (_miningOres.Count > 0)
|
||
{
|
||
saver.validTimes = GetGatherNum(leftPoint);
|
||
}
|
||
}
|
||
}
|
||
else
|
||
{
|
||
_lastOre = null;
|
||
}
|
||
// if (num == 0)
|
||
// {
|
||
// SetFirstOre(allChildren[num],leftPoint);
|
||
// }
|
||
//
|
||
// if (num > 0)
|
||
// {
|
||
// SetLastOre(allChildren[num],leftPoint);
|
||
// }
|
||
// }
|
||
}
|
||
private async Task GenerateAndCollectOres(int realPoints)
|
||
{
|
||
ELog($"GenerateAndCollectOresStart realPoints={realPoints}");
|
||
var step = _lastMiningProgress;
|
||
var collectedPointsTo = _manager.CollectPointAndCalcValid(step,_usedPoints);
|
||
// 根据点数销毁对应数量的矿石
|
||
DestroyOres();
|
||
var oreCount = CalculateOreCount(realPoints);
|
||
await CollectOreAnimation(step,oreCount);
|
||
_drawMiningPanel.RunCollectOreAnimation(step, oreCount);
|
||
await trainController.RunOreIncreaseAnimation(step,collectedPointsTo - realPoints,collectedPointsTo);
|
||
ELog("GenerateAndCollectOresFinish");
|
||
}
|
||
//
|
||
[SerializeField]
|
||
private float baseValue = 0.1f;
|
||
[SerializeField]
|
||
private float fluctuation = 0.01f; // 浮动范围 ±0.01
|
||
private async Task CollectOreAnimation(int step, int oreCount)
|
||
{
|
||
var tasks = new List<Task>();
|
||
var iCount = _miningOres.Count;
|
||
if (_lastOre)
|
||
{
|
||
iCount += 1;
|
||
}
|
||
FlowELog($"CollectOreAnimation step={step} oreCount={oreCount} oreGroups={iCount}");
|
||
if (iCount <= 0)
|
||
return;
|
||
|
||
var listOrePos = _miningOres.Select(ore => ore.position).ToList();
|
||
if (_lastOre)
|
||
{
|
||
listOrePos.Add(_lastOre.position);
|
||
}
|
||
|
||
var num = oreCount / iCount; // 共20个,每组 10个
|
||
for (var i = 0; i < iCount ; i++)
|
||
{
|
||
tasks.Add(CollectOreGroups(i,num ));
|
||
}
|
||
await Task.WhenAll(tasks);
|
||
return;
|
||
|
||
//
|
||
async Task CollectOreGroups(int index ,int num )
|
||
{
|
||
// var posStart = Mathf.Max(0,index * (num - 1));
|
||
// Log($"CollectOreGroups-> {index} {num} {posStart}");
|
||
//
|
||
var childTasks = new List<Task>();
|
||
for (var i = 0; i < num; ++i)
|
||
{
|
||
var random2 = Random.Range(baseValue - fluctuation, baseValue + fluctuation);
|
||
await Awaiters.Seconds(oreGenerateDelay + random2);
|
||
var ore = CreateFlyOre(index , listOrePos);
|
||
if (ore)
|
||
{
|
||
childTasks.Add(trainController.CollectOre(step, ore));
|
||
}
|
||
}
|
||
|
||
// await Task.WhenAll(childTasks);
|
||
await Task.WhenAny(childTasks);
|
||
}
|
||
}
|
||
private int DestroyOres()
|
||
{
|
||
var num = 0;
|
||
if (_miningOres is { Count: > 0 })
|
||
{
|
||
foreach (var child in _miningOres)
|
||
{
|
||
// var oreController = child.gameObject.GetComponent<OreController>();
|
||
// if (oreController)
|
||
// {
|
||
// // oreController.ResetValues();
|
||
// Destroy(oreController);
|
||
// }
|
||
child.gameObject.SetActive(false);
|
||
}
|
||
num += _miningOres.Count;
|
||
}
|
||
|
||
if (_lastOre)
|
||
{
|
||
// MiningOreProgress(_lastOre,1)
|
||
num += 1;
|
||
}
|
||
return num;
|
||
}
|
||
// 隐藏矿石的数量
|
||
private int DestroyOres(int step ,int points)
|
||
{
|
||
if (points == -1)
|
||
{
|
||
points = _manager.GetStepPoints(step);
|
||
}
|
||
var num = _manager.CalcWaNum(points,out var leftPoint);
|
||
ELog($"DestroyOres step={step} num={num}");
|
||
|
||
|
||
var pointTrans = miningPoints.GetPoint(step);
|
||
var oresRoot = pointTrans.Find("ores");
|
||
var allChildren = oresRoot.Cast<Transform>().ToList();
|
||
num = Mathf.Min(num, allChildren.Count);
|
||
for (var i = 0; i < num; ++i)
|
||
{
|
||
var child = allChildren[i];
|
||
// var oreController = child.gameObject.GetComponent<OreController>();
|
||
// if (oreController)
|
||
// {
|
||
// // oreController.ResetValues();
|
||
// // Destroy(oreController);
|
||
// }
|
||
child.gameObject.SetActive(false);
|
||
}
|
||
|
||
if (leftPoint > 0)
|
||
{
|
||
if (num < allChildren.Count)
|
||
{
|
||
var trans = allChildren[num];
|
||
var oreController = trans.gameObject.GetComponent<OreController>();
|
||
if (!oreController)
|
||
{
|
||
oreController = trans.gameObject.AddComponent<OreController>();
|
||
}
|
||
// oreController.ResetValues();
|
||
oreController.UpdateMiningTimes(GetGatherNum(leftPoint));
|
||
|
||
// oreController.miningTimes = 0;
|
||
// oreController.InQueue = false;
|
||
// oreController.Score = leftPoint;
|
||
// oreController.maxTimes = gatherNumPerDuration;
|
||
// oreController.validTimes = gatherNumPerDuration;
|
||
// // _lastOre = trans;
|
||
// if (_miningOres.Count > 0)
|
||
// {
|
||
// saver.validTimes = GetGatherNum(leftPoint);
|
||
// }
|
||
// oreController.UpdateOre();
|
||
}
|
||
}
|
||
// else
|
||
// {
|
||
// _lastOre = null;
|
||
// }
|
||
|
||
|
||
// if (_lastOre)
|
||
// {
|
||
// var oreController = _lastOre.GetComponent<OreController>();
|
||
// if (oreController)
|
||
// {
|
||
// oreController.UpdateOre();
|
||
// }
|
||
// }
|
||
return num;
|
||
}
|
||
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
|
||
// };
|
||
//return _manager.CalcWaNum(points);
|
||
return points;
|
||
}
|
||
|
||
private GameObject CreateFlyOre(int index, List<Vector3> list)
|
||
{
|
||
var idx = index % list.Count ;
|
||
// Log($"CreateOre -> {index} {list.Count} {idx}");
|
||
return CreateFlyOre(list[idx]);
|
||
}
|
||
private GameObject CreateFlyOre(Vector3 position)
|
||
{
|
||
// Log($"CreateOre -> {position}");
|
||
|
||
if (miningFlyResourcePrefabs == null || miningFlyResourcePrefabs.Length == 0)
|
||
return null;
|
||
// 随机选择一个矿石预制体
|
||
var orePos = new Vector3(position.x, position.y + 1, position.z);
|
||
// var idx = _manager.GatherData.CurrentMiningProgress;
|
||
// var prefab = miningResourcePrefabs[Random.Range(0, miningResourcePrefabs.Length)];
|
||
var idx = _lastMiningProgress;
|
||
var prefab = miningFlyResourcePrefabs[idx];
|
||
// var ore = Instantiate(prefab, orePos, Quaternion.identity,transform);
|
||
var ore = Instantiate(prefab, orePos,prefab.transform.rotation,transform);
|
||
// ore.transform.position = orePos;
|
||
ore.SetActive(true);
|
||
_activeMiningResources.Add(ore);
|
||
return ore;
|
||
}
|
||
#endregion
|
||
|
||
public void ResetScene()
|
||
{
|
||
|
||
// 重置 位置
|
||
character1.transform.position = _bornPos1;
|
||
character1.step = -1;
|
||
character1.col = -1;
|
||
character2.transform.position = _bornPos2;
|
||
character1.step = -1;
|
||
character2.col = -1;
|
||
|
||
// 重置
|
||
trainController.transform.position = _trainBornPos;
|
||
|
||
// 重置奖杯
|
||
var trophyPoint = miningPoints.GetTrophyPoint();
|
||
var fxCelebrate = trophyPoint.Find("fx_partnermining_celebrate");
|
||
if (fxCelebrate)
|
||
{
|
||
fxCelebrate.gameObject.SetActive(false);
|
||
}
|
||
// 声音
|
||
var audioFinished = trophyPoint.Find("audio_finished");
|
||
if (audioFinished)
|
||
{
|
||
audioFinished.gameObject.SetActive(false);
|
||
}
|
||
|
||
|
||
// 清理场景中的矿石
|
||
foreach (var ore in _activeMiningResources)
|
||
{
|
||
if (ore) DestroyImmediate(ore);
|
||
}
|
||
|
||
_activeMiningResources.Clear();
|
||
|
||
// 重置挖矿点
|
||
miningPoints?.ResetPoints();
|
||
|
||
// 重置火车状态
|
||
trainController?.ResetTrain();
|
||
|
||
//
|
||
vcamArea.Priority = areaBasePriority;
|
||
_vCamCharacter.Priority = chaBasePriority;
|
||
// _vCamSwitch.Priority = zeroPriority;
|
||
|
||
_drawMiningPanel.Reset();
|
||
_miningOres.Clear();
|
||
}
|
||
private void OnDisable()
|
||
{
|
||
if (!_vCamSwitch) return;
|
||
// 方法1:将该相机移动到当前优先级子队列顶部,通常会成为Live或在混合后成为Live
|
||
_vCamSwitch.MoveToTopOfPrioritySubqueue();
|
||
|
||
}
|
||
|
||
private void OnDestroy()
|
||
{
|
||
_disposables?.Dispose();
|
||
_disposables = null;
|
||
}
|
||
|
||
|
||
public void SetupMainCharacter(bool isFriend = false)
|
||
{
|
||
mainCharacter = character1;
|
||
otherCharacter = character2;
|
||
if (isFriend)
|
||
{
|
||
mainCharacter = character2;
|
||
otherCharacter= character1;
|
||
}
|
||
|
||
mainCharacter.IsMainCharacter = true;
|
||
otherCharacter.IsMainCharacter = false;
|
||
_vCamCharacter.Follow = mainCharacter.transform.Find("lookatPoint");
|
||
}
|
||
|
||
public int GetAniIndexByShowType(string showType)
|
||
{
|
||
var typeList = new List<string>
|
||
{
|
||
"Basic",
|
||
"Advanced",
|
||
"Master",
|
||
};
|
||
var idx = typeList.IndexOf(showType);
|
||
return idx;
|
||
}
|
||
public async Task UpdatePlayerShowType(string showType)
|
||
{
|
||
// var typeList = new List<string>
|
||
// {
|
||
// "Basic",
|
||
// "Advanced",
|
||
// "Master",
|
||
// };
|
||
// var idx = typeList.IndexOf(showType);
|
||
var animType = GetAniIndexByShowType(showType);
|
||
if (animType != mainCharacter.GetAnimatorShowType())
|
||
{
|
||
await mainCharacter.UpdateShowType(animType);
|
||
}
|
||
}
|
||
|
||
private bool _isShowingSettlement = false;
|
||
public async Task CheckForStepCompletion()
|
||
{
|
||
Log($"CheckNodeCompletion miningProgress={_lastMiningProgress}");
|
||
if (_manager?.GatherData == null) return;
|
||
var currentMiningProgress = _lastMiningProgress;
|
||
var maxSteps = _manager.MaxSteps;
|
||
Log($"NodeCompletionRange maxSteps={maxSteps} currentProgress={currentMiningProgress}");
|
||
|
||
|
||
_isStageRewardLogic = _manager.PlayGetStageReward();
|
||
if (_isStageRewardLogic)
|
||
{
|
||
await CheckStageRewardFinished();
|
||
}
|
||
Log($"PlayStageReward miningProgress={_lastMiningProgress}");
|
||
if (_manager.IsStepFinished(_manager.CurrentBuildPartner.SlotId, maxSteps) && !_isShowingSettlement)
|
||
{
|
||
await ShowNodeCompletionSequence();
|
||
}
|
||
}
|
||
private async Task CheckStageRewardFinished()
|
||
{
|
||
if (!_isStageRewardLogic) return;
|
||
while (true)
|
||
{
|
||
if (!_isStageRewardLogic)
|
||
return;
|
||
await Awaiters.Seconds(1f);
|
||
}
|
||
}
|
||
// private async Task CheckFinalRewardFinished()
|
||
// {
|
||
// if (!_isFinalRewardLogic) return;
|
||
// while (true)
|
||
// {
|
||
// if (!_isFinalRewardLogic)
|
||
// return;
|
||
// await Awaiters.Seconds(1f);
|
||
// }
|
||
// }
|
||
private async Task ShowNodeCompletionSequence()
|
||
{
|
||
Log("ShowNodeCompletionSequence");
|
||
if (_isShowingSettlement) return;
|
||
_isShowingSettlement = true;
|
||
try
|
||
{
|
||
Log("NodeSettlementTransitionStart");
|
||
// // 1. 禁用交互
|
||
// SetInteractable(false);
|
||
// EnableAutoScroll(false);
|
||
_drawMiningPanel.SetInteractable(false);
|
||
_drawMiningPanel.EnableAutoScroll(false);
|
||
//
|
||
// _drawMiningPanel.gameObject.SetActive(false);
|
||
_drawMiningPanel.HideUI();
|
||
// //
|
||
await WaitPlayerRunToWinPosition();
|
||
// // // 4. 显示奖杯(如果获得)
|
||
await WaitForRunTrophyAni();
|
||
// 最终奖励
|
||
// await WaitForFinalReward();
|
||
_manager.FinishMining();
|
||
// FinishAllMining();
|
||
}
|
||
finally
|
||
{
|
||
_isShowingSettlement = false;
|
||
}
|
||
}
|
||
|
||
|
||
|
||
// private async Task WaitForFinalReward()
|
||
// {
|
||
// Log("WaitForFinalReward");
|
||
//
|
||
// _isFinalRewardLogic = true;
|
||
// _manager.PlayGetFinalReward();
|
||
// // return Task.CompletedTask;
|
||
// await CheckFinalRewardFinished();
|
||
// }
|
||
private async Task WaitForRunTrophyAni()
|
||
{
|
||
Log("WaitForRunTrophyAnimation");
|
||
|
||
GContext.Publish(new EventPartnerGatherPlayTrophy());
|
||
|
||
var trophyPoint = miningPoints.GetTrophyPoint();
|
||
// 特效
|
||
var fxCelebrate = trophyPoint.Find("fx_partnermining_celebrate");
|
||
if (fxCelebrate)
|
||
{
|
||
fxCelebrate.gameObject.SetActive(true);
|
||
}
|
||
var anim = trophyPoint.GetComponent<Animation>();
|
||
if (anim)
|
||
{
|
||
anim.Play();
|
||
}
|
||
|
||
|
||
var list = new List<Task>
|
||
{
|
||
character1.WaitForIdleFinished(),
|
||
character2.WaitForIdleFinished(),
|
||
};
|
||
await Task.WhenAll(list);
|
||
character1.SetAnimationState("celebrate");
|
||
character2.SetAnimationState("celebrate");
|
||
await character2.WaitForCelebrateFinished();
|
||
}
|
||
|
||
// private async Task WaitForCelebrateFinished()
|
||
// {
|
||
// await character.WaitForCelebrateFinished();
|
||
// }
|
||
private async Task WaitPlayerRunToWinPosition()
|
||
{
|
||
Log("WaitPlayerRunToWinPosition");
|
||
// character.SetIdle();
|
||
// await character.StartIdleSpecial();
|
||
// var targetPoint = miningPoints.GetTrophyPoint();
|
||
var targetPoint = transform.Find("trophy_region");
|
||
var userPoint1 = targetPoint.Find("user_point1");
|
||
var userPoint2 = targetPoint.Find("user_point2");
|
||
// 注意是一个组合,等待全部完成
|
||
var tasks = new List<Task>()
|
||
{
|
||
ExecuteCharacter1Movement(),
|
||
ExecuteCharacter2Movement()
|
||
};
|
||
// tasks.Add(character.MoveToPosition(userPoint1.position, characterMoveSpeed));
|
||
// tasks.Add(character2.MoveToPosition(userPoint2.position, characterMoveSpeed));
|
||
await Task.WhenAll(tasks);
|
||
await Awaiters.NextFrame;
|
||
return;
|
||
async Task ExecuteCharacter1Movement()
|
||
{
|
||
await character1.MoveToPosition(userPoint1.position, characterMoveSpeed);
|
||
character1.FinishMove();
|
||
}
|
||
async Task ExecuteCharacter2Movement()
|
||
{
|
||
await character2.MoveToPosition(userPoint2.position, characterMoveSpeed);
|
||
character2.FinishMove();
|
||
}
|
||
}
|
||
|
||
private static void ELog(object message)
|
||
{
|
||
#if UNITY_EDITOR
|
||
Debug.Log($"<Color=cyan> EventPartnerMiningSceneController {message} </color>");
|
||
#endif
|
||
}
|
||
|
||
private void FlowELog(object message)
|
||
{
|
||
#if UNITY_EDITOR
|
||
_flowLogCounter++;
|
||
if (_flowLogCounter % FlowLogSampleInterval != 0)
|
||
return;
|
||
Log(message);
|
||
#endif
|
||
}
|
||
private void Log(object t)
|
||
{
|
||
Debug.Log($"<Color=cyan> EventPartnerMiningSceneController {t} </color>");
|
||
}
|
||
private void LogWarning(object t)
|
||
{
|
||
Debug.LogWarning($"<Color=yellow> EventPartnerMiningSceneController {t} </color>");
|
||
}
|
||
[System.Diagnostics.Conditional("UNITY_EDITOR")]
|
||
private void Trace(object t)
|
||
{
|
||
if (!EnableTraceLogs) return;
|
||
ELog(t);
|
||
}
|
||
|
||
public void AddPlayerScore(int normalPoints, bool isFriend)
|
||
{
|
||
Log($"AddPlayerScore normalPoints={normalPoints}");
|
||
|
||
if (!isFriend)
|
||
{
|
||
_lastPoints += normalPoints;
|
||
character1.SetSpinPointText(_lastPoints);
|
||
}
|
||
// else
|
||
// {
|
||
// _lastPartnerPoint += normalPoints;
|
||
// character2.SetSpinPointText(_lastPartnerPoint);
|
||
// }
|
||
}
|
||
|
||
public async Task MainPlayerMining(int normalPoints,string showType)
|
||
{
|
||
AddPlayerScore(normalPoints, false);
|
||
// await Awaiters.Seconds(1.0f);
|
||
// var score = _buildPartner.ScorePartnerActual - _buildPartner.ScorePartnerDisplay;
|
||
if (character2.IsMainCharacter)
|
||
{
|
||
SetupMainCharacter(false);
|
||
Log($"CharacterPositionSnapshot character1={character1.transform.position} character2={character2.transform.position}");
|
||
var character1Pos = character1.body.position;
|
||
var character2Pos = character2.body.position;
|
||
|
||
var tasks = new List<Task>();
|
||
async Task ExecuteCharacter1Movement()
|
||
{
|
||
await character1.MoveToPosition(character2Pos, characterMoveSpeed);
|
||
character1.FinishMove();
|
||
// character1.LastTargetPosition = Vector3.zero;
|
||
}
|
||
async Task ExecuteCharacter2Movement()
|
||
{
|
||
await character2.MoveToPosition(character1Pos, characterMoveSpeed);
|
||
character2.FinishMove();
|
||
// character2.LastTargetPosition = Vector3.zero;
|
||
}
|
||
tasks.Add(ExecuteCharacter1Movement());
|
||
tasks.Add(ExecuteCharacter2Movement());
|
||
await Task.WhenAll(tasks);
|
||
await Awaiters.NextFrame;
|
||
}
|
||
|
||
|
||
// await UpdatePlayerPos();
|
||
// await UpdatePlayerShowType(showType);
|
||
await StartMining(normalPoints,showType);
|
||
}
|
||
|
||
// 测试函数
|
||
public async void Test()
|
||
{
|
||
|
||
OnEnterTrophyRegion(null);
|
||
|
||
await Awaiters.Seconds(2f);
|
||
await WaitForRunTrophyAni();
|
||
|
||
// SetPlayerStepAndCol(1,1);
|
||
//
|
||
// Log($"start: mainCharacter.position - >{mainCharacter.transform.position}");
|
||
// await UpdatePlayerShowType("Advanced");
|
||
//
|
||
// mainCharacter.SetAnimationState("moving");
|
||
// await Awaiters.Seconds(1f);
|
||
// // mainCharacter.FinishMove();
|
||
// await FinishMiningStep();
|
||
//
|
||
// // await UpdateShowType(2);
|
||
// // UpdateShowType
|
||
// // await mainCharacter.WaitIdleSpecialFinish(GetPlayerBasePos(mainCharacter));
|
||
//
|
||
// // await Awaiters.Seconds(1f);
|
||
// await UpdatePlayerShowType("Master");
|
||
// await Awaiters.Seconds(1f);
|
||
// mainCharacter.SetAnimationState("moving");
|
||
// await Awaiters.Seconds(1f);
|
||
// await FinishMiningStep();
|
||
// Log($"end: mainCharacter.position - >{mainCharacter.transform.position}");
|
||
//
|
||
// // mainCharacter.FinishMove();
|
||
// // await mainCharacter.WaitIdleSpecialFinish(GetPlayerBasePos(mainCharacter));
|
||
//
|
||
// // await Awaiters.Seconds(1f);
|
||
// await UpdatePlayerShowType("Basic");
|
||
// mainCharacter.SetAnimationState("moving");
|
||
// await Awaiters.Seconds(1f);
|
||
// await FinishMiningStep();
|
||
|
||
}
|
||
}
|
||
} |