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 0000000..c40c6b2 Binary files /dev/null and b/Assets/Icons/homeIcon.png differ diff --git a/Assets/Icons/homeIcon.png.meta b/Assets/Icons/homeIcon.png.meta new file mode 100644 index 0000000..2a22f6b --- /dev/null +++ b/Assets/Icons/homeIcon.png.meta @@ -0,0 +1,143 @@ +fileFormatVersion: 2 +guid: 014f6511aae4941219c1b2bf26a752b9 +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 13 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + sRGBTexture: 1 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapsPreserveCoverage: 0 + alphaTestReferenceValue: 0.5 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + flipGreenChannel: 0 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + vTOnly: 0 + ignoreMipmapLimit: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: 1 + aniso: 1 + mipBias: 0 + wrapU: 1 + wrapV: 1 + wrapW: 0 + nPOTScale: 0 + lightmap: 0 + compressionQuality: 50 + spriteMode: 1 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spritePixelsToUnits: 100 + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spriteGenerateFallbackPhysicsShape: 1 + alphaUsage: 1 + alphaIsTransparency: 1 + spriteTessellationDetail: -1 + textureType: 8 + textureShape: 1 + singleChannelComponent: 0 + flipbookRows: 1 + flipbookColumns: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + ignorePngGamma: 0 + applyGammaDecoding: 0 + swizzle: 50462976 + cookieLightType: 0 + platformSettings: + - serializedVersion: 4 + buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 4 + buildTarget: Standalone + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 4 + buildTarget: Android + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 4 + buildTarget: iOS + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + customData: + physicsShape: [] + bones: [] + spriteID: 5e97eb03825dee720800000000000000 + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + spriteCustomMetadata: + entries: [] + nameFileIdTable: {} + mipmapLimitGroupName: + pSDRemoveMatte: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/ModuleSelector.cs b/Assets/ModuleSelector.cs index e06b267..867d3ab 100644 --- a/Assets/ModuleSelector.cs +++ b/Assets/ModuleSelector.cs @@ -1,49 +1,70 @@ -using System.Collections; -using System.Collections.Generic; -using System.Reflection; using UnityEngine; +using UnityEngine.EventSystems; public class ModuleSelector : MonoBehaviour { public Camera mainCamera; - public Cinemachine.CinemachineVirtualCamera virtualCamera; - private ModuleBase prevModule; //Store previous module then when unselected call that module's unselect function to make panel disappear or something + public UserCameraControl cameraController; + + [System.NonSerialized] + public ModuleBase prevModule; - // Update is called once per frame 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)) { - // Don't process any clicks if the click is over UI element - if (UnityEngine.EventSystems.EventSystem.current.IsPointerOverGameObject()) + // Ignore clicks over UI + if (EventSystem.current != null && + EventSystem.current.IsPointerOverGameObject()) return; - if (prevModule != null) - { - prevModule.DeSelect(); - virtualCamera.LookAt = null; - virtualCamera.Follow = null; - } + ClearSelection(); + Ray ray = mainCamera.ScreenPointToRay(Input.mousePosition); if (Physics.Raycast(ray, out RaycastHit hit)) { ModuleBase module = hit.collider.GetComponentInParent(); - 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