- TowerSelectItem 显示问题
- CombatSelectForm 不同分辨率的适配
This commit is contained in:
SepComet 2026-03-09 19:59:11 +08:00
parent af20eeecfa
commit 2d09b01c55
8 changed files with 145 additions and 52 deletions

View File

@ -20,7 +20,7 @@ namespace GeometryTD.Entity
{ {
userData = null; userData = null;
if (tilemap == null || !TryGetPointerWorldPosition(tilemap, mapTransform, out Vector3 worldPosition, if (tilemap == null || !TryGetPointerWorldPosition(tilemap, mapTransform, out Vector3 worldPosition,
out Vector2 contentPosition)) out Vector2 screenPosition))
{ {
return false; return false;
} }
@ -28,25 +28,25 @@ namespace GeometryTD.Entity
Vector3Int clickedCell = tilemap.WorldToCell(worldPosition); Vector3Int clickedCell = tilemap.WorldToCell(worldPosition);
CombatSelectClickObjectType clickObjectType = CombatSelectClickObjectType.None; CombatSelectClickObjectType clickObjectType = CombatSelectClickObjectType.None;
int towerEntityId = 0; int towerEntityId = 0;
Vector2 resolvedContentPosition = contentPosition; Vector2 resolvedScreenPosition = screenPosition;
if (towerEntityIdByFoundationCell != null && if (towerEntityIdByFoundationCell != null &&
towerEntityIdByFoundationCell.TryGetValue(clickedCell, out int occupiedTowerEntityId)) towerEntityIdByFoundationCell.TryGetValue(clickedCell, out int occupiedTowerEntityId))
{ {
clickObjectType = CombatSelectClickObjectType.Tower; clickObjectType = CombatSelectClickObjectType.Tower;
towerEntityId = occupiedTowerEntityId; towerEntityId = occupiedTowerEntityId;
resolvedContentPosition = BuildContentPositionFromCell(tilemap, clickedCell, contentPosition); resolvedScreenPosition = BuildScreenPositionFromCell(tilemap, clickedCell, screenPosition);
} }
else if (isFoundationCell != null && isFoundationCell(clickedCell)) else if (isFoundationCell != null && isFoundationCell(clickedCell))
{ {
clickObjectType = CombatSelectClickObjectType.Foundation; clickObjectType = CombatSelectClickObjectType.Foundation;
resolvedContentPosition = BuildContentPositionFromCell(tilemap, clickedCell, contentPosition); resolvedScreenPosition = BuildScreenPositionFromCell(tilemap, clickedCell, screenPosition);
} }
userData = new CombatSelectFormUserData userData = new CombatSelectFormUserData
{ {
ClickObjectType = clickObjectType, ClickObjectType = clickObjectType,
ContentPosition = resolvedContentPosition, ScreenPosition = resolvedScreenPosition,
WorldPosition = worldPosition, WorldPosition = worldPosition,
CellPosition = clickedCell, CellPosition = clickedCell,
TowerEntityId = towerEntityId, TowerEntityId = towerEntityId,
@ -59,10 +59,10 @@ namespace GeometryTD.Entity
private static bool TryGetPointerWorldPosition(Tilemap tilemap, Transform mapTransform, private static bool TryGetPointerWorldPosition(Tilemap tilemap, Transform mapTransform,
out Vector3 worldPosition, out Vector3 worldPosition,
out Vector2 contentPosition) out Vector2 screenPosition)
{ {
worldPosition = Vector3.zero; worldPosition = Vector3.zero;
contentPosition = Vector2.zero; screenPosition = Vector2.zero;
Camera mainCamera = GameEntry.Scene != null ? GameEntry.Scene.MainCamera : Camera.main; Camera mainCamera = GameEntry.Scene != null ? GameEntry.Scene.MainCamera : Camera.main;
if (mainCamera == null) if (mainCamera == null)
@ -84,38 +84,37 @@ namespace GeometryTD.Entity
} }
worldPosition = ray.GetPoint(enterDistance); worldPosition = ray.GetPoint(enterDistance);
contentPosition = BuildContentPosition(Input.mousePosition); screenPosition = BuildScreenPosition(Input.mousePosition);
contentPosition = new Vector2((int)contentPosition.x, (int)contentPosition.y);
contentPosition = new Vector2(contentPosition.x + 0.5f, contentPosition.y + 0.5f);
return true; return true;
} }
private static Vector2 BuildContentPosition(Vector3 pointerScreenPosition) private static Vector2 BuildScreenPosition(Vector3 pointerScreenPosition)
{ {
return new Vector2( return new Vector2(pointerScreenPosition.x, pointerScreenPosition.y);
pointerScreenPosition.x - Screen.width * 0.5f,
pointerScreenPosition.y - Screen.height * 0.5f);
} }
private static Vector2 BuildContentPositionFromCell(Tilemap tilemap, Vector3Int cellPosition, private static Vector2 BuildScreenPositionFromCell(Tilemap tilemap, Vector3Int cellPosition,
Vector2 fallbackContentPosition) Vector2 fallbackScreenPosition)
{ {
if (tilemap == null) if (tilemap == null)
{ {
return fallbackContentPosition; return fallbackScreenPosition;
} }
Camera mainCamera = GameEntry.Scene != null ? GameEntry.Scene.MainCamera : Camera.main; Camera mainCamera = GameEntry.Scene != null ? GameEntry.Scene.MainCamera : Camera.main;
if (mainCamera == null) if (mainCamera == null)
{ {
return fallbackContentPosition; return fallbackScreenPosition;
} }
Vector3 cellCenterWorld = tilemap.GetCellCenterWorld(cellPosition); Vector3 cellCenterWorld = tilemap.GetCellCenterWorld(cellPosition);
Vector3 cellScreenPosition = mainCamera.WorldToScreenPoint(cellCenterWorld); Vector3 cellScreenPosition = mainCamera.WorldToScreenPoint(cellCenterWorld);
Vector2 contentPosition = BuildContentPosition(cellScreenPosition); if (cellScreenPosition.z < 0f)
contentPosition = new Vector2((int)contentPosition.x, (int)contentPosition.y); {
return new Vector2(contentPosition.x + 0.5f, contentPosition.y + 0.5f); return fallbackScreenPosition;
}
return BuildScreenPosition(cellScreenPosition);
} }
} }
} }

