feat: 上一步/下一步支持woman步进撤销重做

- StepManager新增自由步进模式(无Config时):
  InitWomanSteps/RecordWomanStep/WomanStepPrevious/WomanStepNext
- PreviousStep/NextStep在_activeSteps为null时走woman步进
- TouchPositionHandler点击后通知StepManager.RecordWomanStep
- PageController在实验启动时调用InitWomanSteps初始化
- 上一步→woman回到上个位置+显示对应touchPoint
- 下一步→woman移到下个位置+显示对应touchPoint
This commit is contained in:
yangbear
2026-06-30 14:32:30 +08:00
parent 524ad732f9
commit 2df79866d0
4 changed files with 173 additions and 21 deletions
+105 -13
View File
@@ -1267,7 +1267,7 @@ MeshRenderer:
m_RenderingLayerMask: 1
m_RendererPriority: 0
m_Materials:
- {fileID: 2100000, guid: 31321ba15b8f8eb4c954353edc038b1d, type: 2}
- {fileID: 992907168}
m_StaticBatchInfo:
firstSubMesh: 0
subMeshCount: 0
@@ -2064,13 +2064,13 @@ Transform:
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 198874067}
serializedVersion: 2
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalRotation: {x: 0, y: 1, z: 0, w: 0}
m_LocalPosition: {x: -8.2, y: 0.184, z: -8.075}
m_LocalScale: {x: 0.38128, y: 0.38128, z: 0.38128}
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 959961359}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_LocalEulerAnglesHint: {x: 0, y: 180, z: 0}
--- !u!135 &198874069
SphereCollider:
m_ObjectHideFlags: 0
@@ -2112,7 +2112,7 @@ MeshRenderer:
m_RenderingLayerMask: 1
m_RendererPriority: 0
m_Materials:
- {fileID: 2100000, guid: 31321ba15b8f8eb4c954353edc038b1d, type: 2}
- {fileID: 2067232988}
m_StaticBatchInfo:
firstSubMesh: 0
subMeshCount: 0
@@ -3111,6 +3111,8 @@ MonoBehaviour:
OnModeUIUpdate:
m_PersistentCalls:
m_Calls: []
_womanObject: {fileID: 0}
_touchArrayObject: {fileID: 0}
--- !u!114 &441640514
MonoBehaviour:
m_ObjectHideFlags: 0
@@ -3555,13 +3557,13 @@ Transform:
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 559340216}
serializedVersion: 2
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalRotation: {x: 0, y: 0, z: -0, w: -1}
m_LocalPosition: {x: -8.27, y: 0.184, z: -9.975}
m_LocalScale: {x: 0.38128, y: 0.38128, z: 0.38128}
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 959961359}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_LocalEulerAnglesHint: {x: 0, y: 360, z: 0}
--- !u!135 &559340218
SphereCollider:
m_ObjectHideFlags: 0
@@ -3603,7 +3605,7 @@ MeshRenderer:
m_RenderingLayerMask: 1
m_RendererPriority: 0
m_Materials:
- {fileID: 2100000, guid: 31321ba15b8f8eb4c954353edc038b1d, type: 2}
- {fileID: 800635141}
m_StaticBatchInfo:
firstSubMesh: 0
subMeshCount: 0
@@ -4430,6 +4432,36 @@ Transform:
m_Children: []
m_Father: {fileID: 754012933}
m_LocalEulerAnglesHint: {x: 0, y: -90, z: 0}
--- !u!21 &800635141
Material:
serializedVersion: 8
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_Name: BlueOutline (Instance)
m_Shader: {fileID: 4800000, guid: 8f9df7221aff6471e9c94f9880c6b198, type: 3}
m_Parent: {fileID: 0}
m_ModifiedSerializedProperties: 0
m_ValidKeywords: []
m_InvalidKeywords: []
m_LightmapFlags: 4
m_EnableInstancingVariants: 0
m_DoubleSidedGI: 0
m_CustomRenderQueue: -1
stringTagMap: {}
disabledShaderPasses: []
m_LockedProperties:
m_SavedProperties:
serializedVersion: 3
m_TexEnvs: []
m_Ints: []
m_Floats:
- _OutlineWidth: 0.08
m_Colors:
- _MainColor: {r: 0.09999997, g: 0.29999998, b: 0.8, a: 0.3}
- _OutlineColor: {r: 0.19999996, g: 0.5, b: 1, a: 1}
m_BuildTextureStacks: []
--- !u!1 &818830064
GameObject:
m_ObjectHideFlags: 0
@@ -5037,13 +5069,13 @@ Transform:
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 958160145}
serializedVersion: 2
m_LocalRotation: {x: 0, y: 1, z: 0, w: 0}
m_LocalRotation: {x: 0, y: 0, z: -0, w: -1}
m_LocalPosition: {x: -8.172, y: 0, z: -10.117}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 754012933}
m_LocalEulerAnglesHint: {x: 0, y: 180, z: 0}
m_LocalEulerAnglesHint: {x: 0, y: 360, z: 0}
--- !u!1 &959961358
GameObject:
m_ObjectHideFlags: 0
@@ -5078,6 +5110,36 @@ Transform:
- {fileID: 198874068}
m_Father: {fileID: 0}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!21 &992907168
Material:
serializedVersion: 8
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_Name: BlueOutline (Instance)
m_Shader: {fileID: 4800000, guid: 8f9df7221aff6471e9c94f9880c6b198, type: 3}
m_Parent: {fileID: 0}
m_ModifiedSerializedProperties: 0
m_ValidKeywords: []
m_InvalidKeywords: []
m_LightmapFlags: 4
m_EnableInstancingVariants: 0
m_DoubleSidedGI: 0
m_CustomRenderQueue: -1
stringTagMap: {}
disabledShaderPasses: []
m_LockedProperties:
m_SavedProperties:
serializedVersion: 3
m_TexEnvs: []
m_Ints: []
m_Floats:
- _OutlineWidth: 0.08
m_Colors:
- _MainColor: {r: 0.09999997, g: 0.29999998, b: 0.8, a: 0.3}
- _OutlineColor: {r: 0.19999996, g: 0.5, b: 1, a: 1}
m_BuildTextureStacks: []
--- !u!1 &1000453385
GameObject:
m_ObjectHideFlags: 0
@@ -5127,7 +5189,7 @@ MonoBehaviour:
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1000453385}
m_Enabled: 1
m_Enabled: 0
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3}
m_Name:
@@ -6419,13 +6481,13 @@ Transform:
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1109298009}
serializedVersion: 2
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: -8.04, y: 0, z: -8.041}
m_LocalRotation: {x: 0, y: 1, z: 0, w: 0}
m_LocalPosition: {x: -8.04, y: 0, z: -7.65}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 754012933}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_LocalEulerAnglesHint: {x: 0, y: 180, z: 0}
--- !u!1 &1127144482
GameObject:
m_ObjectHideFlags: 0
@@ -11700,6 +11762,36 @@ CanvasRenderer:
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 2010075629}
m_CullTransparentMesh: 1
--- !u!21 &2067232988
Material:
serializedVersion: 8
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_Name: BlueOutline (Instance)
m_Shader: {fileID: 4800000, guid: 8f9df7221aff6471e9c94f9880c6b198, type: 3}
m_Parent: {fileID: 0}
m_ModifiedSerializedProperties: 0
m_ValidKeywords: []
m_InvalidKeywords: []
m_LightmapFlags: 4
m_EnableInstancingVariants: 0
m_DoubleSidedGI: 0
m_CustomRenderQueue: -1
stringTagMap: {}
disabledShaderPasses: []
m_LockedProperties:
m_SavedProperties:
serializedVersion: 3
m_TexEnvs: []
m_Ints: []
m_Floats:
- _OutlineWidth: 0.08
m_Colors:
- _MainColor: {r: 0.09999997, g: 0.29999998, b: 0.8, a: 0.3}
- _OutlineColor: {r: 0.19999996, g: 0.5, b: 1, a: 1}
m_BuildTextureStacks: []
--- !u!1 &2109230712
GameObject:
m_ObjectHideFlags: 0
+62 -7
View File
@@ -124,18 +124,15 @@ public class StepManager : MonoBehaviour
public void NextStep()
{
if (_activeSteps == null) return;
if (_currentStepIndex >= _activeSteps.Length - 1)
{
CompleteExperiment();
return;
}
if (_activeSteps == null) { WomanStepNext(); return; }
if (_currentStepIndex >= _activeSteps.Length - 1) { CompleteExperiment(); return; }
GoToStep(_currentStepIndex + 1);
}
public void PreviousStep()
{
if (_activeSteps == null || _currentStepIndex <= 0) return;
if (_activeSteps == null) { WomanStepPrevious(); return; }
if (_currentStepIndex <= 0) return;
GoToStep(_currentStepIndex - 1);
}
@@ -178,4 +175,62 @@ public class StepManager : MonoBehaviour
GameManager.Instance.CurrentFixationMethod = newFixation;
Initialize(GameManager.Instance.CurrentExperimentType, GameManager.Instance.CurrentMode, newFixation);
}
public void InitWomanSteps()
{
_womanObject = GameObject.Find("woman");
_touchArrayObject = GameObject.Find("touchArray");
var pts = GameObject.Find("womanPointArray");
if (pts != null) { _womanMaxStep = pts.transform.childCount; _womanPositions = new Transform[_womanMaxStep]; for (int i = 0; i < _womanMaxStep; i++) _womanPositions[i] = pts.transform.GetChild(i); }
if (_touchArrayObject != null) { _touchPoints = new GameObject[_touchArrayObject.transform.childCount]; for (int i = 0; i < _touchPoints.Length; i++) _touchPoints[i] = _touchArrayObject.transform.GetChild(i).gameObject; }
_womanStepIndex = 0;
Debug.Log($"StepManager: Woman步进已初始化, 共{_womanMaxStep}个位置");
}
public void RecordWomanStep(int newStepIndex) { _womanStepIndex = Mathf.Clamp(newStepIndex, 0, _womanMaxStep); Debug.Log($"StepManager: Woman步进 -> {_womanStepIndex}"); OnStepChanged?.Invoke(_womanStepIndex); }
private void WomanStepPrevious()
{
if (_womanStepIndex <= 0) return;
_womanStepIndex--;
MoveWomanToStep(_womanStepIndex);
UpdateTouchVisibility(_womanStepIndex);
Debug.Log($"StepManager: Woman撤销 -> {_womanStepIndex}");
OnStepChanged?.Invoke(_womanStepIndex);
}
private void WomanStepNext()
{
if (_womanStepIndex >= _womanMaxStep) return;
_womanStepIndex++;
MoveWomanToStep(_womanStepIndex);
UpdateTouchVisibility(_womanStepIndex);
Debug.Log($"StepManager: Woman前进 -> {_womanStepIndex}");
OnStepChanged?.Invoke(_womanStepIndex);
}
private void MoveWomanToStep(int step)
{
if (_womanObject == null || _womanPositions == null || step <= 0 || step > _womanPositions.Length) return;
var t = _womanPositions[step - 1];
_womanObject.transform.position = t.position;
_womanObject.transform.rotation = t.rotation;
}
private void UpdateTouchVisibility(int step)
{
if (_touchPoints == null) return;
for (int i = 0; i < _touchPoints.Length; i++) _touchPoints[i].SetActive(i == step - 1);
}
[Header("=== Woman 步进追踪(不依赖 Config ===")]
[SerializeField] private GameObject _womanObject;
[SerializeField] private GameObject _touchArrayObject;
private int _womanStepIndex = 0;
private int _womanMaxStep = 3;
private Transform[] _womanPositions;
private GameObject[] _touchPoints;
}
@@ -39,6 +39,11 @@ public class TouchPositionHandler : MonoBehaviour
Debug.Log($"[TouchPosition] woman 移动到 {targetPosition.name}");
}
// 通知 StepManager 记录步骤
int stepIndex = transform.GetSiblingIndex() + 1;
var sm = FindObjectOfType<StepManager>();
if (sm != null) sm.RecordWomanStep(stepIndex);
StopAllCoroutines();
if (_meshRenderer != null) _meshRenderer.enabled = false;
+1 -1
View File
@@ -304,7 +304,7 @@ public class PageController : MonoBehaviour
{
Debug.Log("PageController: 片头动画完成,显示 ExperimentPanel");
ActivateExperimentObjects();
ShowPage(Page.Experiment);
var smW = FindObjectOfType<StepManager>(); if (smW != null) smW.InitWomanSteps(); ShowPage(Page.Experiment);
var stepManager = FindObjectOfType<StepManager>();
if (stepManager != null)