TH1/Unity/Assets/Scripts/TH1_Renderer/InGameBubbleManager.cs
2026-03-30 20:23:27 +08:00

268 lines
9.6 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// BubbleData.cs
using System;
using System.Collections.Generic;
using Logic.Action;
using RuntimeData;
using TH1_Logic.Core;
using TH1Renderer;
using UnityEngine;
using System.Linq;
using Logic;
using TH1_Core.Events;
using TH1_Core.Managers;
using UnityEngine.Tilemaps;
using Object = UnityEngine.Object;
using Random = UnityEngine.Random;
namespace TH1_Renderer
{
public enum BubbleType
{
None,
Gather,
Capture,
HeroUpgrade,
Upgrade,
Examine
}
//TODO 做BubbleData序列化相关的工作
[Serializable]
public struct BubbleData
{
public GridData Grid;
public UnitData Unit;
//public HintType HintType;
public BubbleType BubbleType;
public BubbleData(GridData grid , BubbleType bubbleType)
{
Grid = grid;
grid.MainSelfPlayerVisibleUnit(out Unit);
BubbleType = bubbleType;
}
}
[Serializable]
public class InGameBubbleManager
{
//public HashSet<BubbleData> HintSet = new();
//private Dictionary<uint, BubbleData> _idToHintDict = new();
private uint _bubbleRendererIdCounter;
private GameObject _prefabROHint;
private Transform _selfTransform;
//private Dictionary<uint,BubbleRenderer> _ROHintRendererDict = new();
//存储可用的bubbleRendererId
private HashSet<uint> _availableRenderer;
private Dictionary<uint, BubbleRenderer> _dict;
//gid -> rendererid
private Dictionary<uint,uint> _gridHasBubble;
//每次开启一局游戏前,都要初始化的模块
public void Init(Transform selfTransform)
{
_bubbleRendererIdCounter = 0;
_prefabROHint = Resources.Load<GameObject>("Prefab/bubblePrefab");
_selfTransform = selfTransform;
_availableRenderer = new HashSet<uint>();
_dict = new Dictionary<uint, BubbleRenderer>();
_gridHasBubble = new Dictionary<uint,uint>();
}
//每局游戏开始前都要更新的
public void OnGameStart()
{
_bubbleRendererIdCounter = 0;
_availableRenderer = new HashSet<uint>();
_dict = new Dictionary<uint, BubbleRenderer>();
_gridHasBubble = new Dictionary<uint,uint>();
foreach (Transform child in _selfTransform.transform)
{
// 对每个子对象调用Destroy
Object.Destroy(child.gameObject);
}
}
public void OnGameClosed()
{
CloseAllBubble();
ClearAllRenderer();
}
public void ClearAllRenderer()
{
foreach (var t in _dict)
t.Value.Destroy();
_dict.Clear();
}
public uint BubbleDataIdGenerator()
{
return _bubbleRendererIdCounter++;
}
//每帧调用所有hintRenderer的update并且将已经结束的Renderer回收
public void Update()
{
if (Main.MapData == null) return;
if (!Main.MapData.CurPlayer?.IsSelfPlayer() ?? true) return;
//遍历所有unit查看哪些单位需要更新bubble显示
foreach (var unit in Main.MapData.UnitMap.UnitList)
{
//如果不是本机玩家
if (!unit.Player(Main.MapData, out var player)||!player.IsSelfPlayer()) continue;
if(!unit.Grid(Main.MapData,out var grid)) continue;
//准备升级行为的参数
var upgradeAction = ActionLogicFactory.GetActionLogic(new CommonActionId()
{ ActionType = CommonActionType.UnitAction, UnitActionType = UnitActionType.Upgrade });
var heroUpgradeAction = ActionLogicFactory.GetActionLogic(new CommonActionId()
{ ActionType = CommonActionType.UnitAction, UnitActionType = UnitActionType.HeroUpgrade });
var captureAction = ActionLogicFactory.GetActionLogic(new CommonActionId()
{ ActionType = CommonActionType.UnitAction, UnitActionType = UnitActionType.Capture });
var starfishAction = ActionLogicFactory.GetActionLogic(new CommonActionId()
{ ActionType = CommonActionType.UnitAction, UnitActionType = UnitActionType.Gather });
var treasureAction = ActionLogicFactory.GetActionLogic(new CommonActionId()
{ ActionType = CommonActionType.UnitAction, UnitActionType = UnitActionType.Examine });
var actionParam = new CommonActionParams(mapData: Main.MapData,
playerData: Main.MapData.PlayerMap.SelfPlayerData, unitData: unit,
gridData: unit.Grid(Main.MapData));
//先判断是否已经有按钮,如果有
bool upgrade = upgradeAction.CheckCan(actionParam);
bool heroUpgrade = heroUpgradeAction.CheckCan(actionParam);
bool capture = captureAction.CheckCan(actionParam);
bool treasure = treasureAction.CheckCan(actionParam);
bool starfish = starfishAction.CheckCan(actionParam);
bool showBubble = upgrade || heroUpgrade || capture || treasure || starfish;
BubbleType bubbleType = BubbleType.Upgrade;
if(heroUpgrade)bubbleType = BubbleType.HeroUpgrade;
if(capture)bubbleType = BubbleType.Capture;
if(treasure)bubbleType = BubbleType.Examine;
if(starfish)bubbleType = BubbleType.Gather;
//判断是否能执行升级行为可以的话播放bubble
if (showBubble)
{
if (_gridHasBubble.ContainsKey(grid.Id)) continue;
if(ShowBubble(new BubbleData(grid,bubbleType),out var rendererId))
_gridHasBubble.Add(grid.Id,rendererId);
}
//如果不应该播放bubble但是有个bubble关掉他
if(!showBubble)
{
if (_gridHasBubble.ContainsKey(grid.Id))
{
if (_dict.TryGetValue(_gridHasBubble[grid.Id], out var renderer))
renderer.ForceClose();
RecycleBubble(_gridHasBubble[grid.Id],grid.Id);
}
}
}
//遍历现在所有存在bubble的格子如果格子上没有unit让这个bubble自动关闭
var deleteList = new List<uint>();
foreach (var t in _gridHasBubble)
{
if (!Main.MapData.GridMap.GetGridDataByGid(t.Key, out var grid)) continue;
if (!grid.MainSelfPlayerVisibleUnit( out var _))
{
if (_dict.TryGetValue(t.Value, out var renderer))
renderer.ForceClose();
deleteList.Add(t.Key);
}
}
//回收这些bubble
foreach (var t in deleteList)
if(_gridHasBubble.TryGetValue(t,out var v))
RecycleBubble(v,t);
}
public bool ShowBubble(BubbleData data,out uint rendererId)
{
//Step #1 获取一个可用的renderer
var id = GetAvailableRenderer();
_availableRenderer.Remove(id);
if (!_dict.TryGetValue(id, out var renderer))
{
Debug.Log($"Fatal error Showbubble can't find dict key id = {id}");
rendererId = 0;
return false;
}
rendererId = renderer.Id;
//Step #2 设置对应的renderer
return renderer.SetInfo(data,onClick:ClickBubble);
}
public uint GetAvailableRenderer()
{
//如果池子里没有可用对象,新创建一个
if (_availableRenderer.Count == 0)
{
var renderer = new BubbleRenderer(BubbleDataIdGenerator(),_prefabROHint,_selfTransform);
_availableRenderer.Add(renderer.Id);
_dict[renderer.Id] = renderer;
return renderer.Id;
}
//否则随便给一个可以用的
return _availableRenderer.First();
}
public void CloseAllBubble()
{
//遍历所有renderer查询是否有不在available set里的有的话就强制关闭
foreach (var t in _dict)
if (!_availableRenderer.Contains(t.Key))
{
t.Value.ForceClose();
_availableRenderer.Add(t.Key);
}
_gridHasBubble.Clear();
}
//被动由逻辑触发
public void RecycleBubble(uint rendererId,uint gid)
{
_availableRenderer.Add(rendererId);
_gridHasBubble.Remove(gid);
}
//由玩家主动触发
public void ClickBubble(uint rendererId,uint gid)
{
RecycleBubble(rendererId,gid);
//UI收回
Main.Instance.MapInteractionLogic.CancelAllHighlight();
EventManager.Publish(new HideAllUIInfo(){});
}
public void TurnStartSetBubble(MapData mapData, PlayerData playerData)
{
}
}
}