添加参战防御塔功能(UI)

This commit is contained in:
SepComet 2026-03-04 20:36:05 +08:00
parent 298345fa17
commit a62309e8c1
25 changed files with 1160 additions and 20 deletions

View File

@ -12,6 +12,7 @@ namespace GeometryTD.CustomComponent
public class PlayerInventoryComponent : GameFrameworkComponent public class PlayerInventoryComponent : GameFrameworkComponent
{ {
private const int TowerLevelCount = 5; private const int TowerLevelCount = 5;
private const int MaxParticipantTowerCount = 4;
private BackpackInventoryData _inventory = new BackpackInventoryData(); private BackpackInventoryData _inventory = new BackpackInventoryData();
private long _nextInstanceId = 1; private long _nextInstanceId = 1;
private bool _initialized; private bool _initialized;
@ -31,6 +32,7 @@ namespace GeometryTD.CustomComponent
public void OnInit() public void OnInit()
{ {
_inventory = CloneInventory(RepoFormUseCase.SampleInventory()); _inventory = CloneInventory(RepoFormUseCase.SampleInventory());
NormalizeParticipantState();
RebuildNextInstanceId(); RebuildNextInstanceId();
_initialized = true; _initialized = true;
Log.Info( Log.Info(
@ -178,6 +180,55 @@ namespace GeometryTD.CustomComponent
_inventory.Gold += resolvedGain; _inventory.Gold += resolvedGain;
} }
public bool TryAddParticipantTower(long towerInstanceId, int maxCount = 4)
{
EnsureInitialized();
int resolvedMaxCount = Mathf.Max(1, maxCount);
resolvedMaxCount = Mathf.Min(resolvedMaxCount, MaxParticipantTowerCount);
if (!TryGetTowerById(towerInstanceId, out TowerItemData tower))
{
return false;
}
_inventory.ParticipantTowerInstanceIds ??= new List<long>();
if (_inventory.ParticipantTowerInstanceIds.Contains(towerInstanceId))
{
tower.IsParticipatingInCombat = true;
return false;
}
if (_inventory.ParticipantTowerInstanceIds.Count >= resolvedMaxCount)
{
return false;
}
_inventory.ParticipantTowerInstanceIds.Add(towerInstanceId);
tower.IsParticipatingInCombat = true;
return true;
}
public bool TryRemoveParticipantTower(long towerInstanceId)
{
EnsureInitialized();
if (towerInstanceId <= 0 || _inventory.ParticipantTowerInstanceIds == null)
{
return false;
}
bool removed = _inventory.ParticipantTowerInstanceIds.Remove(towerInstanceId);
if (!removed)
{
return false;
}
if (TryGetTowerById(towerInstanceId, out TowerItemData tower))
{
tower.IsParticipatingInCombat = false;
}
return true;
}
public bool TryAssembleTower( public bool TryAssembleTower(
long muzzleInstanceId, long muzzleInstanceId,
long bearingInstanceId, long bearingInstanceId,
@ -337,6 +388,27 @@ namespace GeometryTD.CustomComponent
return false; return false;
} }
private bool TryGetTowerById(long towerInstanceId, out TowerItemData tower)
{
tower = null;
if (towerInstanceId <= 0 || _inventory.Towers == null)
{
return false;
}
for (int i = 0; i < _inventory.Towers.Count; i++)
{
TowerItemData candidate = _inventory.Towers[i];
if (candidate != null && candidate.InstanceId == towerInstanceId)
{
tower = candidate;
return true;
}
}
return false;
}
private bool TryBuildTowerStats( private bool TryBuildTowerStats(
MuzzleCompItemData muzzleComp, MuzzleCompItemData muzzleComp,
BearingCompItemData bearingComp, BearingCompItemData bearingComp,
@ -555,6 +627,57 @@ namespace GeometryTD.CustomComponent
_nextInstanceId = Math.Max(1, maxInstanceId + 1); _nextInstanceId = Math.Max(1, maxInstanceId + 1);
} }
private void NormalizeParticipantState()
{
if (_inventory == null)
{
return;
}
_inventory.ParticipantTowerInstanceIds ??= new List<long>();
Dictionary<long, TowerItemData> towerMap = new Dictionary<long, TowerItemData>();
if (_inventory.Towers != null)
{
for (int i = 0; i < _inventory.Towers.Count; i++)
{
TowerItemData tower = _inventory.Towers[i];
if (tower == null || tower.InstanceId <= 0)
{
continue;
}
tower.IsParticipatingInCombat = false;
towerMap[tower.InstanceId] = tower;
}
}
List<long> normalizedIds = new List<long>(_inventory.ParticipantTowerInstanceIds.Count);
HashSet<long> uniqueIds = new HashSet<long>();
for (int i = 0; i < _inventory.ParticipantTowerInstanceIds.Count; i++)
{
if (normalizedIds.Count >= MaxParticipantTowerCount)
{
break;
}
long id = _inventory.ParticipantTowerInstanceIds[i];
if (id <= 0 || !uniqueIds.Add(id))
{
continue;
}
if (!towerMap.TryGetValue(id, out TowerItemData tower))
{
continue;
}
tower.IsParticipatingInCombat = true;
normalizedIds.Add(id);
}
_inventory.ParticipantTowerInstanceIds = normalizedIds;
}
private static BackpackInventoryData CloneInventory(BackpackInventoryData source) private static BackpackInventoryData CloneInventory(BackpackInventoryData source)
{ {
BackpackInventoryData cloned = new BackpackInventoryData(); BackpackInventoryData cloned = new BackpackInventoryData();
@ -613,6 +736,18 @@ namespace GeometryTD.CustomComponent
} }
} }
if (source.ParticipantTowerInstanceIds != null)
{
for (int i = 0; i < source.ParticipantTowerInstanceIds.Count; i++)
{
long id = source.ParticipantTowerInstanceIds[i];
if (id > 0)
{
cloned.ParticipantTowerInstanceIds.Add(id);
}
}
}
return cloned; return cloned;
} }
@ -675,6 +810,7 @@ namespace GeometryTD.CustomComponent
InstanceId = source.InstanceId, InstanceId = source.InstanceId,
Name = source.Name, Name = source.Name,
Rarity = source.Rarity, Rarity = source.Rarity,
IsParticipatingInCombat = source.IsParticipatingInCombat,
MuzzleComponentInstanceId = source.MuzzleComponentInstanceId, MuzzleComponentInstanceId = source.MuzzleComponentInstanceId,
BearingComponentInstanceId = source.BearingComponentInstanceId, BearingComponentInstanceId = source.BearingComponentInstanceId,
BaseComponentInstanceId = source.BaseComponentInstanceId, BaseComponentInstanceId = source.BaseComponentInstanceId,
@ -717,4 +853,4 @@ namespace GeometryTD.CustomComponent
return source != null ? (TagType[])source.Clone() : Array.Empty<TagType>(); return source != null ? (TagType[])source.Clone() : Array.Empty<TagType>();
} }
} }
} }

View File

@ -33,5 +33,7 @@ namespace GeometryTD.Definition
/// 背包中的防御塔实例。 /// 背包中的防御塔实例。
/// </summary> /// </summary>
public List<TowerItemData> Towers { get; set; } = new List<TowerItemData>(); public List<TowerItemData> Towers { get; set; } = new List<TowerItemData>();
public List<long> ParticipantTowerInstanceIds { get; set; } = new List<long>();
} }
} }

