From 93e0ec0ed9c4546bb80384ef79b2a99ca526073d Mon Sep 17 00:00:00 2001 From: Christen Date: Mon, 9 Feb 2026 20:53:23 -0500 Subject: [PATCH 1/6] Added camera movement and home button to bring user back to module structure --- Assets/Icons.meta | 8 + Assets/Icons/homeIcon.png | Bin 0 -> 6259 bytes Assets/Icons/homeIcon.png.meta | 143 +++++++++++ Assets/ModuleSelector.cs | 67 +++-- Assets/Scenes/SampleScene.unity | 413 ++++++++++++++++++++++++++----- Assets/UserCameraControl.cs | 252 +++++++++++++++++++ Assets/UserCameraControl.cs.meta | 2 + 7 files changed, 801 insertions(+), 84 deletions(-) create mode 100644 Assets/Icons.meta create mode 100644 Assets/Icons/homeIcon.png create mode 100644 Assets/Icons/homeIcon.png.meta create mode 100644 Assets/UserCameraControl.cs create mode 100644 Assets/UserCameraControl.cs.meta diff --git a/Assets/Icons.meta b/Assets/Icons.meta new file mode 100644 index 0000000..b111247 --- /dev/null +++ b/Assets/Icons.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 8e20547d53adc426582ff5b3fd086ce5 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Icons/homeIcon.png b/Assets/Icons/homeIcon.png new file mode 100644 index 0000000000000000000000000000000000000000..c40c6b2296a5a1ebeaaf9ba657b2357fafb84de0 GIT binary patch literal 6259 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 - if (module != null && module != prevModule) + if (module != null) { module.OnSelect(); prevModule = module; - virtualCamera.LookAt = module.transform; - virtualCamera.Follow = module.transform; - } - else - { - prevModule = null; + + // Servo highlighting support + ServoMotorModule servo = module.GetComponent(); + ServoMotorModule.selectedModule = servo; + + // tell camera to look at module + if (cameraController != null) + cameraController.LookAtTarget(module.transform); } } else { - prevModule = null; + ClearSelection(); } } } -} + + // Deselect current module and clear selection state + void ClearSelection() + { + if (prevModule != null) + { + prevModule.DeSelect(); + prevModule = null; + } + + ServoMotorModule.selectedModule = null; + + if (EventSystem.current != null) + EventSystem.current.SetSelectedGameObject(null); + } +} \ No newline at end of file diff --git a/Assets/Scenes/SampleScene.unity b/Assets/Scenes/SampleScene.unity index 08403fa..9f9738f 100644 --- a/Assets/Scenes/SampleScene.unity +++ b/Assets/Scenes/SampleScene.unity @@ -376,33 +376,6 @@ GameObject: m_CorrespondingSourceObject: {fileID: 2070925441746177671, guid: a1a802ecaf6775746bb2a929fb554ad8, type: 3} m_PrefabInstance: {fileID: 507316325} m_PrefabAsset: {fileID: 0} ---- !u!114 &119477702 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 119477699} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: 058ebb4ac460d4858a5168bd61608f8e, type: 3} - m_Name: - m_EditorClassIdentifier: - zoomSpeed: 4 - minDistance: 2 - maxDistance: 20 - virtualCamera: {fileID: 119477703} ---- !u!114 &119477703 stripped -MonoBehaviour: - m_CorrespondingSourceObject: {fileID: 2070925441746177913, guid: a1a802ecaf6775746bb2a929fb554ad8, type: 3} - m_PrefabInstance: {fileID: 507316325} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 119477699} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: 45e653bab7fb20e499bda25e1b646fea, type: 3} - m_Name: - m_EditorClassIdentifier: --- !u!114 &119477705 MonoBehaviour: m_ObjectHideFlags: 0 @@ -410,25 +383,13 @@ MonoBehaviour: m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 119477699} - m_Enabled: 1 + m_Enabled: 0 m_EditorHideFlags: 0 m_Script: {fileID: 11500000, guid: a3e78cb07340e40e483ee29459792ca4, type: 3} m_Name: m_EditorClassIdentifier: - mainCamera: {fileID: 963194227} - virtualCamera: {fileID: 119477703} ---- !u!114 &119477707 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 119477699} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: d7183a4f096e7481b9079478193d04a0, type: 3} - m_Name: - m_EditorClassIdentifier: + mainCamera: {fileID: 0} + cameraController: {fileID: 0} --- !u!1001 &154658906 PrefabInstance: m_ObjectHideFlags: 0 @@ -703,6 +664,81 @@ Transform: m_CorrespondingSourceObject: {fileID: 1669686713939424428, guid: 8f54eee4d6fe643ba98e080c86deb5d1, type: 3} m_PrefabInstance: {fileID: 715658897} m_PrefabAsset: {fileID: 0} +--- !u!1 &263702966 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 263702967} + - component: {fileID: 263702969} + - component: {fileID: 263702968} + m_Layer: 5 + m_Name: HomeImg + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &263702967 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 263702966} + 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: 1506978711} + 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: 40, y: 40} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &263702968 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 263702966} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: UnityEngine.UI::UnityEngine.UI.Image + 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: 21300000, guid: 014f6511aae4941219c1b2bf26a752b9, 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!222 &263702969 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 263702966} + m_CullTransparentMesh: 1 --- !u!1 &308277469 GameObject: m_ObjectHideFlags: 0 @@ -1306,6 +1342,7 @@ RectTransform: - {fileID: 1557863855} - {fileID: 395535431} - {fileID: 910000010} + - {fileID: 1506978711} m_Father: {fileID: 0} m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} @@ -1335,33 +1372,37 @@ PrefabInstance: propertyPath: m_Name value: PlayerFollowCamera objectReference: {fileID: 0} - - target: {fileID: 2070925441746177912, guid: a1a802ecaf6775746bb2a929fb554ad8, type: 3} - propertyPath: m_LocalPosition.x + - target: {fileID: 2070925441746177671, guid: a1a802ecaf6775746bb2a929fb554ad8, type: 3} + propertyPath: m_IsActive value: 0 objectReference: {fileID: 0} + - target: {fileID: 2070925441746177912, guid: a1a802ecaf6775746bb2a929fb554ad8, type: 3} + propertyPath: m_LocalPosition.x + value: 628.26337 + objectReference: {fileID: 0} - target: {fileID: 2070925441746177912, guid: a1a802ecaf6775746bb2a929fb554ad8, type: 3} propertyPath: m_LocalPosition.y - value: 1.5 + value: 0.588705 objectReference: {fileID: 0} - target: {fileID: 2070925441746177912, guid: a1a802ecaf6775746bb2a929fb554ad8, type: 3} propertyPath: m_LocalPosition.z - value: -5 + value: 925.5157 objectReference: {fileID: 0} - target: {fileID: 2070925441746177912, guid: a1a802ecaf6775746bb2a929fb554ad8, type: 3} propertyPath: m_LocalRotation.w - value: 0.9890959 + value: 0.7670636 objectReference: {fileID: 0} - target: {fileID: 2070925441746177912, guid: a1a802ecaf6775746bb2a929fb554ad8, type: 3} propertyPath: m_LocalRotation.x - value: 0.14498226 + value: 0.022258926 objectReference: {fileID: 0} - target: {fileID: 2070925441746177912, guid: a1a802ecaf6775746bb2a929fb554ad8, type: 3} propertyPath: m_LocalRotation.y - value: 0.025600422 + value: -0.6409151 objectReference: {fileID: 0} - target: {fileID: 2070925441746177912, guid: a1a802ecaf6775746bb2a929fb554ad8, type: 3} propertyPath: m_LocalRotation.z - value: -0.0037525252 + value: 0.018598305 objectReference: {fileID: 0} - target: {fileID: 2070925441746177912, guid: a1a802ecaf6775746bb2a929fb554ad8, type: 3} propertyPath: m_LocalEulerAnglesHint.x @@ -1375,24 +1416,26 @@ PrefabInstance: propertyPath: m_LocalEulerAnglesHint.z value: 0 objectReference: {fileID: 0} + - target: {fileID: 2070925441746177913, guid: a1a802ecaf6775746bb2a929fb554ad8, type: 3} + propertyPath: m_Follow + value: + objectReference: {fileID: 0} - target: {fileID: 2070925441746177913, guid: a1a802ecaf6775746bb2a929fb554ad8, type: 3} propertyPath: m_LookAt value: objectReference: {fileID: 0} + - target: {fileID: 2070925441746177913, guid: a1a802ecaf6775746bb2a929fb554ad8, type: 3} + propertyPath: m_Enabled + value: 0 + objectReference: {fileID: 0} m_RemovedComponents: - {fileID: 2070925442191277752, guid: a1a802ecaf6775746bb2a929fb554ad8, type: 3} m_RemovedGameObjects: [] m_AddedGameObjects: [] m_AddedComponents: - - targetCorrespondingSourceObject: {fileID: 2070925441746177671, guid: a1a802ecaf6775746bb2a929fb554ad8, type: 3} - insertIndex: -1 - addedObject: {fileID: 119477702} - targetCorrespondingSourceObject: {fileID: 2070925441746177671, guid: a1a802ecaf6775746bb2a929fb554ad8, type: 3} insertIndex: -1 addedObject: {fileID: 119477705} - - targetCorrespondingSourceObject: {fileID: 2070925441746177671, guid: a1a802ecaf6775746bb2a929fb554ad8, type: 3} - insertIndex: -1 - addedObject: {fileID: 119477707} - targetCorrespondingSourceObject: {fileID: 2070925442191277755, guid: a1a802ecaf6775746bb2a929fb554ad8, type: 3} insertIndex: -1 addedObject: {fileID: 1135363931} @@ -3876,6 +3919,8 @@ GameObject: - component: {fileID: 963194227} - component: {fileID: 963194226} - component: {fileID: 963194229} + - component: {fileID: 963194230} + - component: {fileID: 963194231} m_Layer: 0 m_Name: Main Camera m_TagString: MainCamera @@ -3950,8 +3995,8 @@ Transform: m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 963194225} serializedVersion: 2 - m_LocalRotation: {x: 0.14498226, y: 0.02560042, z: -0.003752525, w: 0.9890959} - m_LocalPosition: {x: 0, y: 1.5, z: -5} + m_LocalRotation: {x: 0.022258928, y: -0.64091516, z: 0.018598307, w: 0.76706356} + m_LocalPosition: {x: 628.26337, y: 0.588705, z: 925.5157} m_LocalScale: {x: 1, y: 1, z: 1} m_ConstrainProportionsScale: 0 m_Children: [] @@ -3964,7 +4009,7 @@ MonoBehaviour: m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 963194225} - m_Enabled: 1 + m_Enabled: 0 m_EditorHideFlags: 0 m_Script: {fileID: 11500000, guid: 72ece51f2901e7445ab60da3685d6b5f, type: 3} m_Name: @@ -3977,7 +4022,7 @@ MonoBehaviour: m_BlendUpdateMethod: 1 m_DefaultBlend: m_Style: 1 - m_Time: 2 + m_Time: 0 m_CustomCurve: serializedVersion: 2 m_Curve: [] @@ -3991,6 +4036,45 @@ MonoBehaviour: m_CameraActivatedEvent: m_PersistentCalls: m_Calls: [] +--- !u!114 &963194230 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 963194225} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 664693941061d4a4ab8a0a945db827f3, type: 3} + m_Name: + m_EditorClassIdentifier: Assembly-CSharp::UserCameraControl + mainCamera: {fileID: 963194227} + handCursor: {fileID: 0} + eyeCursor: {fileID: 0} + cursorHotspot: {x: 0, y: 0} + panSpeed: 3.5 + zoomSpeed: 10 + moveSmoothTime: 0.12 + orbitSpeed: 150 + minPitch: -80 + maxPitch: 80 + orbitSmoothTime: 0.08 + lookAtDuration: 0.25 + homeDuration: 0.35 +--- !u!114 &963194231 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 963194225} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: a3e78cb07340e40e483ee29459792ca4, type: 3} + m_Name: + m_EditorClassIdentifier: '::' + mainCamera: {fileID: 963194227} + cameraController: {fileID: 963194230} --- !u!1 &974551545 GameObject: m_ObjectHideFlags: 0 @@ -4632,7 +4716,7 @@ MonoBehaviour: m_Name: m_EditorClassIdentifier: m_BindingMode: 1 - m_FollowOffset: {x: 0, y: 1.5, z: -5} + m_FollowOffset: {x: 5.128378, y: 0.302705, z: -0.9264084} m_XDamping: 1 m_YDamping: 1 m_ZDamping: 1 @@ -5904,6 +5988,139 @@ PrefabInstance: m_AddedGameObjects: [] m_AddedComponents: [] m_SourcePrefab: {fileID: 100100000, guid: 8f54eee4d6fe643ba98e080c86deb5d1, type: 3} +--- !u!1 &1506978710 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1506978711} + - component: {fileID: 1506978714} + - component: {fileID: 1506978713} + - component: {fileID: 1506978712} + m_Layer: 5 + m_Name: HomeButton + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &1506978711 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1506978710} + 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: 263702967} + m_Father: {fileID: 431914656} + 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: -936, y: 467} + m_SizeDelta: {x: 50, y: 50} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &1506978712 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1506978710} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 4e29b1a8efbd4b44bb3f3716e73f07ff, type: 3} + m_Name: + m_EditorClassIdentifier: UnityEngine.UI::UnityEngine.UI.Button + 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: 1506978713} + m_OnClick: + m_PersistentCalls: + m_Calls: + - m_Target: {fileID: 963194230} + m_TargetAssemblyTypeName: UserCameraControl, Assembly-CSharp + m_MethodName: FindModuleStructure + m_Mode: 1 + m_Arguments: + m_ObjectArgument: {fileID: 0} + m_ObjectArgumentAssemblyTypeName: UnityEngine.Object, UnityEngine + m_IntArgument: 0 + m_FloatArgument: 0 + m_StringArgument: + m_BoolArgument: 0 + m_CallState: 2 +--- !u!114 &1506978713 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1506978710} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: UnityEngine.UI::UnityEngine.UI.Image + 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: 10905, guid: 0000000000000000f000000000000000, type: 0} + 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!222 &1506978714 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1506978710} + m_CullTransparentMesh: 1 --- !u!1 &1508932496 GameObject: m_ObjectHideFlags: 0 @@ -7542,6 +7759,79 @@ CanvasRenderer: m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 2029991572} m_CullTransparentMesh: 1 +--- !u!1001 &2031445727 +PrefabInstance: + m_ObjectHideFlags: 0 + serializedVersion: 2 + m_Modification: + serializedVersion: 3 + m_TransformParent: {fileID: 0} + m_Modifications: + - target: {fileID: 7364692261245862742, guid: 6ffe98828f23843f4814a5dc44baaf85, type: 3} + propertyPath: m_Name + value: DCActualFinal + objectReference: {fileID: 0} + - target: {fileID: 7364692261245862742, guid: 6ffe98828f23843f4814a5dc44baaf85, type: 3} + propertyPath: m_IsActive + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 8999369412263894087, guid: 6ffe98828f23843f4814a5dc44baaf85, type: 3} + propertyPath: m_LocalScale.x + value: 100 + objectReference: {fileID: 0} + - target: {fileID: 8999369412263894087, guid: 6ffe98828f23843f4814a5dc44baaf85, type: 3} + propertyPath: m_LocalScale.y + value: 100 + objectReference: {fileID: 0} + - target: {fileID: 8999369412263894087, guid: 6ffe98828f23843f4814a5dc44baaf85, type: 3} + propertyPath: m_LocalScale.z + value: 100 + objectReference: {fileID: 0} + - target: {fileID: 8999369412263894087, guid: 6ffe98828f23843f4814a5dc44baaf85, type: 3} + propertyPath: m_LocalPosition.x + value: 622.5 + objectReference: {fileID: 0} + - target: {fileID: 8999369412263894087, guid: 6ffe98828f23843f4814a5dc44baaf85, type: 3} + propertyPath: m_LocalPosition.y + value: 0.59 + objectReference: {fileID: 0} + - target: {fileID: 8999369412263894087, guid: 6ffe98828f23843f4814a5dc44baaf85, type: 3} + propertyPath: m_LocalPosition.z + value: 925.69 + objectReference: {fileID: 0} + - target: {fileID: 8999369412263894087, guid: 6ffe98828f23843f4814a5dc44baaf85, type: 3} + propertyPath: m_LocalRotation.w + value: 0.009781737 + objectReference: {fileID: 0} + - target: {fileID: 8999369412263894087, guid: 6ffe98828f23843f4814a5dc44baaf85, type: 3} + propertyPath: m_LocalRotation.x + value: 0.7069807 + objectReference: {fileID: 0} + - target: {fileID: 8999369412263894087, guid: 6ffe98828f23843f4814a5dc44baaf85, type: 3} + propertyPath: m_LocalRotation.y + value: -0.7070592 + objectReference: {fileID: 0} + - target: {fileID: 8999369412263894087, guid: 6ffe98828f23843f4814a5dc44baaf85, type: 3} + propertyPath: m_LocalRotation.z + value: -0.012243745 + objectReference: {fileID: 0} + - target: {fileID: 8999369412263894087, guid: 6ffe98828f23843f4814a5dc44baaf85, type: 3} + propertyPath: m_LocalEulerAnglesHint.x + value: 180.2 + objectReference: {fileID: 0} + - target: {fileID: 8999369412263894087, guid: 6ffe98828f23843f4814a5dc44baaf85, type: 3} + propertyPath: m_LocalEulerAnglesHint.y + value: 1.7850037 + objectReference: {fileID: 0} + - target: {fileID: 8999369412263894087, guid: 6ffe98828f23843f4814a5dc44baaf85, type: 3} + propertyPath: m_LocalEulerAnglesHint.z + value: 90.003 + objectReference: {fileID: 0} + m_RemovedComponents: [] + m_RemovedGameObjects: [] + m_AddedGameObjects: [] + m_AddedComponents: [] + m_SourcePrefab: {fileID: 100100000, guid: 6ffe98828f23843f4814a5dc44baaf85, type: 3} --- !u!4 &2036759262 stripped Transform: m_CorrespondingSourceObject: {fileID: 7998878104662105930, guid: 5c6ff9c85cb0b4e54a56a4714e2245e7, type: 3} @@ -8036,3 +8326,4 @@ SceneRoots: - {fileID: 943453644} - {fileID: 387671720} - {fileID: 7391572} + - {fileID: 2031445727} diff --git a/Assets/UserCameraControl.cs b/Assets/UserCameraControl.cs new file mode 100644 index 0000000..082b10e --- /dev/null +++ b/Assets/UserCameraControl.cs @@ -0,0 +1,252 @@ +using UnityEngine; +using UnityEngine.EventSystems; +using System.Collections; + +public class UserCameraControl : MonoBehaviour +{ + [Header("References")] + public Camera mainCamera; + + [Header("Cursors")] + public Texture2D handCursor; + public Texture2D eyeCursor; + public Vector2 cursorHotspot = Vector2.zero; + + [Header("Move")] + public float panSpeed = 3.5f; // units/sec + public float zoomSpeed = 6f; // scroll multiplier + public float moveSmoothTime = 0.12f; // higher = snappier, lower = floatier + + [Header("Orbit")] + public float orbitSpeed = 180f; // degrees/sec per pixel-ish delta + public float minPitch = -20f; + public float maxPitch = 80f; + public float orbitSmoothTime = 0.08f; + + [Header("Look / Home Smooth")] + public float lookAtDuration = 0.25f; + public float homeDuration = 0.35f; + + // internal angles + float yaw; + float pitch; + + // rotation smoothing + Vector2 lastMouse; + bool orbiting; + float yawDeltaVel, pitchDeltaVel; + float yawDeltaSmoothed, pitchDeltaSmoothed; + + // movement smoothing + Vector3 targetPosition; + Vector3 positionVel; + + Coroutine lookRoutine; + Coroutine homeRoutine; + + void Awake() + { + if (!mainCamera) mainCamera = Camera.main; + + targetPosition = transform.position; + SyncAnglesFromTransform(); + } + + void Update() + { + if (EventSystem.current && EventSystem.current.IsPointerOverGameObject()) + { + SetCursor(null); + return; + } + + HandleKeyboardPanAndZoom(); + HandleOrbit(); + + // smooth position every frame + transform.position = Vector3.SmoothDamp( + transform.position, + targetPosition, + ref positionVel, + moveSmoothTime, + Mathf.Infinity, + Time.unscaledDeltaTime + ); + + if (!Input.GetMouseButton(0) && !Input.GetMouseButton(1)) + SetCursor(null); + } + + void HandleOrbit() + { + if (Input.GetMouseButtonDown(1)) + { + orbiting = true; + SetCursor(eyeCursor); + + // stop any scripted rotation so user has control + StopLookRoutine(); + + SyncAnglesFromTransform(); + lastMouse = (Vector2)Input.mousePosition; + + yawDeltaSmoothed = pitchDeltaSmoothed = 0f; + yawDeltaVel = pitchDeltaVel = 0f; + } + + if (Input.GetMouseButtonUp(1)) + orbiting = false; + + if (!orbiting) return; + + float dt = Time.unscaledDeltaTime; + + Vector2 mouse = (Vector2)Input.mousePosition; + Vector2 delta = mouse - lastMouse; + lastMouse = mouse; + + float targetYawDelta = delta.x * orbitSpeed * dt; + float targetPitchDelta = -delta.y * orbitSpeed * dt; + + yawDeltaSmoothed = Mathf.SmoothDamp(yawDeltaSmoothed, targetYawDelta, ref yawDeltaVel, orbitSmoothTime); + pitchDeltaSmoothed = Mathf.SmoothDamp(pitchDeltaSmoothed, targetPitchDelta, ref pitchDeltaVel, orbitSmoothTime); + + yaw += yawDeltaSmoothed; + pitch += pitchDeltaSmoothed; + pitch = Mathf.Clamp(pitch, minPitch, maxPitch); + + transform.rotation = Quaternion.Euler(pitch, yaw, 0f); + } + + void HandleKeyboardPanAndZoom() + { + float dt = Time.unscaledDeltaTime; + + Vector3 right = transform.right; + Vector3 up = transform.up; + + Vector3 move = Vector3.zero; + if (Input.GetKey(KeyCode.W)) move += up; + if (Input.GetKey(KeyCode.S)) move -= up; + if (Input.GetKey(KeyCode.D)) move += right; + if (Input.GetKey(KeyCode.A)) move -= right; + + float scroll = Input.mouseScrollDelta.y; + if (Mathf.Abs(scroll) > 0.001f) + move += transform.forward * (scroll * zoomSpeed); + + if (move.sqrMagnitude < 0.0000001f) return; + + // write into targetPosition instead of snapping transform.position + targetPosition += move * panSpeed * dt; + } + + // -------- Public API used by ModuleSelector / UI -------- + + public void LookAtTarget(Transform target) + { + if (target == null) return; + + StopLookRoutine(); + lookRoutine = StartCoroutine(SmoothLookAt(target.position, lookAtDuration)); + } + + public void FindModuleStructure() + { + GameObject topologyRoot = GameObject.Find("GeneratedTopology"); + if (topologyRoot == null) return; + + Vector3 focus = topologyRoot.transform.position; + + float defaultYaw = 0f; + float defaultPitch = 20f; + float defaultDistance = 10f; + + float clampedPitch = Mathf.Clamp(defaultPitch, minPitch, maxPitch); + Quaternion rot = Quaternion.Euler(clampedPitch, defaultYaw, 0f); + Vector3 homePos = focus - (rot * Vector3.forward) * defaultDistance; + + StopLookRoutine(); + if (homeRoutine != null) StopCoroutine(homeRoutine); + homeRoutine = StartCoroutine(SmoothMoveAndRotate(homePos, rot, homeDuration)); + } + + // -------- Smooth routines -------- + + IEnumerator SmoothLookAt(Vector3 targetPoint, float duration) + { + Quaternion start = transform.rotation; + Quaternion end = Quaternion.LookRotation((targetPoint - transform.position).normalized, Vector3.up); + + float t = 0f; + while (t < 1f) + { + t += Time.unscaledDeltaTime / Mathf.Max(0.0001f, duration); + transform.rotation = Quaternion.Slerp(start, end, t); + yield return null; + } + + SyncAnglesFromTransform(); + lookRoutine = null; + } + + IEnumerator SmoothMoveAndRotate(Vector3 endPos, Quaternion endRot, float duration) + { + Vector3 startPos = transform.position; + Quaternion startRot = transform.rotation; + + float t = 0f; + while (t < 1f) + { + t += Time.unscaledDeltaTime / Mathf.Max(0.0001f, duration); + + // position + Vector3 pos = Vector3.Lerp(startPos, endPos, t); + transform.position = pos; + + // rotation + transform.rotation = Quaternion.Slerp(startRot, endRot, t); + + yield return null; + } + + // keep move smoothing target aligned so it doesn't “fight” after home + targetPosition = transform.position; + positionVel = Vector3.zero; + + SyncAnglesFromTransform(); + homeRoutine = null; + } + + void StopLookRoutine() + { + if (lookRoutine != null) + { + StopCoroutine(lookRoutine); + lookRoutine = null; + } + } + + // -------- Helpers -------- + + void SyncAnglesFromTransform() + { + Vector3 e = transform.eulerAngles; + yaw = NormalizeAngle(e.y); + pitch = NormalizeAngle(e.x); + pitch = Mathf.Clamp(pitch, minPitch, maxPitch); + transform.rotation = Quaternion.Euler(pitch, yaw, 0f); + } + + static float NormalizeAngle(float angle) + { + angle %= 360f; + if (angle > 180f) angle -= 360f; + return angle; + } + + void SetCursor(Texture2D tex) + { + Cursor.SetCursor(tex, cursorHotspot, CursorMode.Auto); + } +} \ No newline at end of file diff --git a/Assets/UserCameraControl.cs.meta b/Assets/UserCameraControl.cs.meta new file mode 100644 index 0000000..acd73e9 --- /dev/null +++ b/Assets/UserCameraControl.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: 664693941061d4a4ab8a0a945db827f3 \ No newline at end of file From cf5bf4b23b49aefac52e54cddea9382a0b6c12f6 Mon Sep 17 00:00:00 2001 From: Christen Date: Wed, 11 Feb 2026 17:27:30 -0500 Subject: [PATCH 2/6] Fixed up some issues with camera rotation and removed functionality where moving camera disables servo and dc ui panels --- Assets/ModuleSelector.cs | 8 ----- Assets/Scenes/SampleScene.unity | 5 ++- Assets/UserCameraControl.cs | 59 +++++++++++++++++++++++--------- Assets/UserCameraControl.cs.meta | 11 +++++- 4 files changed, 56 insertions(+), 27 deletions(-) diff --git a/Assets/ModuleSelector.cs b/Assets/ModuleSelector.cs index 867d3ab..cc95dcc 100644 --- a/Assets/ModuleSelector.cs +++ b/Assets/ModuleSelector.cs @@ -11,14 +11,6 @@ public class ModuleSelector : MonoBehaviour void Update() { - // If user is moving the camera, deselect current module - if (Input.GetKey(KeyCode.W) || Input.GetKey(KeyCode.A) || - Input.GetKey(KeyCode.S) || Input.GetKey(KeyCode.D)) - { - ClearSelection(); - return; - } - if (Input.GetMouseButtonDown(0)) { // Ignore clicks over UI diff --git a/Assets/Scenes/SampleScene.unity b/Assets/Scenes/SampleScene.unity index 9f9738f..f59275c 100644 --- a/Assets/Scenes/SampleScene.unity +++ b/Assets/Scenes/SampleScene.unity @@ -4055,10 +4055,13 @@ MonoBehaviour: panSpeed: 3.5 zoomSpeed: 10 moveSmoothTime: 0.12 - orbitSpeed: 150 + orbitSpeed: 20 minPitch: -80 maxPitch: 80 orbitSmoothTime: 0.08 + lockCursorWhileOrbiting: 1 + maxMouseDelta: 40 + orbitSmoothing: 0.08 lookAtDuration: 0.25 homeDuration: 0.35 --- !u!114 &963194231 diff --git a/Assets/UserCameraControl.cs b/Assets/UserCameraControl.cs index 082b10e..c17ad19 100644 --- a/Assets/UserCameraControl.cs +++ b/Assets/UserCameraControl.cs @@ -18,11 +18,19 @@ public class UserCameraControl : MonoBehaviour public float moveSmoothTime = 0.12f; // higher = snappier, lower = floatier [Header("Orbit")] - public float orbitSpeed = 180f; // degrees/sec per pixel-ish delta + public float orbitSpeed = 20f; // degrees/sec per pixel-ish delta public float minPitch = -20f; public float maxPitch = 80f; public float orbitSmoothTime = 0.08f; + [Header("Orbit Feel")] + public bool lockCursorWhileOrbiting = true; + public float maxMouseDelta = 40f; // clamps rare huge spikes + public float orbitSmoothing = 0.08f; // 0 = no smoothing, ~0.05-0.15 feels nice + + Vector2 orbitDeltaSmoothed; + Vector2 orbitDeltaVel; + [Header("Look / Home Smooth")] public float lookAtDuration = 0.25f; public float homeDuration = 0.35f; @@ -84,35 +92,52 @@ public class UserCameraControl : MonoBehaviour orbiting = true; SetCursor(eyeCursor); - // stop any scripted rotation so user has control - StopLookRoutine(); - SyncAnglesFromTransform(); - lastMouse = (Vector2)Input.mousePosition; - yawDeltaSmoothed = pitchDeltaSmoothed = 0f; - yawDeltaVel = pitchDeltaVel = 0f; + if (lockCursorWhileOrbiting) + { + Cursor.lockState = CursorLockMode.Locked; + Cursor.visible = false; + } + + orbitDeltaSmoothed = Vector2.zero; + orbitDeltaVel = Vector2.zero; } if (Input.GetMouseButtonUp(1)) + { orbiting = false; + if (lockCursorWhileOrbiting) + { + Cursor.lockState = CursorLockMode.None; + Cursor.visible = true; + } + + orbitDeltaSmoothed = Vector2.zero; + orbitDeltaVel = Vector2.zero; + return; + } + if (!orbiting) return; - float dt = Time.unscaledDeltaTime; + // Use Input axes while locked (stable, no screen-edge issues) + float dx = Input.GetAxisRaw("Mouse X"); + float dy = Input.GetAxisRaw("Mouse Y"); - Vector2 mouse = (Vector2)Input.mousePosition; - Vector2 delta = mouse - lastMouse; - lastMouse = mouse; + // Clamp rare spikes (frame hitch / window focus changes) + dx = Mathf.Clamp(dx, -maxMouseDelta, maxMouseDelta); + dy = Mathf.Clamp(dy, -maxMouseDelta, maxMouseDelta); - float targetYawDelta = delta.x * orbitSpeed * dt; - float targetPitchDelta = -delta.y * orbitSpeed * dt; + Vector2 targetDelta = new Vector2(dx, dy); - yawDeltaSmoothed = Mathf.SmoothDamp(yawDeltaSmoothed, targetYawDelta, ref yawDeltaVel, orbitSmoothTime); - pitchDeltaSmoothed = Mathf.SmoothDamp(pitchDeltaSmoothed, targetPitchDelta, ref pitchDeltaVel, orbitSmoothTime); + if (orbitSmoothing > 0f) + orbitDeltaSmoothed = Vector2.SmoothDamp(orbitDeltaSmoothed, targetDelta, ref orbitDeltaVel, orbitSmoothing); + else + orbitDeltaSmoothed = targetDelta; - yaw += yawDeltaSmoothed; - pitch += pitchDeltaSmoothed; + yaw += orbitDeltaSmoothed.x * orbitSpeed; + pitch -= orbitDeltaSmoothed.y * orbitSpeed; pitch = Mathf.Clamp(pitch, minPitch, maxPitch); transform.rotation = Quaternion.Euler(pitch, yaw, 0f); diff --git a/Assets/UserCameraControl.cs.meta b/Assets/UserCameraControl.cs.meta index acd73e9..65efbf9 100644 --- a/Assets/UserCameraControl.cs.meta +++ b/Assets/UserCameraControl.cs.meta @@ -1,2 +1,11 @@ fileFormatVersion: 2 -guid: 664693941061d4a4ab8a0a945db827f3 \ No newline at end of file +guid: 664693941061d4a4ab8a0a945db827f3 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: From eaed3e4fed46b53952258a932053a29d7e7c2c7e Mon Sep 17 00:00:00 2001 From: Christen Date: Wed, 11 Feb 2026 17:47:50 -0500 Subject: [PATCH 3/6] Fixed home button placement --- Assets/Scenes/SampleScene.unity | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Assets/Scenes/SampleScene.unity b/Assets/Scenes/SampleScene.unity index f59275c..30b0d4e 100644 --- a/Assets/Scenes/SampleScene.unity +++ b/Assets/Scenes/SampleScene.unity @@ -6025,11 +6025,11 @@ RectTransform: - {fileID: 263702967} m_Father: {fileID: 431914656} 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: -936, y: 467} + m_AnchorMin: {x: 0, y: 1} + m_AnchorMax: {x: 0, y: 1} + m_AnchoredPosition: {x: 0, y: 0} m_SizeDelta: {x: 50, y: 50} - m_Pivot: {x: 0.5, y: 0.5} + m_Pivot: {x: 0, y: 1} --- !u!114 &1506978712 MonoBehaviour: m_ObjectHideFlags: 0 From 4c3dbd253264660e92ce75c4c5c4b5c8a8e6ead4 Mon Sep 17 00:00:00 2001 From: Leo Qu Date: Thu, 12 Feb 2026 23:29:05 -0500 Subject: [PATCH 4/6] Track homeIcon.png with Git LFS Co-authored-by: Cursor --- Assets/Icons/homeIcon.png | Bin 6259 -> 129 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/Assets/Icons/homeIcon.png b/Assets/Icons/homeIcon.png index c40c6b2296a5a1ebeaaf9ba657b2357fafb84de0..b6f1c395d6c1d71ddab416420d729065d7406164 100644 GIT binary patch literal 129 zcmWN?K@!3s3;@78uiyg~5+IcRrVSv>sB{eW;OliSdzH8J@zQP1Q#NDnecm2bmjCT@ zEIgh@&cfybHG0<4b_}!;M|3_EbQIRTqC;m9EqnH4UFPHgLd_AvL94g8CUTrA$7%_H MKuP}=O&F5;0dhGdegFUf literal 6259 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 vttncb7V~lG5Xza-|97Im|KbE~TZP8fES55(ta Date: Thu, 12 Feb 2026 23:50:20 -0500 Subject: [PATCH 5/6] Update Unity project version to 6000.3.6f1 Co-authored-by: Cursor --- ProjectSettings/ProjectVersion.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ProjectSettings/ProjectVersion.txt b/ProjectSettings/ProjectVersion.txt index 7a6f40b..a4b5984 100644 --- a/ProjectSettings/ProjectVersion.txt +++ b/ProjectSettings/ProjectVersion.txt @@ -1,2 +1,2 @@ -m_EditorVersion: 2022.3.62f1 -m_EditorVersionWithRevision: 2022.3.62f1 (4af31df58517) +m_EditorVersion: 6000.3.6f1 +m_EditorVersionWithRevision: 6000.3.6f1 (bbb010bdb8a3) From b37685ba959303300faf28d1fddf752057bb3cce Mon Sep 17 00:00:00 2001 From: Leo Qu Date: Thu, 12 Feb 2026 23:54:25 -0500 Subject: [PATCH 6/6] Revert "Track homeIcon.png with Git LFS" This reverts commit 4c3dbd253264660e92ce75c4c5c4b5c8a8e6ead4. --- Assets/Icons/homeIcon.png | Bin 129 -> 6259 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/Assets/Icons/homeIcon.png b/Assets/Icons/homeIcon.png index b6f1c395d6c1d71ddab416420d729065d7406164..c40c6b2296a5a1ebeaaf9ba657b2357fafb84de0 100644 GIT binary patch literal 6259 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 MKuP}=O&F5;0dhGdegFUf