diff --git a/Assets/GameMain/Entities/TowerEntity.prefab b/Assets/GameMain/Entities/TowerEntity.prefab index a31ab9c..d40a4a0 100644 --- a/Assets/GameMain/Entities/TowerEntity.prefab +++ b/Assets/GameMain/Entities/TowerEntity.prefab @@ -76,7 +76,7 @@ SpriteRenderer: m_SortingOrder: 2 m_Sprite: {fileID: 7482667652216324306, guid: 5ba74e3a185274149b15c24b321bead2, type: 3} - m_Color: {r: 1, g: 0.40566027, b: 0.40566027, a: 1} + m_Color: {r: 1, g: 1, b: 1, a: 1} m_FlipX: 0 m_FlipY: 0 m_DrawMode: 0 @@ -103,6 +103,7 @@ MonoBehaviour: _bulletTypeId: 501 _muzzlePoint: {fileID: 7637292285124107611} _bulletSpeed: 12 + _renderer: {fileID: 7170949026143225663} --- !u!1 &1221576993898367501 GameObject: m_ObjectHideFlags: 0 @@ -113,7 +114,6 @@ GameObject: m_Component: - component: {fileID: 6791423131335728073} - component: {fileID: 8183383920109690380} - - component: {fileID: 3255949411223456789} - component: {fileID: 4014432302095443276} m_Layer: 0 m_Name: TowerEntity @@ -160,18 +160,6 @@ MonoBehaviour: _attackRangeLineWidth: 0.08 _attackRangeColor: {r: 0.1, g: 1, b: 0.4, a: 0.8} _attackRangeZOffset: -0.01 ---- !u!114 &3255949411223456789 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1221576993898367501} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: d87f56efd9024709a3baf8ef8a6f4fd3, type: 3} - m_Name: - m_EditorClassIdentifier: --- !u!120 &4014432302095443276 LineRenderer: serializedVersion: 2 @@ -379,6 +367,7 @@ MonoBehaviour: _attackRange: 5 _aimToleranceAngle: 2 _rotateRoot: {fileID: 5517541809701307552} + _renderer: {fileID: 7775658596736532582} --- !u!1 &4867507345079921359 GameObject: m_ObjectHideFlags: 0 @@ -456,7 +445,7 @@ SpriteRenderer: m_SortingOrder: 0 m_Sprite: {fileID: 7482667652216324306, guid: 80a3790c48fc91d4ebcb4d7e2efbb8c8, type: 3} - m_Color: {r: 0.3584906, g: 0.3584906, b: 0.3584906, a: 1} + m_Color: {r: 1, g: 1, b: 1, a: 1} m_FlipX: 0 m_FlipY: 0 m_DrawMode: 0 @@ -480,3 +469,4 @@ MonoBehaviour: m_EditorClassIdentifier: _attackSpeed: 1 _attackPropertyType: 1 + _renderer: {fileID: 6516390239457838709} diff --git a/Assets/GameMain/Scripts/Components/BasicBaseComp.cs b/Assets/GameMain/Scripts/Components/BasicBaseComp.cs index ec19f60..e99d3f3 100644 --- a/Assets/GameMain/Scripts/Components/BasicBaseComp.cs +++ b/Assets/GameMain/Scripts/Components/BasicBaseComp.cs @@ -7,8 +7,11 @@ namespace Components public class BasicBaseComp : MonoBehaviour { [SerializeField] [Min(0.01f)] private float _attackSpeed = 1f; + [SerializeField] private AttackPropertyType _attackPropertyType = AttackPropertyType.Physics; + [SerializeField] private SpriteRenderer _renderer; + private float _cooldownRemaining; public float AttackSpeed => _attackSpeed; @@ -29,6 +32,14 @@ namespace Components _cooldownRemaining = 0f; } + public void SetColor(Color color) + { + if (_renderer != null) + { + _renderer.color = color; + } + } + public void Tick(float deltaTime) { if (_cooldownRemaining <= 0f) diff --git a/Assets/GameMain/Scripts/Components/BasicBearingComp.cs b/Assets/GameMain/Scripts/Components/BasicBearingComp.cs index e75cf22..da94261 100644 --- a/Assets/GameMain/Scripts/Components/BasicBearingComp.cs +++ b/Assets/GameMain/Scripts/Components/BasicBearingComp.cs @@ -6,10 +6,15 @@ namespace Components public class BasicBearingComp : MonoBehaviour { [SerializeField] [Min(1f)] private float _rotateSpeed = 180f; + [SerializeField] [Min(0.1f)] private float _attackRange = 5f; + [SerializeField] [Min(0.1f)] private float _aimToleranceAngle = 2f; + [SerializeField] private Transform _rotateRoot; + [SerializeField] private SpriteRenderer _renderer; + public float RotateSpeed => _rotateSpeed; public float AttackRange => _attackRange; public float AimToleranceAngle => _aimToleranceAngle; @@ -26,6 +31,14 @@ namespace Components _attackRange = 5f; } + public void SetColor(Color color) + { + if (_renderer != null) + { + _renderer.color = color; + } + } + public bool IsTargetInRange(Transform target, Transform origin = null) { if (target == null) diff --git a/Assets/GameMain/Scripts/Components/ShooterMuzzleComp.cs b/Assets/GameMain/Scripts/Components/ShooterMuzzleComp.cs index a9361da..d8f9932 100644 --- a/Assets/GameMain/Scripts/Components/ShooterMuzzleComp.cs +++ b/Assets/GameMain/Scripts/Components/ShooterMuzzleComp.cs @@ -9,11 +9,17 @@ namespace Components public class ShooterMuzzleComp : MonoBehaviour { [SerializeField] [Min(1f)] private int _attackDamage = 100; + [SerializeField] private AttackMethodType _attackMethodType = AttackMethodType.NormalBullet; + [SerializeField] [Min(1)] private int _bulletTypeId = 501; + [SerializeField] private Transform _muzzlePoint; + [SerializeField] [Min(0.1f)] private float _bulletSpeed = 12f; + [SerializeField] private SpriteRenderer _renderer; + public int AttackDamage => _attackDamage; public AttackMethodType AttackMethodType => _attackMethodType; @@ -31,6 +37,14 @@ namespace Components _bulletTypeId = 501; } + public void SetColor(Color color) + { + if (_renderer != null) + { + _renderer.color = color; + } + } + public bool Attack(Transform target) { return Attack(target, AttackPropertyType.None); diff --git a/Assets/GameMain/Scripts/Components/TowerController.cs b/Assets/GameMain/Scripts/Components/TowerController.cs index 1addfde..28e3b64 100644 --- a/Assets/GameMain/Scripts/Components/TowerController.cs +++ b/Assets/GameMain/Scripts/Components/TowerController.cs @@ -10,7 +10,8 @@ namespace Components private const string AttackRangeIndicatorObjectName = "AttackRangeIndicator"; private const int MinTowerLevel = 0; private const int MaxTowerLevel = 4; - private static Material s_AttackRangeSharedMaterial; + + private static Material _attackRangeSharedMaterial; [SerializeField] private ShooterMuzzleComp _muzzleComp; [SerializeField] private BasicBearingComp _bearingComp; @@ -27,6 +28,9 @@ namespace Components private float _retargetTimer; private float _attackRange; private int _towerLevel; + private Color _muzzleColor = Color.white; + private Color _bearingColor = Color.white; + private Color _baseColor = Color.white; public Transform CurrentTarget => _currentTarget; @@ -40,6 +44,12 @@ namespace Components OnInit(stats, MinTowerLevel); } + public void OnInit(TowerStatsData stats, int towerLevel, Color muzzleColor, Color bearingColor, Color baseColor) + { + SetComponentColors(muzzleColor, bearingColor, baseColor); + OnInit(stats, towerLevel); + } + public void OnInit(TowerStatsData stats, int towerLevel) { ResolveComponents(); @@ -57,6 +67,7 @@ namespace Components _muzzleComp?.OnInit(attackDamage, stats.AttackMethodType); _bearingComp?.OnInit(rotateSpeed, attackRange); _baseComp?.OnInit(attackSpeed, stats.AttackPropertyType); + ApplyComponentColors(); SetAttackRange(attackRange); SetAttackRangeVisible(false); _currentTarget = null; @@ -90,6 +101,14 @@ namespace Components RebuildAttackRangeGeometry(); } + public void SetComponentColors(Color muzzleColor, Color bearingColor, Color baseColor) + { + _muzzleColor = muzzleColor; + _bearingColor = bearingColor; + _baseColor = baseColor; + ApplyComponentColors(); + } + public void SetTarget(Transform target) { _currentTarget = target; @@ -141,9 +160,9 @@ namespace Components EnemyEntity bestEnemy = null; float bestDistanceSquared = float.MaxValue; - for (int i = 0; i < EnemyEntity.ActiveEnemies.Count; i++) + + foreach (var enemy in EnemyEntity.ActiveEnemies) { - EnemyEntity enemy = EnemyEntity.ActiveEnemies[i]; if (enemy == null || !enemy.isActiveAndEnabled) { continue; @@ -164,6 +183,13 @@ namespace Components return bestEnemy != null ? bestEnemy.transform : null; } + private void ApplyComponentColors() + { + _muzzleComp?.SetColor(_muzzleColor); + _bearingComp?.SetColor(_bearingColor); + _baseComp?.SetColor(_baseColor); + } + private void ResolveComponents() { if (_muzzleComp == null) @@ -181,6 +207,7 @@ namespace Components _baseComp = GetComponent(); } + ApplyComponentColors(); EnsureAttackRangeRenderer(); } @@ -250,18 +277,18 @@ namespace Components _attackRangeRenderer.allowOcclusionWhenDynamic = false; _attackRangeRenderer.enabled = false; - if (s_AttackRangeSharedMaterial == null) + if (_attackRangeSharedMaterial == null) { Shader lineShader = Shader.Find("Sprites/Default"); if (lineShader != null) { - s_AttackRangeSharedMaterial = new Material(lineShader); + _attackRangeSharedMaterial = new Material(lineShader); } } - if (s_AttackRangeSharedMaterial != null) + if (_attackRangeSharedMaterial != null) { - _attackRangeRenderer.sharedMaterial = s_AttackRangeSharedMaterial; + _attackRangeRenderer.sharedMaterial = _attackRangeSharedMaterial; } } diff --git a/Assets/GameMain/Scripts/CustomComponent/CombatNode/CombatNodeComponent.cs b/Assets/GameMain/Scripts/CustomComponent/CombatNode/CombatNodeComponent.cs index 69add4e..4c81af6 100644 --- a/Assets/GameMain/Scripts/CustomComponent/CombatNode/CombatNodeComponent.cs +++ b/Assets/GameMain/Scripts/CustomComponent/CombatNode/CombatNodeComponent.cs @@ -23,6 +23,7 @@ namespace GeometryTD.CustomComponent private readonly Dictionary> _spawnEntriesByPhaseId = new(); private readonly Dictionary> _selectedSpawnEntriesByPhaseId = new(); private readonly List _levelIdBuffer = new(); + private readonly List _currentBuildTowerStats = new(); private readonly CombatScheduler _combatScheduler = new CombatScheduler(); private bool _runtimeInitialized; @@ -39,6 +40,7 @@ namespace GeometryTD.CustomComponent public int CurrentBaseHp => _currentBaseHp; public bool LastCombatSucceeded => _lastCombatSucceeded; public bool CanEndCombat => _combatScheduler.CanEndCombat; + public int CurrentBuildTowerCount => _currentBuildTowerStats.Count; public int LastDefeatedEnemyCount { get; private set; } public int LastGainedCoin { get; private set; } public int LastGainedGold { get; private set; } @@ -88,6 +90,7 @@ namespace GeometryTD.CustomComponent _spawnEntriesByPhaseId.Clear(); _selectedSpawnEntriesByPhaseId.Clear(); _levelIdBuffer.Clear(); + _currentBuildTowerStats.Clear(); IDataTable dtLevel = GameEntry.DataTable.GetDataTable(); IDataTable dtLevelPhase = GameEntry.DataTable.GetDataTable(); @@ -181,6 +184,7 @@ namespace GeometryTD.CustomComponent public void StartCombat() { + _currentBuildTowerStats.Clear(); if (!EnsureCombatRuntimeInitialized()) { Log.Warning("CombatNodeComponent start failed. Missing scheduler runtime."); @@ -216,6 +220,7 @@ namespace GeometryTD.CustomComponent } CurrentLevel = selectedLevel; + CacheBuildTowerStatsSnapshot(); _isCombatActive = false; _currentCoin = Mathf.Max(0, selectedLevel.StartCoin); _currentGold = 0; @@ -230,6 +235,7 @@ namespace GeometryTD.CustomComponent _currentCoin = 0; _currentGold = 0; _currentBaseHp = 0; + _currentBuildTowerStats.Clear(); return; } @@ -252,6 +258,7 @@ namespace GeometryTD.CustomComponent _currentGold = 0; _currentBaseHp = 0; CurrentLevel = null; + _currentBuildTowerStats.Clear(); GameEntry.Event.Fire(this, NodeCompleteEventArgs.Create()); } @@ -281,6 +288,7 @@ namespace GeometryTD.CustomComponent LastDefeatedEnemyCount = 0; LastGainedCoin = 0; LastGainedGold = 0; + _currentBuildTowerStats.Clear(); ShutdownCombatRuntime(); } @@ -341,6 +349,18 @@ namespace GeometryTD.CustomComponent return true; } + public bool TryGetBuildTowerStats(int buildIndex, out TowerStatsData stats) + { + stats = null; + if (buildIndex < 0 || buildIndex >= _currentBuildTowerStats.Count) + { + return false; + } + + stats = CloneTowerStats(_currentBuildTowerStats[buildIndex]); + return stats != null; + } + public void AddCoin(int coin) { int gainCoin = Mathf.Max(0, coin); @@ -353,6 +373,54 @@ namespace GeometryTD.CustomComponent FireCoinChangedEventIfNeeded(); } + + private void CacheBuildTowerStatsSnapshot() + { + _currentBuildTowerStats.Clear(); + if (GameEntry.PlayerInventory == null) + { + return; + } + + IReadOnlyList towers = GameEntry.PlayerInventory.GetParticipantTowerSnapshot(); + if (towers == null || towers.Count <= 0) + { + return; + } + + for (int i = 0; i < towers.Count; i++) + { + TowerItemData tower = towers[i]; + TowerStatsData clonedStats = CloneTowerStats(tower?.Stats); + if (clonedStats == null) + { + continue; + } + + _currentBuildTowerStats.Add(clonedStats); + } + } + + private static TowerStatsData CloneTowerStats(TowerStatsData source) + { + if (source == null) + { + return null; + } + + return new TowerStatsData + { + AttackDamage = source.AttackDamage != null ? (int[])source.AttackDamage.Clone() : null, + DamageRandomRate = source.DamageRandomRate, + RotateSpeed = source.RotateSpeed != null ? (float[])source.RotateSpeed.Clone() : null, + AttackRange = source.AttackRange != null ? (float[])source.AttackRange.Clone() : null, + AttackSpeed = source.AttackSpeed != null ? (float[])source.AttackSpeed.Clone() : null, + AttackMethodType = source.AttackMethodType, + AttackPropertyType = source.AttackPropertyType, + Tags = source.Tags != null ? (TagType[])source.Tags.Clone() : null + }; + } + private void OnDestroy() { OnShutdown(); @@ -437,3 +505,5 @@ namespace GeometryTD.CustomComponent } } } + + diff --git a/Assets/GameMain/Scripts/CustomComponent/PlayerInventory/PlayerInventoryComponent.cs b/Assets/GameMain/Scripts/CustomComponent/PlayerInventory/PlayerInventoryComponent.cs index 06d6cd8..a3e4743 100644 --- a/Assets/GameMain/Scripts/CustomComponent/PlayerInventory/PlayerInventoryComponent.cs +++ b/Assets/GameMain/Scripts/CustomComponent/PlayerInventory/PlayerInventoryComponent.cs @@ -1,4 +1,5 @@ -using GeometryTD.CustomUtility; +using System.Collections.Generic; +using GeometryTD.CustomUtility; using GeometryTD.Definition; using UnityGameFramework.Runtime; @@ -44,6 +45,31 @@ namespace GeometryTD.CustomComponent return _queryModel.GetSnapshot(); } + public IReadOnlyList GetParticipantTowerSnapshot() + { + EnsureInitialized(); + + BackpackInventoryData inventory = _queryModel.Inventory; + if (inventory?.ParticipantTowerInstanceIds == null || inventory.ParticipantTowerInstanceIds.Count <= 0) + { + return new List(); + } + + List result = new List(inventory.ParticipantTowerInstanceIds.Count); + for (int i = 0; i < inventory.ParticipantTowerInstanceIds.Count && result.Count < MaxParticipantTowerCount; i++) + { + long towerId = inventory.ParticipantTowerInstanceIds[i]; + if (!_queryModel.TryGetTowerById(towerId, out TowerItemData tower) || tower == null) + { + continue; + } + + result.Add(InventoryCloneUtility.CloneTower(tower)); + } + + return result; + } + public void MergeInventory(BackpackInventoryData gainedInventory) { EnsureInitialized(); @@ -126,3 +152,4 @@ namespace GeometryTD.CustomComponent } } } + diff --git a/Assets/GameMain/Scripts/Definition/DataStruct/BackpackInventoryData.cs b/Assets/GameMain/Scripts/Definition/DataStruct/BackpackInventoryData.cs index 0067135..e7198dd 100644 --- a/Assets/GameMain/Scripts/Definition/DataStruct/BackpackInventoryData.cs +++ b/Assets/GameMain/Scripts/Definition/DataStruct/BackpackInventoryData.cs @@ -34,6 +34,9 @@ namespace GeometryTD.Definition /// public List Towers { get; set; } = new List(); + /// + /// 参与战斗的防御塔 Id。 + /// public List ParticipantTowerInstanceIds { get; set; } = new List(); } } diff --git a/Assets/GameMain/Scripts/Definition/DataStruct/TowerItemData.cs b/Assets/GameMain/Scripts/Definition/DataStruct/TowerItemData.cs index 8e7b27f..ee19111 100644 --- a/Assets/GameMain/Scripts/Definition/DataStruct/TowerItemData.cs +++ b/Assets/GameMain/Scripts/Definition/DataStruct/TowerItemData.cs @@ -1,4 +1,6 @@ using System; +using Newtonsoft.Json; +using UnityEngine; namespace GeometryTD.Definition { @@ -41,7 +43,7 @@ namespace GeometryTD.Definition public RarityType Rarity { get; set; } public bool IsParticipatingInCombat { get; set; } - + /// /// 构成该防御塔的枪口组件实例 Id。 /// @@ -61,5 +63,9 @@ namespace GeometryTD.Definition /// 防御塔独立属性,不依赖组件对象引用。 /// public TowerStatsData Stats { get; set; } = new TowerStatsData(); + + [JsonIgnore] public Sprite ComposedIconSprite { get; set; } + + [JsonIgnore] public string ComposedIconKey { get; set; } } -} +} \ No newline at end of file diff --git a/Assets/GameMain/Scripts/Entity/EntityData/TowerData.cs b/Assets/GameMain/Scripts/Entity/EntityData/TowerData.cs index d69252a..fd4b23d 100644 --- a/Assets/GameMain/Scripts/Entity/EntityData/TowerData.cs +++ b/Assets/GameMain/Scripts/Entity/EntityData/TowerData.cs @@ -9,15 +9,22 @@ namespace GeometryTD.Entity.EntityData { [SerializeField] private TowerStatsData _stats = new TowerStatsData(); [SerializeField] private int _towerLevel = 0; + [SerializeField] private Color _muzzleColor = Color.white; + [SerializeField] private Color _bearingColor = Color.white; + [SerializeField] private Color _baseColor = Color.white; public TowerData(int entityId, int typeId, Vector3 position, Quaternion rotation, - TowerStatsData stats, int towerLevel = 0) + TowerStatsData stats, int towerLevel = 0, Color? muzzleColor = null, Color? bearingColor = null, + Color? baseColor = null) : base(entityId, typeId) { Position = position; Rotation = rotation; _stats = stats ?? new TowerStatsData(); _towerLevel = Mathf.Max(0, towerLevel); + _muzzleColor = muzzleColor ?? Color.white; + _bearingColor = bearingColor ?? Color.white; + _baseColor = baseColor ?? Color.white; } public TowerStatsData Stats @@ -31,5 +38,23 @@ namespace GeometryTD.Entity.EntityData get => _towerLevel; set => _towerLevel = Mathf.Max(0, value); } + + public Color MuzzleColor + { + get => _muzzleColor; + set => _muzzleColor = value; + } + + public Color BearingColor + { + get => _bearingColor; + set => _bearingColor = value; + } + + public Color BaseColor + { + get => _baseColor; + set => _baseColor = value; + } } } diff --git a/Assets/GameMain/Scripts/Entity/EntityLogic/MapEntity.cs b/Assets/GameMain/Scripts/Entity/EntityLogic/MapEntity.cs index 68e94de..d9af5dc 100644 --- a/Assets/GameMain/Scripts/Entity/EntityLogic/MapEntity.cs +++ b/Assets/GameMain/Scripts/Entity/EntityLogic/MapEntity.cs @@ -1,5 +1,7 @@ using System; using System.Collections.Generic; +using GeometryTD.CustomComponent; +using GeometryTD.CustomUtility; using GeometryTD.Map; using GeometryTD.Definition; using GeometryTD.Entity.EntityData; @@ -14,12 +16,17 @@ namespace GeometryTD.Entity public class MapEntity : EntityBase { private const int DefaultTowerTypeId = 401; + private static readonly Spawner[] EmptySpawners = Array.Empty(); [SerializeField] private bool _enableCombatSelectInput = true; + [SerializeField] private int _towerTypeId = DefaultTowerTypeId; + [SerializeField] private int[] _buildTowerCosts = { 40, 60, 60, 80 }; + [SerializeField] private int _upgradeCost = 50; + [SerializeField] private int _destroyGain = 40; private MapDataRefs _mapDataRefs; @@ -29,6 +36,8 @@ namespace GeometryTD.Entity private CombatSelectInputService _combatSelectInputService; private TowerPlacementService _towerPlacementService; private TowerSelectionPresenter _towerSelectionPresenter; + + private readonly BuildTowerVisualInfo[] _buildTowerVisualInfos = new BuildTowerVisualInfo[4]; public IReadOnlyList PathCells => _mapTopologyService != null ? _mapTopologyService.PathCells @@ -209,22 +218,38 @@ namespace GeometryTD.Entity } _combatSelectFormUseCase.SetCoinProvider(GetCurrentCoin); + BackpackInventoryData inventorySnapshot = GameEntry.PlayerInventory != null + ? GameEntry.PlayerInventory.GetInventorySnapshot() + : null; + IReadOnlyList participantTowers = GameEntry.PlayerInventory != null + ? GameEntry.PlayerInventory.GetParticipantTowerSnapshot() + : null; + Dictionary muzzleMap = BuildComponentMap(inventorySnapshot?.MuzzleComponents); + Dictionary bearingMap = BuildComponentMap(inventorySnapshot?.BearingComponents); + Dictionary baseMap = BuildComponentMap(inventorySnapshot?.BaseComponents); + int currentBuildTowerCount = GetCurrentBuildTowerCount(); for (int i = 0; i < 4; i++) { int buildIndex = i; + int buildCost = GetBuildTowerCost(buildIndex); + bool isBuildAvailable = buildIndex < currentBuildTowerCount; + BuildTowerVisualInfo buildVisual = ResolveBuildTowerVisual(participantTowers, buildIndex, muzzleMap, bearingMap, baseMap); + _buildTowerVisualInfos[buildIndex] = buildVisual; _combatSelectFormUseCase.SetBuildAction( buildIndex, - () => TryBuildTower(buildIndex), - GetBuildTowerCost(buildIndex)); + isBuildAvailable ? () => TryBuildTower(buildIndex) : (Func)null, + buildCost, + null, + isBuildAvailable, + buildVisual.BaseColor, + buildVisual.BearingColor, + buildVisual.MuzzleColor); + _combatSelectFormUseCase.SetBuildVisible(buildIndex, isBuildAvailable); } - _combatSelectFormUseCase.SetUpgradeAction( - TryUpgradeTower, - Mathf.Max(0, _upgradeCost)); - _combatSelectFormUseCase.SetDestroyAction( - TryDestroyTower, - Mathf.Max(0, _destroyGain)); + _combatSelectFormUseCase.SetUpgradeAction(TryUpgradeTower, Mathf.Max(0, _upgradeCost)); + _combatSelectFormUseCase.SetDestroyAction(TryDestroyTower, Mathf.Max(0, _destroyGain)); } private void HandleCombatSelectInput() @@ -275,8 +300,18 @@ namespace GeometryTD.Entity return false; } + CombatNodeComponent combatNode = GameEntry.CombatNode; + if (combatNode == null || !combatNode.TryGetBuildTowerStats(buildIndex, out TowerStatsData buildTowerStats)) + { + return false; + } + + BuildTowerVisualInfo buildVisual = buildIndex >= 0 && buildIndex < _buildTowerVisualInfos.Length + ? _buildTowerVisualInfos[buildIndex] + : BuildTowerVisualInfo.Default; + if (!_towerPlacementService.TryBuildTower(selectedFoundationCell, IsFoundationCell, buildIndex, _buildTowerCosts, - _towerTypeId, Tilemap, TryConsumeCoin, AddCoin, out int towerEntityId)) + buildTowerStats, buildVisual.MuzzleColor, buildVisual.BearingColor, buildVisual.BaseColor, _towerTypeId, Tilemap, TryConsumeCoin, AddCoin, out int towerEntityId)) { return false; } @@ -350,6 +385,77 @@ namespace GeometryTD.Entity return Mathf.Max(0, _buildTowerCosts[buildIndex]); } + private static int GetCurrentBuildTowerCount() + { + if (GameEntry.CombatNode == null) + { + return 0; + } + + return Mathf.Clamp(GameEntry.CombatNode.CurrentBuildTowerCount, 0, 4); + } + + + private static BuildTowerVisualInfo ResolveBuildTowerVisual( + IReadOnlyList participantTowers, + int buildIndex, + IReadOnlyDictionary muzzleMap, + IReadOnlyDictionary bearingMap, + IReadOnlyDictionary baseMap) + { + if (participantTowers == null || buildIndex < 0 || buildIndex >= participantTowers.Count) + { + return BuildTowerVisualInfo.Default; + } + + TowerItemData tower = participantTowers[buildIndex]; + if (tower == null) + { + return BuildTowerVisualInfo.Default; + } + + Color muzzleColor = ResolveComponentColor(muzzleMap, tower.MuzzleComponentInstanceId); + Color bearingColor = ResolveComponentColor(bearingMap, tower.BearingComponentInstanceId); + Color baseColor = ResolveComponentColor(baseMap, tower.BaseComponentInstanceId); + return new BuildTowerVisualInfo(muzzleColor, bearingColor, baseColor); + } + + private static Color ResolveComponentColor(IReadOnlyDictionary componentMap, long componentId) + where TComp : TowerCompItemData + { + if (componentMap == null || componentId <= 0) + { + return Color.white; + } + + return componentMap.TryGetValue(componentId, out TComp component) && component != null + ? IconColorGenerator.GenerateForComponent(component) + : Color.white; + } + + private static Dictionary BuildComponentMap(IReadOnlyList items) + where TComp : TowerCompItemData + { + Dictionary map = new Dictionary(); + if (items == null) + { + return map; + } + + for (int i = 0; i < items.Count; i++) + { + TComp item = items[i]; + if (item == null || item.InstanceId <= 0) + { + continue; + } + + map[item.InstanceId] = item; + } + + return map; + } + private static bool TryConsumeCoin(int cost) { int requiredCoin = Mathf.Max(0, cost); @@ -371,6 +477,22 @@ namespace GeometryTD.Entity return GameEntry.CombatNode != null ? Mathf.Max(0, GameEntry.CombatNode.CurrentCoin) : 0; } + private readonly struct BuildTowerVisualInfo + { + public static BuildTowerVisualInfo Default => new BuildTowerVisualInfo(Color.white, Color.white, Color.white); + + public BuildTowerVisualInfo(Color muzzleColor, Color bearingColor, Color baseColor) + { + MuzzleColor = muzzleColor; + BearingColor = bearingColor; + BaseColor = baseColor; + } + + public Color MuzzleColor { get; } + public Color BearingColor { get; } + public Color BaseColor { get; } + } + private static void AddCoin(int coin) { int amount = Mathf.Max(0, coin); @@ -382,3 +504,4 @@ namespace GeometryTD.Entity } } } + diff --git a/Assets/GameMain/Scripts/Entity/EntityLogic/TowerEntity.cs b/Assets/GameMain/Scripts/Entity/EntityLogic/TowerEntity.cs index 3cfe681..dba64fc 100644 --- a/Assets/GameMain/Scripts/Entity/EntityLogic/TowerEntity.cs +++ b/Assets/GameMain/Scripts/Entity/EntityLogic/TowerEntity.cs @@ -53,7 +53,12 @@ namespace GeometryTD.Entity return; } - _towerController.OnInit(towerData.Stats, towerData.TowerLevel); + _towerController.OnInit( + towerData.Stats, + towerData.TowerLevel, + towerData.MuzzleColor, + towerData.BearingColor, + towerData.BaseColor); } protected override void OnUpdate(float elapseSeconds, float realElapseSeconds) diff --git a/Assets/GameMain/Scripts/PoolObjectBase/TowerRepoItemObject.cs b/Assets/GameMain/Scripts/PoolObjectBase/TowerRepoItemObject.cs new file mode 100644 index 0000000..ade0663 --- /dev/null +++ b/Assets/GameMain/Scripts/PoolObjectBase/TowerRepoItemObject.cs @@ -0,0 +1,28 @@ +using GameFramework; +using GameFramework.ObjectPool; +using GeometryTD.UI; +using UnityEngine; + +namespace GeometryTD.PoolObjectBase +{ + public class TowerRepoItemObject : ObjectBase + { + public static TowerRepoItemObject Create(object target) + { + TowerRepoItemObject itemObject = ReferencePool.Acquire(); + itemObject.Initialize(target); + return itemObject; + } + + protected override void Release(bool isShutdown) + { + TowerRepoItem item = (TowerRepoItem)Target; + if (item == null) + { + return; + } + + Object.Destroy(item.gameObject); + } + } +} diff --git a/Assets/GameMain/Scripts/PoolObjectBase/TowerRepoItemObject.cs.meta b/Assets/GameMain/Scripts/PoolObjectBase/TowerRepoItemObject.cs.meta new file mode 100644 index 0000000..c7e89da --- /dev/null +++ b/Assets/GameMain/Scripts/PoolObjectBase/TowerRepoItemObject.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 6f6f2603e451c5f4f9b0d0cb8ee247d6 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/GameMain/Scripts/Scene/Map/TowerPlacementService.cs b/Assets/GameMain/Scripts/Scene/Map/TowerPlacementService.cs index 2c83bc2..ce86a9f 100644 --- a/Assets/GameMain/Scripts/Scene/Map/TowerPlacementService.cs +++ b/Assets/GameMain/Scripts/Scene/Map/TowerPlacementService.cs @@ -40,7 +40,7 @@ namespace GeometryTD.Map } public bool TryBuildTower(Vector3Int foundationCell, Func isFoundationCell, int buildIndex, - int[] buildTowerCosts, int towerTypeId, Tilemap tilemap, Func tryConsumeCoin, + int[] buildTowerCosts, TowerStatsData buildTowerStats, Color muzzleColor, Color bearingColor, Color baseColor, int towerTypeId, Tilemap tilemap, Func tryConsumeCoin, Action addCoin, out int towerEntityId) { @@ -55,14 +55,19 @@ namespace GeometryTD.Map return false; } + TowerStatsData towerStats = CloneTowerStats(buildTowerStats); + if (towerStats == null) + { + return false; + } + int buildCost = GetBuildTowerCost(buildTowerCosts, buildIndex); if (tryConsumeCoin != null && !tryConsumeCoin(buildCost)) { return false; } - TowerStatsData towerStats = BuildTowerStats(buildIndex); - if (!TryShowTowerEntity(foundationCell, towerStats, towerTypeId, tilemap, out int newTowerEntityId)) + if (!TryShowTowerEntity(foundationCell, towerStats, muzzleColor, bearingColor, baseColor, towerTypeId, tilemap, out int newTowerEntityId)) { addCoin?.Invoke(buildCost); return false; @@ -177,7 +182,7 @@ namespace GeometryTD.Map return Mathf.Max(0, buildTowerCosts[buildIndex]); } - private static bool TryShowTowerEntity(Vector3Int foundationCell, TowerStatsData towerStats, + private static bool TryShowTowerEntity(Vector3Int foundationCell, TowerStatsData towerStats, Color muzzleColor, Color bearingColor, Color baseColor, int towerTypeId, Tilemap tilemap, out int towerEntityId) { @@ -192,7 +197,7 @@ namespace GeometryTD.Map Vector3 towerPosition = tilemap != null ? tilemap.GetCellCenterWorld(foundationCell) : foundationCell; towerPosition.z = 0f; var towerData = new TowerData(entityId, typeId, towerPosition, Quaternion.identity, towerStats, - MinTowerLevel); + MinTowerLevel, muzzleColor, bearingColor, baseColor); GameEntry.Entity.ShowDefenseTower(towerData); towerEntityId = entityId; @@ -346,4 +351,4 @@ namespace GeometryTD.Map return values != null ? values.Length : 0; } } -} \ No newline at end of file +} diff --git a/Assets/GameMain/Scripts/UI/Combat/Context/TowerSelectItemContext.cs b/Assets/GameMain/Scripts/UI/Combat/Context/TowerSelectItemContext.cs index b698c0f..f6e5d47 100644 --- a/Assets/GameMain/Scripts/UI/Combat/Context/TowerSelectItemContext.cs +++ b/Assets/GameMain/Scripts/UI/Combat/Context/TowerSelectItemContext.cs @@ -10,5 +10,6 @@ namespace GeometryTD.UI public bool IsInteractable; public CombatSelectActionType ActionType; public int ActionIndex; + public TowerIconAreaContext TowerIconAreaContext; } } diff --git a/Assets/GameMain/Scripts/UI/Combat/Controller/CombatFinishFormController.cs b/Assets/GameMain/Scripts/UI/Combat/Controller/CombatFinishFormController.cs index 6911352..f3c4e64 100644 --- a/Assets/GameMain/Scripts/UI/Combat/Controller/CombatFinishFormController.cs +++ b/Assets/GameMain/Scripts/UI/Combat/Controller/CombatFinishFormController.cs @@ -116,9 +116,8 @@ namespace GeometryTD.UI if (inventory.Towers != null) { - for (int i = 0; i < inventory.Towers.Count; i++) + foreach (TowerItemData tower in inventory.Towers) { - var tower = inventory.Towers[i]; if (tower == null) { continue; @@ -131,7 +130,7 @@ namespace GeometryTD.UI EnduranceRate01 = ItemDescUtility.ResolveTowerEnduranceRate(tower, muzzleMap, bearingMap, baseMap), ClickActionType = RepoItemClickActionType.OpenDetail, ComponentSlotType = TowerCompSlotType.None, - IconAreaContext = BuildIconAreaContext(tower) + IconAreaContext = BuildTowerIconContext(tower, muzzleMap, bearingMap, baseMap) }); AddItemDescSeed( @@ -145,9 +144,8 @@ namespace GeometryTD.UI if (inventory.MuzzleComponents != null) { - for (int i = 0; i < inventory.MuzzleComponents.Count; i++) + foreach (MuzzleCompItemData item in inventory.MuzzleComponents) { - var item = inventory.MuzzleComponents[i]; if (item == null) { continue; @@ -174,7 +172,7 @@ namespace GeometryTD.UI if (inventory.BearingComponents != null) { - foreach (var item in inventory.BearingComponents) + foreach (BearingCompItemData item in inventory.BearingComponents) { if (item == null) { @@ -202,9 +200,8 @@ namespace GeometryTD.UI if (inventory.BaseComponents != null) { - for (int i = 0; i < inventory.BaseComponents.Count; i++) + foreach (BaseCompItemData item in inventory.BaseComponents) { - var item = inventory.BaseComponents[i]; if (item == null) { continue; @@ -232,6 +229,38 @@ namespace GeometryTD.UI return itemContexts.ToArray(); } + private static TowerIconAreaContext BuildTowerIconContext( + TowerItemData tower, + IReadOnlyDictionary muzzleMap, + IReadOnlyDictionary bearingMap, + IReadOnlyDictionary baseMap) + { + if (tower == null) + { + return null; + } + + return new TowerIconAreaContext + { + Rarity = tower.Rarity, + MuzzleColor = ResolveComponentColor(tower.MuzzleComponentInstanceId, muzzleMap), + BearingColor = ResolveComponentColor(tower.BearingComponentInstanceId, bearingMap), + BaseColor = ResolveComponentColor(tower.BaseComponentInstanceId, baseMap) + }; + } + + private static Color ResolveComponentColor(long instanceId, IReadOnlyDictionary componentMap) + where TComp : TowerCompItemData + { + if (instanceId > 0 && componentMap != null && componentMap.TryGetValue(instanceId, out TComp comp) && + comp != null) + { + return IconColorGenerator.GenerateForComponent(comp); + } + + return Color.white; + } + private void AddItemDescSeed(long itemId, string title, string typeText, string description, TagType[] tags) { if (itemId <= 0) @@ -274,9 +303,8 @@ namespace GeometryTD.UI return map; } - for (int i = 0; i < items.Count; i++) + foreach (TComp item in items) { - TComp item = items[i]; if (item == null || item.InstanceId <= 0) { continue; @@ -288,35 +316,13 @@ namespace GeometryTD.UI return map; } - private static IconAreaContext BuildIconAreaContext(TowerItemData tower) - { - if (tower == null) - { - return new IconAreaContext - { - ComponentSlotType = TowerCompSlotType.None, - Rarity = RarityType.None, - Color = Color.white, - Icon = null - }; - } - - return new IconAreaContext - { - ComponentSlotType = TowerCompSlotType.None, - Rarity = tower.Rarity, - Color = IconColorGenerator.GenerateForTower(tower), - Icon = null - }; - } - private static IconAreaContext BuildIconAreaContext(TowerCompItemData item) { if (item == null) { return new IconAreaContext { - ComponentSlotType = TowerCompSlotType.None, + ComponentSlotType = TowerCompSlotType.None, Rarity = RarityType.None, Color = Color.white, Icon = null @@ -332,6 +338,8 @@ namespace GeometryTD.UI }; } + #region Event Handlers + private void OnCombatFinishReturnButtonClicked(object sender, GameEventArgs e) { if (!IsEventFromCurrentForm(sender) || !(e is CombatFinishReturnEventArgs)) @@ -370,6 +378,8 @@ namespace GeometryTD.UI }); } + #endregion + private bool IsEventFromCurrentForm(object sender) { if (Form == null) @@ -392,3 +402,7 @@ namespace GeometryTD.UI } } } + + + + diff --git a/Assets/GameMain/Scripts/UI/Combat/Controller/CombatSelectFormController.cs b/Assets/GameMain/Scripts/UI/Combat/Controller/CombatSelectFormController.cs index fb67ffa..7707db3 100644 --- a/Assets/GameMain/Scripts/UI/Combat/Controller/CombatSelectFormController.cs +++ b/Assets/GameMain/Scripts/UI/Combat/Controller/CombatSelectFormController.cs @@ -229,7 +229,13 @@ namespace GeometryTD.UI IsVisible = rawData.IsVisible, IsInteractable = rawData.IsInteractable, ActionType = rawData.ActionType, - ActionIndex = rawData.ActionIndex + ActionIndex = rawData.ActionIndex, + TowerIconAreaContext = new TowerIconAreaContext() + { + BaseColor = rawData.BaseColor, + BearingColor = rawData.BearingColor, + MuzzleColor = rawData.MuzzleColor + } }; } @@ -284,4 +290,4 @@ namespace GeometryTD.UI RefreshFromUseCase(); } } -} +} \ No newline at end of file diff --git a/Assets/GameMain/Scripts/UI/Combat/RawData/TowerSelectItemRawData.cs b/Assets/GameMain/Scripts/UI/Combat/RawData/TowerSelectItemRawData.cs index 05b9aa3..e02daef 100644 --- a/Assets/GameMain/Scripts/UI/Combat/RawData/TowerSelectItemRawData.cs +++ b/Assets/GameMain/Scripts/UI/Combat/RawData/TowerSelectItemRawData.cs @@ -11,5 +11,9 @@ namespace GeometryTD.UI public bool IsInteractable; public CombatSelectActionType ActionType; public int ActionIndex; + public bool UseTowerLayers; + public Color BaseColor = Color.white; + public Color BearingColor = Color.white; + public Color MuzzleColor = Color.white; } } diff --git a/Assets/GameMain/Scripts/UI/Combat/UseCase/CombatSelectFormUseCase.cs b/Assets/GameMain/Scripts/UI/Combat/UseCase/CombatSelectFormUseCase.cs index 8940786..7351736 100644 --- a/Assets/GameMain/Scripts/UI/Combat/UseCase/CombatSelectFormUseCase.cs +++ b/Assets/GameMain/Scripts/UI/Combat/UseCase/CombatSelectFormUseCase.cs @@ -42,6 +42,19 @@ namespace GeometryTD.UI } public void SetBuildAction(int buildIndex, Func buildAction, int cost, Sprite icon = null) + { + SetBuildAction(buildIndex, buildAction, cost, icon, false, Color.white, Color.white, Color.white); + } + + public void SetBuildAction( + int buildIndex, + Func buildAction, + int cost, + Sprite icon, + bool useTowerLayers, + Color baseColor, + Color bearingColor, + Color muzzleColor) { if (buildIndex < 0 || buildIndex >= _buildOptions.Length) { @@ -54,6 +67,10 @@ namespace GeometryTD.UI option.Icon = icon; option.IsGain = false; option.IsVisible = true; + option.UseTowerLayers = useTowerLayers; + option.BaseColor = baseColor; + option.BearingColor = bearingColor; + option.MuzzleColor = muzzleColor; } public void SetBuildAction(int buildIndex, Action buildAction, int cost, Sprite icon = null) @@ -75,6 +92,16 @@ namespace GeometryTD.UI icon); } + public void SetBuildVisible(int buildIndex, bool visible) + { + if (buildIndex < 0 || buildIndex >= _buildOptions.Length) + { + return; + } + + _buildOptions[buildIndex].IsVisible = visible; + } + public void SetUpgradeAction(Func upgradeAction, int cost, Sprite icon = null) { _upgradeOption.Action = upgradeAction; @@ -82,6 +109,7 @@ namespace GeometryTD.UI _upgradeOption.Icon = icon; _upgradeOption.IsGain = false; _upgradeOption.IsVisible = true; + _upgradeOption.UseTowerLayers = false; } public void SetUpgradeAction(Action upgradeAction, int cost, Sprite icon = null) @@ -109,6 +137,7 @@ namespace GeometryTD.UI _destroyOption.Icon = icon; _destroyOption.IsGain = true; _destroyOption.IsVisible = true; + _destroyOption.UseTowerLayers = false; } public void SetDestroyAction(Action destroyAction, int gain, Sprite icon = null) @@ -278,7 +307,11 @@ namespace GeometryTD.UI IsVisible = option.IsVisible, IsInteractable = option.Action != null && CanExecute(option, currentCoin), ActionType = option.ActionType, - ActionIndex = option.ActionIndex + ActionIndex = option.ActionIndex, + UseTowerLayers = option.UseTowerLayers, + BaseColor = option.BaseColor, + BearingColor = option.BearingColor, + MuzzleColor = option.MuzzleColor }; } @@ -293,6 +326,10 @@ namespace GeometryTD.UI public bool IsVisible = true; public Sprite Icon; public Func Action; + public bool UseTowerLayers; + public Color BaseColor = Color.white; + public Color BearingColor = Color.white; + public Color MuzzleColor = Color.white; public Option(CombatSelectActionType actionType, int actionIndex, bool requiresAffordable) { diff --git a/Assets/GameMain/Scripts/UI/Combat/View/TowerSelectItem.cs b/Assets/GameMain/Scripts/UI/Combat/View/TowerSelectItem.cs index 409c87b..d7d8cf6 100644 --- a/Assets/GameMain/Scripts/UI/Combat/View/TowerSelectItem.cs +++ b/Assets/GameMain/Scripts/UI/Combat/View/TowerSelectItem.cs @@ -2,20 +2,23 @@ using TMPro; using UnityEngine; using UnityEngine.UI; using GeometryTD.CustomEvent; -using UnityGameFramework.Runtime; namespace GeometryTD.UI { public class TowerSelectItem : MonoBehaviour { [SerializeField] private Image _icon; - + [SerializeField] private TMP_Text _price; - + [SerializeField] private CommonButton _button; - + + [SerializeField] private TowerIconArea _towerIconArea; + private TowerSelectItemContext _context; + private Sprite _defaultIcon; + private bool _hasCachedDefaultIcon; public void OnInit(TowerSelectItemContext context) @@ -23,28 +26,45 @@ namespace GeometryTD.UI CacheDefaultIcon(); _context = context; - if (_icon != null) + if (context.ActionType == CombatSelectActionType.BuildTower) { - if (context != null && context.Icon != null) + _icon?.gameObject.SetActive(false); + _towerIconArea?.OnInit(_context.TowerIconAreaContext); + + if (_price != null) { - _icon.sprite = context.Icon; - } - else if (_defaultIcon != null) - { - _icon.sprite = _defaultIcon; + _price.text = context.PriceText ?? string.Empty; } - _icon.enabled = _icon.sprite != null; + if (_button != null) + { + _button.Interactive = context.IsInteractable; + } } - - if (_price != null) + else if (context.ActionType is CombatSelectActionType.UpgradeTower or CombatSelectActionType.DestroyTower) { - _price.text = context?.PriceText ?? string.Empty; + if (_icon != null) + { + _icon.sprite = _context.Icon ?? _defaultIcon; + _icon.gameObject.SetActive(true); + } + + _towerIconArea?.OnReset(); + + if (_price != null) + { + _price.text = context.PriceText ?? string.Empty; + } + + if (_button != null) + { + _button.Interactive = context.IsInteractable; + } } - - if (_button != null) + else { - _button.Interactive = context != null && context.IsInteractable; + _icon?.gameObject.SetActive(false); + _towerIconArea?.OnReset(); } } @@ -59,6 +79,8 @@ namespace GeometryTD.UI _icon.enabled = _icon.sprite != null; } + _towerIconArea.OnReset(); + if (_price != null) { _price.text = string.Empty; @@ -93,4 +115,4 @@ namespace GeometryTD.UI _hasCachedDefaultIcon = true; } } -} +} \ No newline at end of file diff --git a/Assets/GameMain/Scripts/UI/Game/Context/CompAreaContext.cs b/Assets/GameMain/Scripts/UI/Game/Context/CompAreaContext.cs index 32294df..f53fb44 100644 --- a/Assets/GameMain/Scripts/UI/Game/Context/CompAreaContext.cs +++ b/Assets/GameMain/Scripts/UI/Game/Context/CompAreaContext.cs @@ -2,6 +2,7 @@ namespace GeometryTD.UI { public class CompAreaContext { - public RepoItemContext[] Items; + public RepoItemContext[] ComponentItems; + public TowerRepoItemContext[] TowerItems; } } diff --git a/Assets/GameMain/Scripts/UI/Game/Context/ParticipantAreaContext.cs b/Assets/GameMain/Scripts/UI/Game/Context/ParticipantAreaContext.cs index ef10ae5..8bb52bc 100644 --- a/Assets/GameMain/Scripts/UI/Game/Context/ParticipantAreaContext.cs +++ b/Assets/GameMain/Scripts/UI/Game/Context/ParticipantAreaContext.cs @@ -2,7 +2,7 @@ namespace GeometryTD.UI { public class ParticipantAreaContext : UIContext { - public RepoItemContext[] Items; + public TowerRepoItemContext[] TowerItems; public int MaxCount; } } diff --git a/Assets/GameMain/Scripts/UI/Game/Context/TowerRepoItemContext.cs b/Assets/GameMain/Scripts/UI/Game/Context/TowerRepoItemContext.cs new file mode 100644 index 0000000..83d8832 --- /dev/null +++ b/Assets/GameMain/Scripts/UI/Game/Context/TowerRepoItemContext.cs @@ -0,0 +1,9 @@ +using System; + +namespace GeometryTD.UI +{ + [Serializable] + public class TowerRepoItemContext : RepoItemContext + { + } +} diff --git a/Assets/GameMain/Scripts/UI/Game/Context/TowerRepoItemContext.cs.meta b/Assets/GameMain/Scripts/UI/Game/Context/TowerRepoItemContext.cs.meta new file mode 100644 index 0000000..a2ac9c9 --- /dev/null +++ b/Assets/GameMain/Scripts/UI/Game/Context/TowerRepoItemContext.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 813496ec671788a4b975fa980ce16555 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/GameMain/Scripts/UI/Game/Controller/RepoFormController.ContextBuilder.cs b/Assets/GameMain/Scripts/UI/Game/Controller/RepoFormController.ContextBuilder.cs index fd926df..04a8f16 100644 --- a/Assets/GameMain/Scripts/UI/Game/Controller/RepoFormController.ContextBuilder.cs +++ b/Assets/GameMain/Scripts/UI/Game/Controller/RepoFormController.ContextBuilder.cs @@ -10,8 +10,9 @@ namespace GeometryTD.UI { private RepoFormContext BuildContext(RepoFormRawData rawData) { - _itemContextMap.Clear(); + _itemClickActionMap.Clear(); _itemDescSeedMap.Clear(); + _compAreaTowerIds.Clear(); if (rawData?.Inventory == null) { _participantTowerIds.Clear(); @@ -22,7 +23,8 @@ namespace GeometryTD.UI Dictionary bearingMap = BuildComponentMap(rawData.Inventory.BearingComponents); Dictionary baseMap = BuildComponentMap(rawData.Inventory.BaseComponents); Dictionary towerMap = BuildTowerMap(rawData.Inventory.Towers); - List items = new List(); + List componentItems = new List(); + List towerItems = new List(); if (rawData.Inventory.Towers != null) { @@ -33,15 +35,9 @@ namespace GeometryTD.UI continue; } - AddItemContext(items, new RepoItemContext - { - InstanceId = tower.InstanceId, - CanDrag = true, - EnduranceRate01 = ItemDescUtility.ResolveTowerEnduranceRate(tower, muzzleMap, bearingMap, baseMap), - ClickActionType = RepoItemClickActionType.OpenDetail, - ComponentSlotType = TowerCompSlotType.None, - IconAreaContext = BuildIconAreaContext(tower) - }); + TowerRepoItemContext towerContext = BuildTowerRepoItemContext(tower, muzzleMap, bearingMap, baseMap, + RepoItemClickActionType.OpenDetail, true); + AddTowerItemContext(towerItems, towerContext); AddItemDescSeed( tower.InstanceId, tower.Name, @@ -60,7 +56,7 @@ namespace GeometryTD.UI continue; } - AddItemContext(items, new RepoItemContext + RepoItemContext componentContext = new RepoItemContext { InstanceId = item.InstanceId, CanDrag = true, @@ -68,7 +64,8 @@ namespace GeometryTD.UI ClickActionType = RepoItemClickActionType.OpenDetail, ComponentSlotType = TowerCompSlotType.Muzzle, IconAreaContext = BuildIconAreaContext(item) - }); + }; + AddComponentItemContext(componentItems, componentContext); AddItemDescSeed( item.InstanceId, item.Name, @@ -87,7 +84,7 @@ namespace GeometryTD.UI continue; } - AddItemContext(items, new RepoItemContext + RepoItemContext componentContext = new RepoItemContext { InstanceId = item.InstanceId, CanDrag = true, @@ -95,7 +92,8 @@ namespace GeometryTD.UI ClickActionType = RepoItemClickActionType.OpenDetail, ComponentSlotType = TowerCompSlotType.Bearing, IconAreaContext = BuildIconAreaContext(item) - }); + }; + AddComponentItemContext(componentItems, componentContext); AddItemDescSeed( item.InstanceId, item.Name, @@ -114,7 +112,7 @@ namespace GeometryTD.UI continue; } - AddItemContext(items, new RepoItemContext + RepoItemContext componentContext = new RepoItemContext { InstanceId = item.InstanceId, CanDrag = true, @@ -122,7 +120,8 @@ namespace GeometryTD.UI ClickActionType = RepoItemClickActionType.OpenDetail, ComponentSlotType = TowerCompSlotType.Base, IconAreaContext = BuildIconAreaContext(item) - }); + }; + AddComponentItemContext(componentItems, componentContext); AddItemDescSeed( item.InstanceId, item.Name, @@ -140,13 +139,14 @@ namespace GeometryTD.UI CombineAreaContext = new CombineAreaContext(), CompAreaContext = new CompAreaContext { - Items = items.ToArray() + ComponentItems = componentItems.ToArray(), + TowerItems = towerItems.ToArray() }, ParticipantAreaContext = participantAreaContext }; } - private void AddItemContext(List items, RepoItemContext itemContext) + private void AddComponentItemContext(List items, RepoItemContext itemContext) { if (itemContext == null) { @@ -154,7 +154,19 @@ namespace GeometryTD.UI } items.Add(itemContext); - _itemContextMap[itemContext.InstanceId] = itemContext; + _itemClickActionMap[itemContext.InstanceId] = itemContext.ClickActionType; + } + + private void AddTowerItemContext(List items, TowerRepoItemContext itemContext) + { + if (itemContext == null) + { + return; + } + + items.Add(itemContext); + _itemClickActionMap[itemContext.InstanceId] = itemContext.ClickActionType; + _compAreaTowerIds.Add(itemContext.InstanceId); } private void AddItemDescSeed(long itemId, string title, string typeText, string description, TagType[] tags) @@ -243,7 +255,7 @@ namespace GeometryTD.UI IReadOnlyDictionary baseMap) { _participantTowerIds.Clear(); - List participantItems = new List(); + List participantItems = new List(); if (inventory?.ParticipantTowerInstanceIds != null && towerMap != null) { for (int i = 0; i < inventory.ParticipantTowerInstanceIds.Count; i++) @@ -264,41 +276,33 @@ namespace GeometryTD.UI continue; } - participantItems.Add(new RepoItemContext + TowerRepoItemContext towerContext = BuildTowerRepoItemContext(tower, muzzleMap, bearingMap, baseMap, + RepoItemClickActionType.RemoveParticipant, false); + if (towerContext != null) { - InstanceId = tower.InstanceId, - CanDrag = false, - EnduranceRate01 = ItemDescUtility.ResolveTowerEnduranceRate(tower, muzzleMap, bearingMap, baseMap), - ClickActionType = RepoItemClickActionType.RemoveParticipant, - ComponentSlotType = TowerCompSlotType.None, - IconAreaContext = BuildIconAreaContext(tower) - }); + participantItems.Add(towerContext); + _itemClickActionMap[towerContext.InstanceId] = towerContext.ClickActionType; + } } } return new ParticipantAreaContext { - Items = participantItems.ToArray(), + TowerItems = participantItems.ToArray(), MaxCount = MaxParticipantCount }; } private void ApplyParticipantSelection() { - if (Form == null || _itemContextMap.Count <= 0) + if (Form == null || _compAreaTowerIds.Count <= 0) { return; } - foreach (KeyValuePair pair in _itemContextMap) + foreach (long towerId in _compAreaTowerIds) { - RepoItemContext itemContext = pair.Value; - if (itemContext == null || itemContext.ComponentSlotType != TowerCompSlotType.None) - { - continue; - } - - Form.SetRepoItemSelected(pair.Key, _participantTowerIds.Contains(pair.Key)); + Form.SetRepoItemSelected(towerId, _participantTowerIds.Contains(towerId)); } } @@ -319,25 +323,33 @@ namespace GeometryTD.UI ApplyParticipantSelection(); } - private static IconAreaContext BuildIconAreaContext(TowerItemData tower) + private static TowerRepoItemContext BuildTowerRepoItemContext( + TowerItemData tower, + IReadOnlyDictionary muzzleMap, + IReadOnlyDictionary bearingMap, + IReadOnlyDictionary baseMap, + RepoItemClickActionType clickActionType, + bool canDrag) { if (tower == null) { - return new IconAreaContext - { - ComponentSlotType = TowerCompSlotType.None, - Rarity = RarityType.None, - Color = Color.white, - Icon = null - }; + return null; } - return new IconAreaContext + return new TowerRepoItemContext { + InstanceId = tower.InstanceId, + CanDrag = canDrag, + EnduranceRate01 = ItemDescUtility.ResolveTowerEnduranceRate(tower, muzzleMap, bearingMap, baseMap), + ClickActionType = clickActionType, ComponentSlotType = TowerCompSlotType.None, - Rarity = tower.Rarity, - Color = IconColorGenerator.GenerateForTower(tower), - Icon = null + IconAreaContext = new TowerIconAreaContext + { + Rarity = tower.Rarity, + MuzzleColor = ResolveComponentColor(tower.MuzzleComponentInstanceId, muzzleMap), + BearingColor = ResolveComponentColor(tower.BearingComponentInstanceId, bearingMap), + BaseColor = ResolveComponentColor(tower.BaseComponentInstanceId, baseMap) + } }; } @@ -362,5 +374,21 @@ namespace GeometryTD.UI Icon = null }; } + + private static Color ResolveComponentColor(long instanceId, + IReadOnlyDictionary componentMap) + where TComp : TowerCompItemData + { + if (instanceId > 0 && + componentMap != null && + componentMap.TryGetValue(instanceId, out TComp component) && + component != null) + { + return IconColorGenerator.GenerateForComponent(component); + } + + return Color.white; + } } } + diff --git a/Assets/GameMain/Scripts/UI/Game/Controller/RepoFormController.cs b/Assets/GameMain/Scripts/UI/Game/Controller/RepoFormController.cs index 016cba0..c515806 100644 --- a/Assets/GameMain/Scripts/UI/Game/Controller/RepoFormController.cs +++ b/Assets/GameMain/Scripts/UI/Game/Controller/RepoFormController.cs @@ -11,9 +11,11 @@ namespace GeometryTD.UI { private const int MaxParticipantCount = 4; private RepoFormUseCase _useCase; - private readonly Dictionary _itemContextMap = new Dictionary(); + private readonly Dictionary _itemClickActionMap = + new Dictionary(); private readonly Dictionary _itemDescSeedMap = new Dictionary(); private readonly HashSet _participantTowerIds = new HashSet(); + private readonly HashSet _compAreaTowerIds = new HashSet(); private sealed class ItemDescSeed { @@ -111,14 +113,9 @@ namespace GeometryTD.UI } RepoItemClickActionType clickActionType = RepoItemClickActionType.OpenDetail; - if (sender is RepoItem clickedItem && clickedItem.Context != null) + if (_itemClickActionMap.TryGetValue(args.ItemId, out RepoItemClickActionType mappedAction)) { - clickActionType = clickedItem.Context.ClickActionType; - } - else if (_itemContextMap.TryGetValue(args.ItemId, out RepoItemContext itemContextFromMap) && - itemContextFromMap != null) - { - clickActionType = itemContextFromMap.ClickActionType; + clickActionType = mappedAction; } if (args.ItemId <= 0) @@ -170,7 +167,7 @@ namespace GeometryTD.UI return; } - if (Form == null || !_itemContextMap.ContainsKey(args.ItemId)) + if (Form == null || !_itemClickActionMap.ContainsKey(args.ItemId)) { return; } @@ -212,8 +209,8 @@ namespace GeometryTD.UI { return; } - - this.CloseUI(); + + CloseUI(); } private void OnRepoCombineRequested(object sender, GameEventArgs e) @@ -258,12 +255,12 @@ namespace GeometryTD.UI { return; } - + if (_useCase == null || Form == null || args.TowerItemId <= 0) { return; } - + if (!_useCase.TryAddParticipantTower(args.TowerItemId)) { return; diff --git a/Assets/GameMain/Scripts/UI/Game/UseCase/RepoFormUseCase.cs b/Assets/GameMain/Scripts/UI/Game/UseCase/RepoFormUseCase.cs index a15f1bf..e40b742 100644 --- a/Assets/GameMain/Scripts/UI/Game/UseCase/RepoFormUseCase.cs +++ b/Assets/GameMain/Scripts/UI/Game/UseCase/RepoFormUseCase.cs @@ -67,11 +67,6 @@ namespace GeometryTD.UI InventoryParticipantUtility.NormalizeParticipantState(_fallbackInventory, MaxParticipantCount); return _fallbackInventory; } - - public static BackpackInventoryData SampleInventory() - { - return InventorySeedUtility.CreateSampleInventory(); - } } } diff --git a/Assets/GameMain/Scripts/UI/Game/View/CombineArea.cs b/Assets/GameMain/Scripts/UI/Game/View/CombineArea.cs index 2e99f28..195510d 100644 --- a/Assets/GameMain/Scripts/UI/Game/View/CombineArea.cs +++ b/Assets/GameMain/Scripts/UI/Game/View/CombineArea.cs @@ -1,5 +1,5 @@ -using GeometryTD.Definition; using GeometryTD.CustomEvent; +using GeometryTD.Definition; using UnityEngine; using UnityEngine.EventSystems; @@ -102,19 +102,15 @@ namespace GeometryTD.UI return; } - RepoItem repoItem = pointerDrag.GetComponent(); - if (repoItem == null) - { - repoItem = pointerDrag.GetComponentInParent(); - } - - if (repoItem == null) + IRepoDragItemView dragItem = pointerDrag.GetComponent() ?? + pointerDrag.GetComponentInParent(); + if (dragItem == null) { return; } - bool assigned = TryAssignItem(repoItem.Context); - repoItem.SetDropResult(assigned); + bool assigned = TryAssignItem(dragItem.ComponentContext); + dragItem.SetDropResult(assigned); } private CombineSlotItem FindSlot(TowerCompSlotType slotType) diff --git a/Assets/GameMain/Scripts/UI/Game/View/CompArea.cs b/Assets/GameMain/Scripts/UI/Game/View/CompArea.cs index 8c734cd..a9abd90 100644 --- a/Assets/GameMain/Scripts/UI/Game/View/CompArea.cs +++ b/Assets/GameMain/Scripts/UI/Game/View/CompArea.cs @@ -11,12 +11,17 @@ namespace GeometryTD.UI { [FormerlySerializedAs("m_Content")] [SerializeField] private Transform _content; [FormerlySerializedAs("m_ItemTemplate")] [SerializeField] private RepoItem _itemTemplate; + [SerializeField] private TowerRepoItem _towerItemTemplate; [FormerlySerializedAs("m_InstancePoolCapacity")] [SerializeField] private int _instancePoolCapacity = 64; - private readonly List _activeItems = new List(); - private readonly Dictionary _itemMap = new Dictionary(); - private IObjectPool _itemPool; - private string _poolName; + private readonly List _activeComponentItems = new List(); + private readonly List _activeTowerItems = new List(); + private readonly Dictionary _componentItemMap = new Dictionary(); + private readonly Dictionary _towerItemMap = new Dictionary(); + private IObjectPool _componentItemPool; + private IObjectPool _towerItemPool; + private string _componentPoolName; + private string _towerPoolName; public void OnInit(CompAreaContext context) { @@ -29,31 +34,46 @@ namespace GeometryTD.UI EnsurePool(); OnReset(); - if (context.Items == null || context.Items.Length == 0) + if (context.ComponentItems != null) { - return; + foreach (RepoItemContext itemContext in context.ComponentItems) + { + RepoItem item = CreateOrSpawnComponentItem(); + if (item == null) + { + continue; + } + + item.gameObject.SetActive(true); + item.OnInit(itemContext); + _activeComponentItems.Add(item); + _componentItemMap[itemContext.InstanceId] = item; + } } - foreach (var itemContext in context.Items) + if (context.TowerItems != null) { - RepoItem item = CreateOrSpawnItem(); - if (item == null) + foreach (TowerRepoItemContext itemContext in context.TowerItems) { - continue; - } + TowerRepoItem item = CreateOrSpawnTowerItem(); + if (item == null) + { + continue; + } - item.gameObject.SetActive(true); - item.OnInit(itemContext); - _activeItems.Add(item); - _itemMap[itemContext.InstanceId] = item; + item.gameObject.SetActive(true); + item.OnInit(itemContext); + _activeTowerItems.Add(item); + _towerItemMap[itemContext.InstanceId] = item; + } } } public void OnReset() { - for (int i = _activeItems.Count - 1; i >= 0; i--) + for (int i = _activeComponentItems.Count - 1; i >= 0; i--) { - RepoItem item = _activeItems[i]; + RepoItem item = _activeComponentItems[i]; if (item == null) { continue; @@ -61,49 +81,102 @@ namespace GeometryTD.UI item.OnReset(); item.gameObject.SetActive(false); - _itemPool?.Unspawn(item); + _componentItemPool?.Unspawn(item); } - _activeItems.Clear(); - _itemMap.Clear(); + for (int i = _activeTowerItems.Count - 1; i >= 0; i--) + { + TowerRepoItem item = _activeTowerItems[i]; + if (item == null) + { + continue; + } + + item.OnReset(); + item.gameObject.SetActive(false); + _towerItemPool?.Unspawn(item); + } + + _activeComponentItems.Clear(); + _activeTowerItems.Clear(); + _componentItemMap.Clear(); + _towerItemMap.Clear(); } private void OnDestroy() { OnReset(); - _itemPool?.ReleaseAllUnused(); + _componentItemPool?.ReleaseAllUnused(); + _towerItemPool?.ReleaseAllUnused(); } private void EnsurePool() { - if (_itemPool != null) + if (_componentItemPool == null) { - return; + _componentPoolName = $"RepoItemPool_{GetInstanceID()}"; + _componentItemPool = + GameEntry.ObjectPool.CreateSingleSpawnObjectPool(_componentPoolName, + _instancePoolCapacity); } - _poolName = $"RepoItemPool_{GetInstanceID()}"; - _itemPool = GameEntry.ObjectPool.CreateSingleSpawnObjectPool(_poolName, _instancePoolCapacity); + if (_towerItemPool == null) + { + _towerPoolName = $"TowerRepoItemPool_{GetInstanceID()}"; + _towerItemPool = + GameEntry.ObjectPool.CreateSingleSpawnObjectPool(_towerPoolName, + _instancePoolCapacity); + } } - private RepoItem CreateOrSpawnItem() + private RepoItem CreateOrSpawnComponentItem() { - if (_itemPool == null) + if (_componentItemPool == null) { return null; } - RepoItemObject itemObject = _itemPool.Spawn(); + RepoItemObject itemObject = _componentItemPool.Spawn(); RepoItem item = itemObject != null ? (RepoItem)itemObject.Target : null; if (item == null) { if (_itemTemplate == null) { - Log.Warning("CompArea requires an item template."); + Log.Warning("CompArea requires a component item template."); return null; } item = Instantiate(_itemTemplate); - _itemPool.Register(RepoItemObject.Create(item), true); + _componentItemPool.Register(RepoItemObject.Create(item), true); + } + + if (_content != null) + { + item.transform.SetParent(_content, false); + } + + return item; + } + + private TowerRepoItem CreateOrSpawnTowerItem() + { + if (_towerItemPool == null) + { + return null; + } + + TowerRepoItemObject itemObject = _towerItemPool.Spawn(); + TowerRepoItem item = itemObject != null ? (TowerRepoItem)itemObject.Target : null; + if (item == null) + { + if (_towerItemTemplate == null) + { + Log.Warning("CompArea requires a tower item template."); + return null; + } + + item = Instantiate(_towerItemTemplate); + _towerItemPool.Register(TowerRepoItemObject.Create(item), true); } if (_content != null) @@ -116,12 +189,15 @@ namespace GeometryTD.UI public void SetItemSelected(long itemId, bool isSelected) { - if (!_itemMap.TryGetValue(itemId, out RepoItem item)) + if (_componentItemMap.TryGetValue(itemId, out RepoItem componentItem)) { - return; + componentItem.SetSelected(isSelected); } - item.SetSelected(isSelected); + if (_towerItemMap.TryGetValue(itemId, out TowerRepoItem towerItem)) + { + towerItem.SetSelected(isSelected); + } } } } diff --git a/Assets/GameMain/Scripts/UI/Game/View/IRepoDragItemView.cs b/Assets/GameMain/Scripts/UI/Game/View/IRepoDragItemView.cs new file mode 100644 index 0000000..f7d3018 --- /dev/null +++ b/Assets/GameMain/Scripts/UI/Game/View/IRepoDragItemView.cs @@ -0,0 +1,19 @@ +using GeometryTD.Definition; + +namespace GeometryTD.UI +{ + public interface IRepoDragItemView + { + long InstanceId { get; } + + bool CanDrag { get; } + + TowerCompSlotType ComponentSlotType { get; } + + RepoItemClickActionType ClickActionType { get; } + + RepoItemContext ComponentContext { get; } + + void SetDropResult(bool assigned); + } +} diff --git a/Assets/GameMain/Scripts/UI/Game/View/IRepoDragItemView.cs.meta b/Assets/GameMain/Scripts/UI/Game/View/IRepoDragItemView.cs.meta new file mode 100644 index 0000000..c55ca76 --- /dev/null +++ b/Assets/GameMain/Scripts/UI/Game/View/IRepoDragItemView.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 5cb3c8e275a9ba646a58a2656af31faa +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/GameMain/Scripts/UI/Game/View/ParticipantArea.cs b/Assets/GameMain/Scripts/UI/Game/View/ParticipantArea.cs index 2433976..a910399 100644 --- a/Assets/GameMain/Scripts/UI/Game/View/ParticipantArea.cs +++ b/Assets/GameMain/Scripts/UI/Game/View/ParticipantArea.cs @@ -12,12 +12,12 @@ namespace GeometryTD.UI public class ParticipantArea : MonoBehaviour, IDropHandler { [SerializeField] private Transform _content; - [SerializeField] private RepoItem _itemTemplate; + [SerializeField] private TowerRepoItem _towerItemTemplate; [SerializeField] private int _instancePoolCapacity = 8; - private readonly List _activeItems = new List(); + private readonly List _activeItems = new List(); private readonly HashSet _boundItemIds = new HashSet(); - private IObjectPool _itemPool; + private IObjectPool _itemPool; private string _poolName; private int _maxCount = 4; @@ -27,20 +27,20 @@ namespace GeometryTD.UI EnsurePool(); _maxCount = Mathf.Max(1, context != null ? context.MaxCount : 4); - if (context?.Items == null || context.Items.Length <= 0) + if (context?.TowerItems == null || context.TowerItems.Length <= 0) { return; } - for (int i = 0; i < context.Items.Length; i++) + for (int i = 0; i < context.TowerItems.Length; i++) { - RepoItemContext itemContext = context.Items[i]; + TowerRepoItemContext itemContext = context.TowerItems[i]; if (itemContext == null || itemContext.InstanceId <= 0) { continue; } - RepoItem item = CreateOrSpawnItem(); + TowerRepoItem item = CreateOrSpawnItem(); if (item == null) { continue; @@ -57,7 +57,7 @@ namespace GeometryTD.UI { for (int i = _activeItems.Count - 1; i >= 0; i--) { - RepoItem item = _activeItems[i]; + TowerRepoItem item = _activeItems[i]; if (item == null) { continue; @@ -79,19 +79,19 @@ namespace GeometryTD.UI _itemPool?.ReleaseAllUnused(); } - public bool CanAssign(RepoItemContext itemContext) + public bool CanAssign(IRepoDragItemView dragItem) { - if (itemContext == null || itemContext.InstanceId <= 0) + if (dragItem == null || dragItem.InstanceId <= 0) { return false; } - if (itemContext.ComponentSlotType != TowerCompSlotType.None) + if (dragItem.ComponentSlotType != TowerCompSlotType.None) { return false; } - if (_boundItemIds.Contains(itemContext.InstanceId)) + if (_boundItemIds.Contains(dragItem.InstanceId)) { return false; } @@ -117,21 +117,21 @@ namespace GeometryTD.UI return; } - RepoItem repoItem = pointerDrag.GetComponent() ?? pointerDrag.GetComponentInParent(); - if (repoItem == null) + IRepoDragItemView dragItem = pointerDrag.GetComponent() ?? + pointerDrag.GetComponentInParent(); + if (dragItem == null) { return; } - RepoItemContext itemContext = repoItem.Context; - bool assigned = CanAssign(itemContext); - repoItem.SetDropResult(assigned); + bool assigned = CanAssign(dragItem); + dragItem.SetDropResult(assigned); if (!assigned) { return; } - GameEntry.Event.Fire(this, RepoParticipantAssignRequestedEventArgs.Create(itemContext.InstanceId)); + GameEntry.Event.Fire(this, RepoParticipantAssignRequestedEventArgs.Create(dragItem.InstanceId)); } private void EnsurePool() @@ -141,29 +141,30 @@ namespace GeometryTD.UI return; } - _poolName = $"ParticipantRepoItemPool_{GetInstanceID()}"; - _itemPool = GameEntry.ObjectPool.CreateSingleSpawnObjectPool(_poolName, _instancePoolCapacity); + _poolName = $"ParticipantTowerRepoItemPool_{GetInstanceID()}"; + _itemPool = + GameEntry.ObjectPool.CreateSingleSpawnObjectPool(_poolName, _instancePoolCapacity); } - private RepoItem CreateOrSpawnItem() + private TowerRepoItem CreateOrSpawnItem() { if (_itemPool == null) { return null; } - RepoItemObject itemObject = _itemPool.Spawn(); - RepoItem item = itemObject != null ? (RepoItem)itemObject.Target : null; + TowerRepoItemObject itemObject = _itemPool.Spawn(); + TowerRepoItem item = itemObject != null ? (TowerRepoItem)itemObject.Target : null; if (item == null) { - if (_itemTemplate == null) + if (_towerItemTemplate == null) { - Log.Warning("ParticipantArea requires an item template."); + Log.Warning("ParticipantArea requires a tower item template."); return null; } - item = Instantiate(_itemTemplate); - _itemPool.Register(RepoItemObject.Create(item), true); + item = Instantiate(_towerItemTemplate); + _itemPool.Register(TowerRepoItemObject.Create(item), true); } if (_content != null) diff --git a/Assets/GameMain/Scripts/UI/Game/View/RepoItem.cs b/Assets/GameMain/Scripts/UI/Game/View/RepoItem.cs index ddf0131..88f5e70 100644 --- a/Assets/GameMain/Scripts/UI/Game/View/RepoItem.cs +++ b/Assets/GameMain/Scripts/UI/Game/View/RepoItem.cs @@ -6,10 +6,10 @@ using UnityEngine.UI; namespace GeometryTD.UI { - public class RepoItem : MonoBehaviour, IBeginDragHandler, IDragHandler, IEndDragHandler + public class RepoItem : MonoBehaviour, IBeginDragHandler, IDragHandler, IEndDragHandler, IRepoDragItemView { [SerializeField] private Image _bgImage; - + [SerializeField] private IconArea _iconArea; private static readonly Color SelectedColor = new Color32(255, 216, 102, 255); @@ -20,8 +20,8 @@ namespace GeometryTD.UI [SerializeField] private RepoItemContext _context; private CanvasGroup _canvasGroup; private RectTransform _dragRoot; - private GameObject _dragGhostObject; - private RectTransform _dragGhostRect; + protected GameObject _dragGhostObject; + protected RectTransform _dragGhostRect; private bool _isSelected; private bool _isDragging; private bool _dropHandled; @@ -29,6 +29,24 @@ namespace GeometryTD.UI public RepoItemContext Context => _context; + public long InstanceId => _context != null ? _context.InstanceId : 0; + + bool IRepoDragItemView.CanDrag => _context != null && _context.CanDrag; + + public TowerCompSlotType ComponentSlotType => + _context != null ? _context.ComponentSlotType : TowerCompSlotType.None; + + public RepoItemClickActionType ClickActionType => + _context != null ? _context.ClickActionType : RepoItemClickActionType.OpenDetail; + + public RepoItemContext ComponentContext => _context; + + protected IconArea IconArea => _iconArea; + + protected Image BackgroundImage => _bgImage; + + protected RectTransform DragRoot => _dragRoot; + private void Awake() { _canvasGroup = GetComponent(); @@ -43,7 +61,7 @@ namespace GeometryTD.UI ResetDragState(); } - public void OnInit(RepoItemContext context) + public virtual void OnInit(RepoItemContext context) { if (context == null) { @@ -52,14 +70,13 @@ namespace GeometryTD.UI } _context = context; - _iconArea.OnInit(context.IconAreaContext); SetSelected(false); ResetDragState(); } - public void OnReset() + public virtual void OnReset() { _context = null; _iconArea.OnReset(); @@ -165,6 +182,7 @@ namespace GeometryTD.UI { _canvasGroup.blocksRaycasts = true; } + DestroyDragGhost(); _dragRoot = null; @@ -232,7 +250,7 @@ namespace GeometryTD.UI return canvas.rootCanvas.transform as RectTransform; } - private bool CreateDragGhost() + protected virtual bool CreateDragGhost() { DestroyDragGhost(); @@ -246,7 +264,6 @@ namespace GeometryTD.UI 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; @@ -260,7 +277,8 @@ namespace GeometryTD.UI return false; } - _dragGhostObject = new GameObject("RepoItemDragGhost", typeof(RectTransform), typeof(CanvasGroup), typeof(Image)); + _dragGhostObject = new GameObject("RepoItemDragGhost", typeof(RectTransform), typeof(CanvasGroup), + typeof(Image)); _dragGhostObject.layer = gameObject.layer; _dragGhostRect = _dragGhostObject.GetComponent(); @@ -273,6 +291,7 @@ namespace GeometryTD.UI { iconSize = DefaultDragGhostSize; } + _dragGhostRect.sizeDelta = iconSize; Image ghostImage = _dragGhostObject.GetComponent(); @@ -290,7 +309,7 @@ namespace GeometryTD.UI return true; } - private void UpdateDragGhostPosition(PointerEventData eventData) + protected virtual void UpdateDragGhostPosition(PointerEventData eventData) { if (_dragGhostRect == null || _dragRoot == null || eventData == null) { @@ -304,7 +323,7 @@ namespace GeometryTD.UI } } - private void DestroyDragGhost() + protected virtual void DestroyDragGhost() { if (_dragGhostObject != null) { @@ -329,3 +348,4 @@ namespace GeometryTD.UI } } } + diff --git a/Assets/GameMain/Scripts/UI/Game/View/TowerRepoItem.cs b/Assets/GameMain/Scripts/UI/Game/View/TowerRepoItem.cs new file mode 100644 index 0000000..3648827 --- /dev/null +++ b/Assets/GameMain/Scripts/UI/Game/View/TowerRepoItem.cs @@ -0,0 +1,109 @@ +using UnityEngine; +using UnityEngine.UI; + +namespace GeometryTD.UI +{ + public class TowerRepoItem : RepoItem + { + private static readonly Vector2 DefaultTowerDragGhostSize = new Vector2(64f, 64f); + + public new TowerRepoItemContext Context => base.Context as TowerRepoItemContext; + + public void OnInit(TowerRepoItemContext context) + { + base.OnInit(context); + } + + protected override bool CreateDragGhost() + { + DestroyDragGhost(); + + if (DragRoot == null) + { + return false; + } + + TowerIconArea towerIconArea = IconArea as TowerIconArea; + if (towerIconArea == null) + { + return base.CreateDragGhost(); + } + + _dragGhostObject = new GameObject("TowerRepoItemDragGhost", typeof(RectTransform), typeof(CanvasGroup)); + _dragGhostObject.layer = gameObject.layer; + + _dragGhostRect = _dragGhostObject.GetComponent(); + _dragGhostRect.SetParent(DragRoot, false); + _dragGhostRect.anchorMin = new Vector2(0.5f, 0.5f); + _dragGhostRect.anchorMax = new Vector2(0.5f, 0.5f); + _dragGhostRect.pivot = new Vector2(0.5f, 0.5f); + + Vector2 iconSize = IconArea != null ? IconArea.CurrentIconSize : Vector2.zero; + if (iconSize.x <= 0f || iconSize.y <= 0f) + { + iconSize = BackgroundImage != null ? BackgroundImage.rectTransform.rect.size : DefaultTowerDragGhostSize; + } + + if (iconSize.x <= 0f || iconSize.y <= 0f) + { + iconSize = DefaultTowerDragGhostSize; + } + + _dragGhostRect.sizeDelta = iconSize; + + bool hasAnyLayer = false; + hasAnyLayer |= TryCreateLayer("Base", towerIconArea.BaseIconSprite, towerIconArea.BaseIconColor, + towerIconArea.BaseIconMaterial, _dragGhostRect, 0); + hasAnyLayer |= TryCreateLayer("Bearing", towerIconArea.BearingIconSprite, towerIconArea.BearingIconColor, + towerIconArea.BearingIconMaterial, _dragGhostRect, 1); + hasAnyLayer |= TryCreateLayer("Muzzle", towerIconArea.MuzzleIconSprite, towerIconArea.MuzzleIconColor, + towerIconArea.MuzzleIconMaterial, _dragGhostRect, 2); + + if (!hasAnyLayer) + { + DestroyDragGhost(); + return base.CreateDragGhost(); + } + + CanvasGroup ghostCanvasGroup = _dragGhostObject.GetComponent(); + ghostCanvasGroup.blocksRaycasts = false; + ghostCanvasGroup.interactable = false; + + _dragGhostObject.transform.SetAsLastSibling(); + return true; + } + + private static bool TryCreateLayer( + string layerName, + Sprite sprite, + Color color, + Material material, + RectTransform parent, + int siblingIndex) + { + if (parent == null || sprite == null) + { + return false; + } + + GameObject layerObject = new GameObject($"TowerGhost{layerName}", typeof(RectTransform), typeof(Image)); + layerObject.layer = parent.gameObject.layer; + + RectTransform layerRect = layerObject.GetComponent(); + layerRect.SetParent(parent, false); + layerRect.anchorMin = Vector2.zero; + layerRect.anchorMax = Vector2.one; + layerRect.offsetMin = Vector2.zero; + layerRect.offsetMax = Vector2.zero; + layerRect.SetSiblingIndex(siblingIndex); + + Image layerImage = layerObject.GetComponent(); + layerImage.raycastTarget = false; + layerImage.sprite = sprite; + layerImage.color = color; + layerImage.material = material; + layerImage.preserveAspect = true; + return true; + } + } +} diff --git a/Assets/GameMain/Scripts/UI/Game/View/TowerRepoItem.cs.meta b/Assets/GameMain/Scripts/UI/Game/View/TowerRepoItem.cs.meta new file mode 100644 index 0000000..065d2bd --- /dev/null +++ b/Assets/GameMain/Scripts/UI/Game/View/TowerRepoItem.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: caf7b65cc179a5d46828128f574ed63e +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/GameMain/Scripts/UI/General/Context/TowerIconAreaContext.cs b/Assets/GameMain/Scripts/UI/General/Context/TowerIconAreaContext.cs new file mode 100644 index 0000000..a3c2da3 --- /dev/null +++ b/Assets/GameMain/Scripts/UI/General/Context/TowerIconAreaContext.cs @@ -0,0 +1,21 @@ +using System; +using GeometryTD.Definition; +using UnityEngine; + +namespace GeometryTD.UI +{ + [Serializable] + public class TowerIconAreaContext : IconAreaContext + { + public Color MuzzleColor = Color.white; + public Color BearingColor = Color.white; + public Color BaseColor = Color.white; + + public TowerIconAreaContext() + { + ComponentSlotType = TowerCompSlotType.None; + Color = Color.white; + Icon = null; + } + } +} diff --git a/Assets/GameMain/Scripts/UI/General/Context/TowerIconAreaContext.cs.meta b/Assets/GameMain/Scripts/UI/General/Context/TowerIconAreaContext.cs.meta new file mode 100644 index 0000000..76b3901 --- /dev/null +++ b/Assets/GameMain/Scripts/UI/General/Context/TowerIconAreaContext.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: e3576597006db5b458566429f98a6f43 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/GameMain/Scripts/UI/General/View/IconArea.cs b/Assets/GameMain/Scripts/UI/General/View/IconArea.cs index 0d04888..ba73959 100644 --- a/Assets/GameMain/Scripts/UI/General/View/IconArea.cs +++ b/Assets/GameMain/Scripts/UI/General/View/IconArea.cs @@ -1,4 +1,3 @@ -using System; using GeometryTD.Definition; using UnityEngine; using UnityEngine.UI; @@ -14,15 +13,17 @@ namespace GeometryTD.UI private IconAreaContext _context; - public Sprite CurrentIconSprite => _icon != null ? _icon.sprite : null; + public virtual Sprite CurrentIconSprite => _icon != null ? _icon.sprite : null; - public Color CurrentIconColor => _icon != null ? _icon.color : Color.white; + public virtual Color CurrentIconColor => _icon != null ? _icon.color : Color.white; - public Vector2 CurrentIconSize => _icon != null ? _icon.rectTransform.rect.size : Vector2.zero; + public virtual Vector2 CurrentIconSize => _icon != null ? _icon.rectTransform.rect.size : Vector2.zero; - public Material CurrentIconMaterial => _icon != null ? _icon.material : null; + public virtual Material CurrentIconMaterial => _icon != null ? _icon.material : null; - public void OnInit(IconAreaContext context) + public virtual RectTransform IconRectTransform => _icon != null ? _icon.rectTransform : null; + + public virtual void OnInit(IconAreaContext context) { if (context == null) { @@ -46,9 +47,10 @@ namespace GeometryTD.UI SetRarity(_context.Rarity); SetIconColor(_context.Color); + SetIconVisible(true); } - public void SetIcon(Sprite sprite) + public virtual void SetIcon(Sprite sprite) { if (_icon != null) { @@ -56,7 +58,7 @@ namespace GeometryTD.UI } } - public void SetRarity(RarityType rarity) + public virtual void SetRarity(RarityType rarity) { if (_board == null) { @@ -74,7 +76,7 @@ namespace GeometryTD.UI }; } - public void SetIconColor(Color color) + public virtual void SetIconColor(Color color) { if (_icon == null) { @@ -84,11 +86,20 @@ namespace GeometryTD.UI _icon.color = color; } - public void OnReset() + public virtual void SetIconVisible(bool visible) + { + if (_icon != null) + { + _icon.enabled = visible; + } + } + + public virtual void OnReset() { SetIcon(null); SetRarity(RarityType.None); SetIconColor(Color.clear); + SetIconVisible(true); } } } diff --git a/Assets/GameMain/Scripts/UI/General/View/TowerIconArea.cs b/Assets/GameMain/Scripts/UI/General/View/TowerIconArea.cs new file mode 100644 index 0000000..0d339f2 --- /dev/null +++ b/Assets/GameMain/Scripts/UI/General/View/TowerIconArea.cs @@ -0,0 +1,72 @@ +using UnityEngine; +using UnityEngine.UI; + +namespace GeometryTD.UI +{ + public class TowerIconArea : IconArea + { + [SerializeField] private Image _baseIcon; + + [SerializeField] private Image _bearingIcon; + + [SerializeField] private Image _muzzleIcon; + + public Sprite BaseIconSprite => _baseIcon != null ? _baseIcon.sprite : null; + + public Sprite BearingIconSprite => _bearingIcon != null ? _bearingIcon.sprite : null; + + public Sprite MuzzleIconSprite => _muzzleIcon != null ? _muzzleIcon.sprite : null; + + public Color BaseIconColor => _baseIcon != null ? _baseIcon.color : Color.white; + + public Color BearingIconColor => _bearingIcon != null ? _bearingIcon.color : Color.white; + + public Color MuzzleIconColor => _muzzleIcon != null ? _muzzleIcon.color : Color.white; + + public Material BaseIconMaterial => _baseIcon != null ? _baseIcon.material : null; + + public Material BearingIconMaterial => _bearingIcon != null ? _bearingIcon.material : null; + + public Material MuzzleIconMaterial => _muzzleIcon != null ? _muzzleIcon.material : null; + + public override void OnInit(IconAreaContext context) + { + if (!(context is TowerIconAreaContext towerContext)) + { + base.OnInit(context); + return; + } + + SetRarity(towerContext.Rarity); + SetIconVisible(false); + + SetLayerColor(_baseIcon, towerContext.BaseColor); + SetLayerColor(_bearingIcon, towerContext.BearingColor); + SetLayerColor(_muzzleIcon, towerContext.MuzzleColor); + } + + public void OnInit(TowerIconAreaContext context) + { + OnInit((IconAreaContext)context); + } + + public override void OnReset() + { + base.OnReset(); + SetLayerColor(_baseIcon, Color.clear); + SetLayerColor(_bearingIcon, Color.clear); + SetLayerColor(_muzzleIcon, Color.clear); + SetIconVisible(false); + } + + private static void SetLayerColor(Image icon, Color color) + { + if (icon == null) + { + return; + } + + icon.color = color; + } + } +} diff --git a/Assets/GameMain/Scripts/UI/General/View/TowerIconArea.cs.meta b/Assets/GameMain/Scripts/UI/General/View/TowerIconArea.cs.meta new file mode 100644 index 0000000..fa3e6a4 --- /dev/null +++ b/Assets/GameMain/Scripts/UI/General/View/TowerIconArea.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 33a1436bff53c844e858f3bced1565ca +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/GameMain/Scripts/UI/General/IconColorGenerator.cs b/Assets/GameMain/Scripts/Utility/IconColorGenerator.cs similarity index 100% rename from Assets/GameMain/Scripts/UI/General/IconColorGenerator.cs rename to Assets/GameMain/Scripts/Utility/IconColorGenerator.cs diff --git a/Assets/GameMain/Scripts/UI/General/IconColorGenerator.cs.meta b/Assets/GameMain/Scripts/Utility/IconColorGenerator.cs.meta similarity index 100% rename from Assets/GameMain/Scripts/UI/General/IconColorGenerator.cs.meta rename to Assets/GameMain/Scripts/Utility/IconColorGenerator.cs.meta diff --git a/Assets/GameMain/Scripts/Utility/InventoryCloneUtility.cs b/Assets/GameMain/Scripts/Utility/InventoryCloneUtility.cs index 35a1652..a281889 100644 --- a/Assets/GameMain/Scripts/Utility/InventoryCloneUtility.cs +++ b/Assets/GameMain/Scripts/Utility/InventoryCloneUtility.cs @@ -1,4 +1,4 @@ -using System; +using System; using GeometryTD.Definition; using UnityEngine; @@ -162,7 +162,9 @@ namespace GeometryTD.CustomUtility MuzzleComponentInstanceId = source.MuzzleComponentInstanceId, BearingComponentInstanceId = source.BearingComponentInstanceId, BaseComponentInstanceId = source.BaseComponentInstanceId, - Stats = CloneTowerStats(source.Stats) + Stats = CloneTowerStats(source.Stats), + ComposedIconSprite = source.ComposedIconSprite, + ComposedIconKey = source.ComposedIconKey }; } @@ -205,3 +207,4 @@ namespace GeometryTD.CustomUtility } + diff --git a/Assets/GameMain/Scripts/Utility/InventorySeedUtility.cs b/Assets/GameMain/Scripts/Utility/InventorySeedUtility.cs index b4d7388..8938d27 100644 --- a/Assets/GameMain/Scripts/Utility/InventorySeedUtility.cs +++ b/Assets/GameMain/Scripts/Utility/InventorySeedUtility.cs @@ -19,41 +19,12 @@ namespace GeometryTD.CustomUtility Rarity = RarityType.Green, Endurance = 90f, IsAssembledIntoTower = true, - AttackDamage = new[] { 20, 30, 40, 50, 80 }, + AttackDamage = new[] { 200, 300, 400, 500, 800 }, DamageRandomRate = 0.05f, AttackMethodType = AttackMethodType.NormalBullet, Constraint = string.Empty, Tags = new[] { TagType.Fire } }; - inventory.MuzzleComponents.Add(muzzle); - inventory.MuzzleComponents.Add(new MuzzleCompItemData - { - InstanceId = 10002, - ConfigId = 2, - Name = "控制枪口", - Rarity = RarityType.Blue, - Endurance = 80, - IsAssembledIntoTower = false, - AttackDamage = new[] { 30, 50, 70, 90, 100 }, - DamageRandomRate = 0.01f, - AttackMethodType = AttackMethodType.NormalBullet, - Constraint = string.Empty, - Tags = new[] { TagType.Ice, TagType.FreezeMask } - }); - inventory.MuzzleComponents.Add(new MuzzleCompItemData - { - InstanceId = 10003, - ConfigId = 3, - Name = "穿透枪口", - Rarity = RarityType.Purple, - Endurance = 97f, - IsAssembledIntoTower = false, - AttackDamage = new[] { 50, 55, 60, 80, 90 }, - DamageRandomRate = 0.02f, - AttackMethodType = AttackMethodType.NormalBullet, - Constraint = string.Empty, - Tags = new[] { TagType.Pierce, TagType.Crit } - }); BearingCompItemData bearing = new BearingCompItemData { @@ -63,38 +34,11 @@ namespace GeometryTD.CustomUtility Rarity = RarityType.Green, Endurance = 1f, IsAssembledIntoTower = true, - RotateSpeed = new[] { 10f, 12f, 13f, 14f, 15f }, - AttackRange = new[] { 2f, 2f, 2f, 2f, 2f }, + RotateSpeed = new[] { 100f, 120f, 130f, 140f, 150f }, + AttackRange = new[] { 3f, 4f, 5f, 6f, 8f }, Constraint = string.Empty, Tags = new[] { TagType.Fire } }; - inventory.BearingComponents.Add(bearing); - inventory.BearingComponents.Add(new BearingCompItemData - { - InstanceId = 20002, - ConfigId = 2, - Name = "控制轴承", - Rarity = RarityType.Blue, - Endurance = 20, - IsAssembledIntoTower = false, - RotateSpeed = new[] { 20f, 25f, 30f, 32f, 35f }, - AttackRange = new[] { 6f, 6.5f, 7f, 8f, 8f }, - Constraint = string.Empty, - Tags = new[] { TagType.Ice, TagType.Shatter } - }); - inventory.BearingComponents.Add(new BearingCompItemData - { - InstanceId = 20003, - ConfigId = 3, - Name = "穿透轴承", - Rarity = RarityType.Purple, - Endurance = 96f, - IsAssembledIntoTower = false, - RotateSpeed = new[] { 60f, 70f, 80f, 90f, 100f }, - AttackRange = new[] { 4f, 4.5f, 5f, 5.5f, 6f }, - Constraint = string.Empty, - Tags = new[] { TagType.Pierce, TagType.Overpenetrate } - }); BaseCompItemData baseComp = new BaseCompItemData { @@ -104,38 +48,11 @@ namespace GeometryTD.CustomUtility Rarity = RarityType.Green, Endurance = 88f, IsAssembledIntoTower = true, - AttackSpeed = new[] { 2f, 1.5f, 1f, 0.8f, 0.7f }, + AttackSpeed = new[] { 1f, 2f, 3f, 3.5f, 0.7f }, AttackPropertyType = AttackPropertyType.Fire, Constraint = string.Empty, Tags = new[] { TagType.Fire } }; - inventory.BaseComponents.Add(baseComp); - inventory.BaseComponents.Add(new BaseCompItemData - { - InstanceId = 30002, - ConfigId = 2, - Name = "控制底座", - Rarity = RarityType.Blue, - Endurance = 50f, - IsAssembledIntoTower = false, - AttackSpeed = new[] { 4f, 4.2f, 4.4f, 4.6f, 4.8f }, - AttackPropertyType = AttackPropertyType.Ice, - Constraint = string.Empty, - Tags = new[] { TagType.Ice, TagType.AbsoluteZero } - }); - inventory.BaseComponents.Add(new BaseCompItemData - { - InstanceId = 30003, - ConfigId = 3, - Name = "穿透底座", - Rarity = RarityType.Purple, - Endurance = 30f, - IsAssembledIntoTower = false, - AttackSpeed = new[] { 1f, 1f, 1f, 1f, 1f }, - AttackPropertyType = AttackPropertyType.Physics, - Constraint = string.Empty, - Tags = new[] { TagType.Pierce, TagType.Execution } - }); TowerItemData tower = new TowerItemData { @@ -151,35 +68,103 @@ namespace GeometryTD.CustomUtility AttackDamage = new[] { 200, 220, 240, 260, 300 }, DamageRandomRate = 0f, RotateSpeed = new[] { 200f, 210f, 220f, 230f, 240f }, - AttackRange = new[] { 4.5f, 4.7f, 4.9f, 5.1f, 5.3f }, - AttackSpeed = new[] { 1.5f, 1.2f, 1.1f, 1.0f, 0.8f }, + AttackRange = new[] { 4.5f, 4.5f, 4.5f, 4.5f, 4.5f }, + AttackSpeed = new[] { 1.0f, 1.2f, 1.3f, 1.4f, 0.5f }, AttackMethodType = AttackMethodType.NormalBullet, AttackPropertyType = AttackPropertyType.Fire, Tags = new[] { TagType.Fire, TagType.BurnSpread } } }; + + inventory.MuzzleComponents.Add(muzzle); + inventory.BaseComponents.Add(baseComp); + inventory.BearingComponents.Add(bearing); inventory.Towers.Add(tower); - inventory.Towers.Add(new TowerItemData + inventory.MuzzleComponents.Add(new MuzzleCompItemData { - InstanceId = 90002, - Name = "测试防御塔-B", + InstanceId = 10002, + ConfigId = 2, + Name = "控制枪口", Rarity = RarityType.Blue, - IsParticipatingInCombat = false, - MuzzleComponentInstanceId = 0, - BearingComponentInstanceId = 0, - BaseComponentInstanceId = 0, - Stats = new TowerStatsData - { - AttackDamage = new[] { 200, 220, 240, 260, 300 }, - DamageRandomRate = 0.1f, - RotateSpeed = new[] { 200f, 210f, 220f, 230f, 240f }, - AttackRange = new[] { 4.5f, 4.7f, 4.9f, 5.1f, 5.3f }, - AttackSpeed = new[] { 1.5f, 1.2f, 1.1f, 1.0f, 0.8f }, - AttackMethodType = AttackMethodType.NormalBullet, - AttackPropertyType = AttackPropertyType.Physics, - Tags = new[] { TagType.Pierce } - } + Endurance = 80, + IsAssembledIntoTower = false, + AttackDamage = new[] { 200, 300, 400, 500, 600 }, + DamageRandomRate = 0.01f, + AttackMethodType = AttackMethodType.NormalBullet, + Constraint = string.Empty, + Tags = new[] { TagType.Ice, TagType.FreezeMask } + }); + + inventory.MuzzleComponents.Add(new MuzzleCompItemData + { + InstanceId = 10003, + ConfigId = 3, + Name = "穿透枪口", + Rarity = RarityType.Purple, + Endurance = 97f, + IsAssembledIntoTower = false, + AttackDamage = new[] { 50, 55, 60, 80, 90 }, + DamageRandomRate = 0.02f, + AttackMethodType = AttackMethodType.NormalBullet, + Constraint = string.Empty, + Tags = new[] { TagType.Pierce, TagType.Crit } + }); + + inventory.BearingComponents.Add(new BearingCompItemData + { + InstanceId = 20002, + ConfigId = 2, + Name = "控制轴承", + Rarity = RarityType.Blue, + Endurance = 20, + IsAssembledIntoTower = false, + RotateSpeed = new[] { 200f, 250f, 300f, 320f, 350f }, + AttackRange = new[] { 6f, 6.5f, 7f, 8f, 8f }, + Constraint = string.Empty, + Tags = new[] { TagType.Ice, TagType.Shatter } + }); + + inventory.BearingComponents.Add(new BearingCompItemData + { + InstanceId = 20003, + ConfigId = 3, + Name = "穿透轴承", + Rarity = RarityType.Purple, + Endurance = 96f, + IsAssembledIntoTower = false, + RotateSpeed = new[] { 60f, 70f, 80f, 90f, 100f }, + AttackRange = new[] { 4f, 4.5f, 5f, 5.5f, 6f }, + Constraint = string.Empty, + Tags = new[] { TagType.Pierce, TagType.Overpenetrate } + }); + + inventory.BaseComponents.Add(new BaseCompItemData + { + InstanceId = 30002, + ConfigId = 2, + Name = "控制底座", + Rarity = RarityType.Blue, + Endurance = 50f, + IsAssembledIntoTower = false, + AttackSpeed = new[] { 4f, 4.2f, 4.4f, 4.6f, 4.8f }, + AttackPropertyType = AttackPropertyType.Ice, + Constraint = string.Empty, + Tags = new[] { TagType.Ice, TagType.AbsoluteZero } + }); + + inventory.BaseComponents.Add(new BaseCompItemData + { + InstanceId = 30003, + ConfigId = 3, + Name = "穿透底座", + Rarity = RarityType.Purple, + Endurance = 30f, + IsAssembledIntoTower = false, + AttackSpeed = new[] { 1f, 1f, 1f, 1f, 1f }, + AttackPropertyType = AttackPropertyType.Physics, + Constraint = string.Empty, + Tags = new[] { TagType.Pierce, TagType.Execution } }); inventory.ParticipantTowerInstanceIds.Add(90001); diff --git a/Assets/GameMain/Scripts/Utility/TowerComposedIconCacheUtility.cs b/Assets/GameMain/Scripts/Utility/TowerComposedIconCacheUtility.cs new file mode 100644 index 0000000..480147a --- /dev/null +++ b/Assets/GameMain/Scripts/Utility/TowerComposedIconCacheUtility.cs @@ -0,0 +1,130 @@ +using System.Collections.Generic; +using GeometryTD.Definition; +using UnityEngine; + +namespace GeometryTD.CustomUtility +{ + public static class TowerComposedIconCacheUtility + { + private const string MuzzleAssetName = "Muzzle"; + private const string BearingAssetName = "Bearing"; + private const string BaseAssetName = "Base"; + + private static Sprite _muzzleSprite; + private static Sprite _bearingSprite; + private static Sprite _baseSprite; + private static bool s_RequestedMuzzle; + private static bool s_RequestedBearing; + private static bool s_RequestedBase; + + public static Sprite ResolveTowerIconSprite( + TowerItemData tower, + IReadOnlyDictionary muzzleMap, + IReadOnlyDictionary bearingMap, + IReadOnlyDictionary baseMap) + { + if (tower == null) + { + return null; + } + + if (!TryGetComponents(tower, muzzleMap, bearingMap, baseMap, + out MuzzleCompItemData muzzleComp, + out BearingCompItemData bearingComp, + out BaseCompItemData baseComp)) + { + return null; + } + + Color muzzleColor = IconColorGenerator.GenerateForComponent(muzzleComp); + Color bearingColor = IconColorGenerator.GenerateForComponent(bearingComp); + Color baseColor = IconColorGenerator.GenerateForComponent(baseComp); + + string cacheKey = TowerIconComposeUtility.BuildCacheKey( + tower.MuzzleComponentInstanceId, + tower.BearingComponentInstanceId, + tower.BaseComponentInstanceId, + muzzleColor, + bearingColor, + baseColor); + + if (tower.ComposedIconSprite != null && string.Equals(tower.ComposedIconKey, cacheKey)) + { + return tower.ComposedIconSprite; + } + + EnsureBaseSpritesRequested(); + if (_muzzleSprite == null || _bearingSprite == null || _baseSprite == null) + { + return null; + } + + Sprite composedSprite = TowerIconComposeUtility.Compose( + _muzzleSprite, + muzzleColor, + _bearingSprite, + bearingColor, + _baseSprite, + baseColor); + + if (composedSprite == null) + { + return null; + } + + tower.ComposedIconSprite = composedSprite; + tower.ComposedIconKey = cacheKey; + return composedSprite; + } + + private static bool TryGetComponents( + TowerItemData tower, + IReadOnlyDictionary muzzleMap, + IReadOnlyDictionary bearingMap, + IReadOnlyDictionary baseMap, + out MuzzleCompItemData muzzleComp, + out BearingCompItemData bearingComp, + out BaseCompItemData baseComp) + { + muzzleComp = null; + bearingComp = null; + baseComp = null; + + if (tower == null || muzzleMap == null || bearingMap == null || baseMap == null) + { + return false; + } + + return muzzleMap.TryGetValue(tower.MuzzleComponentInstanceId, out muzzleComp) && + bearingMap.TryGetValue(tower.BearingComponentInstanceId, out bearingComp) && + baseMap.TryGetValue(tower.BaseComponentInstanceId, out baseComp) && + muzzleComp != null && bearingComp != null && baseComp != null; + } + + private static void EnsureBaseSpritesRequested() + { + if (GameEntry.SpriteCache == null) + { + return; + } + + if (!s_RequestedMuzzle) + { + s_RequestedMuzzle = true; + GameEntry.SpriteCache.GetSprite(MuzzleAssetName, sprite => { _muzzleSprite = sprite; }); + } + + if (!s_RequestedBearing) + { + s_RequestedBearing = true; + GameEntry.SpriteCache.GetSprite(BearingAssetName, sprite => { _bearingSprite = sprite; }); + } + + if (!s_RequestedBase) + { + s_RequestedBase = true; + GameEntry.SpriteCache.GetSprite(BaseAssetName, sprite => { _baseSprite = sprite; }); + } + } + } +} diff --git a/Assets/GameMain/Scripts/Utility/TowerComposedIconCacheUtility.cs.meta b/Assets/GameMain/Scripts/Utility/TowerComposedIconCacheUtility.cs.meta new file mode 100644 index 0000000..80d1ad8 --- /dev/null +++ b/Assets/GameMain/Scripts/Utility/TowerComposedIconCacheUtility.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: a705ccdd02d2d3440934d4ab06228547 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/GameMain/Scripts/Utility/TowerIconComposeUtility.cs b/Assets/GameMain/Scripts/Utility/TowerIconComposeUtility.cs new file mode 100644 index 0000000..256f55e --- /dev/null +++ b/Assets/GameMain/Scripts/Utility/TowerIconComposeUtility.cs @@ -0,0 +1,148 @@ +using System; +using System.Globalization; +using UnityEngine; + +namespace GeometryTD.CustomUtility +{ + public static class TowerIconComposeUtility + { + public static Sprite Compose( + Sprite muzzleSprite, + Color muzzleColor, + Sprite bearingSprite, + Color bearingColor, + Sprite baseSprite, + Color baseColor) + { + if (muzzleSprite == null || bearingSprite == null || baseSprite == null) + { + return null; + } + + Sprite referenceSprite = muzzleSprite ?? bearingSprite ?? baseSprite; + if (referenceSprite == null) + { + return null; + } + + int width = Mathf.RoundToInt(referenceSprite.rect.width); + int height = Mathf.RoundToInt(referenceSprite.rect.height); + if (width <= 0 || height <= 0) + { + return null; + } + + return ComposeWithRenderTexture( + muzzleSprite, + muzzleColor, + bearingSprite, + bearingColor, + baseSprite, + baseColor, + width, + height, + referenceSprite); + } + + public static string BuildCacheKey( + long muzzleId, + long bearingId, + long baseId, + Color muzzleColor, + Color bearingColor, + Color baseColor) + { + return string.Format( + CultureInfo.InvariantCulture, + "v2|{0}|{1}|{2}|{3}|{4}|{5}", + muzzleId, + bearingId, + baseId, + ToColorKey(muzzleColor), + ToColorKey(bearingColor), + ToColorKey(baseColor)); + } + + private static Sprite ComposeWithRenderTexture( + Sprite muzzleSprite, + Color muzzleColor, + Sprite bearingSprite, + Color bearingColor, + Sprite baseSprite, + Color baseColor, + int width, + int height, + Sprite referenceSprite) + { + RenderTexture rt = RenderTexture.GetTemporary(width, height, 0, RenderTextureFormat.ARGB32); + RenderTexture previous = RenderTexture.active; + try + { + RenderTexture.active = rt; + GL.PushMatrix(); + GL.LoadPixelMatrix(0f, width, 0f, height); + GL.Clear(true, true, Color.clear); + + DrawSpriteToRenderTarget(baseSprite, baseColor, width, height); + DrawSpriteToRenderTarget(bearingSprite, bearingColor, width, height); + DrawSpriteToRenderTarget(muzzleSprite, muzzleColor, width, height); + + GL.PopMatrix(); + + Texture2D composedTexture = new Texture2D(width, height, TextureFormat.RGBA32, false); + composedTexture.ReadPixels(new Rect(0f, 0f, width, height), 0, 0); + composedTexture.Apply(false, false); + return CreateSprite(composedTexture, referenceSprite); + } + catch (Exception) + { + return null; + } + finally + { + RenderTexture.active = previous; + RenderTexture.ReleaseTemporary(rt); + } + } + + private static void DrawSpriteToRenderTarget(Sprite sprite, Color color, int width, int height) + { + if (sprite == null || sprite.texture == null) + { + return; + } + + Rect textureRect = sprite.textureRect; + Texture texture = sprite.texture; + Rect uvRect = new Rect( + textureRect.x / texture.width, + textureRect.y / texture.height, + textureRect.width / texture.width, + textureRect.height / texture.height); + + Graphics.DrawTexture(new Rect(0f, 0f, width, height), texture, uvRect, 0, 0, 0, 0, color); + } + + private static Sprite CreateSprite(Texture2D texture, Sprite referenceSprite) + { + if (texture == null || referenceSprite == null) + { + return null; + } + + float width = Mathf.Max(1f, referenceSprite.rect.width); + float height = Mathf.Max(1f, referenceSprite.rect.height); + Vector2 pivot = new Vector2(referenceSprite.pivot.x / width, referenceSprite.pivot.y / height); + return Sprite.Create(texture, new Rect(0f, 0f, texture.width, texture.height), pivot, referenceSprite.pixelsPerUnit); + } + + private static string ToColorKey(Color color) + { + Color32 c = color; + return c.r.ToString("X2", CultureInfo.InvariantCulture) + + c.g.ToString("X2", CultureInfo.InvariantCulture) + + c.b.ToString("X2", CultureInfo.InvariantCulture) + + c.a.ToString("X2", CultureInfo.InvariantCulture); + } + } +} diff --git a/Assets/GameMain/Scripts/Utility/TowerIconComposeUtility.cs.meta b/Assets/GameMain/Scripts/Utility/TowerIconComposeUtility.cs.meta new file mode 100644 index 0000000..cbb1d26 --- /dev/null +++ b/Assets/GameMain/Scripts/Utility/TowerIconComposeUtility.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: d9256e2c4f74b7448afbdbac8f7cb26f +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/GameMain/UI/UIForms/CombatSelectForm.prefab b/Assets/GameMain/UI/UIForms/CombatSelectForm.prefab index fe0b697..6c68ba1 100644 --- a/Assets/GameMain/UI/UIForms/CombatSelectForm.prefab +++ b/Assets/GameMain/UI/UIForms/CombatSelectForm.prefab @@ -976,6 +976,17 @@ PrefabInstance: serializedVersion: 3 m_TransformParent: {fileID: 1714606292658179489} m_Modifications: + - target: {fileID: 272351400812969041, guid: b656295a0a0134840bdcd41e203f12c7, + type: 3} + propertyPath: m_Type + value: 1 + objectReference: {fileID: 0} + - target: {fileID: 272351400812969041, guid: b656295a0a0134840bdcd41e203f12c7, + type: 3} + propertyPath: m_Sprite + value: + objectReference: {fileID: 21300000, guid: 9f847ec5e66e03e4ead1d3c5f7b510e8, + type: 3} - target: {fileID: 274828358581623048, guid: b656295a0a0134840bdcd41e203f12c7, type: 3} propertyPath: m_Pivot.x diff --git a/Assets/GameMain/UI/UIForms/RepoForm.prefab b/Assets/GameMain/UI/UIForms/RepoForm.prefab index b7e49a4..faccc68 100644 --- a/Assets/GameMain/UI/UIForms/RepoForm.prefab +++ b/Assets/GameMain/UI/UIForms/RepoForm.prefab @@ -52,6 +52,8 @@ MonoBehaviour: _content: {fileID: 1805918912036091081} _itemTemplate: {fileID: 8394974685918372820, guid: 2ead8e403e355dd4b9296a9d0a871a83, type: 3} + _towerItemTemplate: {fileID: 4730609612906943122, guid: 81bda3e30070fa34884bafbe9a9c72f9, + type: 3} _instancePoolCapacity: 64 --- !u!1 &2380285751925872027 GameObject: @@ -181,7 +183,7 @@ MonoBehaviour: m_Name: m_EditorClassIdentifier: _content: {fileID: 6811784024412969593} - _itemTemplate: {fileID: 8394974685918372820, guid: 2ead8e403e355dd4b9296a9d0a871a83, + _towerItemTemplate: {fileID: 4730609612906943122, guid: 81bda3e30070fa34884bafbe9a9c72f9, type: 3} _instancePoolCapacity: 8 --- !u!222 &5388327515888957795 diff --git a/Assets/GameMain/UI/UIItems/TowerIconArea.prefab b/Assets/GameMain/UI/UIItems/TowerIconArea.prefab new file mode 100644 index 0000000..f7eaf9c --- /dev/null +++ b/Assets/GameMain/UI/UIItems/TowerIconArea.prefab @@ -0,0 +1,447 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!1 &177671855419091867 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 3323726282767525619} + - component: {fileID: 399955496901366910} + - component: {fileID: 7579875247493712075} + m_Layer: 5 + m_Name: TowerIconArea + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &3323726282767525619 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 177671855419091867} + 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: 1038851730778667217} + - {fileID: 2859743021803601866} + - {fileID: 6845015578436394914} + m_Father: {fileID: 0} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: -20, y: -20} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!222 &399955496901366910 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 177671855419091867} + m_CullTransparentMesh: 1 +--- !u!114 &7579875247493712075 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 177671855419091867} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 33a1436bff53c844e858f3bced1565ca, type: 3} + m_Name: + m_EditorClassIdentifier: + _board: {fileID: 1792178769172340962} + _icon: {fileID: 4918346613506060866} + _baseIcon: {fileID: 7285567316465127825} + _bearingIcon: {fileID: 4366841213109481872} + _muzzleIcon: {fileID: 4666251790512386674} +--- !u!1 &803783036851305114 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 2859743021803601866} + - component: {fileID: 4968140022138979945} + - component: {fileID: 4918346613506060866} + m_Layer: 5 + m_Name: Image + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &2859743021803601866 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 803783036851305114} + 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: 3323726282767525619} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!222 &4968140022138979945 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 803783036851305114} + m_CullTransparentMesh: 1 +--- !u!114 &4918346613506060866 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 803783036851305114} + 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: 1} + 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 &1636419954436272212 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 9145919182730712671} + - component: {fileID: 2651698208426096613} + - component: {fileID: 4366841213109481872} + m_Layer: 5 + m_Name: Bearing + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &9145919182730712671 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1636419954436272212} + 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: 1 + m_Children: + - {fileID: 6782923152009204558} + m_Father: {fileID: 6845015578436394914} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!222 &2651698208426096613 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1636419954436272212} + m_CullTransparentMesh: 1 +--- !u!114 &4366841213109481872 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1636419954436272212} + 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: 1} + m_RaycastTarget: 0 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: -2413806693520163455, guid: e31321df62f1587469b0733897970679, + type: 3} + 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 &2318020840094036371 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 6782923152009204558} + - component: {fileID: 3207702065525898594} + - component: {fileID: 4666251790512386674} + m_Layer: 5 + m_Name: Muzzle + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &6782923152009204558 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2318020840094036371} + 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: 1 + m_Children: [] + m_Father: {fileID: 9145919182730712671} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: 29.586662} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0.5, y: 0.2886667} +--- !u!222 &3207702065525898594 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2318020840094036371} + m_CullTransparentMesh: 1 +--- !u!114 &4666251790512386674 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2318020840094036371} + 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: 0.24213827, b: 0.24213827, a: 1} + m_RaycastTarget: 0 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 7482667652216324306, guid: 5ba74e3a185274149b15c24b321bead2, + type: 3} + 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 &5542159351280798647 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1038851730778667217} + - component: {fileID: 2454678530691112152} + - component: {fileID: 1792178769172340962} + m_Layer: 5 + m_Name: board + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &1038851730778667217 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 5542159351280798647} + 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: 3323726282767525619} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 20, y: 20} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!222 &2454678530691112152 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 5542159351280798647} + m_CullTransparentMesh: 1 +--- !u!114 &1792178769172340962 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 5542159351280798647} + 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: 1} + m_RaycastTarget: 0 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 21300000, guid: a8c07bbe04fdaf04b80e27f651a8edd6, type: 3} + m_Type: 1 + 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 &5919608345427997939 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 6845015578436394914} + - component: {fileID: 1519331956184262112} + - component: {fileID: 7285567316465127825} + m_Layer: 5 + m_Name: Base + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &6845015578436394914 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 5919608345427997939} + 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: 1 + m_Children: + - {fileID: 9145919182730712671} + m_Father: {fileID: 3323726282767525619} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!222 &1519331956184262112 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 5919608345427997939} + m_CullTransparentMesh: 1 +--- !u!114 &7285567316465127825 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 5919608345427997939} + 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: 0.13836467, g: 0.13836467, b: 0.13836467, a: 1} + m_RaycastTarget: 0 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 7482667652216324306, guid: 80a3790c48fc91d4ebcb4d7e2efbb8c8, + type: 3} + 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 diff --git a/Assets/GameMain/UI/UIItems/TowerIconArea.prefab.meta b/Assets/GameMain/UI/UIItems/TowerIconArea.prefab.meta new file mode 100644 index 0000000..2b45cea --- /dev/null +++ b/Assets/GameMain/UI/UIItems/TowerIconArea.prefab.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: ab6ee7e8b2a678544af490543d99f665 +PrefabImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/GameMain/UI/UIItems/TowerRepoItem.prefab b/Assets/GameMain/UI/UIItems/TowerRepoItem.prefab new file mode 100644 index 0000000..e93f56d --- /dev/null +++ b/Assets/GameMain/UI/UIItems/TowerRepoItem.prefab @@ -0,0 +1,356 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!1 &1986516583823050331 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 6860417479053386125} + - component: {fileID: 8570341357903165526} + - component: {fileID: 5089068592453588603} + m_Layer: 5 + m_Name: bg + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &6860417479053386125 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1986516583823050331} + 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: 8349727755164431499} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!222 &8570341357903165526 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1986516583823050331} + m_CullTransparentMesh: 1 +--- !u!114 &5089068592453588603 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1986516583823050331} + 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: 0.5, g: 0.5, b: 0.5, 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_Sprite: {fileID: 21300000, guid: 9f847ec5e66e03e4ead1d3c5f7b510e8, type: 3} + m_Type: 1 + 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 &3287359693314616602 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 7253748148476290235} + - component: {fileID: 412242389824419156} + - component: {fileID: 4730609612906943122} + m_Layer: 5 + m_Name: TowerRepoItem + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &7253748148476290235 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 3287359693314616602} + 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: 8349727755164431499} + - {fileID: 884849595327022251} + m_Father: {fileID: 0} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 0, y: 0} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 160, y: 160} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!222 &412242389824419156 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 3287359693314616602} + m_CullTransparentMesh: 1 +--- !u!114 &4730609612906943122 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 3287359693314616602} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: caf7b65cc179a5d46828128f574ed63e, type: 3} + m_Name: + m_EditorClassIdentifier: + _bgImage: {fileID: 5089068592453588603} + _iconArea: {fileID: 5428668331781712531} + _context: + InstanceId: 0 + CanDrag: 0 + EnduranceRate01: 0 + ClickActionType: 0 + ComponentSlotType: 0 + IconAreaContext: + Rarity: 0 + ComponentSlotType: 0 + Color: {r: 1, g: 1, b: 1, a: 1} + Icon: {fileID: 0} +--- !u!1 &5586290829740215320 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 8349727755164431499} + - component: {fileID: 8024563988191439697} + m_Layer: 5 + m_Name: CommonButton + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &8349727755164431499 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 5586290829740215320} + 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: 6860417479053386125} + m_Father: {fileID: 7253748148476290235} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &8024563988191439697 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 5586290829740215320} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: a5079836f95c2a44b96fa331487ebb70, type: 3} + m_Name: + m_EditorClassIdentifier: + _onHover: + m_PersistentCalls: + m_Calls: [] + _onClick: + m_PersistentCalls: + m_Calls: + - m_Target: {fileID: 4730609612906943122} + m_TargetAssemblyTypeName: GeometryTD.UI.TowerRepoItem, Assembly-CSharp + m_MethodName: OnClick + m_Mode: 1 + m_Arguments: + m_ObjectArgument: {fileID: 0} + m_ObjectArgumentAssemblyTypeName: UnityEngine.Object, UnityEngine + m_IntArgument: 10001 + m_FloatArgument: 0 + m_StringArgument: + m_BoolArgument: 0 + m_CallState: 2 + _onHoverEnd: + m_PersistentCalls: + m_Calls: [] + _allowFade: 1 +--- !u!1001 &2479127645651034712 +PrefabInstance: + m_ObjectHideFlags: 0 + serializedVersion: 2 + m_Modification: + serializedVersion: 3 + m_TransformParent: {fileID: 7253748148476290235} + m_Modifications: + - target: {fileID: 177671855419091867, guid: ab6ee7e8b2a678544af490543d99f665, + type: 3} + propertyPath: m_Name + value: TowerIconArea + objectReference: {fileID: 0} + - target: {fileID: 3323726282767525619, guid: ab6ee7e8b2a678544af490543d99f665, + type: 3} + propertyPath: m_Pivot.x + value: 0.5 + objectReference: {fileID: 0} + - target: {fileID: 3323726282767525619, guid: ab6ee7e8b2a678544af490543d99f665, + type: 3} + propertyPath: m_Pivot.y + value: 0.5 + objectReference: {fileID: 0} + - target: {fileID: 3323726282767525619, guid: ab6ee7e8b2a678544af490543d99f665, + type: 3} + propertyPath: m_AnchorMax.x + value: 1 + objectReference: {fileID: 0} + - target: {fileID: 3323726282767525619, guid: ab6ee7e8b2a678544af490543d99f665, + type: 3} + propertyPath: m_AnchorMax.y + value: 1 + objectReference: {fileID: 0} + - target: {fileID: 3323726282767525619, guid: ab6ee7e8b2a678544af490543d99f665, + type: 3} + propertyPath: m_AnchorMin.x + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 3323726282767525619, guid: ab6ee7e8b2a678544af490543d99f665, + type: 3} + propertyPath: m_AnchorMin.y + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 3323726282767525619, guid: ab6ee7e8b2a678544af490543d99f665, + type: 3} + propertyPath: m_SizeDelta.x + value: -20 + objectReference: {fileID: 0} + - target: {fileID: 3323726282767525619, guid: ab6ee7e8b2a678544af490543d99f665, + type: 3} + propertyPath: m_SizeDelta.y + value: -20 + objectReference: {fileID: 0} + - target: {fileID: 3323726282767525619, guid: ab6ee7e8b2a678544af490543d99f665, + type: 3} + propertyPath: m_LocalPosition.x + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 3323726282767525619, guid: ab6ee7e8b2a678544af490543d99f665, + type: 3} + propertyPath: m_LocalPosition.y + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 3323726282767525619, guid: ab6ee7e8b2a678544af490543d99f665, + type: 3} + propertyPath: m_LocalPosition.z + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 3323726282767525619, guid: ab6ee7e8b2a678544af490543d99f665, + type: 3} + propertyPath: m_LocalRotation.w + value: 1 + objectReference: {fileID: 0} + - target: {fileID: 3323726282767525619, guid: ab6ee7e8b2a678544af490543d99f665, + type: 3} + propertyPath: m_LocalRotation.x + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 3323726282767525619, guid: ab6ee7e8b2a678544af490543d99f665, + type: 3} + propertyPath: m_LocalRotation.y + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 3323726282767525619, guid: ab6ee7e8b2a678544af490543d99f665, + type: 3} + propertyPath: m_LocalRotation.z + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 3323726282767525619, guid: ab6ee7e8b2a678544af490543d99f665, + type: 3} + propertyPath: m_AnchoredPosition.x + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 3323726282767525619, guid: ab6ee7e8b2a678544af490543d99f665, + type: 3} + propertyPath: m_AnchoredPosition.y + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 3323726282767525619, guid: ab6ee7e8b2a678544af490543d99f665, + type: 3} + propertyPath: m_LocalEulerAnglesHint.x + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 3323726282767525619, guid: ab6ee7e8b2a678544af490543d99f665, + type: 3} + propertyPath: m_LocalEulerAnglesHint.y + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 3323726282767525619, guid: ab6ee7e8b2a678544af490543d99f665, + type: 3} + propertyPath: m_LocalEulerAnglesHint.z + value: 0 + objectReference: {fileID: 0} + m_RemovedComponents: [] + m_RemovedGameObjects: [] + m_AddedGameObjects: [] + m_AddedComponents: [] + m_SourcePrefab: {fileID: 100100000, guid: ab6ee7e8b2a678544af490543d99f665, type: 3} +--- !u!224 &884849595327022251 stripped +RectTransform: + m_CorrespondingSourceObject: {fileID: 3323726282767525619, guid: ab6ee7e8b2a678544af490543d99f665, + type: 3} + m_PrefabInstance: {fileID: 2479127645651034712} + m_PrefabAsset: {fileID: 0} +--- !u!114 &5428668331781712531 stripped +MonoBehaviour: + m_CorrespondingSourceObject: {fileID: 7579875247493712075, guid: ab6ee7e8b2a678544af490543d99f665, + type: 3} + m_PrefabInstance: {fileID: 2479127645651034712} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 33a1436bff53c844e858f3bced1565ca, type: 3} + m_Name: + m_EditorClassIdentifier: diff --git a/Assets/GameMain/UI/UIItems/TowerRepoItem.prefab.meta b/Assets/GameMain/UI/UIItems/TowerRepoItem.prefab.meta new file mode 100644 index 0000000..df4688c --- /dev/null +++ b/Assets/GameMain/UI/UIItems/TowerRepoItem.prefab.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 81bda3e30070fa34884bafbe9a9c72f9 +PrefabImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/GameMain/UI/UIItems/TowerSelectItem.prefab b/Assets/GameMain/UI/UIItems/TowerSelectItem.prefab index 1dee9a6..b0dbe32 100644 --- a/Assets/GameMain/UI/UIItems/TowerSelectItem.prefab +++ b/Assets/GameMain/UI/UIItems/TowerSelectItem.prefab @@ -1,80 +1,5 @@ %YAML 1.1 %TAG !u! tag:unity3d.com,2011: ---- !u!1 &5412566102378209566 -GameObject: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - serializedVersion: 6 - m_Component: - - component: {fileID: 4152009404387722330} - - component: {fileID: 3873445585384354699} - - component: {fileID: 272351400812969041} - m_Layer: 5 - m_Name: Icon - m_TagString: Untagged - m_Icon: {fileID: 0} - m_NavMeshLayer: 0 - m_StaticEditorFlags: 0 - m_IsActive: 1 ---- !u!224 &4152009404387722330 -RectTransform: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 5412566102378209566} - 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: 8201350274026178469} - 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: 0, y: 0} - m_SizeDelta: {x: 80, y: 80} - m_Pivot: {x: 0.5, y: 0.5} ---- !u!222 &3873445585384354699 -CanvasRenderer: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 5412566102378209566} - m_CullTransparentMesh: 1 ---- !u!114 &272351400812969041 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 5412566102378209566} - 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: 1} - 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: 21300146, guid: 29c9cded5e558164aaf8c9bf08aa1510, type: 3} - 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 &6361423396692704141 GameObject: m_ObjectHideFlags: 0 @@ -100,7 +25,7 @@ RectTransform: m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 6361423396692704141} - m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + 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 @@ -179,8 +104,9 @@ RectTransform: m_LocalScale: {x: 1, y: 1, z: 1} m_ConstrainProportionsScale: 0 m_Children: - - {fileID: 8201350274026178469} - {fileID: 28444767019028035} + - {fileID: 2412538576477069160} + - {fileID: 8201350274026178469} m_Father: {fileID: 0} m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0.5, y: 0.5} @@ -200,9 +126,158 @@ MonoBehaviour: m_Script: {fileID: 11500000, guid: 4da5ef45ee18db44ebe3c015dddb61d6, type: 3} m_Name: m_EditorClassIdentifier: - _icon: {fileID: 272351400812969041} + _icon: {fileID: 5411719625189444569} _price: {fileID: 6134693184638222351} _button: {fileID: 8644563062325311724} + _towerIconArea: {fileID: 7379728654387442000} +--- !u!1001 &1106531443240827291 +PrefabInstance: + m_ObjectHideFlags: 0 + serializedVersion: 2 + m_Modification: + serializedVersion: 3 + m_TransformParent: {fileID: 274828358581623048} + m_Modifications: + - target: {fileID: 177671855419091867, guid: ab6ee7e8b2a678544af490543d99f665, + type: 3} + propertyPath: m_Name + value: TowerIconArea + objectReference: {fileID: 0} + - target: {fileID: 3323726282767525619, guid: ab6ee7e8b2a678544af490543d99f665, + type: 3} + propertyPath: m_Pivot.x + value: 0.5 + objectReference: {fileID: 0} + - target: {fileID: 3323726282767525619, guid: ab6ee7e8b2a678544af490543d99f665, + type: 3} + propertyPath: m_Pivot.y + value: 0.5 + objectReference: {fileID: 0} + - target: {fileID: 3323726282767525619, guid: ab6ee7e8b2a678544af490543d99f665, + type: 3} + propertyPath: m_AnchorMax.x + value: 1 + objectReference: {fileID: 0} + - target: {fileID: 3323726282767525619, guid: ab6ee7e8b2a678544af490543d99f665, + type: 3} + propertyPath: m_AnchorMax.y + value: 1 + objectReference: {fileID: 0} + - target: {fileID: 3323726282767525619, guid: ab6ee7e8b2a678544af490543d99f665, + type: 3} + propertyPath: m_AnchorMin.x + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 3323726282767525619, guid: ab6ee7e8b2a678544af490543d99f665, + type: 3} + propertyPath: m_AnchorMin.y + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 3323726282767525619, guid: ab6ee7e8b2a678544af490543d99f665, + type: 3} + propertyPath: m_SizeDelta.x + value: -20 + objectReference: {fileID: 0} + - target: {fileID: 3323726282767525619, guid: ab6ee7e8b2a678544af490543d99f665, + type: 3} + propertyPath: m_SizeDelta.y + value: -20 + objectReference: {fileID: 0} + - target: {fileID: 3323726282767525619, guid: ab6ee7e8b2a678544af490543d99f665, + type: 3} + propertyPath: m_LocalPosition.x + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 3323726282767525619, guid: ab6ee7e8b2a678544af490543d99f665, + type: 3} + propertyPath: m_LocalPosition.y + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 3323726282767525619, guid: ab6ee7e8b2a678544af490543d99f665, + type: 3} + propertyPath: m_LocalPosition.z + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 3323726282767525619, guid: ab6ee7e8b2a678544af490543d99f665, + type: 3} + propertyPath: m_LocalRotation.w + value: 1 + objectReference: {fileID: 0} + - target: {fileID: 3323726282767525619, guid: ab6ee7e8b2a678544af490543d99f665, + type: 3} + propertyPath: m_LocalRotation.x + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 3323726282767525619, guid: ab6ee7e8b2a678544af490543d99f665, + type: 3} + propertyPath: m_LocalRotation.y + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 3323726282767525619, guid: ab6ee7e8b2a678544af490543d99f665, + type: 3} + propertyPath: m_LocalRotation.z + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 3323726282767525619, guid: ab6ee7e8b2a678544af490543d99f665, + type: 3} + propertyPath: m_AnchoredPosition.x + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 3323726282767525619, guid: ab6ee7e8b2a678544af490543d99f665, + type: 3} + propertyPath: m_AnchoredPosition.y + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 3323726282767525619, guid: ab6ee7e8b2a678544af490543d99f665, + type: 3} + propertyPath: m_LocalEulerAnglesHint.x + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 3323726282767525619, guid: ab6ee7e8b2a678544af490543d99f665, + type: 3} + propertyPath: m_LocalEulerAnglesHint.y + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 3323726282767525619, guid: ab6ee7e8b2a678544af490543d99f665, + type: 3} + propertyPath: m_LocalEulerAnglesHint.z + value: 0 + objectReference: {fileID: 0} + m_RemovedComponents: [] + m_RemovedGameObjects: [] + m_AddedGameObjects: [] + m_AddedComponents: [] + m_SourcePrefab: {fileID: 100100000, guid: ab6ee7e8b2a678544af490543d99f665, type: 3} +--- !u!224 &2412538576477069160 stripped +RectTransform: + m_CorrespondingSourceObject: {fileID: 3323726282767525619, guid: ab6ee7e8b2a678544af490543d99f665, + type: 3} + m_PrefabInstance: {fileID: 1106531443240827291} + m_PrefabAsset: {fileID: 0} +--- !u!114 &5411719625189444569 stripped +MonoBehaviour: + m_CorrespondingSourceObject: {fileID: 4918346613506060866, guid: ab6ee7e8b2a678544af490543d99f665, + type: 3} + m_PrefabInstance: {fileID: 1106531443240827291} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: +--- !u!114 &7379728654387442000 stripped +MonoBehaviour: + m_CorrespondingSourceObject: {fileID: 7579875247493712075, guid: ab6ee7e8b2a678544af490543d99f665, + type: 3} + m_PrefabInstance: {fileID: 1106531443240827291} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 33a1436bff53c844e858f3bced1565ca, type: 3} + m_Name: + m_EditorClassIdentifier: --- !u!1001 &5730140866277425490 PrefabInstance: m_ObjectHideFlags: 0 @@ -216,6 +291,11 @@ PrefabInstance: propertyPath: m_Name value: CommonButton objectReference: {fileID: 0} + - target: {fileID: 1341699087252484061, guid: 2307f223279813546a43b221ddd496cc, + type: 3} + propertyPath: m_Color.a + value: 0 + objectReference: {fileID: 0} - target: {fileID: 1920576543566152029, guid: 2307f223279813546a43b221ddd496cc, type: 3} propertyPath: m_text @@ -351,34 +431,24 @@ PrefabInstance: propertyPath: m_LocalEulerAnglesHint.z value: 0 objectReference: {fileID: 0} - - target: {fileID: 7744090569424522082, guid: 2307f223279813546a43b221ddd496cc, - type: 3} - propertyPath: m_AnchorMax.y - value: 0.5 - objectReference: {fileID: 0} - - target: {fileID: 7744090569424522082, guid: 2307f223279813546a43b221ddd496cc, - type: 3} - propertyPath: m_AnchorMin.y - value: 0.5 - objectReference: {fileID: 0} - target: {fileID: 7744090569424522082, guid: 2307f223279813546a43b221ddd496cc, type: 3} propertyPath: m_SizeDelta.y - value: 60 + value: -50.000023 + objectReference: {fileID: 0} + - target: {fileID: 7744090569424522082, guid: 2307f223279813546a43b221ddd496cc, + type: 3} + propertyPath: m_AnchoredPosition.x + value: 0 objectReference: {fileID: 0} - target: {fileID: 7744090569424522082, guid: 2307f223279813546a43b221ddd496cc, type: 3} propertyPath: m_AnchoredPosition.y - value: -80 + value: -75.000015 objectReference: {fileID: 0} m_RemovedComponents: [] - m_RemovedGameObjects: - - {fileID: 7888786393168201163, guid: 2307f223279813546a43b221ddd496cc, type: 3} - m_AddedGameObjects: - - targetCorrespondingSourceObject: {fileID: 4491355866364659447, guid: 2307f223279813546a43b221ddd496cc, - type: 3} - insertIndex: -1 - addedObject: {fileID: 4152009404387722330} + m_RemovedGameObjects: [] + m_AddedGameObjects: [] m_AddedComponents: [] m_SourcePrefab: {fileID: 100100000, guid: 2307f223279813546a43b221ddd496cc, type: 3} --- !u!114 &6134693184638222351 stripped