450 lines
14 KiB
C#
450 lines
14 KiB
C#
using asap.core;
|
||
using cfg;
|
||
using Cinemachine;
|
||
using GameCore;
|
||
using System;
|
||
using System.Collections;
|
||
using System.Collections.Generic;
|
||
using UniRx;
|
||
using UnityEngine;
|
||
|
||
namespace game
|
||
{
|
||
public class WashingGameBase : MonoBehaviour
|
||
{
|
||
[Tooltip("游戏ID")]
|
||
public int m_GameID = 0;
|
||
|
||
[Tooltip("摄像机跟随路径")]
|
||
public CinemachinePath m_CameraPath;
|
||
|
||
[Tooltip("路径停歇点索引,循环执行。eg:5个点,执行到最后一个位置会从移动到初始位置开始。")]
|
||
public List<int> m_RestIndexList = new List<int>();
|
||
|
||
[Tooltip("摄像机移动速度")]
|
||
public float m_CameraSpeed = 4f;
|
||
|
||
[Tooltip("磁性距离,距离目标点一定距离,即认为到达目标点。")]
|
||
public float m_MagneticDistance = 0.01f;
|
||
|
||
[Tooltip("摄像机聚焦的位置(Transform)。")]
|
||
[SerializeField] protected Transform m_CameraFocusedTransform;
|
||
|
||
#region 虚拟摄像机
|
||
protected CameraFollowPathMoveController m_CameraMoveController;
|
||
|
||
/// <summary>
|
||
/// 停靠点数量
|
||
/// </summary>
|
||
/// <returns></returns>
|
||
protected int GetCameraPathRestCount()
|
||
{
|
||
if (m_CameraMoveController == null) return 0;
|
||
return m_CameraMoveController.RestCount;
|
||
}
|
||
/// <summary>
|
||
/// 摄像机跳转停靠点索引
|
||
/// </summary>
|
||
/// <param name="index"></param>
|
||
protected void JumpCameraToRestIndex(int index)
|
||
{
|
||
if (m_CameraMoveController == null) return;
|
||
m_CameraMoveController.JumpToRestIndex(index);
|
||
}
|
||
/// <summary>
|
||
/// 摄像机向前移动到下一个停靠点
|
||
/// </summary>
|
||
protected void ForwardCameraToNextRest()
|
||
{
|
||
if (m_CameraMoveController is null) return;
|
||
m_CameraMoveController.ForwardToNextRest();
|
||
}
|
||
/// <summary>
|
||
/// 摄像机向后移动到下一个停靠点
|
||
/// </summary>
|
||
protected void BackwardCameraToNextRest()
|
||
{
|
||
if (m_CameraMoveController is null) return;
|
||
m_CameraMoveController.BackwardToNextRest();
|
||
}
|
||
/// <summary>
|
||
/// 当前停靠点索引
|
||
/// </summary>
|
||
/// <returns></returns>
|
||
public int GetCameraCurrentMoveIndex()
|
||
{
|
||
if (m_CameraMoveController is null) return 0;
|
||
return m_CameraMoveController.MoveIndex;
|
||
}
|
||
/// <summary>
|
||
/// 向前跳到下一个停靠点
|
||
/// </summary>
|
||
protected void JumpCameraToNextRestForward()
|
||
{
|
||
if (m_CameraMoveController is null) return;
|
||
m_CameraMoveController.JumpToNextRestForward();
|
||
}
|
||
/// <summary>
|
||
/// 向后跳到下一个停靠点
|
||
/// </summary>
|
||
protected void JumpCameraToNextRestBackward()
|
||
{
|
||
if (m_CameraMoveController is null) return;
|
||
int index = m_CameraMoveController.JumpToNextRestBackward();
|
||
}
|
||
#endregion
|
||
|
||
#region 数据&状态相关
|
||
// 游戏类型
|
||
protected EventWashingOperation m_GameType = EventWashingOperation.None;
|
||
public EventWashingOperation GameType { get => m_GameType; }
|
||
|
||
protected string m_GameName;
|
||
|
||
//private bool m_IsGamePausing = false;
|
||
|
||
protected CinemachineVirtualCamera m_VirtualCamera;
|
||
|
||
public int GameID { get => m_GameID; }
|
||
|
||
protected EventWashingDataManager m_DataManager;
|
||
|
||
/// <summary>
|
||
/// 设置数据
|
||
/// </summary>
|
||
/// <param name="virtualCamera"></param>
|
||
/// <param name="cameraFollowPathMoveController"></param>
|
||
/// <param name="tool"></param>
|
||
public virtual void ResetAndInitData(CinemachineVirtualCamera virtualCamera, CameraFollowPathMoveController cameraFollowPathMoveController, OperatingToolsBase tool)
|
||
{
|
||
if (virtualCamera != null)
|
||
{
|
||
m_VirtualCamera = virtualCamera;
|
||
if (m_CameraFocusedTransform != null)
|
||
{
|
||
m_VirtualCamera.LookAt = m_CameraFocusedTransform;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
Debug.LogError("--- WashingGameBase ResetAndInitData 找不到虚拟相机,virtualCamera");
|
||
}
|
||
|
||
if (cameraFollowPathMoveController != null && m_CameraPath != null && m_RestIndexList != null)
|
||
{
|
||
m_CameraMoveController = cameraFollowPathMoveController;
|
||
m_CameraMoveController.ResetAndInit(m_CameraPath, m_RestIndexList, m_MagneticDistance);
|
||
m_CameraMoveController.JumpToRestIndex(0);
|
||
m_CameraMoveController.enabled = true;
|
||
m_CameraMoveController.Speed = m_CameraSpeed;
|
||
}
|
||
else
|
||
{
|
||
Debug.LogError("--- WashingGameBase ResetAndInitData 找不到正确的路径配置,PathMoveControlle、CameraPath 或者 RestIndexList");
|
||
}
|
||
|
||
if (tool != null)
|
||
{
|
||
m_Tool = tool;
|
||
m_Tool.gameObject.SetActive(true);
|
||
m_Tool.JumpToExhibition();
|
||
m_Tool.StopExecuting();
|
||
}
|
||
else
|
||
{
|
||
Debug.LogError("--- WashingGameBase ResetAndInitData 找不到工具包");
|
||
}
|
||
}
|
||
|
||
protected EventWashingActionStatus m_Status = EventWashingActionStatus.Invalid;
|
||
|
||
/// <summary>
|
||
/// 切换状态
|
||
/// </summary>
|
||
/// <param name="status"></param>
|
||
protected void ChangeStatus(EventWashingActionStatus status)
|
||
{
|
||
m_Status = status;
|
||
}
|
||
#endregion
|
||
|
||
#region 代币相关
|
||
protected List<UpdateOperationSet> m_UpdateOperationSets = new List<UpdateOperationSet>();
|
||
private bool m_IsShowingTokenNotEnough = false;
|
||
private float m_ShowingTokenNotEnoughCD = 0.0f;
|
||
|
||
/// <summary>
|
||
/// 代币是否足够消费
|
||
/// </summary>
|
||
/// <param name="spend"></param>
|
||
/// <returns></returns>
|
||
protected bool IsTokenEnough(int spend)
|
||
{
|
||
if (m_DataManager == null) return false;
|
||
bool isEnough = m_DataManager.IsEnough(spend);
|
||
if (isEnough == false && m_IsShowingTokenNotEnough == false)
|
||
{
|
||
ToastPanel.Show(LocalizationMgr.GetText("UI_ToastPanel_89"));
|
||
m_IsShowingTokenNotEnough = true;
|
||
}
|
||
m_ShowingTokenNotEnoughCD = 0.3f;
|
||
|
||
return isEnough;
|
||
}
|
||
|
||
protected bool ConsumeTokens(int count)
|
||
{
|
||
if (m_DataManager == null) return false;
|
||
bool isEnough = m_DataManager.ConsumeTokens(count);
|
||
if (isEnough == false)
|
||
{
|
||
if (m_IsShowingTokenNotEnough == false)
|
||
{
|
||
ToastPanel.Show(LocalizationMgr.GetText("UI_ToastPanel_89"));
|
||
m_IsShowingTokenNotEnough = true;
|
||
}
|
||
m_ShowingTokenNotEnoughCD = 0.3f;
|
||
|
||
m_DataManager.SetEnergy(0f, 0f);
|
||
|
||
SetEnergyShortage();
|
||
PauseGame();
|
||
}
|
||
else
|
||
{
|
||
ResumeGame();
|
||
SetEnergyEnough();
|
||
|
||
float step = 1f / m_DataManager.WashingData.StepEnergyConsume;
|
||
|
||
m_DataManager.SetEnergy(1f, step);
|
||
|
||
UpdateOperationSet updateOperationSet = GetUpdateOperationSet();
|
||
if (updateOperationSet != null) m_UpdateOperationSets.Add(updateOperationSet);
|
||
}
|
||
return isEnough;
|
||
}
|
||
|
||
protected virtual void UpdateTokenConsume()
|
||
{
|
||
if (m_DataManager == null || m_DataManager.WashingData == null) return;
|
||
|
||
if (m_DataManager.WashingData.Energy <= 0f || m_DataManager.WashingData.EnergyConsumptionSpeed <= 0f) return;
|
||
|
||
ResumeGame();
|
||
SetEnergyEnough();
|
||
|
||
UpdateOperationSet updateOperationSet = GetUpdateOperationSet();
|
||
if (updateOperationSet != null) m_UpdateOperationSets.Add(updateOperationSet);
|
||
}
|
||
|
||
protected virtual UpdateOperationSet GetUpdateOperationSet()
|
||
{
|
||
if (m_DataManager == null) return null;
|
||
UpdateOperationSet updateOperationSet = new UpdateOperationSet();
|
||
updateOperationSet.Update = m_DataManager.UpdateToken;
|
||
updateOperationSet.IsUpdateOver = m_DataManager.IsUpdateTokenOver;
|
||
updateOperationSet.Callback = ConsumeTokens;
|
||
return updateOperationSet;
|
||
}
|
||
protected virtual void SetEnergyShortage()
|
||
{
|
||
|
||
}
|
||
protected virtual void SetEnergyEnough()
|
||
{
|
||
|
||
}
|
||
|
||
protected bool HaveEnergy()
|
||
{
|
||
if (m_DataManager != null && m_DataManager.WashingData != null) return m_DataManager.WashingData.Energy > 0f;
|
||
return false;
|
||
}
|
||
#endregion
|
||
|
||
#region 工具功能
|
||
// 操作工具
|
||
protected OperatingToolsBase m_Tool;
|
||
public OperatingToolsBase ToolsBase { get => m_Tool; }
|
||
|
||
/// <summary>
|
||
/// 工具跳转到展示区
|
||
/// </summary>
|
||
public void JumpToolToExhibition()
|
||
{
|
||
if (m_Tool == null) return;
|
||
m_Tool.JumpToExhibition();
|
||
}
|
||
|
||
/// <summary>
|
||
/// 工具移动到操作区 Transform
|
||
/// </summary>
|
||
/// <param name="transform"></param>
|
||
public void MoveToolToTransform(Transform transform)
|
||
{
|
||
if (m_Tool is null) return;
|
||
m_Tool.MoveToTransform(transform);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 工具移动到展示区
|
||
/// </summary>
|
||
public void MoveToolToExhibition()
|
||
{
|
||
if (m_Tool is null) return;
|
||
m_Tool.MoveToExhibition();
|
||
}
|
||
#endregion
|
||
|
||
#region 新手引导
|
||
protected bool m_IsGuiding = false;
|
||
#endregion
|
||
|
||
#region 生命周期
|
||
protected virtual void OnEnable()
|
||
{
|
||
|
||
}
|
||
|
||
protected virtual void OnDisable()
|
||
{
|
||
disposables.Dispose();
|
||
}
|
||
|
||
protected virtual void OnDestroy()
|
||
{
|
||
disposables.Dispose();
|
||
disposables = null;
|
||
}
|
||
|
||
protected virtual void Update()
|
||
{
|
||
if (m_ShowingTokenNotEnoughCD > 0f)
|
||
{
|
||
m_ShowingTokenNotEnoughCD -= Time.deltaTime;
|
||
if (m_ShowingTokenNotEnoughCD <= 0f)
|
||
{
|
||
m_ShowingTokenNotEnoughCD = 0f;
|
||
m_IsShowingTokenNotEnough = false;
|
||
}
|
||
}
|
||
}
|
||
|
||
protected virtual void LateUpdate()
|
||
{
|
||
int count = m_UpdateOperationSets.Count;
|
||
for (int i = count - 1; i >= 0; i--)
|
||
{
|
||
var updateOperationSet = m_UpdateOperationSets[i];
|
||
if (updateOperationSet != null)
|
||
{
|
||
updateOperationSet.Update(Time.deltaTime);
|
||
if (updateOperationSet.IsUpdateOver())
|
||
{
|
||
if (!IsGameOver())
|
||
updateOperationSet.Callback(1);
|
||
m_UpdateOperationSets.Remove(updateOperationSet);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
public virtual void InitGame(string name)
|
||
{
|
||
this.m_GameName = name;
|
||
this.m_GameType = EventWashingOperation.None;
|
||
this.m_Status = EventWashingActionStatus.Invalid;
|
||
}
|
||
|
||
public virtual void EnterGame()
|
||
{
|
||
|
||
}
|
||
|
||
protected virtual void AfterEnterGame()
|
||
{
|
||
if (m_DataManager != null)
|
||
{
|
||
if (m_DataManager.IsEnough(1)) SetEnergyEnough();
|
||
else SetEnergyShortage();
|
||
}
|
||
}
|
||
|
||
public virtual void SaveContext()
|
||
{
|
||
|
||
}
|
||
|
||
public virtual void LoadContext()
|
||
{
|
||
|
||
}
|
||
|
||
public virtual void SyncData()
|
||
{
|
||
if (m_DataManager != null)
|
||
{
|
||
m_DataManager.SyncData();
|
||
}
|
||
}
|
||
|
||
protected virtual void PauseGame()
|
||
{
|
||
//m_IsGamePausing = true;
|
||
}
|
||
|
||
protected virtual void ResumeGame()
|
||
{
|
||
//m_IsGamePausing = false;
|
||
}
|
||
|
||
public virtual void Fresh(EventWashingDataManager dataManager)
|
||
{
|
||
m_DataManager = dataManager;
|
||
SyncData();
|
||
UpdateTokenConsume();
|
||
if (m_DataManager != null && dataManager.WashingData != null) dataManager.WashingData.ClearLocalDataExceptGroup(m_GameName);
|
||
}
|
||
|
||
public virtual void GameOver()
|
||
{
|
||
SyncData();
|
||
|
||
if (m_CameraMoveController != null)
|
||
{
|
||
m_CameraMoveController.enabled = false;
|
||
}
|
||
if (m_Tool != null)
|
||
{
|
||
m_Tool.MoveToExhibition();
|
||
m_Tool.StopExecuting();
|
||
}
|
||
m_UpdateOperationSets.Clear();
|
||
}
|
||
|
||
public bool IsGameOver()
|
||
{
|
||
if (m_DataManager == null || m_DataManager.WashingData == null) return true;
|
||
|
||
bool isOver = m_DataManager.IsGameOver();
|
||
if (isOver) GameOver();
|
||
return isOver;
|
||
}
|
||
#endregion
|
||
|
||
#region 事件相关
|
||
protected CompositeDisposable disposables = new CompositeDisposable();
|
||
public void Subscribe<T>(Action<T> eventAction, string eventId = null)
|
||
{
|
||
IObservable<T> observable = FishingYachtAct.GetEvent<T>(eventId);
|
||
|
||
if (observable != null)
|
||
{
|
||
observable.Subscribe<T>(eventAction).AddTo(disposables);
|
||
}
|
||
}
|
||
#endregion
|
||
}
|
||
}
|