Merge remote-tracking branch 'origin/develop' into feature/chat_01

This commit is contained in:
CuongNV
2026-04-09 11:57:49 +07:00
9 changed files with 299 additions and 51 deletions
+196 -31
View File
@@ -646,6 +646,141 @@ MonoBehaviour:
m_FillOrigin: 0
m_UseSpriteMesh: 0
m_PixelsPerUnitMultiplier: 1
--- !u!1 &273846344218051884
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 2430319032688992992}
- component: {fileID: 5677368834917231984}
- component: {fileID: 7495533776153823427}
- component: {fileID: 4558769830047620468}
- component: {fileID: 1109319106486568870}
m_Layer: 5
m_Name: Pickup_btn
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!224 &2430319032688992992
RectTransform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 273846344218051884}
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: 3483809415181351540}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0.5, y: 0}
m_AnchorMax: {x: 0.5, y: 0}
m_AnchoredPosition: {x: 135, y: 132}
m_SizeDelta: {x: 60, y: 60}
m_Pivot: {x: 0.5, y: 0}
--- !u!222 &5677368834917231984
CanvasRenderer:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 273846344218051884}
m_CullTransparentMesh: 1
--- !u!114 &7495533776153823427
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 273846344218051884}
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: 9022503099529048306, guid: 205ebb1fc3847174cb78c7574a2b5a7d, 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!114 &4558769830047620468
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 273846344218051884}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 4e29b1a8efbd4b44bb3f3716e73f07ff, type: 3}
m_Name:
m_EditorClassIdentifier:
m_Navigation:
m_Mode: 3
m_WrapAround: 0
m_SelectOnUp: {fileID: 0}
m_SelectOnDown: {fileID: 0}
m_SelectOnLeft: {fileID: 0}
m_SelectOnRight: {fileID: 0}
m_Transition: 1
m_Colors:
m_NormalColor: {r: 1, g: 1, b: 1, a: 1}
m_HighlightedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1}
m_PressedColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1}
m_SelectedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1}
m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608}
m_ColorMultiplier: 1
m_FadeDuration: 0.1
m_SpriteState:
m_HighlightedSprite: {fileID: 0}
m_PressedSprite: {fileID: 0}
m_SelectedSprite: {fileID: 0}
m_DisabledSprite: {fileID: 0}
m_AnimationTriggers:
m_NormalTrigger: Normal
m_HighlightedTrigger: Highlighted
m_PressedTrigger: Pressed
m_SelectedTrigger: Selected
m_DisabledTrigger: Disabled
m_Interactable: 1
m_TargetGraphic: {fileID: 7495533776153823427}
m_OnClick:
m_PersistentCalls:
m_Calls: []
--- !u!114 &1109319106486568870
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 273846344218051884}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 3e67d421887e31f4ea9eee290568e9d2, type: 3}
m_Name:
m_EditorClassIdentifier:
button: {fileID: 4558769830047620468}
maxSearchRadius: 80
--- !u!1 &335905991743982376
GameObject:
m_ObjectHideFlags: 0
@@ -3286,9 +3421,13 @@ MonoBehaviour:
_cinemachineCamera: {fileID: 0}
orbital: {fileID: 0}
dragDeadZone: 0.009259259
horizontalRotationPerScreen: 60
horizontalRotationPerScreen: 180
verticalRotationPerScreen: 500
_migratedDeadZoneToNormalized: 1
_lockView: 0
onViewLockChanged:
m_PersistentCalls:
m_Calls: []
enableZoom: 1
orbitScaleMin: 0.5
orbitScaleMax: 2
@@ -11483,6 +11622,7 @@ RectTransform:
- {fileID: 4528532603973220147}
- {fileID: 4742272256638967314}
- {fileID: 5087414730531131461}
- {fileID: 2430319032688992992}
m_Father: {fileID: 3233441867675090637}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0}
@@ -11509,6 +11649,7 @@ MonoBehaviour:
_btnTaskTrace: {fileID: 3253955040536933532}
_taskTraceParent: {fileID: 2578159539417438268}
_btnTeamList: {fileID: 540188344648694736}
_lockviewList: {fileID: 0}
--- !u!1 &7352847439676120744
GameObject:
m_ObjectHideFlags: 0
@@ -18760,6 +18901,30 @@ PrefabInstance:
propertyPath: m_LocalEulerAnglesHint.z
value: 0
objectReference: {fileID: 0}
- target: {fileID: 1847659348073965440, guid: a531b4b63ab8355419f297fe10d32abe, type: 3}
propertyPath: m_AnchorMax.y
value: 0
objectReference: {fileID: 0}
- target: {fileID: 1847659348073965440, guid: a531b4b63ab8355419f297fe10d32abe, type: 3}
propertyPath: m_AnchorMin.y
value: 0
objectReference: {fileID: 0}
- target: {fileID: 1847659348073965440, guid: a531b4b63ab8355419f297fe10d32abe, type: 3}
propertyPath: m_SizeDelta.x
value: 0
objectReference: {fileID: 0}
- target: {fileID: 1847659348073965440, guid: a531b4b63ab8355419f297fe10d32abe, type: 3}
propertyPath: m_SizeDelta.y
value: 0
objectReference: {fileID: 0}
- target: {fileID: 1847659348073965440, guid: a531b4b63ab8355419f297fe10d32abe, type: 3}
propertyPath: m_AnchoredPosition.x
value: 0
objectReference: {fileID: 0}
- target: {fileID: 1847659348073965440, guid: a531b4b63ab8355419f297fe10d32abe, type: 3}
propertyPath: m_AnchoredPosition.y
value: 0
objectReference: {fileID: 0}
- target: {fileID: 2445625116770621752, guid: a531b4b63ab8355419f297fe10d32abe, type: 3}
propertyPath: m_AnchorMax.y
value: 0
@@ -20560,7 +20725,7 @@ PrefabInstance:
m_Modifications:
- target: {fileID: 281531643843465414, guid: f2e88ae97c9b2624dbbad1d5fc0c14b8, type: 3}
propertyPath: m_SizeDelta.y
value: 0
value: 34.75
objectReference: {fileID: 0}
- target: {fileID: 612290564657202925, guid: f2e88ae97c9b2624dbbad1d5fc0c14b8, type: 3}
propertyPath: m_text
@@ -20568,7 +20733,7 @@ PrefabInstance:
objectReference: {fileID: 0}
- target: {fileID: 720995613977598853, guid: f2e88ae97c9b2624dbbad1d5fc0c14b8, type: 3}
propertyPath: m_SizeDelta.y
value: 0
value: 4
objectReference: {fileID: 0}
- target: {fileID: 1565091892493587231, guid: f2e88ae97c9b2624dbbad1d5fc0c14b8, type: 3}
propertyPath: m_AnchorMax.y
@@ -20592,19 +20757,19 @@ PrefabInstance:
objectReference: {fileID: 0}
- target: {fileID: 1807009239444610075, guid: f2e88ae97c9b2624dbbad1d5fc0c14b8, type: 3}
propertyPath: m_AnchorMax.y
value: 0
value: 1
objectReference: {fileID: 0}
- target: {fileID: 1807009239444610075, guid: f2e88ae97c9b2624dbbad1d5fc0c14b8, type: 3}
propertyPath: m_AnchorMin.y
value: 0
value: 1
objectReference: {fileID: 0}
- target: {fileID: 1807009239444610075, guid: f2e88ae97c9b2624dbbad1d5fc0c14b8, type: 3}
propertyPath: m_AnchoredPosition.x
value: 0
value: 73.5
objectReference: {fileID: 0}
- target: {fileID: 1807009239444610075, guid: f2e88ae97c9b2624dbbad1d5fc0c14b8, type: 3}
propertyPath: m_AnchoredPosition.y
value: 0
value: -320.36667
objectReference: {fileID: 0}
- target: {fileID: 1845571473519222713, guid: f2e88ae97c9b2624dbbad1d5fc0c14b8, type: 3}
propertyPath: m_Pivot.x
@@ -20708,35 +20873,35 @@ PrefabInstance:
objectReference: {fileID: 0}
- target: {fileID: 2316633321864138780, guid: f2e88ae97c9b2624dbbad1d5fc0c14b8, type: 3}
propertyPath: m_AnchorMax.y
value: 0
value: 1
objectReference: {fileID: 0}
- target: {fileID: 2316633321864138780, guid: f2e88ae97c9b2624dbbad1d5fc0c14b8, type: 3}
propertyPath: m_AnchorMin.y
value: 0
value: 1
objectReference: {fileID: 0}
- target: {fileID: 2316633321864138780, guid: f2e88ae97c9b2624dbbad1d5fc0c14b8, type: 3}
propertyPath: m_AnchoredPosition.x
value: 0
value: 73.5
objectReference: {fileID: 0}
- target: {fileID: 2316633321864138780, guid: f2e88ae97c9b2624dbbad1d5fc0c14b8, type: 3}
propertyPath: m_AnchoredPosition.y
value: 0
value: -557.43335
objectReference: {fileID: 0}
- target: {fileID: 2833899088985087574, guid: f2e88ae97c9b2624dbbad1d5fc0c14b8, type: 3}
propertyPath: m_AnchorMax.y
value: 0
value: 1
objectReference: {fileID: 0}
- target: {fileID: 2833899088985087574, guid: f2e88ae97c9b2624dbbad1d5fc0c14b8, type: 3}
propertyPath: m_AnchorMin.y
value: 0
value: 1
objectReference: {fileID: 0}
- target: {fileID: 2833899088985087574, guid: f2e88ae97c9b2624dbbad1d5fc0c14b8, type: 3}
propertyPath: m_AnchoredPosition.x
value: 0
value: 73.5
objectReference: {fileID: 0}
- target: {fileID: 2833899088985087574, guid: f2e88ae97c9b2624dbbad1d5fc0c14b8, type: 3}
propertyPath: m_AnchoredPosition.y
value: 0
value: -82.4
objectReference: {fileID: 0}
- target: {fileID: 2971518514894512202, guid: f2e88ae97c9b2624dbbad1d5fc0c14b8, type: 3}
propertyPath: m_AnchorMax.y
@@ -20776,19 +20941,19 @@ PrefabInstance:
objectReference: {fileID: 0}
- target: {fileID: 3932182246454713380, guid: f2e88ae97c9b2624dbbad1d5fc0c14b8, type: 3}
propertyPath: m_AnchorMax.y
value: 0
value: 1
objectReference: {fileID: 0}
- target: {fileID: 3932182246454713380, guid: f2e88ae97c9b2624dbbad1d5fc0c14b8, type: 3}
propertyPath: m_AnchorMin.y
value: 0
value: 1
objectReference: {fileID: 0}
- target: {fileID: 3932182246454713380, guid: f2e88ae97c9b2624dbbad1d5fc0c14b8, type: 3}
propertyPath: m_AnchoredPosition.x
value: 0
value: 73.5
objectReference: {fileID: 0}
- target: {fileID: 3932182246454713380, guid: f2e88ae97c9b2624dbbad1d5fc0c14b8, type: 3}
propertyPath: m_AnchoredPosition.y
value: 0
value: -675.9667
objectReference: {fileID: 0}
- target: {fileID: 5246174072855755290, guid: f2e88ae97c9b2624dbbad1d5fc0c14b8, type: 3}
propertyPath: maxPoolSize
@@ -20796,47 +20961,47 @@ PrefabInstance:
objectReference: {fileID: 0}
- target: {fileID: 5523955004350801122, guid: f2e88ae97c9b2624dbbad1d5fc0c14b8, type: 3}
propertyPath: m_AnchorMax.y
value: 0
value: 1
objectReference: {fileID: 0}
- target: {fileID: 5523955004350801122, guid: f2e88ae97c9b2624dbbad1d5fc0c14b8, type: 3}
propertyPath: m_AnchorMin.y
value: 0
value: 1
objectReference: {fileID: 0}
- target: {fileID: 5523955004350801122, guid: f2e88ae97c9b2624dbbad1d5fc0c14b8, type: 3}
propertyPath: m_AnchoredPosition.x
value: 0
value: 73.5
objectReference: {fileID: 0}
- target: {fileID: 5523955004350801122, guid: f2e88ae97c9b2624dbbad1d5fc0c14b8, type: 3}
propertyPath: m_AnchoredPosition.y
value: 0
value: -201.83334
objectReference: {fileID: 0}
- target: {fileID: 6384211195128645007, guid: f2e88ae97c9b2624dbbad1d5fc0c14b8, type: 3}
propertyPath: m_AnchorMax.y
value: 0
value: 1
objectReference: {fileID: 0}
- target: {fileID: 6384211195128645007, guid: f2e88ae97c9b2624dbbad1d5fc0c14b8, type: 3}
propertyPath: m_AnchorMin.y
value: 0
value: 1
objectReference: {fileID: 0}
- target: {fileID: 6384211195128645007, guid: f2e88ae97c9b2624dbbad1d5fc0c14b8, type: 3}
propertyPath: m_AnchoredPosition.x
value: 0
value: 73.5
objectReference: {fileID: 0}
- target: {fileID: 6384211195128645007, guid: f2e88ae97c9b2624dbbad1d5fc0c14b8, type: 3}
propertyPath: m_AnchoredPosition.y
value: 0
value: -438.9
objectReference: {fileID: 0}
- target: {fileID: 6789168510972833533, guid: f2e88ae97c9b2624dbbad1d5fc0c14b8, type: 3}
propertyPath: m_AnchorMax.x
value: 0
value: 1
objectReference: {fileID: 0}
- target: {fileID: 6789168510972833533, guid: f2e88ae97c9b2624dbbad1d5fc0c14b8, type: 3}
propertyPath: m_AnchorMax.y
value: 0
value: 1
objectReference: {fileID: 0}
- target: {fileID: 6921900574306804872, guid: f2e88ae97c9b2624dbbad1d5fc0c14b8, type: 3}
propertyPath: m_SizeDelta.x
value: 0
value: -794.61884
objectReference: {fileID: 0}
- target: {fileID: 7404691444252589623, guid: f2e88ae97c9b2624dbbad1d5fc0c14b8, type: 3}
propertyPath: m_Name
@@ -20864,7 +21029,7 @@ PrefabInstance:
objectReference: {fileID: 0}
- target: {fileID: 8043788806156166990, guid: f2e88ae97c9b2624dbbad1d5fc0c14b8, type: 3}
propertyPath: m_SizeDelta.y
value: 0
value: 34.75
objectReference: {fileID: 0}
- target: {fileID: 8844668668090027388, guid: f2e88ae97c9b2624dbbad1d5fc0c14b8, type: 3}
propertyPath: m_AnchorMax.y
+2 -2
View File
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:f85e6e6bc4d5b6af2e103cf46a846213439f86c209bed0512839f28b8c23a7c6
size 326984
oid sha256:13a594f73641f7ee47a7a46bc38cd207d4ae93cfbccbdd33052c91d62aead223
size 294261
@@ -1,6 +1,7 @@
using Unity.Cinemachine;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.Events;
namespace BrewMonster
{
@@ -15,6 +16,11 @@ namespace BrewMonster
[SerializeField] private float verticalRotationPerScreen = 500f;
[SerializeField, HideInInspector] private bool _migratedDeadZoneToNormalized;
[Header("Lock view")]
[Tooltip("When locked: no zoom; drag only orbits around world Y (horizontal axis).")]
[SerializeField] private bool _lockView;
[SerializeField] private UnityEvent<bool> onViewLockChanged;
[Header("Zoom (orbit scale)")]
[Tooltip("RadialAxis scales camera distance: effective distance = Orbital Follow Radius × this value.")]
[SerializeField] private bool enableZoom = true;
@@ -30,6 +36,26 @@ namespace BrewMonster
public CinemachineOrbitalFollow Orbital { get => orbital;}
public bool ViewLocked => _lockView;
public void SetViewLocked(bool locked)
{
if (_lockView == locked)
{
return;
}
_lockView = locked;
onViewLockChanged?.Invoke(_lockView);
}
public void ToggleViewLocked()
{
SetViewLocked(!_lockView);
}
private bool CanApplyZoom => enableZoom && !_lockView;
void OnEnable()
{
Instance = this;
@@ -55,9 +81,11 @@ namespace BrewMonster
if (normalizedDelta.sqrMagnitude >= normalizedDeadZone * normalizedDeadZone)
{
orbital.HorizontalAxis.Value += normalizedDelta.x * horizontalRotationPerScreen;
//orbital.HorizontalAxis.Value = Mathf.Clamp(orbital.HorizontalAxis.Value, -360f, 360f);
orbital.VerticalAxis.Value -= normalizedDelta.y * verticalRotationPerScreen;
orbital.VerticalAxis.Value = Mathf.Clamp(orbital.VerticalAxis.Value, -360f, 360f);
if (!_lockView)
{
orbital.VerticalAxis.Value -= normalizedDelta.y * verticalRotationPerScreen;
orbital.VerticalAxis.Value = Mathf.Clamp(orbital.VerticalAxis.Value, -360f, 360f);
}
}
}
@@ -124,7 +152,7 @@ namespace BrewMonster
private void ApplyRadialZoomDelta(float delta)
{
if (!enableZoom || orbital == null || Mathf.Abs(delta) < 1e-6f)
if (!CanApplyZoom || orbital == null || Mathf.Abs(delta) < 1e-6f)
{
return;
}
@@ -136,7 +164,7 @@ namespace BrewMonster
private void UpdatePinchZoom()
{
if (!enableZoom || orbital == null)
if (!CanApplyZoom || orbital == null)
{
_pinchZoomActive = false;
return;
@@ -204,7 +232,7 @@ namespace BrewMonster
}
#if UNITY_EDITOR || UNITY_STANDALONE || UNITY_WEBGL
if (enableZoom && orbital != null)
if (CanApplyZoom && orbital != null)
{
float scroll = Input.mouseScrollDelta.y;
if (Mathf.Abs(scroll) > Mathf.Epsilon)
@@ -0,0 +1,38 @@
using UnityEngine;
using UnityEngine.UI;
namespace BrewMonster
{
/// <summary>
/// Wires a UI <see cref="Button"/> to <see cref="CameraController.ToggleViewLocked"/>.
/// Add to the same GameObject as the button or assign the reference in the Inspector.
/// </summary>
public class CameraViewLockButton : MonoBehaviour
{
[SerializeField] private Button lockToggleButton;
private void OnEnable()
{
if (lockToggleButton != null)
{
lockToggleButton.onClick.AddListener(OnLockButtonClicked);
}
}
private void OnDisable()
{
if (lockToggleButton != null)
{
lockToggleButton.onClick.RemoveListener(OnLockButtonClicked);
}
}
private void OnLockButtonClicked()
{
if (CameraController.Instance != null)
{
CameraController.Instance.ToggleViewLocked();
}
}
}
}
@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 10cef83c908cb734eaa7fe6c336aa621
@@ -2079,7 +2079,7 @@ namespace BrewMonster.UI
for (j = 0; j < pTalk.windows[i].num_option; j++)
{
strText = GetStringFromTable(249);
strText += pTalk.windows[i].options[j].text;
strText += Encoding.Unicode.GetString(MemoryMarshal.AsBytes<ushort>(pTalk.windows[i].options[j].text));
m_pLst_Main.AddString(strText);
nIndex = m_pLst_Main.GetCount() - 1;
m_pLst_Main.SetItemData(nIndex, pTalk.windows[i].options[j].id);
@@ -2201,7 +2201,7 @@ namespace BrewMonster.UI
for (j = 0; j < pTalk.windows[i].num_option; j++)
{
strText = GetStringFromTable(249);
strText += pTalk.windows[i].options[j].text;
strText += Encoding.Unicode.GetString(MemoryMarshal.AsBytes<ushort>(pTalk.windows[i].options[j].text));
m_pLst_Main.AddString(strText);
nIndex = m_pLst_Main.GetCount() - 1;
m_pLst_Main.SetItemData(nIndex, pTalk.windows[i].options[j].id);
@@ -26,7 +26,7 @@ namespace BrewMonster
_btnInvntory.onClick.AddListener(OnInventoryClicked);
_btnTeam.onValueChanged.AddListener(OnTeamClicked);
_btnTaskTrace.onValueChanged.AddListener(OnTaskTraceClicked);
_btnTeamList.onClick.AddListener(OnTeamListClicked);
_btnTeamList.onClick.AddListener(OnTeamListClicked);
EventBus.Unsubscribe<UIEvent>(OnUIEvent);
EventBus.Subscribe<UIEvent>(OnUIEvent);
}
+14
View File
@@ -63,6 +63,7 @@ namespace BrewMonster
private CECPetCorral m_pPetCorral;
private List<CECObject> m_aTabSels = new List<CECObject>();
private int m_lastAutoSelectNearestId = 0;
private List<CECSkill> m_aPtSkills = new List<CECSkill>();
private List<CECSkill> m_aPsSkills = new List<CECSkill>();
private List<CECSkill> m_aEquipSkills = new List<CECSkill>();
@@ -2812,10 +2813,22 @@ namespace BrewMonster
int idNewSel = 0;
if (sorted.Count == 0)
{
m_lastAutoSelectNearestId = 0;
idNewSel = idCurSel;
}
else
{
int nearestId = sorted[0].id;
if (nearestId != 0 && nearestId != m_lastAutoSelectNearestId)
{
// If the nearest target changed (movement/spawn/despawn), reset cycle back to nearest
m_lastAutoSelectNearestId = nearestId;
idNewSel = nearestId;
}
else
{
m_lastAutoSelectNearestId = nearestId;
int idx = -1;
for (int i = 0; i < sorted.Count; i++)
{
@@ -2827,6 +2840,7 @@ namespace BrewMonster
}
int nextIdx = idx < 0 ? 0 : (idx + 1) % sorted.Count;
idNewSel = sorted[nextIdx].id;
}
}
// Select the target if found / 如果找到目标则选择它
+10 -9
View File
@@ -5,8 +5,8 @@
This document provides a comprehensive plan to convert the Perfect World skill GFX (graphical effects) system from C++ to Unity C#. The system handles visual effects when players cast skills, including projectile flight, hit effects, and various movement patterns.
**Date Created:** 2026-02-11
**Last Updated:** 2026-02-24
**Status:** Phase 1 Complete — Movement system created, scale removed (Particle Systems)
**Last Updated:** 2026-04-08
**Status:** Phase 1 Complete — Movement system, state machine, per-event GFX flags all working
**Complexity:** Medium - Core structure exists, needs wiring up
---
@@ -65,9 +65,9 @@ GFX Spawning (fly/hit) - Instantiate prefabs ✅ IMPLEMENTED (CECSkillGfxEvent)
| `CECAttackEvent` | `CECAttacksMan.cs` | ✅ Working (full DoFire with Player/NPC/weapon branches) |
| `A3DSkillGfxComposerMan` | `A3DSkillGfxComposerMan.cs` | ✅ Complete (load, play, lookup) |
| `A3DSkillGfxComposer` | `CECAttacksMan.cs` (partial) + `CECSkillGfxMan.cs` (partial) | ✅ Mostly complete (Load from SkillStub, Play, AddOneTarget) |
| `A3DSkillGfxMan` | `A3DSkillGfxMan.cs` | ✅ Working (AddSkillGfxEvent, clustering, scale removed) |
| `A3DSkillGfxEvent` | `A3DSkillGfxMan.cs` | ✅ State machine working (Wait→Flying→Hit→Finished) |
| `CECSkillGfxEvent` | `CECSkillGfxMan.cs` | ✅ Working (Tick, SpawnFlyGfx, SpawnHitGfx, HitTarget) |
| `A3DSkillGfxMan` | `A3DSkillGfxMan.cs` | ✅ Working (AddSkillGfxEvent, clustering, scale removed, per-event fly/hit flags) |
| `A3DSkillGfxEvent` | `A3DSkillGfxMan.cs` | ✅ State machine working (Wait→Flying→Hit→Finished), `m_bShowFlyGfx`/`m_bShowHitGfx` flags |
| `CECSkillGfxEvent` | `CECSkillGfxMan.cs` | ✅ Working (Tick, SpawnFlyGfx, SpawnHitGfx, HitTarget — respects per-event show flags) |
| `SkillGfxMan` | `CECSkillGfxMan.cs` | ✅ Event pool, Tick loop, GetEmptyEvent |
| `CGfxMoveBase` (Movement) | `CGfxMoveBase.cs` | ✅ Created (Linear + OnTarget, factory method) |
| `CECMultiSectionSkillMan` | `CECAttacksMan.cs` | ⚠️ Structure done, LoadConfig not implemented |
@@ -816,11 +816,11 @@ m_pMoveMethod.TickMove(dwDeltaTime, m_vHostPos, m_vTargetPos);
**Solution:** Remove SpawnGFX call from `AddOneSkillGfxEvent()`. GFX spawning should happen inside `CECSkillGfxEvent.Tick()` when transitioning from Wait→Flying state.
### 6.4 Challenge: GFX String vs Prefab in AddSkillGfxEvent
### 6.4 Challenge: GFX String vs Prefab in AddSkillGfxEvent ✅ RESOLVED
**Issue:** `AddSkillGfxEvent` receives `string szFlyGfx` / `string szHitGfx`, but the actual prefab is on the composer.
**Issue:** `AddSkillGfxEvent` receives `string szFlyGfx` / `string szHitGfx`, but the actual prefab is on the composer. All events shared the same composer, so `SpawnFlyGfx()` always called `m_pComposer.GetFlyGFX()` and spawned a fly GFX — even for secondary targets where `AddOneTarget()` had nulled the string via `enumAttArea`. This caused wide-area skills to spawn redundant fly GFX on every target instead of only the main target.
**Solution:** The event already receives `pComposer` reference. Use `pComposer.GetFlyGFX()` / `pComposer.GetHitGFX()` for instantiation. The string params can be used for null-check (if empty, skip fly/hit).
**Solution (implemented 2026-04-08):** Added per-event `m_bShowFlyGfx` / `m_bShowHitGfx` boolean flags on `A3DSkillGfxEvent`. In `AddOneSkillGfxEvent()`, flags are set based on whether `szFlyGfx` / `szHitGfx` are non-null. `SpawnFlyGfx()` and `SpawnHitGfx()` in `CECSkillGfxEvent` early-return when the flag is false. Flags reset to `true` in `Resume()` for event pool reuse.
### 6.5 Challenge: Timing Synchronization
@@ -952,13 +952,14 @@ BMLogger.Log($"[GFX_FLOW] HitTarget at {vTarget}");
**End of Document**
This plan was last updated 2026-02-24. **Phase 1 is now complete (~95%)**:
This plan was last updated 2026-04-08. **Phase 1 is now complete (100%)**:
1. ✅ Movement system created (`CGfxMoveBase`, `CGfxLinearMove`, `CGfxOnTargetMove`)
2. ✅ State machine working (Wait→Flying→Hit→Finished)
3. ✅ GFX spawning via `CECSkillGfxEvent` (SpawnFlyGfx, SpawnHitGfx)
4. ✅ Scale parameters removed — Unity Particle Systems handle their own scale
5. ✅ SkillGfxMan.Tick() wired into Update loop
6. ✅ NPC skill GFX path wired up
7. ✅ Area skill (`enumAttArea`) per-event fly/hit GFX suppression — secondary targets no longer spawn redundant fly GFX
**Remaining Phase 2+ work:**
- Additional movement modes (Parabolic, Missile, Helix, etc.)