View File

@ -39,6 +39,8 @@ namespace GeometryTD.Definition
/// 防御塔品质。 /// 防御塔品质。
/// </summary> /// </summary>
public RarityType Rarity { get; set; } public RarityType Rarity { get; set; }
public bool IsParticipatingInCombat { get; set; }
/// <summary> /// <summary>
/// 构成该防御塔的枪口组件实例 Id。 /// 构成该防御塔的枪口组件实例 Id。

View File

@ -0,0 +1,9 @@
namespace GeometryTD.Definition
{
public enum RepoItemClickActionType
{
OpenDetail,
RemoveParticipant,
}
}

View File

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: abb9d4102f124528956d4ab5dcfd54a4
timeCreated: 1772625883

View File

@ -0,0 +1,27 @@
using GameFramework;
using GameFramework.Event;
namespace GeometryTD.CustomEvent
{
public sealed class RepoParticipantAssignRequestedEventArgs : GameEventArgs
{
public static int EventId => typeof(RepoParticipantAssignRequestedEventArgs).GetHashCode();
public override int Id => EventId;
public long TowerItemId { get; private set; }
public static RepoParticipantAssignRequestedEventArgs Create(long towerItemId)
{
RepoParticipantAssignRequestedEventArgs args =
ReferencePool.Acquire<RepoParticipantAssignRequestedEventArgs>();
args.TowerItemId = towerItemId;
return args;
}
public override void Clear()
{
TowerItemId = 0;
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: e28c7dca1c4d6684f949e3ea257b5ad8
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,27 @@
using GameFramework;
using GameFramework.Event;
namespace GeometryTD.CustomEvent
{
public sealed class RepoParticipantRemoveRequestedEventArgs : GameEventArgs
{
public static int EventId => typeof(RepoParticipantRemoveRequestedEventArgs).GetHashCode();
public override int Id => EventId;
public long TowerItemId { get; private set; }
public static RepoParticipantRemoveRequestedEventArgs Create(long towerItemId)
{
RepoParticipantRemoveRequestedEventArgs args =
ReferencePool.Acquire<RepoParticipantRemoveRequestedEventArgs>();
args.TowerItemId = towerItemId;
return args;
}
public override void Clear()
{
TowerItemId = 0;
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 1438388ea5334474da123eadd2a55fc8
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -129,6 +129,7 @@ namespace GeometryTD.UI
InstanceId = tower.InstanceId, InstanceId = tower.InstanceId,
CanDrag = false, CanDrag = false,
EnduranceRate01 = ItemDescUtility.ResolveTowerEnduranceRate(tower, muzzleMap, bearingMap, baseMap), EnduranceRate01 = ItemDescUtility.ResolveTowerEnduranceRate(tower, muzzleMap, bearingMap, baseMap),
ClickActionType = RepoItemClickActionType.OpenDetail,
ComponentSlotType = TowerCompSlotType.None, ComponentSlotType = TowerCompSlotType.None,
IconAreaContext = BuildIconAreaContext(tower) IconAreaContext = BuildIconAreaContext(tower)
}); });
@ -157,6 +158,7 @@ namespace GeometryTD.UI
InstanceId = item.InstanceId, InstanceId = item.InstanceId,
CanDrag = false, CanDrag = false,
EnduranceRate01 = ItemDescUtility.ResolveComponentEnduranceRate(item), EnduranceRate01 = ItemDescUtility.ResolveComponentEnduranceRate(item),
ClickActionType = RepoItemClickActionType.OpenDetail,
ComponentSlotType = TowerCompSlotType.Muzzle, ComponentSlotType = TowerCompSlotType.Muzzle,
IconAreaContext = BuildIconAreaContext(item) IconAreaContext = BuildIconAreaContext(item)
}); });
@ -184,6 +186,7 @@ namespace GeometryTD.UI
InstanceId = item.InstanceId, InstanceId = item.InstanceId,
CanDrag = false, CanDrag = false,
EnduranceRate01 = ItemDescUtility.ResolveComponentEnduranceRate(item), EnduranceRate01 = ItemDescUtility.ResolveComponentEnduranceRate(item),
ClickActionType = RepoItemClickActionType.OpenDetail,
ComponentSlotType = TowerCompSlotType.Bearing, ComponentSlotType = TowerCompSlotType.Bearing,
IconAreaContext = BuildIconAreaContext(item) IconAreaContext = BuildIconAreaContext(item)
}); });
@ -212,6 +215,7 @@ namespace GeometryTD.UI
InstanceId = item.InstanceId, InstanceId = item.InstanceId,
CanDrag = false, CanDrag = false,
EnduranceRate01 = ItemDescUtility.ResolveComponentEnduranceRate(item), EnduranceRate01 = ItemDescUtility.ResolveComponentEnduranceRate(item),
ClickActionType = RepoItemClickActionType.OpenDetail,
ComponentSlotType = TowerCompSlotType.Base, ComponentSlotType = TowerCompSlotType.Base,
IconAreaContext = BuildIconAreaContext(item) IconAreaContext = BuildIconAreaContext(item)
}); });

View File

@ -0,0 +1,8 @@
namespace GeometryTD.UI
{
public class ParticipantAreaContext : UIContext
{
public RepoItemContext[] Items;
public int MaxCount;
}
}

View File

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: dba2ecceff78486fb2a251e7c28ce9c0
timeCreated: 1772624131

View File

@ -6,5 +6,6 @@ namespace GeometryTD.UI
{ {
public CombineAreaContext CombineAreaContext; public CombineAreaContext CombineAreaContext;
public CompAreaContext CompAreaContext; public CompAreaContext CompAreaContext;
public ParticipantAreaContext ParticipantAreaContext;
} }
} }

View File

@ -0,0 +1,8 @@
namespace GeometryTD.UI
{
public enum RepoItemClickActionType : byte
{
OpenDetail = 0,
RemoveParticipant = 1
}
}

View File