View File

@ -5,7 +5,7 @@ namespace GeometryTD.UI
public class CombatSelectFormContext : UIContext public class CombatSelectFormContext : UIContext
{ {
public bool IsVisible; public bool IsVisible;
public Vector2 ContentPosition; public Vector2 ScreenPosition;
public bool ShowBuildArea; public bool ShowBuildArea;
public bool ShowFuncArea; public bool ShowFuncArea;
public TowerSelectItemContext[] BuildItems; public TowerSelectItemContext[] BuildItems;

View File

@ -99,13 +99,13 @@ namespace GeometryTD.UI
{ {
case CombatSelectClickObjectType.Foundation: case CombatSelectClickObjectType.Foundation:
_useCase.SetUpgradeVisible(true); _useCase.SetUpgradeVisible(true);
_useCase.ShowForFoundation(userData.ContentPosition); _useCase.ShowForFoundation(userData.ScreenPosition);
break; break;
case CombatSelectClickObjectType.Tower: case CombatSelectClickObjectType.Tower:
_useCase.SetUpgradePrice(userData.UpgradeCost); _useCase.SetUpgradePrice(userData.UpgradeCost);
_useCase.SetUpgradeVisible(!userData.IsTowerAtMaxLevel); _useCase.SetUpgradeVisible(!userData.IsTowerAtMaxLevel);
_useCase.SetDestroyGain(userData.DestroyGain); _useCase.SetDestroyGain(userData.DestroyGain);
_useCase.ShowForTower(userData.ContentPosition); _useCase.ShowForTower(userData.ScreenPosition);
break; break;
default: default:
_useCase.Hide(); _useCase.Hide();
@ -127,7 +127,7 @@ namespace GeometryTD.UI
_useCase = combatSelectFormUseCase; _useCase = combatSelectFormUseCase;
} }
public int? ShowForFoundation(Vector2 contentPosition) public int? ShowForFoundation(Vector2 screenPosition)
{ {
if (_useCase == null) if (_useCase == null)
{ {
@ -136,11 +136,11 @@ namespace GeometryTD.UI
} }
_useCase.SetUpgradeVisible(true); _useCase.SetUpgradeVisible(true);
_useCase.ShowForFoundation(contentPosition); _useCase.ShowForFoundation(screenPosition);
return OpenUI(_useCase.TryRefresh()); return OpenUI(_useCase.TryRefresh());
} }
public int? ShowForTower(Vector2 contentPosition, int upgradeCost, int destroyGain) public int? ShowForTower(Vector2 screenPosition, int upgradeCost, int destroyGain)
{ {
if (_useCase == null) if (_useCase == null)
{ {
@ -151,7 +151,7 @@ namespace GeometryTD.UI
_useCase.SetUpgradePrice(upgradeCost); _useCase.SetUpgradePrice(upgradeCost);
_useCase.SetUpgradeVisible(true); _useCase.SetUpgradeVisible(true);
_useCase.SetDestroyGain(destroyGain); _useCase.SetDestroyGain(destroyGain);
_useCase.ShowForTower(contentPosition); _useCase.ShowForTower(screenPosition);
return OpenUI(_useCase.TryRefresh()); return OpenUI(_useCase.TryRefresh());
} }
@ -190,7 +190,7 @@ namespace GeometryTD.UI
return new CombatSelectFormContext return new CombatSelectFormContext
{ {
IsVisible = rawData.IsVisible, IsVisible = rawData.IsVisible,
ContentPosition = rawData.ContentPosition, ScreenPosition = rawData.ScreenPosition,
ShowBuildArea = rawData.IsVisible && rawData.DisplayMode == CombatSelectDisplayMode.Build, ShowBuildArea = rawData.IsVisible && rawData.DisplayMode == CombatSelectDisplayMode.Build,
ShowFuncArea = rawData.IsVisible && rawData.DisplayMode == CombatSelectDisplayMode.Func, ShowFuncArea = rawData.IsVisible && rawData.DisplayMode == CombatSelectDisplayMode.Func,
BuildItems = BuildItemContexts(rawData.BuildItems), BuildItems = BuildItemContexts(rawData.BuildItems),

View File

@ -5,7 +5,7 @@ namespace GeometryTD.UI
public class CombatSelectFormRawData public class CombatSelectFormRawData
{ {
public bool IsVisible; public bool IsVisible;
public Vector2 ContentPosition; public Vector2 ScreenPosition;
public CombatSelectDisplayMode DisplayMode; public CombatSelectDisplayMode DisplayMode;
public TowerSelectItemRawData[] BuildItems; public TowerSelectItemRawData[] BuildItems;
public TowerSelectItemRawData UpgradeItem; public TowerSelectItemRawData UpgradeItem;

View File

@ -5,7 +5,7 @@ namespace GeometryTD.UI
public class CombatSelectFormUserData public class CombatSelectFormUserData
{ {
public CombatSelectClickObjectType ClickObjectType; public CombatSelectClickObjectType ClickObjectType;
public Vector2 ContentPosition; public Vector2 ScreenPosition;
public Vector3 WorldPosition; public Vector3 WorldPosition;
public Vector3Int CellPosition; public Vector3Int CellPosition;
public int TowerEntityId; public int TowerEntityId;

View File

@ -14,7 +14,7 @@ namespace GeometryTD.UI
private Func<int> _coinProvider; private Func<int> _coinProvider;
private bool _isVisible; private bool _isVisible;
private CombatSelectDisplayMode _displayMode = CombatSelectDisplayMode.Hidden; private CombatSelectDisplayMode _displayMode = CombatSelectDisplayMode.Hidden;
private Vector2 _contentPosition; private Vector2 _screenPosition;
public CombatSelectFormUseCase() public CombatSelectFormUseCase()
{ {
@ -174,16 +174,16 @@ namespace GeometryTD.UI
_destroyOption.IsGain = true; _destroyOption.IsGain = true;
} }
public void ShowForFoundation(Vector2 contentPosition) public void ShowForFoundation(Vector2 screenPosition)
{ {
_contentPosition = contentPosition; _screenPosition = screenPosition;
_displayMode = CombatSelectDisplayMode.Build; _displayMode = CombatSelectDisplayMode.Build;
_isVisible = true; _isVisible = true;
} }
public void ShowForTower(Vector2 contentPosition) public void ShowForTower(Vector2 screenPosition)
{ {
_contentPosition = contentPosition; _screenPosition = screenPosition;
_displayMode = CombatSelectDisplayMode.Func; _displayMode = CombatSelectDisplayMode.Func;
_isVisible = true; _isVisible = true;
} }
@ -239,7 +239,7 @@ namespace GeometryTD.UI
return new CombatSelectFormRawData return new CombatSelectFormRawData
{ {
IsVisible = _isVisible, IsVisible = _isVisible,
ContentPosition = _contentPosition, ScreenPosition = _screenPosition,
DisplayMode = _displayMode, DisplayMode = _displayMode,
BuildItems = buildItems, BuildItems = buildItems,
UpgradeItem = BuildOptionRawData(_upgradeOption, currentCoin), UpgradeItem = BuildOptionRawData(_upgradeOption, currentCoin),

View File

@ -33,7 +33,7 @@ namespace GeometryTD.UI
return; return;
} }
_content.anchoredPosition = context.ContentPosition; _content.anchoredPosition = ResolveContentAnchoredPosition(context.ScreenPosition);
if (_buildArea != null) if (_buildArea != null)
{ {
@ -107,5 +107,35 @@ namespace GeometryTD.UI
Transform contentTransform = transform.Find("Content"); Transform contentTransform = transform.Find("Content");
_content = contentTransform as RectTransform; _content = contentTransform as RectTransform;
} }
private Vector2 ResolveContentAnchoredPosition(Vector2 screenPosition)
{
if (_content == null)
{
return Vector2.zero;
}
RectTransform parentRect = _content.parent as RectTransform;
if (parentRect == null)
{
return screenPosition;
}
Canvas canvas = _content.GetComponentInParent<Canvas>();
Canvas rootCanvas = canvas != null ? canvas.rootCanvas : null;
Camera uiCamera = null;
if (rootCanvas != null && rootCanvas.renderMode != RenderMode.ScreenSpaceOverlay)
{
uiCamera = rootCanvas.worldCamera != null ? rootCanvas.worldCamera : Camera.main;
}
if (!RectTransformUtility.ScreenPointToLocalPointInRectangle(parentRect, screenPosition, uiCamera,
out Vector2 localPoint))
{
return Vector2.zero;
}
return localPoint;
}
} }
} }

View File

@ -1,5 +1,80 @@
%YAML 1.1 %YAML 1.1
%TAG !u! tag:unity3d.com,2011: %TAG !u! tag:unity3d.com,2011:
--- !u!1 &3060068991883162593
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 8925646583573969405}
- component: {fileID: 188918238517848746}
- component: {fileID: 1983669471491993411}
m_Layer: 5
m_Name: Icon
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!224 &8925646583573969405
RectTransform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 3060068991883162593}
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: 274828358581623048}
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 &188918238517848746
CanvasRenderer:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 3060068991883162593}
m_CullTransparentMesh: 1
--- !u!114 &1983669471491993411
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 3060068991883162593}
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: 21300144, 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 --- !u!1 &6361423396692704141
GameObject: GameObject:
m_ObjectHideFlags: 0 m_ObjectHideFlags: 0
@ -105,6 +180,7 @@ RectTransform:
m_ConstrainProportionsScale: 0 m_ConstrainProportionsScale: 0
m_Children: m_Children:
- {fileID: 28444767019028035} - {fileID: 28444767019028035}
- {fileID: 8925646583573969405}
- {fileID: 2412538576477069160} - {fileID: 2412538576477069160}
- {fileID: 8201350274026178469} - {fileID: 8201350274026178469}
m_Father: {fileID: 0} m_Father: {fileID: 0}
@ -126,7 +202,7 @@ MonoBehaviour:
m_Script: {fileID: 11500000, guid: 4da5ef45ee18db44ebe3c015dddb61d6, type: 3} m_Script: {fileID: 11500000, guid: 4da5ef45ee18db44ebe3c015dddb61d6, type: 3}
m_Name: m_Name:
m_EditorClassIdentifier: m_EditorClassIdentifier:
_icon: {fileID: 5411719625189444569} _icon: {fileID: 1983669471491993411}
_price: {fileID: 6134693184638222351} _price: {fileID: 6134693184638222351}
_button: {fileID: 8644563062325311724} _button: {fileID: 8644563062325311724}
_towerIconArea: {fileID: 7379728654387442000} _towerIconArea: {fileID: 7379728654387442000}
@ -254,18 +330,6 @@ RectTransform:
type: 3} type: 3}
m_PrefabInstance: {fileID: 1106531443240827291} m_PrefabInstance: {fileID: 1106531443240827291}
m_PrefabAsset: {fileID: 0} 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 --- !u!114 &7379728654387442000 stripped
MonoBehaviour: MonoBehaviour:
m_CorrespondingSourceObject: {fileID: 7579875247493712075, guid: ab6ee7e8b2a678544af490543d99f665, m_CorrespondingSourceObject: {fileID: 7579875247493712075, guid: ab6ee7e8b2a678544af490543d99f665,