添加参战防御塔功能(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
@@ -129,6 +129,7 @@ namespace GeometryTD.UI
InstanceId = tower.InstanceId,
CanDrag = false,
EnduranceRate01 = ItemDescUtility.ResolveTowerEnduranceRate(tower, muzzleMap, bearingMap, baseMap),
ClickActionType = RepoItemClickActionType.OpenDetail,
ComponentSlotType = TowerCompSlotType.None,
IconAreaContext = BuildIconAreaContext(tower)
});
@@ -157,6 +158,7 @@ namespace GeometryTD.UI
InstanceId = item.InstanceId,
CanDrag = false,
EnduranceRate01 = ItemDescUtility.ResolveComponentEnduranceRate(item),
ClickActionType = RepoItemClickActionType.OpenDetail,
ComponentSlotType = TowerCompSlotType.Muzzle,
IconAreaContext = BuildIconAreaContext(item)
});
@@ -184,6 +186,7 @@ namespace GeometryTD.UI
InstanceId = item.InstanceId,
CanDrag = false,
EnduranceRate01 = ItemDescUtility.ResolveComponentEnduranceRate(item),
ClickActionType = RepoItemClickActionType.OpenDetail,
ComponentSlotType = TowerCompSlotType.Bearing,
IconAreaContext = BuildIconAreaContext(item)
});
@@ -212,6 +215,7 @@ namespace GeometryTD.UI
InstanceId = item.InstanceId,
CanDrag = false,
EnduranceRate01 = ItemDescUtility.ResolveComponentEnduranceRate(item),
ClickActionType = RepoItemClickActionType.OpenDetail,
ComponentSlotType = TowerCompSlotType.Base,
IconAreaContext = BuildIconAreaContext(item)
});
@@ -0,0 +1,8 @@
namespace GeometryTD.UI
{
public class ParticipantAreaContext : UIContext
{
public RepoItemContext[] Items;
public int MaxCount;
}
}
@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: dba2ecceff78486fb2a251e7c28ce9c0
timeCreated: 1772624131
@@ -6,5 +6,6 @@ namespace GeometryTD.UI
{
public CombineAreaContext CombineAreaContext;
public CompAreaContext CompAreaContext;
public ParticipantAreaContext ParticipantAreaContext;
}
}
@@ -0,0 +1,8 @@
namespace GeometryTD.UI
{
public enum RepoItemClickActionType : byte
{
OpenDetail = 0,
RemoveParticipant = 1
}
}
@@ -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
@@ -9,6 +9,7 @@ namespace GeometryTD.UI
public long InstanceId;
public bool CanDrag;
public float EnduranceRate01;
public RepoItemClickActionType ClickActionType;
public TowerCompSlotType ComponentSlotType;
public IconAreaContext IconAreaContext;
}
@@ -11,9 +11,11 @@ namespace GeometryTD.UI
{
public class RepoFormController : UIFormControllerCommonBase<RepoFormContext, RepoForm>
{
private const int MaxParticipantCount = 4;
private RepoFormUseCase _useCase;
private readonly Dictionary<long, RepoItemContext> _itemContextMap = new Dictionary<long, RepoItemContext>();
private readonly Dictionary<long, ItemDescSeed> _itemDescSeedMap = new Dictionary<long, ItemDescSeed>();
private readonly HashSet<long> _participantTowerIds = new HashSet<long>();
private sealed class ItemDescSeed
{
@@ -28,6 +30,7 @@ namespace GeometryTD.UI
protected override void RefreshUI(RepoForm form, RepoFormContext context)
{
form.RefreshUI(context);
ApplyParticipantSelection();
}
protected override void SubscribeCustomEvents()
@@ -36,6 +39,8 @@ namespace GeometryTD.UI
GameEntry.Event.Subscribe(RepoItemDragEndedEventArgs.EventId, OnRepoItemDragEnded);
GameEntry.Event.Subscribe(CombineSlotClickedEventArgs.EventId, OnCombineSlotClicked);
GameEntry.Event.Subscribe(RepoCombineRequestedEventArgs.EventId, OnRepoCombineRequested);
GameEntry.Event.Subscribe(RepoParticipantAssignRequestedEventArgs.EventId, OnRepoParticipantAssignRequested);
GameEntry.Event.Subscribe(RepoParticipantRemoveRequestedEventArgs.EventId, OnRepoParticipantRemoveRequested);
GameEntry.Event.Subscribe(RepoFormReturnEventArgs.EventId, OnRepoFormReturn);
}
@@ -45,6 +50,8 @@ namespace GeometryTD.UI
GameEntry.Event.Unsubscribe(RepoItemDragEndedEventArgs.EventId, OnRepoItemDragEnded);
GameEntry.Event.Unsubscribe(CombineSlotClickedEventArgs.EventId, OnCombineSlotClicked);
GameEntry.Event.Unsubscribe(RepoCombineRequestedEventArgs.EventId, OnRepoCombineRequested);
GameEntry.Event.Unsubscribe(RepoParticipantAssignRequestedEventArgs.EventId, OnRepoParticipantAssignRequested);
GameEntry.Event.Unsubscribe(RepoParticipantRemoveRequestedEventArgs.EventId, OnRepoParticipantRemoveRequested);
GameEntry.Event.Unsubscribe(RepoFormReturnEventArgs.EventId, OnRepoFormReturn);
}
@@ -99,12 +106,14 @@ namespace GeometryTD.UI
_itemDescSeedMap.Clear();
if (rawData?.Inventory == null)
{
_participantTowerIds.Clear();
return null;
}
Dictionary<long, MuzzleCompItemData> muzzleMap = BuildComponentMap(rawData.Inventory.MuzzleComponents);
Dictionary<long, BearingCompItemData> bearingMap = BuildComponentMap(rawData.Inventory.BearingComponents);
Dictionary<long, BaseCompItemData> baseMap = BuildComponentMap(rawData.Inventory.BaseComponents);
Dictionary<long, TowerItemData> towerMap = BuildTowerMap(rawData.Inventory.Towers);
List<RepoItemContext> items = new List<RepoItemContext>();
if (rawData.Inventory.Towers != null)
@@ -121,6 +130,7 @@ namespace GeometryTD.UI
InstanceId = tower.InstanceId,
CanDrag = true,
EnduranceRate01 = ItemDescUtility.ResolveTowerEnduranceRate(tower, muzzleMap, bearingMap, baseMap),
ClickActionType = RepoItemClickActionType.OpenDetail,
ComponentSlotType = TowerCompSlotType.None,
IconAreaContext = BuildIconAreaContext(tower)
});
@@ -147,6 +157,7 @@ namespace GeometryTD.UI
InstanceId = item.InstanceId,
CanDrag = true,
EnduranceRate01 = ItemDescUtility.ResolveComponentEnduranceRate(item),
ClickActionType = RepoItemClickActionType.OpenDetail,
ComponentSlotType = TowerCompSlotType.Muzzle,
IconAreaContext = BuildIconAreaContext(item)
});
@@ -173,6 +184,7 @@ namespace GeometryTD.UI
InstanceId = item.InstanceId,
CanDrag = true,
EnduranceRate01 = ItemDescUtility.ResolveComponentEnduranceRate(item),
ClickActionType = RepoItemClickActionType.OpenDetail,
ComponentSlotType = TowerCompSlotType.Bearing,
IconAreaContext = BuildIconAreaContext(item)
});
@@ -199,6 +211,7 @@ namespace GeometryTD.UI
InstanceId = item.InstanceId,
CanDrag = true,
EnduranceRate01 = ItemDescUtility.ResolveComponentEnduranceRate(item),
ClickActionType = RepoItemClickActionType.OpenDetail,
ComponentSlotType = TowerCompSlotType.Base,
IconAreaContext = BuildIconAreaContext(item)
});
@@ -211,13 +224,17 @@ namespace GeometryTD.UI
}
}
ParticipantAreaContext participantAreaContext =
BuildParticipantAreaContext(rawData.Inventory, towerMap, muzzleMap, bearingMap, baseMap);
return new RepoFormContext
{
CombineAreaContext = new CombineAreaContext(),
CompAreaContext = new CompAreaContext
{
Items = items.ToArray()
}
},
ParticipantAreaContext = participantAreaContext
};
}
@@ -288,6 +305,112 @@ namespace GeometryTD.UI
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)
{
if (tower == null)
@@ -447,9 +570,60 @@ namespace GeometryTD.UI
if (latestContext != null)
{
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)
{
if (Form == null)
@@ -4,11 +4,14 @@ namespace GeometryTD.UI
{
public class RepoFormUseCase : IUIUseCase
{
private const int MaxParticipantCount = 4;
private BackpackInventoryData _fallbackInventory;
public RepoFormRawData CreateInitialModel()
{
BackpackInventoryData sample = GameEntry.PlayerInventory != null
? GameEntry.PlayerInventory.GetInventorySnapshot()
: SampleInventory();
: GetOrCreateFallbackInventory();
return new RepoFormRawData
{
Inventory = sample
@@ -29,6 +32,169 @@ namespace GeometryTD.UI
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()
{
BackpackInventoryData inventory = new BackpackInventoryData
@@ -167,6 +333,7 @@ namespace GeometryTD.UI
InstanceId = 90001,
Name = "测试防御塔-A",
Rarity = RarityType.Green,
IsParticipatingInCombat = true,
MuzzleComponentInstanceId = muzzle.InstanceId,
BearingComponentInstanceId = bearing.InstanceId,
BaseComponentInstanceId = baseComp.InstanceId,
@@ -189,6 +356,7 @@ namespace GeometryTD.UI
InstanceId = 90002,
Name = "测试防御塔-B",
Rarity = RarityType.Blue,
IsParticipatingInCombat = false,
MuzzleComponentInstanceId = 0,
BearingComponentInstanceId = 0,
BaseComponentInstanceId = 0,
@@ -205,6 +373,8 @@ namespace GeometryTD.UI
}
});
inventory.ParticipantTowerInstanceIds.Add(90001);
return inventory;
}
}
@@ -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;
}
}
}
@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 23b62a700198440baabc75e28f901578
timeCreated: 1772624093
@@ -7,7 +7,10 @@ namespace GeometryTD.UI
public class RepoForm : UGuiForm
{
[SerializeField] private CombineArea _combineArea;
[SerializeField] private CompArea _compArea;
[SerializeField] private ParticipantArea _participantArea;
public void RefreshUI(RepoFormContext context)
{
@@ -18,6 +21,7 @@ namespace GeometryTD.UI
_combineArea?.OnInit(context.CombineAreaContext);
_compArea?.OnInit(context.CompAreaContext);
_participantArea?.OnInit(context.ParticipantAreaContext);
}
public bool TryAssignItemToCombineArea(RepoItemContext itemContext)
@@ -46,6 +50,11 @@ namespace GeometryTD.UI
_compArea?.SetItemSelected(itemId, isSelected);
}
public void RefreshParticipantArea(ParticipantAreaContext context)
{
_participantArea?.OnInit(context);
}
protected override void OnOpen(object userData)
{
base.OnOpen(userData);
@@ -62,6 +71,7 @@ namespace GeometryTD.UI
{
_combineArea?.OnReset();
_compArea?.OnReset();
_participantArea?.OnReset();
base.OnClose(isShutdown, userData);
}
@@ -70,4 +80,4 @@ namespace GeometryTD.UI
GameEntry.Event.Fire(this, RepoFormReturnEventArgs.Create());
}
}
}
}
@@ -108,6 +108,12 @@ namespace GeometryTD.UI
return;
}
if (_context.ClickActionType == RepoItemClickActionType.RemoveParticipant)
{
GameEntry.Event.Fire(this, RepoParticipantRemoveRequestedEventArgs.Create(_context.InstanceId));
return;
}
StartPendingOpenDetail();
}
@@ -195,7 +201,12 @@ namespace GeometryTD.UI
private bool CanStartDrag(PointerEventData eventData)
{
if (_context == null || _isSelected || _isDragging)
if (_context == null || _isDragging)
{
return false;
}
if (_isSelected && _context.ComponentSlotType != TowerCompSlotType.None)
{
return false;
}
@@ -205,11 +216,6 @@ namespace GeometryTD.UI
return false;
}
if (_context.ComponentSlotType == TowerCompSlotType.None)
{
return false;
}
if (eventData == null || eventData.button != PointerEventData.InputButton.Left)
{
return false;
@@ -292,12 +298,25 @@ namespace GeometryTD.UI
{
DestroyDragGhost();
if (_dragRoot == null || _iconArea == null)
if (_dragRoot == null)
{
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)
{
return false;
@@ -312,7 +331,6 @@ namespace GeometryTD.UI
_dragGhostRect.anchorMax = 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)
{
iconSize = DefaultDragGhostSize;
@@ -322,8 +340,8 @@ namespace GeometryTD.UI
Image ghostImage = _dragGhostObject.GetComponent<Image>();
ghostImage.raycastTarget = false;
ghostImage.sprite = iconSprite;
ghostImage.color = _iconArea.CurrentIconColor;
ghostImage.material = _iconArea.CurrentIconMaterial;
ghostImage.color = iconColor;
ghostImage.material = iconMaterial;
ghostImage.preserveAspect = true;
CanvasGroup ghostCanvasGroup = _dragGhostObject.GetComponent<CanvasGroup>();