@ -0,0 +1 @@
fileFormatVersion: 2`nguid: d3f0b6db2f8d4310b1f6c6f61d2075d1`nMonoImporter:`n externalObjects: {}`n serializedVersion: 2`n defaultReferences: []`n executionOrder: 0`n icon: {instanceID: 0}`n userData: `n assetBundleName: `n assetBundleVariant: `n

View File

@ -9,6 +9,7 @@ namespace GeometryTD.UI
public long InstanceId; public long InstanceId;
public bool CanDrag; public bool CanDrag;
public float EnduranceRate01; public float EnduranceRate01;
public RepoItemClickActionType ClickActionType;
public TowerCompSlotType ComponentSlotType; public TowerCompSlotType ComponentSlotType;
public IconAreaContext IconAreaContext; public IconAreaContext IconAreaContext;
} }

View File

@ -11,9 +11,11 @@ namespace GeometryTD.UI
{ {
public class RepoFormController : UIFormControllerCommonBase<RepoFormContext, RepoForm> public class RepoFormController : UIFormControllerCommonBase<RepoFormContext, RepoForm>
{ {
private const int MaxParticipantCount = 4;
private RepoFormUseCase _useCase; private RepoFormUseCase _useCase;
private readonly Dictionary<long, RepoItemContext> _itemContextMap = new Dictionary<long, RepoItemContext>(); private readonly Dictionary<long, RepoItemContext> _itemContextMap = new Dictionary<long, RepoItemContext>();
private readonly Dictionary<long, ItemDescSeed> _itemDescSeedMap = new Dictionary<long, ItemDescSeed>(); private readonly Dictionary<long, ItemDescSeed> _itemDescSeedMap = new Dictionary<long, ItemDescSeed>();
private readonly HashSet<long> _participantTowerIds = new HashSet<long>();
private sealed class ItemDescSeed private sealed class ItemDescSeed
{ {
@ -28,6 +30,7 @@ namespace GeometryTD.UI
protected override void RefreshUI(RepoForm form, RepoFormContext context) protected override void RefreshUI(RepoForm form, RepoFormContext context)
{ {
form.RefreshUI(context); form.RefreshUI(context);
ApplyParticipantSelection();
} }
protected override void SubscribeCustomEvents() protected override void SubscribeCustomEvents()
@ -36,6 +39,8 @@ namespace GeometryTD.UI
GameEntry.Event.Subscribe(RepoItemDragEndedEventArgs.EventId, OnRepoItemDragEnded); GameEntry.Event.Subscribe(RepoItemDragEndedEventArgs.EventId, OnRepoItemDragEnded);
GameEntry.Event.Subscribe(CombineSlotClickedEventArgs.EventId, OnCombineSlotClicked); GameEntry.Event.Subscribe(CombineSlotClickedEventArgs.EventId, OnCombineSlotClicked);
GameEntry.Event.Subscribe(RepoCombineRequestedEventArgs.EventId, OnRepoCombineRequested); GameEntry.Event.Subscribe(RepoCombineRequestedEventArgs.EventId, OnRepoCombineRequested);
GameEntry.Event.Subscribe(RepoParticipantAssignRequestedEventArgs.EventId, OnRepoParticipantAssignRequested);
GameEntry.Event.Subscribe(RepoParticipantRemoveRequestedEventArgs.EventId, OnRepoParticipantRemoveRequested);
GameEntry.Event.Subscribe(RepoFormReturnEventArgs.EventId, OnRepoFormReturn); GameEntry.Event.Subscribe(RepoFormReturnEventArgs.EventId, OnRepoFormReturn);
} }
@ -45,6 +50,8 @@ namespace GeometryTD.UI
GameEntry.Event.Unsubscribe(RepoItemDragEndedEventArgs.EventId, OnRepoItemDragEnded); GameEntry.Event.Unsubscribe(RepoItemDragEndedEventArgs.EventId, OnRepoItemDragEnded);
GameEntry.Event.Unsubscribe(CombineSlotClickedEventArgs.EventId, OnCombineSlotClicked); GameEntry.Event.Unsubscribe(CombineSlotClickedEventArgs.EventId, OnCombineSlotClicked);
GameEntry.Event.Unsubscribe(RepoCombineRequestedEventArgs.EventId, OnRepoCombineRequested); GameEntry.Event.Unsubscribe(RepoCombineRequestedEventArgs.EventId, OnRepoCombineRequested);
GameEntry.Event.Unsubscribe(RepoParticipantAssignRequestedEventArgs.EventId, OnRepoParticipantAssignRequested);
GameEntry.Event.Unsubscribe(RepoParticipantRemoveRequestedEventArgs.EventId, OnRepoParticipantRemoveRequested);
GameEntry.Event.Unsubscribe(RepoFormReturnEventArgs.EventId, OnRepoFormReturn); GameEntry.Event.Unsubscribe(RepoFormReturnEventArgs.EventId, OnRepoFormReturn);
} }
@ -99,12 +106,14 @@ namespace GeometryTD.UI
_itemDescSeedMap.Clear(); _itemDescSeedMap.Clear();
if (rawData?.Inventory == null) if (rawData?.Inventory == null)
{ {
_participantTowerIds.Clear();
return null; return null;
} }
Dictionary<long, MuzzleCompItemData> muzzleMap = BuildComponentMap(rawData.Inventory.MuzzleComponents); Dictionary<long, MuzzleCompItemData> muzzleMap = BuildComponentMap(rawData.Inventory.MuzzleComponents);
Dictionary<long, BearingCompItemData> bearingMap = BuildComponentMap(rawData.Inventory.BearingComponents); Dictionary<long, BearingCompItemData> bearingMap = BuildComponentMap(rawData.Inventory.BearingComponents);
Dictionary<long, BaseCompItemData> baseMap = BuildComponentMap(rawData.Inventory.BaseComponents); Dictionary<long, BaseCompItemData> baseMap = BuildComponentMap(rawData.Inventory.BaseComponents);
Dictionary<long, TowerItemData> towerMap = BuildTowerMap(rawData.Inventory.Towers);
List<RepoItemContext> items = new List<RepoItemContext>(); List<RepoItemContext> items = new List<RepoItemContext>();
if (rawData.Inventory.Towers != null) if (rawData.Inventory.Towers != null)
@ -121,6 +130,7 @@ namespace GeometryTD.UI
InstanceId = tower.InstanceId, InstanceId = tower.InstanceId,
CanDrag = true, CanDrag = true,
EnduranceRate01 = ItemDescUtility.ResolveTowerEnduranceRate(tower, muzzleMap, bearingMap, baseMap), EnduranceRate01 = ItemDescUtility.ResolveTowerEnduranceRate(tower, muzzleMap, bearingMap, baseMap),
ClickActionType = RepoItemClickActionType.OpenDetail,
ComponentSlotType = TowerCompSlotType.None, ComponentSlotType = TowerCompSlotType.None,
IconAreaContext = BuildIconAreaContext(tower) IconAreaContext = BuildIconAreaContext(tower)
}); });
@ -147,6 +157,7 @@ namespace GeometryTD.UI
InstanceId = item.InstanceId, InstanceId = item.InstanceId,
CanDrag = true, CanDrag = true,
EnduranceRate01 = ItemDescUtility.ResolveComponentEnduranceRate(item), EnduranceRate01 = ItemDescUtility.ResolveComponentEnduranceRate(item),
ClickActionType = RepoItemClickActionType.OpenDetail,
ComponentSlotType = TowerCompSlotType.Muzzle, ComponentSlotType = TowerCompSlotType.Muzzle,
IconAreaContext = BuildIconAreaContext(item) IconAreaContext = BuildIconAreaContext(item)
}); });
@ -173,6 +184,7 @@ namespace GeometryTD.UI
InstanceId = item.InstanceId, InstanceId = item.InstanceId,
CanDrag = true, CanDrag = true,
EnduranceRate01 = ItemDescUtility.ResolveComponentEnduranceRate(item), EnduranceRate01 = ItemDescUtility.ResolveComponentEnduranceRate(item),
ClickActionType = RepoItemClickActionType.OpenDetail,
ComponentSlotType = TowerCompSlotType.Bearing, ComponentSlotType = TowerCompSlotType.Bearing,
IconAreaContext = BuildIconAreaContext(item) IconAreaContext = BuildIconAreaContext(item)
}); });
@ -199,6 +211,7 @@ namespace GeometryTD.UI
InstanceId = item.InstanceId, InstanceId = item.InstanceId,
CanDrag = true, CanDrag = true,
EnduranceRate01 = ItemDescUtility.ResolveComponentEnduranceRate(item), EnduranceRate01 = ItemDescUtility.ResolveComponentEnduranceRate(item),
ClickActionType = RepoItemClickActionType.OpenDetail,
ComponentSlotType = TowerCompSlotType.Base, ComponentSlotType = TowerCompSlotType.Base,
IconAreaContext = BuildIconAreaContext(item) IconAreaContext = BuildIconAreaContext(item)
}); });
@ -211,13 +224,17 @@ namespace GeometryTD.UI
} }
} }
ParticipantAreaContext participantAreaContext =
BuildParticipantAreaContext(rawData.Inventory, towerMap, muzzleMap, bearingMap, baseMap);
return new RepoFormContext return new RepoFormContext
{ {
CombineAreaContext = new CombineAreaContext(), CombineAreaContext = new CombineAreaContext(),
CompAreaContext = new CompAreaContext CompAreaContext = new CompAreaContext
{ {
Items = items.ToArray() Items = items.ToArray()
} },
ParticipantAreaContext = participantAreaContext
}; };
} }
@ -288,6 +305,112 @@ namespace GeometryTD.UI
return map; return map;
} }
private static Dictionary<long, TowerItemData> BuildTowerMap(IReadOnlyList<TowerItemData> towers)
{
Dictionary<long, TowerItemData> map = new Dictionary<long, TowerItemData>();
if (towers == null)
{
return map;
}
for (int i = 0; i < towers.Count; i++)
{
TowerItemData tower = towers[i];
if (tower == null || tower.InstanceId <= 0)
{
continue;
}
map[tower.InstanceId] = tower;
}
return map;
}
private ParticipantAreaContext BuildParticipantAreaContext(
BackpackInventoryData inventory,
IReadOnlyDictionary<long, TowerItemData> towerMap,
IReadOnlyDictionary<long, MuzzleCompItemData> muzzleMap,
IReadOnlyDictionary<long, BearingCompItemData> bearingMap,
IReadOnlyDictionary<long, BaseCompItemData> baseMap)
{
_participantTowerIds.Clear();
List<RepoItemContext> participantItems = new List<RepoItemContext>();
if (inventory?.ParticipantTowerInstanceIds != null && towerMap != null)
{
for (int i = 0; i < inventory.ParticipantTowerInstanceIds.Count; i++)
{
long towerId = inventory.ParticipantTowerInstanceIds[i];
if (towerId <= 0)
{
continue;
}
if (!towerMap.TryGetValue(towerId, out TowerItemData tower) || tower == null)
{
continue;
}
if (!_participantTowerIds.Add(towerId))
{
continue;
}
participantItems.Add(new RepoItemContext
{
InstanceId = tower.InstanceId,
CanDrag = false,
EnduranceRate01 = ItemDescUtility.ResolveTowerEnduranceRate(tower, muzzleMap, bearingMap, baseMap),
ClickActionType = RepoItemClickActionType.RemoveParticipant,
ComponentSlotType = TowerCompSlotType.None,
IconAreaContext = BuildIconAreaContext(tower)
});
}
}
return new ParticipantAreaContext
{
Items = participantItems.ToArray(),
MaxCount = MaxParticipantCount
};
}
private void ApplyParticipantSelection()
{
if (Form == null || _itemContextMap.Count <= 0)
{
return;
}
foreach (KeyValuePair<long, RepoItemContext> pair in _itemContextMap)
{
RepoItemContext itemContext = pair.Value;
if (itemContext == null || itemContext.ComponentSlotType != TowerCompSlotType.None)
{
continue;
}
Form.SetRepoItemSelected(pair.Key, _participantTowerIds.Contains(pair.Key));
}
}
private void RefreshParticipantAreaOnly()
{
if (_useCase == null || Form == null)
{
return;
}
RepoFormContext latestContext = BuildContext(_useCase.CreateInitialModel());
if (latestContext?.ParticipantAreaContext == null)
{
return;
}
Form.RefreshParticipantArea(latestContext.ParticipantAreaContext);
ApplyParticipantSelection();
}
private static IconAreaContext BuildIconAreaContext(TowerItemData tower) private static IconAreaContext BuildIconAreaContext(TowerItemData tower)
{ {
if (tower == null) if (tower == null)
@ -447,9 +570,60 @@ namespace GeometryTD.UI
if (latestContext != null) if (latestContext != null)
{ {
Form.RefreshUI(latestContext); Form.RefreshUI(latestContext);
ApplyParticipantSelection();
} }
} }
private void OnRepoParticipantAssignRequested(object sender, GameEventArgs e)
{
if (!IsEventFromCurrentForm(sender))
{
return;
}
if (!(e is RepoParticipantAssignRequestedEventArgs args))
{
return;
}
if (_useCase == null || Form == null || args.TowerItemId <= 0)
{
return;
}
if (!_useCase.TryAddParticipantTower(args.TowerItemId))
{
return;
}
RefreshParticipantAreaOnly();
}
private void OnRepoParticipantRemoveRequested(object sender, GameEventArgs e)
{
if (!IsEventFromCurrentForm(sender))
{
return;
}
if (!(e is RepoParticipantRemoveRequestedEventArgs args))
{
return;
}
if (_useCase == null || Form == null || args.TowerItemId <= 0)
{
return;
}
if (!_useCase.TryRemoveParticipantTower(args.TowerItemId))
{
return;
}
RefreshParticipantAreaOnly();
}
private bool IsEventFromCurrentForm(object sender) private bool IsEventFromCurrentForm(object sender)
{ {
if (Form == null) if (Form == null)

View File

@ -4,11 +4,14 @@ namespace GeometryTD.UI
{ {
public class RepoFormUseCase : IUIUseCase public class RepoFormUseCase : IUIUseCase
{ {
private const int MaxParticipantCount = 4;
private BackpackInventoryData _fallbackInventory;
public RepoFormRawData CreateInitialModel() public RepoFormRawData CreateInitialModel()
{ {
BackpackInventoryData sample = GameEntry.PlayerInventory != null BackpackInventoryData sample = GameEntry.PlayerInventory != null
? GameEntry.PlayerInventory.GetInventorySnapshot() ? GameEntry.PlayerInventory.GetInventorySnapshot()
: SampleInventory(); : GetOrCreateFallbackInventory();
return new RepoFormRawData return new RepoFormRawData
{ {
Inventory = sample Inventory = sample
@ -29,6 +32,169 @@ namespace GeometryTD.UI
out _); out _);
} }
public bool TryAddParticipantTower(long towerItemId)
{
if (GameEntry.PlayerInventory == null)
{
BackpackInventoryData fallbackInventory = GetOrCreateFallbackInventory();
return TryAddParticipantTowerInternal(fallbackInventory, towerItemId, MaxParticipantCount);
}
return GameEntry.PlayerInventory.TryAddParticipantTower(towerItemId, 4);
}
public bool TryRemoveParticipantTower(long towerItemId)
{
if (GameEntry.PlayerInventory == null)
{
BackpackInventoryData fallbackInventory = GetOrCreateFallbackInventory();
return TryRemoveParticipantTowerInternal(fallbackInventory, towerItemId);
}
return GameEntry.PlayerInventory.TryRemoveParticipantTower(towerItemId);
}
private BackpackInventoryData GetOrCreateFallbackInventory()
{
_fallbackInventory ??= SampleInventory();
NormalizeParticipantState(_fallbackInventory);
return _fallbackInventory;
}
private static bool TryAddParticipantTowerInternal(
BackpackInventoryData inventory,
long towerItemId,
int maxCount)
{
if (inventory == null || towerItemId <= 0)
{
return false;
}
NormalizeParticipantState(inventory);
if (!TryGetTowerById(inventory, towerItemId, out TowerItemData tower))
{
return false;
}
inventory.ParticipantTowerInstanceIds ??= new System.Collections.Generic.List<long>();
if (inventory.ParticipantTowerInstanceIds.Contains(towerItemId))
{
tower.IsParticipatingInCombat = true;
return false;
}
if (inventory.ParticipantTowerInstanceIds.Count >= UnityEngine.Mathf.Max(1, maxCount))
{
return false;
}
inventory.ParticipantTowerInstanceIds.Add(towerItemId);
tower.IsParticipatingInCombat = true;
return true;
}
private static bool TryRemoveParticipantTowerInternal(BackpackInventoryData inventory, long towerItemId)
{
if (inventory == null || towerItemId <= 0)
{
return false;
}
NormalizeParticipantState(inventory);
if (inventory.ParticipantTowerInstanceIds == null)
{
return false;
}
bool removed = inventory.ParticipantTowerInstanceIds.Remove(towerItemId);
if (!removed)
{
return false;
}
if (TryGetTowerById(inventory, towerItemId, out TowerItemData tower))
{
tower.IsParticipatingInCombat = false;
}
return true;
}
private static bool TryGetTowerById(BackpackInventoryData inventory, long towerItemId, out TowerItemData tower)
{
tower = null;
if (inventory?.Towers == null || towerItemId <= 0)
{
return false;
}
for (int i = 0; i < inventory.Towers.Count; i++)
{
TowerItemData candidate = inventory.Towers[i];
if (candidate != null && candidate.InstanceId == towerItemId)
{
tower = candidate;
return true;
}
}
return false;
}
private static void NormalizeParticipantState(BackpackInventoryData inventory)
{
if (inventory == null)
{
return;
}
inventory.ParticipantTowerInstanceIds ??= new System.Collections.Generic.List<long>();
System.Collections.Generic.Dictionary<long, TowerItemData> towerMap =
new System.Collections.Generic.Dictionary<long, TowerItemData>();
if (inventory.Towers != null)
{
for (int i = 0; i < inventory.Towers.Count; i++)
{
TowerItemData tower = inventory.Towers[i];
if (tower == null || tower.InstanceId <= 0)
{
continue;
}
tower.IsParticipatingInCombat = false;
towerMap[tower.InstanceId] = tower;
}
}
System.Collections.Generic.HashSet<long> uniqueIds = new System.Collections.Generic.HashSet<long>();
System.Collections.Generic.List<long> normalizedIds =
new System.Collections.Generic.List<long>(inventory.ParticipantTowerInstanceIds.Count);
for (int i = 0; i < inventory.ParticipantTowerInstanceIds.Count; i++)
{
if (normalizedIds.Count >= MaxParticipantCount)
{
break;
}
long towerId = inventory.ParticipantTowerInstanceIds[i];
if (towerId <= 0 || !uniqueIds.Add(towerId))
{
continue;
}
if (!towerMap.TryGetValue(towerId, out TowerItemData tower))
{
continue;
}
tower.IsParticipatingInCombat = true;
normalizedIds.Add(towerId);
}
inventory.ParticipantTowerInstanceIds = normalizedIds;
}
public static BackpackInventoryData SampleInventory() public static BackpackInventoryData SampleInventory()
{ {
BackpackInventoryData inventory = new BackpackInventoryData BackpackInventoryData inventory = new BackpackInventoryData
@ -167,6 +333,7 @@ namespace GeometryTD.UI
InstanceId = 90001, InstanceId = 90001,
Name = "测试防御塔-A", Name = "测试防御塔-A",
Rarity = RarityType.Green, Rarity = RarityType.Green,
IsParticipatingInCombat = true,
MuzzleComponentInstanceId = muzzle.InstanceId, MuzzleComponentInstanceId = muzzle.InstanceId,
BearingComponentInstanceId = bearing.InstanceId, BearingComponentInstanceId = bearing.InstanceId,
BaseComponentInstanceId = baseComp.InstanceId, BaseComponentInstanceId = baseComp.InstanceId,
@ -189,6 +356,7 @@ namespace GeometryTD.UI
InstanceId = 90002, InstanceId = 90002,
Name = "测试防御塔-B", Name = "测试防御塔-B",
Rarity = RarityType.Blue, Rarity = RarityType.Blue,
IsParticipatingInCombat = false,
MuzzleComponentInstanceId = 0, MuzzleComponentInstanceId = 0,
BearingComponentInstanceId = 0, BearingComponentInstanceId = 0,
BaseComponentInstanceId = 0, BaseComponentInstanceId = 0,
@ -205,6 +373,8 @@ namespace GeometryTD.UI
} }
}); });
inventory.ParticipantTowerInstanceIds.Add(90001);
return inventory; return inventory;
} }
} }

View File

@ -0,0 +1,177 @@
using System.Collections.Generic;
using GameFramework.ObjectPool;
using GeometryTD.CustomEvent;
using GeometryTD.Definition;
using GeometryTD.PoolObjectBase;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityGameFramework.Runtime;
namespace GeometryTD.UI
{
public class ParticipantArea : MonoBehaviour, IDropHandler
{
[SerializeField] private Transform _content;
[SerializeField] private RepoItem _itemTemplate;
[SerializeField] private int _instancePoolCapacity = 8;
private readonly List<RepoItem> _activeItems = new List<RepoItem>();
private readonly HashSet<long> _boundItemIds = new HashSet<long>();
private IObjectPool<RepoItemObject> _itemPool;
private string _poolName;
private int _maxCount = 4;
public void OnInit(ParticipantAreaContext context)
{
OnReset();
EnsurePool();
_maxCount = Mathf.Max(1, context != null ? context.MaxCount : 4);
if (context?.Items == null || context.Items.Length <= 0)
{
return;
}
for (int i = 0; i < context.Items.Length; i++)
{
RepoItemContext itemContext = context.Items[i];
if (itemContext == null || itemContext.InstanceId <= 0)
{
continue;
}
RepoItem item = CreateOrSpawnItem();
if (item == null)
{
continue;
}
item.gameObject.SetActive(true);
item.OnInit(itemContext);
_activeItems.Add(item);
_boundItemIds.Add(itemContext.InstanceId);
}
}
public void OnReset()
{
for (int i = _activeItems.Count - 1; i >= 0; i--)
{
RepoItem item = _activeItems[i];
if (item == null)
{
continue;
}
item.OnReset();
item.gameObject.SetActive(false);
_itemPool?.Unspawn(item);
}
_activeItems.Clear();
_boundItemIds.Clear();
_maxCount = 4;
}
private void OnDestroy()
{
OnReset();
_itemPool?.ReleaseAllUnused();
}
public bool CanAssign(RepoItemContext itemContext)
{
if (itemContext == null || itemContext.InstanceId <= 0)
{
return false;
}
if (itemContext.ComponentSlotType != TowerCompSlotType.None)
{
return false;
}
if (_boundItemIds.Contains(itemContext.InstanceId))
{
return false;
}
if (_boundItemIds.Count >= _maxCount)
{
return false;
}
return true;
}
public void OnDrop(PointerEventData eventData)
{
if (eventData == null)
{
return;
}
GameObject pointerDrag = eventData.pointerDrag;
if (pointerDrag == null)
{
return;
}
RepoItem repoItem = pointerDrag.GetComponent<RepoItem>() ?? pointerDrag.GetComponentInParent<RepoItem>();
if (repoItem == null)
{
return;
}
RepoItemContext itemContext = repoItem.Context;
bool assigned = CanAssign(itemContext);
repoItem.SetDropResult(assigned);
if (!assigned)
{
return;
}
GameEntry.Event.Fire(this, RepoParticipantAssignRequestedEventArgs.Create(itemContext.InstanceId));
}
private void EnsurePool()
{
if (_itemPool != null)
{
return;
}
_poolName = $"ParticipantRepoItemPool_{GetInstanceID()}";
_itemPool = GameEntry.ObjectPool.CreateSingleSpawnObjectPool<RepoItemObject>(_poolName, _instancePoolCapacity);
}
private RepoItem CreateOrSpawnItem()
{
if (_itemPool == null)
{
return null;
}
RepoItemObject itemObject = _itemPool.Spawn();
RepoItem item = itemObject != null ? (RepoItem)itemObject.Target : null;
if (item == null)
{
if (_itemTemplate == null)
{
Log.Warning("ParticipantArea requires an item template.");
return null;
}
item = Instantiate(_itemTemplate);
_itemPool.Register(RepoItemObject.Create(item), true);
}
if (_content != null)
{
item.transform.SetParent(_content, false);
}
return item;
}
}
}

View File

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 23b62a700198440baabc75e28f901578
timeCreated: 1772624093

View File

@ -7,7 +7,10 @@ namespace GeometryTD.UI
public class RepoForm : UGuiForm public class RepoForm : UGuiForm
{ {
[SerializeField] private CombineArea _combineArea; [SerializeField] private CombineArea _combineArea;
[SerializeField] private CompArea _compArea; [SerializeField] private CompArea _compArea;
[SerializeField] private ParticipantArea _participantArea;
public void RefreshUI(RepoFormContext context) public void RefreshUI(RepoFormContext context)
{ {
@ -18,6 +21,7 @@ namespace GeometryTD.UI
_combineArea?.OnInit(context.CombineAreaContext); _combineArea?.OnInit(context.CombineAreaContext);
_compArea?.OnInit(context.CompAreaContext); _compArea?.OnInit(context.CompAreaContext);
_participantArea?.OnInit(context.ParticipantAreaContext);
} }
public bool TryAssignItemToCombineArea(RepoItemContext itemContext) public bool TryAssignItemToCombineArea(RepoItemContext itemContext)
@ -46,6 +50,11 @@ namespace GeometryTD.UI
_compArea?.SetItemSelected(itemId, isSelected); _compArea?.SetItemSelected(itemId, isSelected);
} }
public void RefreshParticipantArea(ParticipantAreaContext context)
{
_participantArea?.OnInit(context);
}
protected override void OnOpen(object userData) protected override void OnOpen(object userData)
{ {
base.OnOpen(userData); base.OnOpen(userData);
@ -62,6 +71,7 @@ namespace GeometryTD.UI
{ {
_combineArea?.OnReset(); _combineArea?.OnReset();
_compArea?.OnReset(); _compArea?.OnReset();
_participantArea?.OnReset();
base.OnClose(isShutdown, userData); base.OnClose(isShutdown, userData);
} }
@ -70,4 +80,4 @@ namespace GeometryTD.UI
GameEntry.Event.Fire(this, RepoFormReturnEventArgs.Create()); GameEntry.Event.Fire(this, RepoFormReturnEventArgs.Create());
} }
} }
} }

View File

@ -108,6 +108,12 @@ namespace GeometryTD.UI
return; return;
} }
if (_context.ClickActionType == RepoItemClickActionType.RemoveParticipant)
{
GameEntry.Event.Fire(this, RepoParticipantRemoveRequestedEventArgs.Create(_context.InstanceId));
return;
}
StartPendingOpenDetail(); StartPendingOpenDetail();
} }
@ -195,7 +201,12 @@ namespace GeometryTD.UI
private bool CanStartDrag(PointerEventData eventData) private bool CanStartDrag(PointerEventData eventData)
{ {
if (_context == null || _isSelected || _isDragging) if (_context == null || _isDragging)
{
return false;
}
if (_isSelected && _context.ComponentSlotType != TowerCompSlotType.None)
{ {
return false; return false;
} }
@ -205,11 +216,6 @@ namespace GeometryTD.UI
return false; return false;
} }
if (_context.ComponentSlotType == TowerCompSlotType.None)
{
return false;
}
if (eventData == null || eventData.button != PointerEventData.InputButton.Left) if (eventData == null || eventData.button != PointerEventData.InputButton.Left)
{ {
return false; return false;
@ -292,12 +298,25 @@ namespace GeometryTD.UI
{ {
DestroyDragGhost(); DestroyDragGhost();
if (_dragRoot == null || _iconArea == null) if (_dragRoot == null)
{ {
return false; return false;
} }
Sprite iconSprite = _iconArea.CurrentIconSprite; Sprite iconSprite = _iconArea != null ? _iconArea.CurrentIconSprite : null;
Color iconColor = _iconArea != null ? _iconArea.CurrentIconColor : Color.white;
Material iconMaterial = _iconArea != null ? _iconArea.CurrentIconMaterial : null;
Vector2 iconSize = _iconArea != null ? _iconArea.CurrentIconSize : Vector2.zero;
// Towers may not have an icon sprite; fall back to background sprite so drag still works.
if (iconSprite == null && _bgImage != null)
{
iconSprite = _bgImage.sprite;
iconColor = _bgImage.color;
iconMaterial = _bgImage.material;
iconSize = _bgImage.rectTransform.rect.size;
}
if (iconSprite == null) if (iconSprite == null)
{ {
return false; return false;
@ -312,7 +331,6 @@ namespace GeometryTD.UI
_dragGhostRect.anchorMax = new Vector2(0.5f, 0.5f); _dragGhostRect.anchorMax = new Vector2(0.5f, 0.5f);
_dragGhostRect.pivot = new Vector2(0.5f, 0.5f); _dragGhostRect.pivot = new Vector2(0.5f, 0.5f);
Vector2 iconSize = _iconArea.CurrentIconSize;
if (iconSize.x <= 0f || iconSize.y <= 0f) if (iconSize.x <= 0f || iconSize.y <= 0f)
{ {
iconSize = DefaultDragGhostSize; iconSize = DefaultDragGhostSize;
@ -322,8 +340,8 @@ namespace GeometryTD.UI
Image ghostImage = _dragGhostObject.GetComponent<Image>(); Image ghostImage = _dragGhostObject.GetComponent<Image>();
ghostImage.raycastTarget = false; ghostImage.raycastTarget = false;
ghostImage.sprite = iconSprite; ghostImage.sprite = iconSprite;
ghostImage.color = _iconArea.CurrentIconColor; ghostImage.color = iconColor;
ghostImage.material = _iconArea.CurrentIconMaterial; ghostImage.material = iconMaterial;
ghostImage.preserveAspect = true; ghostImage.preserveAspect = true;
CanvasGroup ghostCanvasGroup = _dragGhostObject.GetComponent<CanvasGroup>(); CanvasGroup ghostCanvasGroup = _dragGhostObject.GetComponent<CanvasGroup>();

View File

@ -258,7 +258,7 @@ RectTransform:
m_AnchorMin: {x: 0, y: 1} m_AnchorMin: {x: 0, y: 1}
m_AnchorMax: {x: 0, y: 1} m_AnchorMax: {x: 0, y: 1}
m_AnchoredPosition: {x: 30, y: -50} m_AnchoredPosition: {x: 30, y: -50}
m_SizeDelta: {x: 500, y: 100} m_SizeDelta: {x: 740, y: 100}
m_Pivot: {x: 0, y: 1} m_Pivot: {x: 0, y: 1}
--- !u!222 &3590733437255178557 --- !u!222 &3590733437255178557
CanvasRenderer: CanvasRenderer:
@ -393,7 +393,7 @@ RectTransform:
m_AnchorMin: {x: 0, y: 1} m_AnchorMin: {x: 0, y: 1}
m_AnchorMax: {x: 0, y: 1} m_AnchorMax: {x: 0, y: 1}
m_AnchoredPosition: {x: 30, y: -150} m_AnchoredPosition: {x: 30, y: -150}
m_SizeDelta: {x: 500, y: 80} m_SizeDelta: {x: 740, y: 80}
m_Pivot: {x: 0, y: 1} m_Pivot: {x: 0, y: 1}
--- !u!222 &6203466971508003467 --- !u!222 &6203466971508003467
CanvasRenderer: CanvasRenderer:

View File

@ -34,8 +34,8 @@ RectTransform:
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 1, y: 0} m_AnchorMin: {x: 1, y: 0}
m_AnchorMax: {x: 1, y: 1} m_AnchorMax: {x: 1, y: 1}
m_AnchoredPosition: {x: -650, y: -100} m_AnchoredPosition: {x: -650, y: 0}
m_SizeDelta: {x: 1200, y: -200} m_SizeDelta: {x: 1200, y: -400.00003}
m_Pivot: {x: 0.5, y: 0.5} m_Pivot: {x: 0.5, y: 0.5}
--- !u!114 &370202498391855143 --- !u!114 &370202498391855143
MonoBehaviour: MonoBehaviour:
@ -128,6 +128,100 @@ MonoBehaviour:
m_Spacing: {x: 20, y: 20} m_Spacing: {x: 20, y: 20}
m_Constraint: 1 m_Constraint: 1
m_ConstraintCount: 6 m_ConstraintCount: 6
--- !u!1 &3151563931008387230
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 6194629833245286025}
- component: {fileID: 6217930899804600847}
- component: {fileID: 5388327515888957795}
- component: {fileID: 9116268328124443995}
m_Layer: 5
m_Name: ParticipantArea
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!224 &6194629833245286025
RectTransform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 3151563931008387230}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children:
- {fileID: 6046599583992061665}
- {fileID: 6811784024412969593}
m_Father: {fileID: 948419798348630685}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0.5, y: 0.5}
m_AnchorMax: {x: 0.5, y: 0.5}
m_AnchoredPosition: {x: 771.5, y: -560}
m_SizeDelta: {x: 1175, y: 160}
m_Pivot: {x: 0.5, y: 0.5}
--- !u!114 &6217930899804600847
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 3151563931008387230}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 23b62a700198440baabc75e28f901578, type: 3}
m_Name:
m_EditorClassIdentifier:
_content: {fileID: 6811784024412969593}
_itemTemplate: {fileID: 8394974685918372820, guid: 2ead8e403e355dd4b9296a9d0a871a83,
type: 3}
_instancePoolCapacity: 8
--- !u!222 &5388327515888957795
CanvasRenderer:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 3151563931008387230}
m_CullTransparentMesh: 1
--- !u!114 &9116268328124443995
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 3151563931008387230}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3}
m_Name:
m_EditorClassIdentifier:
m_Material: {fileID: 0}
m_Color: {r: 1, g: 1, b: 1, a: 0}
m_RaycastTarget: 1
m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0}
m_Maskable: 1
m_OnCullStateChanged:
m_PersistentCalls:
m_Calls: []
m_Sprite: {fileID: 0}
m_Type: 0
m_PreserveAspect: 0
m_FillCenter: 1
m_FillMethod: 4
m_FillAmount: 1
m_FillClockwise: 1
m_FillOrigin: 0
m_UseSpriteMesh: 0
m_PixelsPerUnitMultiplier: 1
--- !u!1 &3339982533413687751 --- !u!1 &3339982533413687751
GameObject: GameObject:
m_ObjectHideFlags: 0 m_ObjectHideFlags: 0
@ -138,6 +232,8 @@ GameObject:
m_Component: m_Component:
- component: {fileID: 437137211665287909} - component: {fileID: 437137211665287909}
- component: {fileID: 2687805356437946940} - component: {fileID: 2687805356437946940}
- component: {fileID: 5216274833988519258}
- component: {fileID: 2723756476935543858}
m_Layer: 5 m_Layer: 5
m_Name: CombineArea m_Name: CombineArea
m_TagString: Untagged m_TagString: Untagged
@ -192,6 +288,44 @@ MonoBehaviour:
- {fileID: 8189434761781366953} - {fileID: 8189434761781366953}
- {fileID: 7373972901994129571} - {fileID: 7373972901994129571}
- {fileID: 1229930097058638238} - {fileID: 1229930097058638238}
--- !u!222 &5216274833988519258
CanvasRenderer:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 3339982533413687751}
m_CullTransparentMesh: 1
--- !u!114 &2723756476935543858
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 3339982533413687751}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3}
m_Name:
m_EditorClassIdentifier:
m_Material: {fileID: 0}
m_Color: {r: 1, g: 1, b: 1, a: 0}
m_RaycastTarget: 1
m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0}
m_Maskable: 1
m_OnCullStateChanged:
m_PersistentCalls:
m_Calls: []
m_Sprite: {fileID: 0}
m_Type: 0
m_PreserveAspect: 0
m_FillCenter: 1
m_FillMethod: 4
m_FillAmount: 1
m_FillClockwise: 1
m_FillOrigin: 0
m_UseSpriteMesh: 0
m_PixelsPerUnitMultiplier: 1
--- !u!1 &3681983101697451234 --- !u!1 &3681983101697451234
GameObject: GameObject:
m_ObjectHideFlags: 0 m_ObjectHideFlags: 0
@ -243,6 +377,7 @@ MonoBehaviour:
m_EditorClassIdentifier: m_EditorClassIdentifier:
_combineArea: {fileID: 2687805356437946940} _combineArea: {fileID: 2687805356437946940}
_compArea: {fileID: 370202498391855143} _compArea: {fileID: 370202498391855143}
_participantArea: {fileID: 6217930899804600847}
--- !u!1 &4000410608128749255 --- !u!1 &4000410608128749255
GameObject: GameObject:
m_ObjectHideFlags: 0 m_ObjectHideFlags: 0
@ -513,6 +648,203 @@ MonoBehaviour:
m_OnValueChanged: m_OnValueChanged:
m_PersistentCalls: m_PersistentCalls:
m_Calls: [] m_Calls: []
--- !u!1 &4977771823416823721
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 6811784024412969593}
- component: {fileID: 7576549425996255162}
m_Layer: 5
m_Name: Parent
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!224 &6811784024412969593
RectTransform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 4977771823416823721}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 6194629833245286025}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 1}
m_AnchorMax: {x: 0, y: 1}
m_AnchoredPosition: {x: 1175, y: -80}
m_SizeDelta: {x: 700, y: 160}
m_Pivot: {x: 1, y: 0.5}
--- !u!114 &7576549425996255162
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 4977771823416823721}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 30649d3a9faa99c48a7b1166b86bf2a0, type: 3}
m_Name:
m_EditorClassIdentifier:
m_Padding:
m_Left: 0
m_Right: 0
m_Top: 0
m_Bottom: 0
m_ChildAlignment: 3
m_Spacing: 20
m_ChildForceExpandWidth: 0
m_ChildForceExpandHeight: 1
m_ChildControlWidth: 0
m_ChildControlHeight: 0
m_ChildScaleWidth: 0
m_ChildScaleHeight: 0
m_ReverseArrangement: 0
--- !u!1 &5196197715904290498
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 6046599583992061665}
- component: {fileID: 2503187454698265825}
- component: {fileID: 6829657461328831593}
m_Layer: 5
m_Name: TipText
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!224 &6046599583992061665
RectTransform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 5196197715904290498}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 6194629833245286025}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0.5, y: 0.5}
m_AnchorMax: {x: 0.5, y: 0.5}
m_AnchoredPosition: {x: -414.417, y: 0}
m_SizeDelta: {x: 371.1659, y: 160}
m_Pivot: {x: 0.5, y: 0.5}
--- !u!222 &2503187454698265825
CanvasRenderer:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 5196197715904290498}
m_CullTransparentMesh: 1
--- !u!114 &6829657461328831593
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 5196197715904290498}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: f4688fdb7df04437aeb418b961361dc5, type: 3}
m_Name:
m_EditorClassIdentifier:
m_Material: {fileID: 0}
m_Color: {r: 1, g: 1, b: 1, a: 1}
m_RaycastTarget: 1
m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0}
m_Maskable: 1
m_OnCullStateChanged:
m_PersistentCalls:
m_Calls: []
m_text: "\u53C2\u6218\u9632\u5FA1\u5854\uFF1A"
m_isRightToLeft: 0
m_fontAsset: {fileID: 11400000, guid: 99d811b0183246646a2ce8df996f4bca, type: 2}
m_sharedMaterial: {fileID: -1106088975554028259, guid: 99d811b0183246646a2ce8df996f4bca,
type: 2}
m_fontSharedMaterials: []
m_fontMaterial: {fileID: 0}
m_fontMaterials: []
m_fontColor32:
serializedVersion: 2
rgba: 4294967295
m_fontColor: {r: 1, g: 1, b: 1, a: 1}
m_enableVertexGradient: 0
m_colorMode: 3
m_fontColorGradient:
topLeft: {r: 1, g: 1, b: 1, a: 1}
topRight: {r: 1, g: 1, b: 1, a: 1}
bottomLeft: {r: 1, g: 1, b: 1, a: 1}
bottomRight: {r: 1, g: 1, b: 1, a: 1}
m_fontColorGradientPreset: {fileID: 0}
m_spriteAsset: {fileID: 0}
m_tintAllSprites: 0
m_StyleSheet: {fileID: 0}
m_TextStyleHashCode: -1183493901
m_overrideHtmlColors: 0
m_faceColor:
serializedVersion: 2
rgba: 4294967295
m_fontSize: 60
m_fontSizeBase: 60
m_fontWeight: 400
m_enableAutoSizing: 0
m_fontSizeMin: 18
m_fontSizeMax: 72
m_fontStyle: 0
m_HorizontalAlignment: 2
m_VerticalAlignment: 512
m_textAlignment: 65535
m_characterSpacing: 0
m_wordSpacing: 0
m_lineSpacing: 0
m_lineSpacingMax: 0
m_paragraphSpacing: 0
m_charWidthMaxAdj: 0
m_enableWordWrapping: 1
m_wordWrappingRatios: 0.4
m_overflowMode: 0
m_linkedTextComponent: {fileID: 0}
parentLinkedComponent: {fileID: 0}
m_enableKerning: 1
m_enableExtraPadding: 0
checkPaddingRequired: 0
m_isRichText: 1
m_parseCtrlCharacters: 1
m_isOrthographic: 1
m_isCullingEnabled: 0
m_horizontalMapping: 0
m_verticalMapping: 0
m_uvLineOffset: 0
m_geometrySortingOrder: 0
m_IsTextObjectScaleStatic: 0
m_VertexBufferAutoSizeReduction: 0
m_useMaxVisibleDescender: 1
m_pageToDisplay: 1
m_margin: {x: 0, y: 0, z: 0, w: 0}
m_isUsingLegacyAnimationComponent: 0
m_isVolumetricText: 0
m_hasFontAssetChanged: 0
m_baseMaterial: {fileID: 0}
m_maskOffset: {x: 0, y: 0, z: 0, w: 0}
--- !u!1 &5244343103794872216 --- !u!1 &5244343103794872216
GameObject: GameObject:
m_ObjectHideFlags: 0 m_ObjectHideFlags: 0
@ -636,6 +968,7 @@ RectTransform:
- {fileID: 3177067923545511236} - {fileID: 3177067923545511236}
- {fileID: 437137211665287909} - {fileID: 437137211665287909}
- {fileID: 4661661401541872014} - {fileID: 4661661401541872014}
- {fileID: 6194629833245286025}
m_Father: {fileID: 3043356307630469178} m_Father: {fileID: 3043356307630469178}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0} m_AnchorMin: {x: 0, y: 0}

View File

@ -184,7 +184,7 @@ RectTransform:
m_AnchorMin: {x: 0, y: 0} m_AnchorMin: {x: 0, y: 0}
m_AnchorMax: {x: 0, y: 0} m_AnchorMax: {x: 0, y: 0}
m_AnchoredPosition: {x: 0, y: 0} m_AnchoredPosition: {x: 0, y: 0}
m_SizeDelta: {x: 100, y: 100} m_SizeDelta: {x: 160, y: 160}
m_Pivot: {x: 0.5, y: 0.5} m_Pivot: {x: 0.5, y: 0.5}
--- !u!222 &617747730667399833 --- !u!222 &617747730667399833
CanvasRenderer: CanvasRenderer:
@ -211,6 +211,7 @@ MonoBehaviour:
_context: _context:
InstanceId: 0 InstanceId: 0
CanDrag: 0 CanDrag: 0
EnduranceRate01: 0
ComponentSlotType: 0 ComponentSlotType: 0
IconAreaContext: IconAreaContext:
Rarity: 0 Rarity: 0