diff --git a/.gitignore b/.gitignore
index 2875a5f..0fd4828 100644
--- a/.gitignore
+++ b/.gitignore
@@ -99,4 +99,5 @@ crashlytics-build.properties
/bin
/.omc
/.omx
-/.dotnet_home
\ No newline at end of file
+/.dotnet_home
+/.dotnet
\ No newline at end of file
diff --git a/Assets/GameMain/DataTables/UIForm.txt b/Assets/GameMain/DataTables/UIForm.txt
index 20d455b..40e4b76 100644
--- a/Assets/GameMain/DataTables/UIForm.txt
+++ b/Assets/GameMain/DataTables/UIForm.txt
@@ -14,3 +14,4 @@
107 游戏场景覆盖UI MainOverlayForm Overlay False False
108 AI对话UI AIChatForm Overlay False False
109 章节标题UI ChapterTitleForm Overlay False False
+ 110 AI对话入口 AIChatEntryForm Top False False
diff --git a/Assets/GameMain/Scripts/CustomComponent/CombineComponent.cs b/Assets/GameMain/Scripts/CustomComponent/CombineComponent.cs
index 696dd73..072f643 100644
--- a/Assets/GameMain/Scripts/CustomComponent/CombineComponent.cs
+++ b/Assets/GameMain/Scripts/CustomComponent/CombineComponent.cs
@@ -318,6 +318,7 @@ namespace CustomComponent
{
slot.SetOccupiedPart(part);
part.PlaceToSlot(slot);
+ HidePlacedPair(slot, part);
_placedCount++;
AdvanceOrderCursor();
@@ -338,8 +339,6 @@ namespace CustomComponent
}
_isCompleted = true;
-
- GameEntry.Event.Fire(this, CombineCompletedEventArgs.Create());
_onPuzzleCompleted.Invoke();
}
@@ -371,6 +370,19 @@ namespace CustomComponent
GameEntry.Event.Fire(this, CombineFeedbackEventArgs.Create(feedbackType, message));
}
+ private static void HidePlacedPair(CombineSlot slot, CombineDraggablePart part)
+ {
+ if (slot != null && slot.gameObject != null)
+ {
+ slot.gameObject.SetActive(false);
+ }
+
+ if (part != null && part.gameObject != null)
+ {
+ part.gameObject.SetActive(false);
+ }
+ }
+
#endregion
#region Runtime Context
@@ -569,6 +581,7 @@ namespace CustomComponent
for (int i = 0; i < _orderedSlots.Count; i++)
{
CombineSlot slot = _orderedSlots[i];
+ slot.gameObject.SetActive(true);
slot.BindController(this);
slot.ResetSlot();
}
@@ -587,6 +600,7 @@ namespace CustomComponent
continue;
}
+ part.gameObject.SetActive(true);
part.BindController(this);
part.CacheSpawnState();
part.ResetToSpawn();
diff --git a/Assets/GameMain/Scripts/UI/View/CombineDraggablePart.cs b/Assets/GameMain/Scripts/UI/View/CombineDraggablePart.cs
index 5777d15..e63fbb2 100644
--- a/Assets/GameMain/Scripts/UI/View/CombineDraggablePart.cs
+++ b/Assets/GameMain/Scripts/UI/View/CombineDraggablePart.cs
@@ -73,6 +73,8 @@ namespace UI
private Tween _returnTween;
+ private Vector2 _dragPointerOffset = Vector2.zero;
+
#endregion
#region Public Query
@@ -185,10 +187,11 @@ namespace UI
_canvasGroup.blocksRaycasts = false;
MoveToDragRoot();
_rectTransform.SetAsLastSibling();
+ CacheDragOffset(eventData);
}
///
- /// 拖拽中:按指针增量更新锚点位置。
+ /// 拖拽中:按屏幕坐标映射到父节点局部坐标更新位置。
///
public void OnDrag(PointerEventData eventData)
{
@@ -197,6 +200,13 @@ namespace UI
return;
}
+ if (TryGetDragParent(out RectTransform dragParent) &&
+ TryGetPointerLocalPosition(eventData, dragParent, out Vector2 pointerLocalPosition))
+ {
+ _rectTransform.anchoredPosition = pointerLocalPosition + _dragPointerOffset;
+ return;
+ }
+
_rectTransform.anchoredPosition += eventData.delta;
}
@@ -216,6 +226,11 @@ namespace UI
if (!_isPlaced)
{
+ if (ShouldKeepDroppedInPartArea(eventData))
+ {
+ return;
+ }
+
ReturnToSpawnAnimated();
}
}
@@ -273,6 +288,138 @@ namespace UI
}
}
+ private void CacheDragOffset(PointerEventData eventData)
+ {
+ _dragPointerOffset = Vector2.zero;
+
+ if (!TryGetDragParent(out RectTransform dragParent))
+ {
+ return;
+ }
+
+ if (TryGetPointerLocalPosition(eventData, dragParent, out Vector2 pointerLocalPosition))
+ {
+ _dragPointerOffset = _rectTransform.anchoredPosition - pointerLocalPosition;
+ }
+ }
+
+ private bool TryGetDragParent(out RectTransform dragParent)
+ {
+ dragParent = _rectTransform.parent as RectTransform;
+ return dragParent != null;
+ }
+
+ private bool TryGetPointerLocalPosition(PointerEventData eventData, RectTransform targetRect,
+ out Vector2 localPosition)
+ {
+ localPosition = Vector2.zero;
+ if (eventData == null || targetRect == null)
+ {
+ return false;
+ }
+
+ Camera eventCamera = ResolveEventCamera(eventData);
+ return RectTransformUtility.ScreenPointToLocalPointInRectangle(targetRect, eventData.position, eventCamera,
+ out localPosition);
+ }
+
+ private Camera ResolveEventCamera(PointerEventData eventData)
+ {
+ if (eventData != null)
+ {
+ if (eventData.pressEventCamera != null)
+ {
+ return eventData.pressEventCamera;
+ }
+
+ if (eventData.enterEventCamera != null)
+ {
+ return eventData.enterEventCamera;
+ }
+ }
+
+ Canvas canvas = GetComponentInParent