Files
back_cantanBuilding/Assets/Scripts/EventBreak/EventBreakTunnelView.cs
2026-05-26 16:15:54 +08:00

185 lines
6.8 KiB
C#

using System;
using System.Threading.Tasks;
using DG.Tweening;
using UnityEngine;
using UnityEngine.Assertions;
using UnityEngine.UI;
using TMPro;
using System.Collections.Generic;
using asap.core;
using Game;
public class EventBreakTunnelView : MonoBehaviour
{
[SerializeField] private EventBreakBlock[] blocks;
[SerializeField] private Button btnDrill;
[SerializeField] private Transform endPivot, drillStartPivot;
[SerializeField] private EventBreakDrillDisplay drillDisplay;
[SerializeField] private GameObject fxButtonGlitter;
[SerializeField] private TMP_Text textCost;
[SerializeField] private Animator aniBtnDrill;
private float _spawnInterval = 0.1f, _dropDuration = 0.5f, _drillDuration = 0.8f, _dropHeight = 1680,
_drillReadyDuration = 0.5f, _resetTunnelDelay = 10f, _btnPressedDuration = 0.3f, _drillDetectionRange = 50f,
_blockDropSfxDelay = 0.1f;
private AnimationCurve _easeCurve;
private int _tunnelIdx;
private List<Vector3> _blockEndPoints;
private void Start()
{
btnDrill.onClick.AddListener(async () => await StartDrilling());
// foreach (var block in blocks)
// Debug.Log($"[EventBreak] block height: {block.name} at {block.transform.position.y}");
}
public void Init(EventBreakTunnelViewInitInfo info)
{
_blockEndPoints = new List<Vector3>();
foreach (var block in blocks)
{
block.gameObject.SetActive(false);
_blockEndPoints.Add(block.transform.position);
}
drillDisplay.Init(info.Idx);
_spawnInterval = info.SpawnInterval;
_dropDuration = info.DropDuration;
_drillDuration = info.DrillDuration;
_tunnelIdx = info.Idx;
_dropHeight = info.DropHeight;
textCost.text = info.Job.Cost.ToString();
_easeCurve = info.EaseCurve;
_drillReadyDuration = info.DrillReadyDuration;
_resetTunnelDelay = info.ResetTunnelDelay;
_btnPressedDuration = info.ButtonPressedDuration;
_drillDetectionRange = info.DrillDetectionRange;
_blockDropSfxDelay = info.BlockDropSfxDelay;
SetTunnel(info.Job);
}
public async void SetTunnel(DrillJobModel job)
{
try
{
EventBreakAct.EventAggregator.Publish(new EventBreakBlockInput(EEventBreakBlockInputOperation.Block));
aniBtnDrill.Play("Normal");
int jobCount = job.Blocks.Length, blockCount = blocks.Length;
Assert.IsTrue(jobCount == blockCount, $"[EventBreak]Block count mismatch. Got {jobCount} jobs and {blockCount} blocks");
drillDisplay.PlayEnter(drillStartPivot.position);
PlayBlockFallSfx(_blockDropSfxDelay);
for (int i = blocks.Length - 1; i >= 0; i--)
{
blocks[i].Appear(job.Blocks[i], dropHeight: _dropHeight, endPoint: _blockEndPoints[i], dropTime: _dropDuration, easeCurve: _easeCurve);
await Task.Delay(TimeSpan.FromSeconds(_spawnInterval));
}
await Task.Delay(TimeSpan.FromSeconds(_dropDuration + 0.1f));
EventBreakAct.EventAggregator.Publish(new EventBreakBlockInput(EEventBreakBlockInputOperation.Unblock));
}
catch (Exception e)
{
Debug.Log($"[EventBreak] TunnelInitiationError: {e.Message}\n{e.StackTrace}");
}
}
private async void PlayBlockFallSfx(float delay = 0)
{
try
{
await Task.Delay(TimeSpan.FromSeconds(delay));
GContext.Publish(new EventUISound("audio_ui_drill_brick_falling", 0));
}
catch (Exception e)
{
Debug.Log($"[EventBreak] SFX error: {e.Message}\n{e.StackTrace}");
}
}
public async Task StartDrilling()
{
// Debug.Log($"[EventBreak] Click No.{_tunnelIdx}!", this);
if (EventBreakAct.DrillSystem.DoDrillJob(_tunnelIdx))
{
EventBreakAct.EventAggregator.Publish(new EventBreakBlockInput(EEventBreakBlockInputOperation.Block));
PlayBtnPressed();
drillDisplay.PlayDrill();
await Task.Delay(TimeSpan.FromSeconds(_drillReadyDuration));
drillDisplay.GetDrillTween(endPivot.transform.position, _drillDuration)
.OnUpdate(DrillBlocks)
.OnComplete(OnDrillComplete);
}
else
{
EventBreakAct.EventAggregator.Publish(new EventBreakInsufficientTicket());
}
}
public void StartDrillingTest()
{
// Debug.Log($"[EventBreak] Click No.{_tunnelIdx}!", this);
drillDisplay.PlayDrill();
drillDisplay.GetDrillTween(endPivot.transform.position, _drillDuration)
.OnUpdate(DrillBlocks);
// .OnComplete(OnDrillComplete);
}
private async void OnDrillComplete()
{
try
{
await Task.Delay(TimeSpan.FromSeconds(_resetTunnelDelay));
var dm = GContext.container.Resolve<DrillModel>();
SetTunnel(dm.DrillJobList[_tunnelIdx]);
EventBreakAct.EventAggregator.Publish(new EventBreakBlockInput(EEventBreakBlockInputOperation.Unblock));
}
catch (Exception e)
{
Debug.Log($"[EventBreak] ResetTunnelError: {e.Message}\n{e.StackTrace}");
}
}
private void DrillBlocks()
{
foreach (var b in blocks)
{
if (b.gameObject.activeSelf == false)
continue;
var delta = b.transform.position.y - drillDisplay.Y;
if (delta > _drillDetectionRange)
continue;
b.Break();
}
}
public void SetAvailabilityDisplay(bool doesShow)
{
fxButtonGlitter.SetActive(doesShow);
textCost.color = doesShow ? Color.white : Color.red;
}
private async void PlayBtnPressed()
{
var isFxOn = fxButtonGlitter.activeInHierarchy;
try
{
aniBtnDrill.Play("Pressed");
fxButtonGlitter.SetActive(false);
await Task.Delay(TimeSpan.FromSeconds(_btnPressedDuration));
aniBtnDrill.Play("Normal");
fxButtonGlitter.SetActive(isFxOn);
}
catch (Exception e)
{
Debug.Log($"[EventBreak] Button Error: {e.Message}\n{e.StackTrace}");
}
}
}
public class EventBreakTunnelViewInitInfo
{
public DrillJobModel Job { get; set; }
public float SpawnInterval { get; set; }
public float DropDuration { get; set; }
public float DrillDuration { get; set; }
public float DropHeight { get; set; }
public float DrillReadyDuration { get; set; }
public float ResetTunnelDelay { get; set; }
public float ButtonPressedDuration { get; set; }
public float DrillDetectionRange { get; set; }
public float BlockDropSfxDelay { get; set; }
public int Idx { get; set; }
public AnimationCurve EaseCurve { get; set; }
}