397 lines
12 KiB
C#
397 lines
12 KiB
C#
//- 挑战赛- 公路
|
|
|
|
using System;
|
|
using System.Threading.Tasks;
|
|
using asap.core;
|
|
using Cinemachine;
|
|
using GampPlay.ChallengeMatch.Road;
|
|
using UniRx;
|
|
using UnityEditor;
|
|
using UnityEngine;
|
|
using UnityEngine.Playables;
|
|
|
|
//Event
|
|
|
|
namespace GampPlay.ChallengeMatch
|
|
{
|
|
public class ChallengeMatchSceneRoad : MonoBehaviour
|
|
{
|
|
|
|
[SerializeField]
|
|
private ChallengeRegionRoad[] nodeContainer;
|
|
|
|
//
|
|
[Header("当前每阶段时长")]
|
|
[SerializeField] private float[] stepTimes;
|
|
|
|
|
|
[Header("公式周期参数")]
|
|
[SerializeField] private float durationArg = 0.2f;
|
|
|
|
[Header("相机位移等待延时")]
|
|
[SerializeField] private float durationForLocation = 0.25f;
|
|
|
|
[Header("退出延时参数")]
|
|
[SerializeField] private float exitDelayArg = 0.2f;
|
|
|
|
|
|
private Transform _camera;
|
|
|
|
private CinemachineVirtualCamera _vCam;
|
|
|
|
// - 初始化相机
|
|
private CinemachineVirtualCamera _vCamInit;
|
|
|
|
private Transform _roadTruck;
|
|
|
|
private PlayableDirector _playableDirector;
|
|
//- 管理
|
|
private FishingChallengeManager _thisEventManager;
|
|
//- 数据
|
|
private FishingChallengeData _thisEventData;
|
|
|
|
//- 当前阶段
|
|
private int _curStep;
|
|
private double _targetTime;
|
|
private bool _isPlaying;
|
|
private CompositeDisposable _disposables = new();
|
|
|
|
//- 当前的时间
|
|
// private readonly float _stepTime = 1f;
|
|
// private Transform _truck;
|
|
|
|
|
|
|
|
|
|
private void Awake()
|
|
{
|
|
//-
|
|
var targetFrameRate = Application.targetFrameRate;
|
|
Log($"targetFrameRate {targetFrameRate}");
|
|
Log($"Time.timeScale: {Time.timeScale}");
|
|
Log($"Time.fixedDeltaTime: {Time.fixedDeltaTime}");
|
|
|
|
|
|
_camera = transform.Find("CameraRoot/Camera");
|
|
//
|
|
_vCam = _camera.GetComponent<CinemachineVirtualCamera>();
|
|
_vCamInit = transform.Find("CameraRoot/CameraInit").GetComponent<CinemachineVirtualCamera>();
|
|
|
|
_thisEventManager = GContext.container.Resolve<FishingChallengeManager>();
|
|
_thisEventData = _thisEventManager.fishingChallengeData;
|
|
_curStep = _thisEventData.step;
|
|
_playableDirector = transform.Find("road_trucktimeline").GetComponent<PlayableDirector>();
|
|
|
|
_roadTruck = transform.Find("road_truck");
|
|
// InitCamera();
|
|
//- 添加事件
|
|
OnAddEvents();
|
|
}
|
|
private async void Start()
|
|
{
|
|
ELog("Start-> ");
|
|
|
|
_playableDirector.played += OnTimelinePlayed;
|
|
_playableDirector.paused += OnTimelinePaused;
|
|
_playableDirector.stopped += OnTimelineStopped;
|
|
|
|
|
|
InitCurStep();
|
|
await Awaiters.Seconds(0.2f);
|
|
GContext.Publish(new EventSceneLoadComplete());
|
|
ELog("Start-> End");
|
|
|
|
|
|
}
|
|
|
|
private void InitCamera()
|
|
{
|
|
_vCamInit.gameObject.SetActive(true);
|
|
}
|
|
|
|
private void OnEnable()
|
|
{
|
|
_isPlaying = false;
|
|
|
|
}
|
|
private void OnDisable()
|
|
{
|
|
if (_vCam)
|
|
{
|
|
if (Camera.main)
|
|
{
|
|
var brain = Camera.main.GetComponent<CinemachineBrain>();
|
|
brain?.ManualUpdate();
|
|
}
|
|
}
|
|
}
|
|
private void OnDestroy()
|
|
{
|
|
_disposables?.Dispose();
|
|
_disposables = null;
|
|
}
|
|
|
|
|
|
|
|
private void Update()
|
|
{
|
|
#if UNITY_EDITOR
|
|
if (Input.GetKeyDown(KeyCode.N))
|
|
{
|
|
// _curStep = (_curStep + 1) % (_thisEventManager.GetFullStep() + 1);
|
|
// InitCurStep();
|
|
}
|
|
if (Input.GetKeyDown(KeyCode.V))
|
|
{
|
|
var e = new ChallengeCleanStageEvent
|
|
{
|
|
stage = 1,
|
|
};
|
|
OnUpdateStage(e);
|
|
}
|
|
#endif
|
|
if (_isPlaying)
|
|
{
|
|
if (_playableDirector.time >= _targetTime)
|
|
{
|
|
_playableDirector.Pause();
|
|
}
|
|
}
|
|
}
|
|
|
|
#if UNITY_EDITOR
|
|
private void OnGMInitStep(ChallengeInitStepEvent evt)
|
|
{
|
|
_curStep = evt.step;
|
|
InitCurStep();
|
|
}
|
|
#endif
|
|
|
|
#region Game Logic
|
|
private void InitCurStep()
|
|
{
|
|
Log($"InitCurStep -> _curStep = {_curStep}");
|
|
UpdateCurEnv(_curStep);
|
|
// LocationCarStep(_curStep);
|
|
//->
|
|
}
|
|
|
|
|
|
private async void UpdateCurCamera()
|
|
{
|
|
GContext.Publish(new EventUpdateCamera());
|
|
// if (_curStep < 4)
|
|
{
|
|
await LocationCamera();
|
|
}
|
|
// await Awaiters.Seconds(0.2f);
|
|
GContext.Publish(new EventUpdateCameraComplete());
|
|
}
|
|
|
|
private async Task LocationCamera()
|
|
{
|
|
ELog("LocationCamera-> ");
|
|
await Awaiters.Seconds(durationForLocation);
|
|
await SwitchToFollow();
|
|
|
|
ELog("LocationCamera-> Finished");
|
|
//- 5, 2.26,- 50;
|
|
}
|
|
private async Task SwitchToFollow()
|
|
{
|
|
_vCam.transform.position = _vCamInit.transform.position;
|
|
_vCam.transform.rotation = _vCamInit.transform.rotation;
|
|
// 提高优先级触发 Blend
|
|
_vCam.Priority = 15;
|
|
_vCamInit.gameObject.SetActive(false);
|
|
|
|
var deltaY = Math.Abs(_vCamInit.transform.position.y - _roadTruck.position.y);
|
|
ELog($"SwitchToFollow deltaY -> {deltaY} {durationArg * deltaY}");
|
|
await Awaiters.Seconds(durationArg * deltaY);
|
|
// 禁用旧的
|
|
_vCam.Priority = 5;
|
|
}
|
|
|
|
// -等待退出
|
|
private async Task SwitchToExit()
|
|
{
|
|
await Awaiters.NextFrame;
|
|
_vCamInit.gameObject.SetActive(true);
|
|
var deltaY = Math.Abs(_vCamInit.transform.position.y - _roadTruck.position.y);
|
|
await Awaiters.Seconds(durationArg * deltaY + exitDelayArg);
|
|
ELog($"SwitchToExit deltaY -> {deltaY}");
|
|
}
|
|
|
|
|
|
|
|
private void UpdateCurEnv(int step)
|
|
{
|
|
ELog($"UpdateCurEnv -> {step}");
|
|
|
|
var curIndex = step - 1;
|
|
var maxNum = nodeContainer.Length;
|
|
for (var i = curIndex + 1; i < maxNum; ++i)
|
|
{
|
|
_ = nodeContainer[i].UpdateState(CBoxState.Locked);
|
|
}
|
|
if (step > maxNum)
|
|
return;
|
|
if (step == 0)
|
|
{
|
|
nodeContainer[0].Prepare();
|
|
return;
|
|
}
|
|
|
|
for (var i = 0; i <= curIndex; ++i)
|
|
{
|
|
_ = nodeContainer[i].UpdateState(CBoxState.Broken);
|
|
}
|
|
_ = nodeContainer[curIndex].UpdateState(CBoxState.UnLocked);
|
|
}
|
|
|
|
private void LocationCarStep(int step)
|
|
{
|
|
ELog($"LocationCarStep -> {step}");
|
|
|
|
// var stepTime = stepTimes[step];
|
|
|
|
var stepTime = GetStepTime(step);
|
|
|
|
_playableDirector.time = stepTime;
|
|
// _playableDirector.time = step * _stepTime;
|
|
_playableDirector.Evaluate();
|
|
}
|
|
|
|
private float GetStepTime(int step)
|
|
{
|
|
var stepTime = 0f;
|
|
for (var i = 0; i < step; ++i)
|
|
{
|
|
stepTime += stepTimes[i];
|
|
}
|
|
|
|
ELog($"{step}: stepTime -> {stepTime} {_playableDirector.duration} {Math.Min(stepTime, (float)_playableDirector.duration)}");
|
|
|
|
return Math.Min(stepTime, (float)_playableDirector.duration);
|
|
}
|
|
|
|
//-
|
|
private void OnPlay(int step)
|
|
{
|
|
ELog($"OnPlay -> {step} {_targetTime}");
|
|
_playableDirector.Play();
|
|
_targetTime = GetStepTime(step);
|
|
// _targetTime = step * _stepTime;
|
|
}
|
|
|
|
private void OnEnter()
|
|
{
|
|
ELog("OnEnter-> ");
|
|
UpdateCurCamera();
|
|
ELog("OnEnter-> Finished");
|
|
}
|
|
|
|
// private async void OnLeave()
|
|
// {
|
|
// await SwitchToFollow();
|
|
// }
|
|
|
|
|
|
private void OnAddEvents()
|
|
{
|
|
GContext.OnEvent<ChallengeCleanStageEvent>().Subscribe(OnUpdateStage).AddTo(_disposables);
|
|
GContext.OnEvent<ChallengeBrokeStepEvent>().Subscribe(OnBrokeStep).AddTo(_disposables);
|
|
#if UNITY_EDITOR
|
|
GContext.OnEvent<ChallengeInitStepEvent>().Subscribe(OnGMInitStep).AddTo(_disposables);
|
|
#endif
|
|
GContext.OnEvent<ChallengeShowPlayerEvent>().Subscribe(OnShowPlayer).AddTo(_disposables);
|
|
GContext.OnEvent<ChallengeSetAnimationEvent>().Subscribe(OnChallengeTimeEvent).AddTo(_disposables);
|
|
GContext.OnEvent<ChallengeMatchPlayEvent>().Subscribe(e => { OnPlay(e.step); }).AddTo(_disposables);
|
|
GContext.OnEvent<ChallengeSceneEnterEvent>().Subscribe(e => { OnEnter(); }).AddTo(_disposables);
|
|
GContext.OnEvent<ExitMapEvent>().Subscribe(OnExitMap).AddTo(_disposables);
|
|
|
|
|
|
|
|
}
|
|
|
|
private async void OnExitMap(ExitMapEvent e)
|
|
{
|
|
ELog("OnExitMap");
|
|
await SwitchToExit();
|
|
e.Tcs.TrySetResult(true);
|
|
}
|
|
|
|
private void OnChallengeTimeEvent(ChallengeSetAnimationEvent e)
|
|
{
|
|
foreach (var box in nodeContainer)
|
|
{
|
|
box.UpdateTimeController(e);
|
|
}
|
|
}
|
|
|
|
private async void OnUpdateStage(ChallengeCleanStageEvent upStepEvent)
|
|
{
|
|
ELog("OnUpdateStage");
|
|
var stageIndex = upStepEvent.stage - 1;
|
|
if (stageIndex >= 0)
|
|
{
|
|
await nodeContainer[stageIndex].UpdateState(CBoxState.UnLocking);
|
|
}
|
|
upStepEvent.Tcs.SetResult(true);
|
|
}
|
|
|
|
private async void OnBrokeStep(ChallengeBrokeStepEvent brokeEvent)
|
|
{
|
|
ELog($"OnBrokeStep -> {brokeEvent.step}");
|
|
|
|
var step = brokeEvent.step - 1;
|
|
if (step >= 0 && step < nodeContainer.Length)
|
|
{
|
|
await nodeContainer[step].UpdateState(CBoxState.Attacking);
|
|
await Awaiters.Seconds(brokeEvent.dealyTime);
|
|
}
|
|
brokeEvent.Tcs.SetResult(true);
|
|
}
|
|
|
|
public void OnShowPlayer(ChallengeShowPlayerEvent evt)
|
|
{
|
|
LocationCarStep(evt.oldStep);
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region TimeLine
|
|
|
|
void OnTimelinePlayed(PlayableDirector director)
|
|
{
|
|
_isPlaying = true;
|
|
}
|
|
|
|
void OnTimelinePaused(PlayableDirector director)
|
|
{
|
|
_isPlaying = false;
|
|
}
|
|
|
|
void OnTimelineStopped(PlayableDirector director)
|
|
{
|
|
_isPlaying = false;
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region Log
|
|
private static void Log(object message)
|
|
{
|
|
Debug.Log($"<color=orange>{nameof(ChallengeMatchSceneRoad)} => {message} </color>");
|
|
}
|
|
|
|
private static void ELog(object message)
|
|
{
|
|
#if UNITY_EDITOR
|
|
Debug.Log($"<color=orange> {nameof(ChallengeMatchSceneRoad)} => {message} </color>");
|
|
#endif
|
|
}
|
|
#endregion
|
|
|
|
}
|
|
} |