From 9a52384dbbf099de75af7b980b65f3e519f6c11e Mon Sep 17 00:00:00 2001 From: bybohka Date: Thu, 8 Oct 2026 14:38:09 +0300 Subject: [PATCH] =?UTF-8?q?=D0=A0=D0=B0=D0=B1=D0=BE=D1=82=D0=B0=D1=8E=20?= =?UTF-8?q?=D0=BD=D0=B0=D0=B4=20=D1=81=D0=B8=D1=81=D1=82=D0=B5=D0=BC=D0=BE?= =?UTF-8?q?=D0=B9=20=D1=80=D0=B6=D0=B0=D0=B2=D1=87=D0=B8=D0=BD=D1=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Assets/Scenes/SampleScene.unity | 484 +++++++++++++++++- Assets/Scripts/Car/PartData/CartPartData.cs | 5 +- Assets/Scripts/Car/Visuals.meta | 3 + .../Car/Visuals/CarConditionGenerator.cs | 47 ++ .../Car/Visuals/CarConditionGenerator.cs.meta | 3 + Assets/Scripts/Car/Visuals/CarPartVisuals.cs | 45 ++ .../Car/Visuals/CarPartVisuals.cs.meta | 3 + .../Scripts/Car/Visuals/CarRestorationTool.cs | 43 ++ .../Car/Visuals/CarRestorationTool.cs.meta | 3 + .../Scripts/Player/Movement/PlayerMovement.cs | 72 ++- Assets/Scripts/Player/Tools.meta | 3 + .../Scripts/Player/Tools/PlayerToolManager.cs | 71 +++ .../Player/Tools/PlayerToolManager.cs.meta | 3 + Assets/Scripts/Player/Tools/ToolRadialMenu.cs | 92 ++++ .../Player/Tools/ToolRadialMenu.cs.meta | 3 + Packages/manifest.json | 17 +- Packages/packages-lock.json | 18 + ProjectSettings/PackageManagerSettings.asset | 21 +- ProjectSettings/ProjectSettings.asset | 21 +- 19 files changed, 924 insertions(+), 33 deletions(-) create mode 100644 Assets/Scripts/Car/Visuals.meta create mode 100644 Assets/Scripts/Car/Visuals/CarConditionGenerator.cs create mode 100644 Assets/Scripts/Car/Visuals/CarConditionGenerator.cs.meta create mode 100644 Assets/Scripts/Car/Visuals/CarPartVisuals.cs create mode 100644 Assets/Scripts/Car/Visuals/CarPartVisuals.cs.meta create mode 100644 Assets/Scripts/Car/Visuals/CarRestorationTool.cs create mode 100644 Assets/Scripts/Car/Visuals/CarRestorationTool.cs.meta create mode 100644 Assets/Scripts/Player/Tools.meta create mode 100644 Assets/Scripts/Player/Tools/PlayerToolManager.cs create mode 100644 Assets/Scripts/Player/Tools/PlayerToolManager.cs.meta create mode 100644 Assets/Scripts/Player/Tools/ToolRadialMenu.cs create mode 100644 Assets/Scripts/Player/Tools/ToolRadialMenu.cs.meta diff --git a/Assets/Scenes/SampleScene.unity b/Assets/Scenes/SampleScene.unity index fb056ac..f96ffb5 100644 --- a/Assets/Scenes/SampleScene.unity +++ b/Assets/Scenes/SampleScene.unity @@ -132,6 +132,7 @@ GameObject: - component: {fileID: 1891976} - component: {fileID: 1891975} - component: {fileID: 1891979} + - component: {fileID: 1891980} m_Layer: 5 m_Name: GameObject m_TagString: Untagged @@ -217,6 +218,7 @@ RectTransform: m_Children: - {fileID: 454152250} - {fileID: 540779566} + - {fileID: 1799473581} m_Father: {fileID: 0} m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} @@ -238,6 +240,26 @@ MonoBehaviour: m_EditorClassIdentifier: Assembly-CSharp::UIManager interactText: {fileID: 454152251} speedText: {fileID: 540779564} +--- !u!114 &1891980 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1891974} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: aefd5e59eb964d74a70224a9b43918d0, type: 3} + m_Name: + m_EditorClassIdentifier: Assembly-CSharp::ToolRadialMenu + menuPanel: {fileID: 1799473580} + toolManager: {fileID: 25262937} + sectorIcons: + - {fileID: 704922721} + - {fileID: 1435413745} + - {fileID: 816849756} + normalColor: {r: 1, g: 1, b: 1, a: 1} + selectedColor: {r: 1, g: 0.92156863, b: 0.015686275, a: 1} --- !u!1 &19586623 GameObject: m_ObjectHideFlags: 0 @@ -494,6 +516,7 @@ GameObject: - component: {fileID: 25262931} - component: {fileID: 25262930} - component: {fileID: 25262936} + - component: {fileID: 25262937} m_Layer: 0 m_Name: Player m_TagString: Untagged @@ -514,7 +537,13 @@ MonoBehaviour: m_Name: m_EditorClassIdentifier: Assembly-CSharp::PlayerMovement moveSpeed: 5 + crouchSpeed: 2 gravity: -9.81 + crouchKey: 306 + standHeight: 2 + crouchHeight: 1 + crouchTransitionSpeed: 10 + playerCamera: {fileID: 505605456} groundCheck: {fileID: 1401415246} groundDistance: 0.4 groundMask: @@ -625,7 +654,7 @@ Transform: m_GameObject: {fileID: 25262929} serializedVersion: 2 m_LocalRotation: {x: -0, y: -0.6509836, z: -0, w: 0.7590919} - m_LocalPosition: {x: 0, y: 0.99, z: 5.24} + m_LocalPosition: {x: 0, y: 0.943, z: 5.24} m_LocalScale: {x: 1, y: 0.8784, z: 1} m_ConstrainProportionsScale: 0 m_Children: @@ -649,6 +678,25 @@ MonoBehaviour: dropKey: 103 throwKey: 324 throwForce: 15 +--- !u!114 &25262937 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 25262929} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 79b9bf3c26bc4f38a11491b3776b8121, type: 3} + m_Name: + m_EditorClassIdentifier: Assembly-CSharp::PlayerToolManager + currentTool: 0 + toolRange: 2.5 + interactableLayer: + serializedVersion: 2 + m_Bits: 64 + sandSpeed: 0.35 + sprayPaintColor: {r: 0.101960786, g: 0.08627451, b: 0.52156866, a: 1} --- !u!1 &40323470 GameObject: m_ObjectHideFlags: 0 @@ -3827,6 +3875,81 @@ WheelCollider: m_LayerOverridePriority: 0 m_Enabled: 1 m_ProvidesContacts: 0 +--- !u!1 &704922719 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 704922720} + - component: {fileID: 704922722} + - component: {fileID: 704922721} + m_Layer: 5 + m_Name: Hands + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &704922720 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 704922719} + 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: 1799473581} + 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: 45, y: 110} + m_SizeDelta: {x: 100, y: 100} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &704922721 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 704922719} + 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: -1624108181874779714, guid: 4d6142b9bf3a4e74e85be65d6df40034, 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 &704922722 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 704922719} + m_CullTransparentMesh: 1 --- !u!1 &718505703 GameObject: m_ObjectHideFlags: 0 @@ -4292,6 +4415,81 @@ Transform: m_CorrespondingSourceObject: {fileID: 4835899192707740, guid: 167ccd36f78cceb46a4d150b76b96fab, type: 3} m_PrefabInstance: {fileID: 1991430295} m_PrefabAsset: {fileID: 0} +--- !u!1 &816849754 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 816849755} + - component: {fileID: 816849757} + - component: {fileID: 816849756} + m_Layer: 5 + m_Name: SprayCan + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &816849755 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 816849754} + 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: 1799473581} + 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: -79, y: 0} + m_SizeDelta: {x: 100, y: 100} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &816849756 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 816849754} + 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: -1346416522851244930, guid: 8abbcbd04006abb4681b67b2f02db16b, 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 &816849757 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 816849754} + m_CullTransparentMesh: 1 --- !u!1 &832575517 GameObject: m_ObjectHideFlags: 0 @@ -5743,6 +5941,81 @@ BoxCollider: serializedVersion: 3 m_Size: {x: 1.9034042, y: 1.1622311, z: 4.854271} m_Center: {x: -0.18816757, y: 0.6376721, z: -0.31553233} +--- !u!1 &1435413743 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1435413744} + - component: {fileID: 1435413746} + - component: {fileID: 1435413745} + m_Layer: 5 + m_Name: Sander + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &1435413744 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1435413743} + 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: 1799473581} + 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: 168, y: 0} + m_SizeDelta: {x: 100, y: 100} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &1435413745 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1435413743} + 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: 6476413399009122388, guid: 931d01a1adcec0040acf573741d19268, 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 &1435413746 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1435413743} + m_CullTransparentMesh: 1 --- !u!1 &1523640617 GameObject: m_ObjectHideFlags: 0 @@ -7022,6 +7295,44 @@ Transform: - {fileID: 785032467720261863} m_Father: {fileID: 1672258200} m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &1799473580 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1799473581} + m_Layer: 5 + m_Name: RadialMenuPanel + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &1799473581 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1799473580} + 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: 704922720} + - {fileID: 1435413744} + - {fileID: 816849755} + m_Father: {fileID: 1891978} + 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: 100, y: 100} + m_Pivot: {x: 0.5, y: 0.5} --- !u!4 &1813299070 stripped Transform: m_CorrespondingSourceObject: {fileID: 4391732829057842, guid: cfe372357392bfc49a631f6dfb62bbb1, type: 3} @@ -8403,7 +8714,7 @@ MeshRenderer: m_RenderingLayerMask: 1 m_RendererPriority: 0 m_Materials: - - {fileID: 2100000, guid: af16f44144fd7ce4ea95e15c469ecc64, type: 2} + - {fileID: 2100000, guid: 342fcf7bc5fe4a74793cd73faecc7aa5, type: 2} m_StaticBatchInfo: firstSubMesh: 0 subMeshCount: 0 @@ -16046,7 +16357,7 @@ MeshRenderer: m_RenderingLayerMask: 1 m_RendererPriority: 0 m_Materials: - - {fileID: 2100000, guid: af16f44144fd7ce4ea95e15c469ecc64, type: 2} + - {fileID: 2100000, guid: 342fcf7bc5fe4a74793cd73faecc7aa5, type: 2} m_StaticBatchInfo: firstSubMesh: 0 subMeshCount: 0 @@ -27413,7 +27724,7 @@ PrefabInstance: objectReference: {fileID: 0} - target: {fileID: 106582297804416612, guid: a51ba6787c81a7747a92fd99faa633dd, type: 3} propertyPath: m_ForceAppPointDistance - value: 0.7372391 + value: 0.7372392 objectReference: {fileID: 0} - target: {fileID: 106582297804416612, guid: a51ba6787c81a7747a92fd99faa633dd, type: 3} propertyPath: m_SuspensionSpring.damper @@ -27465,7 +27776,7 @@ PrefabInstance: objectReference: {fileID: 0} - target: {fileID: 704510738395191736, guid: a51ba6787c81a7747a92fd99faa633dd, type: 3} propertyPath: m_SuspensionDistance - value: 0.19620003 + value: 0.19620001 objectReference: {fileID: 0} - target: {fileID: 704510738395191736, guid: a51ba6787c81a7747a92fd99faa633dd, type: 3} propertyPath: m_ForceAppPointDistance @@ -27473,7 +27784,7 @@ PrefabInstance: objectReference: {fileID: 0} - target: {fileID: 704510738395191736, guid: a51ba6787c81a7747a92fd99faa633dd, type: 3} propertyPath: m_SuspensionSpring.damper - value: 5558.837 + value: 5558.8364 objectReference: {fileID: 0} - target: {fileID: 704510738395191736, guid: a51ba6787c81a7747a92fd99faa633dd, type: 3} propertyPath: m_SuspensionSpring.spring @@ -27501,11 +27812,11 @@ PrefabInstance: objectReference: {fileID: 0} - target: {fileID: 3325959865401887414, guid: a51ba6787c81a7747a92fd99faa633dd, type: 3} propertyPath: m_SuspensionSpring.damper - value: 4984.2354 + value: 4984.235 objectReference: {fileID: 0} - target: {fileID: 3325959865401887414, guid: a51ba6787c81a7747a92fd99faa633dd, type: 3} propertyPath: m_SuspensionSpring.spring - value: 37195.785 + value: 37195.78 objectReference: {fileID: 0} - target: {fileID: 5982082872690665484, guid: a51ba6787c81a7747a92fd99faa633dd, type: 3} propertyPath: m_Name @@ -27517,7 +27828,7 @@ PrefabInstance: objectReference: {fileID: 0} - target: {fileID: 6233063347235192541, guid: a51ba6787c81a7747a92fd99faa633dd, type: 3} propertyPath: m_ForceAppPointDistance - value: 0.7372391 + value: 0.7372392 objectReference: {fileID: 0} - target: {fileID: 6233063347235192541, guid: a51ba6787c81a7747a92fd99faa633dd, type: 3} propertyPath: m_SuspensionSpring.damper @@ -27736,7 +28047,7 @@ MeshRenderer: m_RenderingLayerMask: 1 m_RendererPriority: 0 m_Materials: - - {fileID: 2100000, guid: af16f44144fd7ce4ea95e15c469ecc64, type: 2} + - {fileID: 2100000, guid: 342fcf7bc5fe4a74793cd73faecc7aa5, type: 2} m_StaticBatchInfo: firstSubMesh: 0 subMeshCount: 0 @@ -35221,7 +35532,7 @@ MeshRenderer: m_RenderingLayerMask: 1 m_RendererPriority: 0 m_Materials: - - {fileID: 2100000, guid: af16f44144fd7ce4ea95e15c469ecc64, type: 2} + - {fileID: 2100000, guid: 342fcf7bc5fe4a74793cd73faecc7aa5, type: 2} m_StaticBatchInfo: firstSubMesh: 0 subMeshCount: 0 @@ -40162,7 +40473,7 @@ MeshRenderer: m_RenderingLayerMask: 1 m_RendererPriority: 0 m_Materials: - - {fileID: 2100000, guid: af16f44144fd7ce4ea95e15c469ecc64, type: 2} + - {fileID: 2100000, guid: 342fcf7bc5fe4a74793cd73faecc7aa5, type: 2} m_StaticBatchInfo: firstSubMesh: 0 subMeshCount: 0 @@ -41192,6 +41503,9 @@ GameObject: - component: {fileID: 7628363394371655494} - component: {fileID: 30206758387541985} - component: {fileID: 7628363394371655495} + - component: {fileID: 7628363394371655497} + - component: {fileID: 7628363394371655496} + - component: {fileID: 7628363394371655498} m_Layer: 6 m_Name: sunburst_door_FR m_TagString: Untagged @@ -47339,7 +47653,7 @@ MeshRenderer: m_RenderingLayerMask: 1 m_RendererPriority: 0 m_Materials: - - {fileID: 2100000, guid: af16f44144fd7ce4ea95e15c469ecc64, type: 2} + - {fileID: 2100000, guid: 342fcf7bc5fe4a74793cd73faecc7aa5, type: 2} m_StaticBatchInfo: firstSubMesh: 0 subMeshCount: 0 @@ -49896,7 +50210,7 @@ MeshRenderer: m_RenderingLayerMask: 1 m_RendererPriority: 0 m_Materials: - - {fileID: 2100000, guid: af16f44144fd7ce4ea95e15c469ecc64, type: 2} + - {fileID: 2100000, guid: 342fcf7bc5fe4a74793cd73faecc7aa5, type: 2} m_StaticBatchInfo: firstSubMesh: 0 subMeshCount: 0 @@ -52496,6 +52810,7 @@ GameObject: - component: {fileID: 3035244932027966785} - component: {fileID: 3035244932027966784} - component: {fileID: 3035244932027966783} + - component: {fileID: 3035244932027966786} m_Layer: 0 m_Name: Hirochi m_TagString: Untagged @@ -52590,6 +52905,21 @@ MonoBehaviour: frontRightMesh: {fileID: 1900989433652124910} rearLeftMesh: {fileID: 3759583277276445777} rearRightMesh: {fileID: 482239282661849437} +--- !u!114 &3035244932027966786 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 3035244932027966781} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 598fbcd97cc34477934893a1802ce999, type: 3} + m_Name: + m_EditorClassIdentifier: Assembly-CSharp::CarConditionGenerator + rustProbability: 0.7 + maxRustAmount: 0.85 + baseCarColor: {r: 0.5, g: 0.5, b: 0.5, a: 1} --- !u!1 &3036468142004751567 GameObject: m_ObjectHideFlags: 0 @@ -70534,7 +70864,7 @@ MeshRenderer: m_RenderingLayerMask: 1 m_RendererPriority: 0 m_Materials: - - {fileID: 2100000, guid: af16f44144fd7ce4ea95e15c469ecc64, type: 2} + - {fileID: 2100000, guid: 342fcf7bc5fe4a74793cd73faecc7aa5, type: 2} m_StaticBatchInfo: firstSubMesh: 0 subMeshCount: 0 @@ -72912,7 +73242,7 @@ MeshRenderer: m_RenderingLayerMask: 1 m_RendererPriority: 0 m_Materials: - - {fileID: 2100000, guid: af16f44144fd7ce4ea95e15c469ecc64, type: 2} + - {fileID: 2100000, guid: 342fcf7bc5fe4a74793cd73faecc7aa5, type: 2} m_StaticBatchInfo: firstSubMesh: 0 subMeshCount: 0 @@ -87517,7 +87847,7 @@ MeshRenderer: m_RenderingLayerMask: 1 m_RendererPriority: 0 m_Materials: - - {fileID: 2100000, guid: af16f44144fd7ce4ea95e15c469ecc64, type: 2} + - {fileID: 2100000, guid: 342fcf7bc5fe4a74793cd73faecc7aa5, type: 2} m_StaticBatchInfo: firstSubMesh: 0 subMeshCount: 0 @@ -88660,7 +88990,7 @@ MeshRenderer: m_RenderingLayerMask: 1 m_RendererPriority: 0 m_Materials: - - {fileID: 2100000, guid: af16f44144fd7ce4ea95e15c469ecc64, type: 2} + - {fileID: 2100000, guid: 342fcf7bc5fe4a74793cd73faecc7aa5, type: 2} m_StaticBatchInfo: firstSubMesh: 0 subMeshCount: 0 @@ -90224,7 +90554,7 @@ MeshRenderer: m_RenderingLayerMask: 1 m_RendererPriority: 0 m_Materials: - - {fileID: 2100000, guid: af16f44144fd7ce4ea95e15c469ecc64, type: 2} + - {fileID: 2100000, guid: 342fcf7bc5fe4a74793cd73faecc7aa5, type: 2} m_StaticBatchInfo: firstSubMesh: 0 subMeshCount: 0 @@ -92138,7 +92468,7 @@ MeshRenderer: m_RenderingLayerMask: 1 m_RendererPriority: 0 m_Materials: - - {fileID: 2100000, guid: af16f44144fd7ce4ea95e15c469ecc64, type: 2} + - {fileID: 2100000, guid: 342fcf7bc5fe4a74793cd73faecc7aa5, type: 2} m_StaticBatchInfo: firstSubMesh: 0 subMeshCount: 0 @@ -113508,7 +113838,7 @@ MeshRenderer: m_RenderingLayerMask: 1 m_RendererPriority: 0 m_Materials: - - {fileID: 2100000, guid: af16f44144fd7ce4ea95e15c469ecc64, type: 2} + - {fileID: 2100000, guid: 342fcf7bc5fe4a74793cd73faecc7aa5, type: 2} m_StaticBatchInfo: firstSubMesh: 0 subMeshCount: 0 @@ -114239,7 +114569,7 @@ MeshRenderer: m_RenderingLayerMask: 1 m_RendererPriority: 0 m_Materials: - - {fileID: 2100000, guid: af16f44144fd7ce4ea95e15c469ecc64, type: 2} + - {fileID: 2100000, guid: 342fcf7bc5fe4a74793cd73faecc7aa5, type: 2} m_StaticBatchInfo: firstSubMesh: 0 subMeshCount: 0 @@ -115899,7 +116229,7 @@ MeshRenderer: m_RenderingLayerMask: 1 m_RendererPriority: 0 m_Materials: - - {fileID: 2100000, guid: af16f44144fd7ce4ea95e15c469ecc64, type: 2} + - {fileID: 2100000, guid: 342fcf7bc5fe4a74793cd73faecc7aa5, type: 2} m_StaticBatchInfo: firstSubMesh: 0 subMeshCount: 0 @@ -120062,6 +120392,50 @@ BoxCollider: serializedVersion: 3 m_Size: {x: 0.27472627, y: 1.0553257, z: 1.1256342} m_Center: {x: -0.08714208, y: -0.02255109, z: -0.5394976} +--- !u!114 &7628363394371655496 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2245899150237664045} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 9aac6d89a0a64dc6ba41ec26a0117e79, type: 3} + m_Name: + m_EditorClassIdentifier: Assembly-CSharp::CarPartAnimator + openRotation: {x: 0, y: -60, z: 0} + speed: 5 +--- !u!114 &7628363394371655497 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2245899150237664045} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 46199851c79547bc8c4f7ac4a0924fa5, type: 3} + m_Name: + m_EditorClassIdentifier: Assembly-CSharp::CarPart + partData: {fileID: 11400000, guid: 63cdc0d4874ebfd4584f130d3a252cdb, type: 2} + mass: 12 + inHandPositionOffset: {x: 0, y: 0, z: 0} + inHandRotationOffset: {x: 0, y: 0, z: 0} +--- !u!114 &7628363394371655498 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2245899150237664045} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: de28a2301d654322a1a3aa450e964901, type: 3} + m_Name: + m_EditorClassIdentifier: Assembly-CSharp::CarPartVisuals + currentRust: 0 + currentColor: {r: 1, g: 1, b: 1, a: 1} --- !u!4 &7628731016262164030 Transform: m_ObjectHideFlags: 0 @@ -120353,6 +120727,8 @@ GameObject: - component: {fileID: 3280270725866653573} - component: {fileID: 1790047687491237794} - component: {fileID: 7640785727775173646} + - component: {fileID: 7640785727775173648} + - component: {fileID: 7640785727775173647} m_Layer: 6 m_Name: sunburst_door_RR_widebody m_TagString: Untagged @@ -120381,6 +120757,36 @@ BoxCollider: serializedVersion: 3 m_Size: {x: 0.29417455, y: 1.04671, z: 0.9075683} m_Center: {x: -0.09699404, y: -0.031863928, z: -0.44528195} +--- !u!114 &7640785727775173647 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 7640785727775173645} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 9aac6d89a0a64dc6ba41ec26a0117e79, type: 3} + m_Name: + m_EditorClassIdentifier: Assembly-CSharp::CarPartAnimator + openRotation: {x: 0, y: -60, z: 0} + speed: 5 +--- !u!114 &7640785727775173648 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 7640785727775173645} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 46199851c79547bc8c4f7ac4a0924fa5, type: 3} + m_Name: + m_EditorClassIdentifier: Assembly-CSharp::CarPart + partData: {fileID: 11400000, guid: 63cdc0d4874ebfd4584f130d3a252cdb, type: 2} + mass: 12 + inHandPositionOffset: {x: 0, y: 0, z: 0} + inHandRotationOffset: {x: 0, y: 0, z: 0} --- !u!4 &7641231345258533193 Transform: m_ObjectHideFlags: 0 @@ -121389,6 +121795,8 @@ GameObject: - component: {fileID: 580786325703677243} - component: {fileID: 7367880245312146407} - component: {fileID: 7708533388283260536} + - component: {fileID: 7708533388283260538} + - component: {fileID: 7708533388283260537} m_Layer: 6 m_Name: sunburst_door_FL m_TagString: Untagged @@ -121417,6 +121825,36 @@ BoxCollider: serializedVersion: 3 m_Size: {x: 0.27630967, y: 1.0550437, z: 1.1257122} m_Center: {x: 0.08660707, y: -0.02266848, z: -0.5395173} +--- !u!114 &7708533388283260537 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 7708533388283260535} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 9aac6d89a0a64dc6ba41ec26a0117e79, type: 3} + m_Name: + m_EditorClassIdentifier: Assembly-CSharp::CarPartAnimator + openRotation: {x: 0, y: 60, z: 0} + speed: 5 +--- !u!114 &7708533388283260538 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 7708533388283260535} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 46199851c79547bc8c4f7ac4a0924fa5, type: 3} + m_Name: + m_EditorClassIdentifier: Assembly-CSharp::CarPart + partData: {fileID: 11400000, guid: 63cdc0d4874ebfd4584f130d3a252cdb, type: 2} + mass: 12 + inHandPositionOffset: {x: 0, y: 0, z: 0} + inHandRotationOffset: {x: 0, y: 0, z: 0} --- !u!33 &7711353794531275585 MeshFilter: m_ObjectHideFlags: 0 diff --git a/Assets/Scripts/Car/PartData/CartPartData.cs b/Assets/Scripts/Car/PartData/CartPartData.cs index 84a6f65..cd9234d 100644 --- a/Assets/Scripts/Car/PartData/CartPartData.cs +++ b/Assets/Scripts/Car/PartData/CartPartData.cs @@ -6,5 +6,8 @@ public class CarPartData : ScriptableObject [Header("Данные детали")] public string partName = "Передний бампер"; public float basePrice = 150f; - [Range(0, 100)] public float condition = 100f; // Состояние детали для оценки авто + [Range(0, 100)] public float condition = 100f; + + [Header("Коррозия и материалы")] + public bool canRust = true; } \ No newline at end of file diff --git a/Assets/Scripts/Car/Visuals.meta b/Assets/Scripts/Car/Visuals.meta new file mode 100644 index 0000000..0152107 --- /dev/null +++ b/Assets/Scripts/Car/Visuals.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 0de206522eb940258e88b78fd9cd8e0c +timeCreated: 1791330354 \ No newline at end of file diff --git a/Assets/Scripts/Car/Visuals/CarConditionGenerator.cs b/Assets/Scripts/Car/Visuals/CarConditionGenerator.cs new file mode 100644 index 0000000..6d0778b --- /dev/null +++ b/Assets/Scripts/Car/Visuals/CarConditionGenerator.cs @@ -0,0 +1,47 @@ +using UnityEngine; + +public class CarConditionGenerator : MonoBehaviour +{ + [Header("Настройки спавна")] + [Range(0f, 1f)] [SerializeField] private float rustProbability = 0.7f; // Шанс появления ржавчины + [SerializeField] private float maxRustAmount = 0.85f; + [SerializeField] private Color baseCarColor = Color.gray; + + private void Start() + { + GenerateCondition(); + } + + [ContextMenu("Сгенерировать состояние")] + public void GenerateCondition() + { + CarPart[] allParts = GetComponentsInChildren(true); + + foreach (var part in allParts) + { + CarPartVisuals visuals = part.GetComponent(); + if (visuals == null) visuals = part.gameObject.AddComponent(); + + // 1. Устанавливаем базовый цвет кузова + visuals.SetPaintColor(baseCarColor); + + // 2. Если деталь пластиковая (бампер) — пропускаем ржавчину + if (part.Data != null && !part.Data.canRust) + { + visuals.SetRust(0f); + continue; + } + + // 3. Рандомизируем ржавчину для металла + if (Random.value < rustProbability) + { + float randomRust = Random.Range(0.2f, maxRustAmount); + visuals.SetRust(randomRust); + } + else + { + visuals.SetRust(0f); + } + } + } +} \ No newline at end of file diff --git a/Assets/Scripts/Car/Visuals/CarConditionGenerator.cs.meta b/Assets/Scripts/Car/Visuals/CarConditionGenerator.cs.meta new file mode 100644 index 0000000..c523a4d --- /dev/null +++ b/Assets/Scripts/Car/Visuals/CarConditionGenerator.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 598fbcd97cc34477934893a1802ce999 +timeCreated: 1791330530 \ No newline at end of file diff --git a/Assets/Scripts/Car/Visuals/CarPartVisuals.cs b/Assets/Scripts/Car/Visuals/CarPartVisuals.cs new file mode 100644 index 0000000..0b385d0 --- /dev/null +++ b/Assets/Scripts/Car/Visuals/CarPartVisuals.cs @@ -0,0 +1,45 @@ +using UnityEngine; + +[RequireComponent(typeof(Renderer))] +public class CarPartVisuals : MonoBehaviour +{ + private Renderer partRenderer; + private MaterialPropertyBlock propertyBlock; + + private static readonly int RustAmountProp = Shader.PropertyToID("_RustAmount"); + private static readonly int BaseColorProp = Shader.PropertyToID("_BaseColor"); + + [Range(0f, 1f)] [SerializeField] private float currentRust = 0f; + [SerializeField] private Color currentColor = Color.white; + + public float CurrentRust => currentRust; + public Color CurrentColor => currentColor; + + private void Awake() + { + partRenderer = GetComponent(); + propertyBlock = new MaterialPropertyBlock(); + } + + public void SetRust(float amount) + { + currentRust = Mathf.Clamp01(amount); + ApplyProperties(); + } + + public void SetPaintColor(Color newColor) + { + currentColor = newColor; + ApplyProperties(); + } + + private void ApplyProperties() + { + if (partRenderer == null) return; + + partRenderer.GetPropertyBlock(propertyBlock); + propertyBlock.SetFloat(RustAmountProp, currentRust); + propertyBlock.SetColor(BaseColorProp, currentColor); + partRenderer.SetPropertyBlock(propertyBlock); + } +} \ No newline at end of file diff --git a/Assets/Scripts/Car/Visuals/CarPartVisuals.cs.meta b/Assets/Scripts/Car/Visuals/CarPartVisuals.cs.meta new file mode 100644 index 0000000..576e2e1 --- /dev/null +++ b/Assets/Scripts/Car/Visuals/CarPartVisuals.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: de28a2301d654322a1a3aa450e964901 +timeCreated: 1791330380 \ No newline at end of file diff --git a/Assets/Scripts/Car/Visuals/CarRestorationTool.cs b/Assets/Scripts/Car/Visuals/CarRestorationTool.cs new file mode 100644 index 0000000..4d825f2 --- /dev/null +++ b/Assets/Scripts/Car/Visuals/CarRestorationTool.cs @@ -0,0 +1,43 @@ +using UnityEngine; + +public class CarRestorationTool : MonoBehaviour +{ + [Header("Параметры")] + [SerializeField] private float cleanSpeed = 0.25f; // Сколько ржавчины снимается в секунду + [SerializeField] private float range = 2.5f; + [SerializeField] private LayerMask interactableLayer; + + private Camera playerCamera; + + private void Awake() + { + playerCamera = Camera.main; + } + + private void Update() + { + // Зажата ЛКМ — процесс чистки + if (Input.GetMouseButton(0)) + { + TryCleanPart(); + } + } + + private void TryCleanPart() + { + Ray ray = new Ray(playerCamera.transform.position, playerCamera.transform.forward); + + if (Physics.Raycast(ray, out RaycastHit hit, range, interactableLayer)) + { + CarPartVisuals visuals = hit.collider.GetComponentInParent(); + + if (visuals != null && visuals.CurrentRust > 0f) + { + float newRust = visuals.CurrentRust - (cleanSpeed * Time.deltaTime); + visuals.SetRust(newRust); + + // Здесь можно запустить систему частиц искр (Particles) и звук шлифмашинки + } + } + } +} \ No newline at end of file diff --git a/Assets/Scripts/Car/Visuals/CarRestorationTool.cs.meta b/Assets/Scripts/Car/Visuals/CarRestorationTool.cs.meta new file mode 100644 index 0000000..0f94a5b --- /dev/null +++ b/Assets/Scripts/Car/Visuals/CarRestorationTool.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: be6ae3f5845047c6b571b3e3a10b5b44 +timeCreated: 1791330653 \ No newline at end of file diff --git a/Assets/Scripts/Player/Movement/PlayerMovement.cs b/Assets/Scripts/Player/Movement/PlayerMovement.cs index a05d530..ea7ade9 100644 --- a/Assets/Scripts/Player/Movement/PlayerMovement.cs +++ b/Assets/Scripts/Player/Movement/PlayerMovement.cs @@ -5,8 +5,16 @@ public class PlayerMovement : MonoBehaviour { [Header("Movement Settings")] [SerializeField] private float moveSpeed = 4f; + [SerializeField] private float crouchSpeed = 2f; [SerializeField] private float gravity = -9.81f; + [Header("Crouch Settings")] + [SerializeField] private KeyCode crouchKey = KeyCode.LeftControl; + [SerializeField] private float standHeight = 2.0f; + [SerializeField] private float crouchHeight = 1.0f; + [SerializeField] private float crouchTransitionSpeed = 10f; + [SerializeField] private Transform playerCamera; // Ссылка на камеру игрока + [Header("Ground Check")] [SerializeField] private Transform groundCheck; [SerializeField] private float groundDistance = 0.4f; @@ -16,11 +24,70 @@ public class PlayerMovement : MonoBehaviour private Vector3 velocity; private bool isGrounded; + private float initialHeight; + private Vector3 standCameraPos; + private Vector3 crouchCameraPos; + private Vector3 initialCenter; + private bool isCrouching; + private void Awake() { controller = GetComponent(); } + private void Start() + { + // Запоминаем исходные значения из Инспектора + initialHeight = controller.height; + initialCenter = controller.center; + + if (playerCamera == null) + { + Camera cam = GetComponentInChildren(); + if (cam != null) playerCamera = cam.transform; + } + + if (playerCamera != null) + { + standCameraPos = playerCamera.localPosition; + // Камера опускается ровно на разницу высоты + crouchCameraPos = new Vector3( + standCameraPos.x, + standCameraPos.y - (standHeight - crouchHeight), + standCameraPos.z + ); + } + } + + private void Update() + { + HandleCrouch(); + } + + private void HandleCrouch() + { + isCrouching = Input.GetKey(crouchKey); + + float targetHeight = isCrouching ? crouchHeight : standHeight; + float currentDelta = initialHeight - targetHeight; + + // ГЛАВНАЯ ФОРМУЛА: дно капсулы остается на земле + Vector3 targetCenter = new Vector3( + initialCenter.x, + initialCenter.y - (currentDelta * 0.5f), + initialCenter.z + ); + + controller.height = Mathf.MoveTowards(controller.height, targetHeight, Time.deltaTime * crouchTransitionSpeed); + controller.center = Vector3.MoveTowards(controller.center, targetCenter, Time.deltaTime * crouchTransitionSpeed); + + if (playerCamera != null) + { + Vector3 targetCamPos = isCrouching ? crouchCameraPos : standCameraPos; + playerCamera.localPosition = Vector3.MoveTowards(playerCamera.localPosition, targetCamPos, Time.deltaTime * crouchTransitionSpeed); + } + } + public void ProcessMove(Vector2 input) { // Проверка касания земли (сфера на уровне ног) @@ -31,9 +98,12 @@ public class PlayerMovement : MonoBehaviour velocity.y = -2f; // Небольшое прижатие к земле для стабильного спуска по склонам } + // Выбор текущей скорости в зависимости от состояния приседа + float currentSpeed = isCrouching ? crouchSpeed : moveSpeed; + // Движение относительно локальных координат игрока Vector3 move = transform.right * input.x + transform.forward * input.y; - controller.Move(move * (moveSpeed * Time.deltaTime)); + controller.Move(move * (currentSpeed * Time.deltaTime)); // Применение гравитации velocity.y += gravity * Time.deltaTime; diff --git a/Assets/Scripts/Player/Tools.meta b/Assets/Scripts/Player/Tools.meta new file mode 100644 index 0000000..c39487c --- /dev/null +++ b/Assets/Scripts/Player/Tools.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: c01700faa0d14262a0eafda9e075cb96 +timeCreated: 1791393477 \ No newline at end of file diff --git a/Assets/Scripts/Player/Tools/PlayerToolManager.cs b/Assets/Scripts/Player/Tools/PlayerToolManager.cs new file mode 100644 index 0000000..e8e1198 --- /dev/null +++ b/Assets/Scripts/Player/Tools/PlayerToolManager.cs @@ -0,0 +1,71 @@ +using UnityEngine; + +public enum ToolType { Hands, Sander, SprayCan } + +public class PlayerToolManager : MonoBehaviour +{ + [Header("Инструмент")] + public ToolType currentTool = ToolType.Hands; + + [Header("Настройки")] + [SerializeField] private float toolRange = 2.5f; + [SerializeField] private LayerMask interactableLayer; + [SerializeField] private float sandSpeed = 0.35f; // Скорость очистки в сек. + [SerializeField] private Color sprayPaintColor = new Color(0.1f, 0.4f, 0.8f); // Выбранный цвет краски + + private Camera playerCam; + + private void Awake() + { + playerCam = GetComponentInChildren(); + } + + private void Update() + { + // Не используем инструменты, если открыто меню или выбраны пустые руки + if (currentTool == ToolType.Hands) return; + + // Зажата ЛКМ — работаем инструментом + if (Input.GetMouseButton(0)) + { + UseActiveTool(); + } + } + + private void UseActiveTool() + { + Ray ray = new Ray(playerCam.transform.position, playerCam.transform.forward); + if (!Physics.Raycast(ray, out RaycastHit hit, toolRange, interactableLayer)) return; + + CarPartVisuals visuals = hit.collider.GetComponentInParent(); + if (visuals == null) return; + + if (currentTool == ToolType.Sander) + { + // ШЛИФОВКА: снижаем ржавчину к 0 + if (visuals.CurrentRust > 0f) + { + float updatedRust = visuals.CurrentRust - (sandSpeed * Time.deltaTime); + visuals.SetRust(updatedRust); + } + } + else if (currentTool == ToolType.SprayCan) + { + // ПОКРАСКА: красим, только если ржавчина удалена + if (visuals.CurrentRust <= 0.05f) + { + visuals.SetPaintColor(sprayPaintColor); + } + else + { + // Подсказка игроку + Debug.Log("Нельзя красить: деталь еще ржавая! Зашлифуйте её."); + } + } + } + + public void SelectTool(ToolType newTool) + { + currentTool = newTool; + } +} \ No newline at end of file diff --git a/Assets/Scripts/Player/Tools/PlayerToolManager.cs.meta b/Assets/Scripts/Player/Tools/PlayerToolManager.cs.meta new file mode 100644 index 0000000..f9a8c04 --- /dev/null +++ b/Assets/Scripts/Player/Tools/PlayerToolManager.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 79b9bf3c26bc4f38a11491b3776b8121 +timeCreated: 1791393489 \ No newline at end of file diff --git a/Assets/Scripts/Player/Tools/ToolRadialMenu.cs b/Assets/Scripts/Player/Tools/ToolRadialMenu.cs new file mode 100644 index 0000000..9841f59 --- /dev/null +++ b/Assets/Scripts/Player/Tools/ToolRadialMenu.cs @@ -0,0 +1,92 @@ +using UnityEngine; +using UnityEngine.UI; + +public class ToolRadialMenu : MonoBehaviour +{ + [Header("Ссылки")] + [SerializeField] private GameObject menuPanel; + [SerializeField] private PlayerToolManager toolManager; + [SerializeField] private Image[] sectorIcons; // 3 иконки (0: Руки, 1: Шлифмашинка, 2: Баллончик) + + [Header("Цвета выделения")] + [SerializeField] private Color normalColor = Color.white; + [SerializeField] private Color selectedColor = Color.yellow; + + private int selectedIndex = 0; + private bool isMenuOpen = false; + + private void Start() + { + menuPanel.SetActive(false); + } + + private void Update() + { + // Открытие/закрытие по клавише Tab + if (Input.GetKeyDown(KeyCode.Tab)) + { + OpenMenu(); + } + else if (Input.GetKeyUp(KeyCode.Tab)) + { + CloseMenuAndApply(); + } + + if (isMenuOpen) + { + CalculateMouseSector(); + } + } + + private void OpenMenu() + { + isMenuOpen = true; + menuPanel.SetActive(true); + + // Разблокируем курсор для кругового выбора + Cursor.lockState = CursorLockMode.None; + Cursor.visible = true; + } + + private void CalculateMouseSector() + { + Vector2 screenCenter = new Vector2(Screen.width * 0.5f, Screen.height * 0.5f); + Vector2 mouseDelta = (Vector2)Input.mousePosition - screenCenter; + + // Если мышь почти в центре — ничего не меняем + if (mouseDelta.magnitude < 30f) return; + + // Вычисляем угол мыши от -180 до 180 градусов + float angle = Mathf.Atan2(mouseDelta.y, mouseDelta.x) * Mathf.Rad2Deg; + if (angle < 0) angle += 360f; // Переводим в 0..360 + + // 3 сектора по 120 градусов: + // Сектор 0 (0..120): Руки + // Сектор 1 (120..240): Шлифмашинка + // Сектор 2 (240..360): Баллончик + selectedIndex = Mathf.FloorToInt(angle / 120f); + + HighlightSelection(); + } + + private void HighlightSelection() + { + for (int i = 0; i < sectorIcons.Length; i++) + { + sectorIcons[i].color = (i == selectedIndex) ? selectedColor : normalColor; + } + } + + private void CloseMenuAndApply() + { + isMenuOpen = false; + menuPanel.SetActive(false); + + // Возвращаем прицел от первого лица + Cursor.lockState = CursorLockMode.Locked; + Cursor.visible = false; + + // Применяем выбранный инструмент + toolManager.SelectTool((ToolType)selectedIndex); + } +} \ No newline at end of file diff --git a/Assets/Scripts/Player/Tools/ToolRadialMenu.cs.meta b/Assets/Scripts/Player/Tools/ToolRadialMenu.cs.meta new file mode 100644 index 0000000..79b5c34 --- /dev/null +++ b/Assets/Scripts/Player/Tools/ToolRadialMenu.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: aefd5e59eb964d74a70224a9b43918d0 +timeCreated: 1791393583 \ No newline at end of file diff --git a/Packages/manifest.json b/Packages/manifest.json index 1289886..63f7627 100644 --- a/Packages/manifest.json +++ b/Packages/manifest.json @@ -45,6 +45,17 @@ "com.unity.modules.vehicles": "1.0.0", "com.unity.modules.video": "1.0.0", "com.unity.modules.wind": "1.0.0", - "com.unity.modules.xr": "1.0.0" - } -} + "com.unity.modules.xr": "1.0.0", + "com.ivanmurzak.unity.mcp": "0.93.2" + }, + "scopedRegistries": [ + { + "name": "package.openupm.com", + "url": "https://package.openupm.com", + "scopes": [ + "com.ivanmurzak", + "extensions.unity" + ] + } + ] +} \ No newline at end of file diff --git a/Packages/packages-lock.json b/Packages/packages-lock.json index fccd8c8..2436de2 100644 --- a/Packages/packages-lock.json +++ b/Packages/packages-lock.json @@ -1,5 +1,16 @@ { "dependencies": { + "com.ivanmurzak.unity.mcp": { + "version": "0.93.2", + "depth": 0, + "source": "registry", + "dependencies": { + "com.unity.test-framework": "1.1.33", + "com.unity.modules.uielements": "1.0.0", + "extensions.unity.playerprefsex": "2.1.5" + }, + "url": "https://package.openupm.com" + }, "com.unity.ai.navigation": { "version": "2.0.14", "depth": 0, @@ -184,6 +195,13 @@ }, "url": "https://packages.unity.com" }, + "extensions.unity.playerprefsex": { + "version": "2.1.5", + "depth": 1, + "source": "registry", + "dependencies": {}, + "url": "https://package.openupm.com" + }, "com.unity.modules.accessibility": { "version": "1.0.0", "depth": 0, diff --git a/ProjectSettings/PackageManagerSettings.asset b/ProjectSettings/PackageManagerSettings.asset index 2114818..aeb6ce5 100644 --- a/ProjectSettings/PackageManagerSettings.asset +++ b/ProjectSettings/PackageManagerSettings.asset @@ -31,14 +31,27 @@ MonoBehaviour: m_Compliance: m_Status: 0 m_Violations: [] - m_ScopedRegistries: [] - m_UserSelectedRegistryName: + m_ScopedRegistries: + - m_Id: scoped:project:package.openupm.com + m_Name: package.openupm.com + m_Url: https://package.openupm.com + m_Scopes: + - com.ivanmurzak + - extensions.unity + m_IsDefault: 0 + m_IsUnityRegistry: 0 + m_Capabilities: 0 + m_ConfigSource: 4 + m_Compliance: + m_Status: 0 + m_Violations: [] + m_UserSelectedRegistryName: package.openupm.com m_UserAddingNewScopedRegistry: 0 m_RegistryInfoDraft: m_Modified: 0 m_ErrorMessage: m_UserModificationsEntityId: - m_rawData: 568105584918792958 + m_rawData: 1099511629249 m_OriginalEntityId: - m_rawData: 568105584918792960 + m_rawData: 1099511629250 m_LoadAssets: 0 diff --git a/ProjectSettings/ProjectSettings.asset b/ProjectSettings/ProjectSettings.asset index 6168c34..1d5cba0 100644 --- a/ProjectSettings/ProjectSettings.asset +++ b/ProjectSettings/ProjectSettings.asset @@ -834,7 +834,26 @@ PlayerSettings: webWasm2023: 1 webEnableSubmoduleStrippingCompatibility: 0 webProgressiveAssetLoading: 0 - scriptingDefineSymbols: {} + scriptingDefineSymbols: + Android: UNITY_MCP_READY;UNITY_MCP_DEPS_6 + EmbeddedLinux: UNITY_MCP_READY;UNITY_MCP_DEPS_6 + GameCoreScarlett: UNITY_MCP_READY;UNITY_MCP_DEPS_6 + GameCoreXboxOne: UNITY_MCP_READY;UNITY_MCP_DEPS_6 + Kepler: UNITY_MCP_READY;UNITY_MCP_DEPS_6 + LinuxHeadlessSimulation: UNITY_MCP_READY;UNITY_MCP_DEPS_6 + Nintendo Switch: UNITY_MCP_READY;UNITY_MCP_DEPS_6 + Nintendo Switch 2: UNITY_MCP_READY;UNITY_MCP_DEPS_6 + PS4: UNITY_MCP_READY;UNITY_MCP_DEPS_6 + PS5: UNITY_MCP_READY;UNITY_MCP_DEPS_6 + QNX: UNITY_MCP_READY;UNITY_MCP_DEPS_6 + Server: UNITY_MCP_READY;UNITY_MCP_DEPS_6 + Standalone: UNITY_MCP_READY;UNITY_MCP_DEPS_6 + VisionOS: UNITY_MCP_READY;UNITY_MCP_DEPS_6 + WebGL: UNITY_MCP_READY;UNITY_MCP_DEPS_6 + Windows Store Apps: UNITY_MCP_READY;UNITY_MCP_DEPS_6 + XboxOne: UNITY_MCP_READY;UNITY_MCP_DEPS_6 + iPhone: UNITY_MCP_READY;UNITY_MCP_DEPS_6 + tvOS: UNITY_MCP_READY;UNITY_MCP_DEPS_6 additionalCompilerArguments: {} platformArchitecture: {} scriptingBackend: