Добавил скрипты для более реалистичной физики, но они шляпа полная.

This commit is contained in:
bybohka 2026-10-14 15:51:37 +03:00
parent f9eb14868d
commit 5f25a8eab4
32 changed files with 490 additions and 1643 deletions

View File

@ -25,6 +25,9 @@ Material:
m_Parent: {fileID: 0}
m_ModifiedSerializedProperties: 0
m_ValidKeywords:
- _METALLICSPECGLOSSMAP
- _NORMALMAP
- _PARALLAXMAP
- _SPECGLOSSMAP
- _SPECULAR_SETUP
m_InvalidKeywords: []
@ -65,7 +68,7 @@ Material:
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _MainTex:
m_Texture: {fileID: 0}
m_Texture: {fileID: 2800000, guid: a9a0a885c2eede34587e12cd1414003c, type: 3}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _MetallicGlossMap:

View File

@ -25,6 +25,9 @@ Material:
m_Parent: {fileID: 0}
m_ModifiedSerializedProperties: 0
m_ValidKeywords:
- _METALLICSPECGLOSSMAP
- _NORMALMAP
- _PARALLAXMAP
- _SPECGLOSSMAP
- _SPECULAR_SETUP
m_InvalidKeywords: []
@ -65,7 +68,7 @@ Material:
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _MainTex:
m_Texture: {fileID: 0}
m_Texture: {fileID: 2800000, guid: f63b585b494c19e408adc8374a32ff38, type: 3}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _MetallicGlossMap:

View File

@ -12,6 +12,9 @@ Material:
m_Parent: {fileID: 0}
m_ModifiedSerializedProperties: 0
m_ValidKeywords:
- _METALLICSPECGLOSSMAP
- _NORMALMAP
- _PARALLAXMAP
- _SPECGLOSSMAP
- _SPECULAR_SETUP
m_InvalidKeywords: []
@ -52,7 +55,7 @@ Material:
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _MainTex:
m_Texture: {fileID: 0}
m_Texture: {fileID: 2800000, guid: d898f1952a888e5459ca4fa61f69aacb, type: 3}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _MetallicGlossMap:

View File

@ -12,6 +12,9 @@ Material:
m_Parent: {fileID: 0}
m_ModifiedSerializedProperties: 0
m_ValidKeywords:
- _METALLICSPECGLOSSMAP
- _NORMALMAP
- _PARALLAXMAP
- _SPECGLOSSMAP
- _SPECULAR_SETUP
m_InvalidKeywords: []
@ -52,7 +55,7 @@ Material:
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _MainTex:
m_Texture: {fileID: 0}
m_Texture: {fileID: 2800000, guid: 190b08caee9510e4094d8fb85df30e6a, type: 3}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _MetallicGlossMap:

View File

@ -25,6 +25,9 @@ Material:
m_Parent: {fileID: 0}
m_ModifiedSerializedProperties: 0
m_ValidKeywords:
- _METALLICSPECGLOSSMAP
- _NORMALMAP
- _PARALLAXMAP
- _SPECGLOSSMAP
- _SPECULAR_SETUP
m_InvalidKeywords: []
@ -65,7 +68,7 @@ Material:
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _MainTex:
m_Texture: {fileID: 0}
m_Texture: {fileID: 2800000, guid: 348b7b1e9b718254eb222c50d2f1b370, type: 3}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _MetallicGlossMap:

View File

@ -64,7 +64,7 @@ Material:
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _MainTex:
m_Texture: {fileID: 0}
m_Texture: {fileID: 2800000, guid: 24ae1851ee4bd6b40903851f84596cc5, type: 3}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _MetallicGlossMap:

View File

@ -12,6 +12,7 @@ Material:
m_Parent: {fileID: 0}
m_ModifiedSerializedProperties: 0
m_ValidKeywords:
- _METALLICSPECGLOSSMAP
- _SPECGLOSSMAP
- _SPECULAR_SETUP
m_InvalidKeywords:
@ -53,7 +54,7 @@ Material:
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _MainTex:
m_Texture: {fileID: 0}
m_Texture: {fileID: 2800000, guid: 027ee668c37651046b8fcc1de158d11b, type: 3}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _MetallicGlossMap:

View File

@ -25,6 +25,7 @@ Material:
m_Parent: {fileID: 0}
m_ModifiedSerializedProperties: 0
m_ValidKeywords:
- _METALLICSPECGLOSSMAP
- _SPECGLOSSMAP
- _SPECULAR_SETUP
m_InvalidKeywords: []
@ -65,7 +66,7 @@ Material:
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _MainTex:
m_Texture: {fileID: 0}
m_Texture: {fileID: 2800000, guid: 62da88ce44d49764b91100a52cc54548, type: 3}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _MetallicGlossMap:

View File

@ -12,6 +12,7 @@ Material:
m_Parent: {fileID: 0}
m_ModifiedSerializedProperties: 0
m_ValidKeywords:
- _METALLICSPECGLOSSMAP
- _SPECGLOSSMAP
- _SPECULAR_SETUP
m_InvalidKeywords:
@ -53,7 +54,7 @@ Material:
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _MainTex:
m_Texture: {fileID: 0}
m_Texture: {fileID: 2800000, guid: efce089419136f94492f8f54bf755a5c, type: 3}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _MetallicGlossMap:

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: a3efdaab9fd94774aa80108ad4e02503
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,98 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!114 &11400000
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 396086e692304e97aab2b9b09066d2b5, type: 3}
m_Name: Hirochi_Physics
m_EditorClassIdentifier: Assembly-CSharp::CarPhysicsData
torqueCurve:
serializedVersion: 2
m_Curve:
- serializedVersion: 3
time: 1
value: 1
inSlope: 0.123904884
outSlope: 0.123904884
tangentMode: 34
weightedMode: 0
inWeight: 0
outWeight: 0.33333334
- serializedVersion: 3
time: 800
value: 100
inSlope: 0.082222715
outSlope: 0.082222715
tangentMode: 34
weightedMode: 0
inWeight: 0.33333334
outWeight: 0.33333334
- serializedVersion: 3
time: 4500
value: 250
inSlope: -0.0137297325
outSlope: -0.0137297325
tangentMode: 34
weightedMode: 0
inWeight: 0.33333334
outWeight: 0.33333334
- serializedVersion: 3
time: 7000
value: 80
inSlope: -0.068
outSlope: -0.068
tangentMode: 34
weightedMode: 0
inWeight: 0.33333334
outWeight: 0
m_PreInfinity: 2
m_PostInfinity: 2
m_RotationOrder: 4
maxRPM: 7000
minRPM: 800
shiftUpRPM: 6000
shiftDownRPM: 2500
gearRatios:
- 3.1
- 2.2
- 1.6
- 1.2
- 0.9
- 0.7
finalDrive: 3.4
maxSteerAngle: 35
steerSmoothing: 10
steerAngleBySpeed:
serializedVersion: 2
m_Curve:
- serializedVersion: 3
time: 0
value: 1
inSlope: 0
outSlope: 0
tangentMode: 136
weightedMode: 0
inWeight: 0.33333334
outWeight: 0.33333334
- serializedVersion: 3
time: 150
value: 0.3
inSlope: 0
outSlope: 0
tangentMode: 136
weightedMode: 0
inWeight: 0.33333334
outWeight: 0.33333334
m_PreInfinity: 2
m_PostInfinity: 2
m_RotationOrder: 4
centerOfMassOffset: {x: 0, y: -0.2, z: 0}
antiRollForce: 5000
brakeForce: 3000
handbrakeFrictionMultiplier: 0.3

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 1865251594a045046b5f77e23e0cb2c6
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 11400000
userData:
assetBundleName:
assetBundleVariant:

View File

@ -1,116 +0,0 @@
using UnityEngine;
using UnityEditor;
using UnityEditor.SceneManagement;
namespace Perekyp.EditorTools
{
[InitializeOnLoad]
public static class SpawnCubesEditor
{
static SpawnCubesEditor()
{
EditorApplication.delayCall += SpawnCubesOnce;
}
private static void SpawnCubesOnce()
{
// Execute spawn of the 6 cubes
ExecuteSpawn();
}
[MenuItem("Tools/Spawn 6 Cubes (2 Rows)")]
public static void ExecuteSpawn()
{
// Clean up previous groups if existing
GameObject oldGroup1 = GameObject.Find("ThreeCubes");
if (oldGroup1 != null)
{
Undo.DestroyObjectImmediate(oldGroup1);
}
GameObject oldGroup2 = GameObject.Find("CubesGroup");
if (oldGroup2 != null)
{
Undo.DestroyObjectImmediate(oldGroup2);
}
GameObject parent = new GameObject("CubesGroup");
Undo.RegisterCreatedObjectUndo(parent, "Create CubesGroup Parent");
// Row 1 (first 3 cubes) and Row 2 (3 new cubes next to them)
// Player is around Z = 5.24 facing negative Z, so Z = 3.5 and Z = 2.0 are directly in view.
Vector3[] positions = new Vector3[]
{
// Row 1 (first row)
new Vector3(-2.0f, 1.0f, 3.5f),
new Vector3( 0.0f, 1.0f, 3.5f),
new Vector3( 2.0f, 1.0f, 3.5f),
// Row 2 (second row, right next to / in front of the first row)
new Vector3(-2.0f, 1.0f, 2.0f),
new Vector3( 0.0f, 1.0f, 2.0f),
new Vector3( 2.0f, 1.0f, 2.0f)
};
Color[] colors = new Color[]
{
// Row 1: Red, Green, Blue
new Color(0.95f, 0.26f, 0.21f), // Red
new Color(0.30f, 0.69f, 0.31f), // Green
new Color(0.13f, 0.59f, 0.95f), // Blue
// Row 2: Red, Green, Blue (matching set)
new Color(0.95f, 0.26f, 0.21f), // Red
new Color(0.30f, 0.69f, 0.31f), // Green
new Color(0.13f, 0.59f, 0.95f) // Blue
};
string[] names = new string[]
{
"Cube_Red_Row1",
"Cube_Green_Row1",
"Cube_Blue_Row1",
"Cube_Red_Row2",
"Cube_Green_Row2",
"Cube_Blue_Row2"
};
Shader urpShader = Shader.Find("Universal Render Pipeline/Lit")
?? Shader.Find("URP/Lit")
?? Shader.Find("Standard");
for (int i = 0; i < 6; i++)
{
GameObject cube = GameObject.CreatePrimitive(PrimitiveType.Cube);
cube.name = names[i];
cube.transform.position = positions[i];
cube.transform.localScale = Vector3.one;
cube.transform.SetParent(parent.transform);
var renderer = cube.GetComponent<Renderer>();
if (renderer != null && urpShader != null)
{
Material mat = new Material(urpShader);
mat.name = $"Mat_{names[i]}";
mat.color = colors[i];
renderer.sharedMaterial = mat;
}
Undo.RegisterCreatedObjectUndo(cube, $"Create {names[i]}");
}
Selection.activeGameObject = parent;
var activeScene = EditorSceneManager.GetActiveScene();
if (activeScene.IsValid())
{
EditorSceneManager.MarkSceneDirty(activeScene);
EditorSceneManager.SaveScene(activeScene);
Debug.Log($"[SpawnCubesEditor] Successfully spawned 6 cubes (2 rows of 3) on scene '{activeScene.name}'!");
}
else
{
Debug.Log("[SpawnCubesEditor] Successfully spawned 6 cubes in the scene!");
}
}
}
}

View File

@ -1,2 +0,0 @@
fileFormatVersion: 2
guid: 403983d9c86a19f4a85074eba6aed3fd

File diff suppressed because it is too large Load Diff

View File

@ -7,13 +7,13 @@ public class VehicleInteraction : MonoBehaviour, IInteractable
[SerializeField] private UIManager uiManager;
private CarOrbitCamera globalCarCamera; // Ссылка на глобальную камеру
private CarController carController;
private AdvancedCarController carController;
private GameObject playerInstance;
private bool isPlayerInside = false;
public bool isPlayerInside = false;
private void Awake()
{
carController = GetComponent<CarController>();
carController = GetComponent<AdvancedCarController>();
// Автоматически находим камеру на сцене, даже если она выключена
globalCarCamera = FindAnyObjectByType<CarOrbitCamera>(FindObjectsInactive.Include);

View File

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: d1396ff771764dc2bcb7e90faac08815
timeCreated: 1791809673

View File

@ -0,0 +1,170 @@
using UnityEngine;
[RequireComponent(typeof(Rigidbody))]
public class AdvancedCarController : MonoBehaviour
{
public float SpeedKmH => rb.linearVelocity.magnitude * 3.6f;
[Header("Данные авто")]
[SerializeField] private CarPhysicsData data;
[Header("Колеса (WheelColliders)")]
[SerializeField] private WheelCollider[] frontWheels;
[SerializeField] private WheelCollider[] rearWheels;
[Header("Состояние деталей (Для диплома)")]
[Range(0.1f, 1f)] public float engineCondition = 1f; // 1 - новое, 0.1 - убитое (не тянет)
[Range(0.1f, 1f)] public float tiresCondition = 1f; // Влияет на держак резины
// Состояние авто
public float CurrentSpeedKmH => rb.linearVelocity.magnitude * 3.6f;
public float EngineRPM { get; private set; }
public int CurrentGear { get; private set; }
private Rigidbody rb;
private float currentSteerAngle;
private WheelFrictionCurve originalRearSidewaysFriction;
// Ввод
private float moveInput, steerInput;
private bool isBraking, isHandbrake;
private void Awake()
{
rb = GetComponent<Rigidbody>();
rb.centerOfMass = data.centerOfMassOffset; // Понижаем центр масс для стабильности
// Запоминаем оригинальное трение для ручника
if (rearWheels.Length > 0)
originalRearSidewaysFriction = rearWheels[0].sidewaysFriction;
}
private void Update()
{
// Чтение инпута (можно заменить на новый Input System)
moveInput = Input.GetAxis("Vertical");
steerInput = Input.GetAxis("Horizontal");
isBraking = Input.GetKey(KeyCode.Space) || (moveInput < 0 && CurrentSpeedKmH > 5f);
isHandbrake = Input.GetKey(KeyCode.LeftShift) || Input.GetKey(KeyCode.Space);
}
private void FixedUpdate()
{
ApplySteering();
ProcessEngineAndGears();
ApplyAntiRollBar();
ProcessHandbrake();
}
public void ProcessInput(float vertical, float horizontal, bool handbrake)
{
moveInput = vertical;
steerInput = horizontal;
isHandbrake = handbrake;
}
private void ApplySteering()
{
// 1. Угол зависит от скорости (на 100 км/ч руль не вывернется на 35 градусов)
float speedMultiplier = data.steerAngleBySpeed.Evaluate(CurrentSpeedKmH);
float targetSteer = steerInput * data.maxSteerAngle * speedMultiplier;
// 2. Сглаживание поворота (руль не дергается мгновенно)
currentSteerAngle = Mathf.Lerp(currentSteerAngle, targetSteer, Time.fixedDeltaTime * data.steerSmoothing);
foreach (var wheel in frontWheels)
{
wheel.steerAngle = currentSteerAngle;
}
}
private void ProcessEngineAndGears()
{
// Считаем средние обороты ведущих колес (допустим, задний привод)
float wheelRPM = 0;
foreach (var w in rearWheels) wheelRPM += Mathf.Abs(w.rpm);
wheelRPM /= rearWheels.Length;
// Вычисляем обороты двигателя через передаточные числа
float gearRatio = data.gearRatios[CurrentGear];
EngineRPM = Mathf.Clamp(wheelRPM * gearRatio * data.finalDrive, data.minRPM, data.maxRPM);
// Автоматическая коробка передач
if (EngineRPM > data.shiftUpRPM && CurrentGear < data.gearRatios.Length - 1)
CurrentGear++;
else if (EngineRPM < data.shiftDownRPM && CurrentGear > 0)
CurrentGear--;
// Получаем крутящий момент по графику и умножаем на состояние двигателя!
float motorTorque = data.torqueCurve.Evaluate(EngineRPM) * gearRatio * data.finalDrive;
float finalTorque = moveInput * motorTorque * engineCondition;
// Применяем газ или тормоз
foreach (var wheel in rearWheels)
{
if (isBraking)
{
wheel.motorTorque = 0;
wheel.brakeTorque = data.brakeForce;
}
else
{
wheel.motorTorque = finalTorque / rearWheels.Length;
wheel.brakeTorque = 0;
}
}
}
private void ProcessHandbrake()
{
foreach (var wheel in rearWheels)
{
if (isHandbrake)
{
wheel.brakeTorque = data.brakeForce;
// ДРИФТ: Уменьшаем боковое сцепление, умножая на износ шин
WheelFrictionCurve fc = wheel.sidewaysFriction;
fc.stiffness = originalRearSidewaysFriction.stiffness * data.handbrakeFrictionMultiplier * tiresCondition;
wheel.sidewaysFriction = fc;
}
else if (!isBraking)
{
wheel.brakeTorque = 0;
// Возвращаем обычное сцепление с поправкой на убитость шин
WheelFrictionCurve fc = wheel.sidewaysFriction;
fc.stiffness = originalRearSidewaysFriction.stiffness * tiresCondition;
wheel.sidewaysFriction = fc;
}
}
}
private void ApplyAntiRollBar()
{
// Стабилизатор поперечной устойчивости для передней и задней оси
ApplyAxleAntiRoll(frontWheels[0], frontWheels[1]);
ApplyAxleAntiRoll(rearWheels[0], rearWheels[1]);
}
private void ApplyAxleAntiRoll(WheelCollider left, WheelCollider right)
{
float travelL = 1.0f;
float travelR = 1.0f;
bool groundedL = left.GetGroundHit(out WheelHit hitL);
if (groundedL) travelL = (-left.transform.InverseTransformPoint(hitL.point).y - left.radius) / left.suspensionDistance;
bool groundedR = right.GetGroundHit(out WheelHit hitR);
if (groundedR) travelR = (-right.transform.InverseTransformPoint(hitR.point).y - right.radius) / right.suspensionDistance;
// Разница сжатия подвески
float antiRollVal = (travelL - travelR) * data.antiRollForce;
// Применяем противодействующую силу (прижимаем поднявшееся колесо)
if (groundedL) rb.AddForceAtPosition(left.transform.up * -antiRollVal, left.transform.position);
if (groundedR) rb.AddForceAtPosition(right.transform.up * antiRollVal, right.transform.position);
}
}

View File

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: c02b03f912164de9ae5c7659d886fae9
timeCreated: 1791809782

View File

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 50a1732ad7494d0ab29474ca2bc918c1
timeCreated: 1791809613

View File

@ -0,0 +1,28 @@
using UnityEngine;
[CreateAssetMenu(fileName = "NewCarPhysics", menuName = "Car System/Physics Data")]
public class CarPhysicsData : ScriptableObject
{
[Header("Двигатель и КПП")]
public AnimationCurve torqueCurve; // Кривая: X - обороты (RPM), Y - крутящий момент (Nm)
public float maxRPM = 7000f;
public float minRPM = 800f;
public float shiftUpRPM = 6000f;
public float shiftDownRPM = 2500f;
public float[] gearRatios = { 3.1f, 2.2f, 1.6f, 1.2f, 0.9f, 0.7f };
public float finalDrive = 3.4f;
[Header("Рулевое управление")]
public float maxSteerAngle = 35f;
public float steerSmoothing = 10f; // Скорость поворота руля
[Tooltip("Как сильно режется угол поворота на высокой скорости")]
public AnimationCurve steerAngleBySpeed; // X - скорость (км/ч), Y - множитель угла (0..1)
[Header("Подвеска и физика")]
public Vector3 centerOfMassOffset = new Vector3(0, -0.2f, 0); // Пониженный центр масс
public float antiRollForce = 5000f; // Стабилизатор поперечной устойчивости
public float brakeForce = 3000f;
[Header("Дрифт (Ручник)")]
public float handbrakeFrictionMultiplier = 0.3f; // Насколько скользкой становится задняя ось
}

View File

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 396086e692304e97aab2b9b09066d2b5
timeCreated: 1791809619

View File

@ -0,0 +1,29 @@
using UnityEngine;
public class WheelVisuals : MonoBehaviour
{
[System.Serializable]
public struct WheelPair
{
public WheelCollider collider;
public Transform mesh;
}
[Header("Привязка колес")]
public WheelPair[] wheels;
private void Update()
{
foreach (var w in wheels)
{
if (w.collider == null || w.mesh == null) continue;
// Получаем физическую позицию колеса
w.collider.GetWorldPose(out Vector3 pos, out Quaternion rot);
// Применяем к 3D-модели
w.mesh.position = pos;
w.mesh.rotation = rot;
}
}
}

View File

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: ce1b65bf09494194a68749d417b0e17a
timeCreated: 1791809850

View File

@ -2,45 +2,80 @@ using UnityEngine;
public class PlayerInteractor : MonoBehaviour
{
[Header("Настройки луча")]
[SerializeField] private float interactRange = 3f;
[SerializeField] private LayerMask interactableLayer; // Создайте слой "Interactable" в Unity
[SerializeField] private KeyCode primaryKey = KeyCode.E;
[SerializeField] private KeyCode secondaryKey = KeyCode.R;
[Header("References")]
[SerializeField] private LayerMask interactableLayer;
[Header("Клавиши управления")]
[SerializeField] private KeyCode primaryKey = KeyCode.E; // Работа с деталью (открыть/взять)
[SerializeField] private KeyCode secondaryKey = KeyCode.R; // Снять деталь
[SerializeField] private KeyCode enterVehicleKey = KeyCode.F; // Сесть в машину
[Header("Ссылки")]
[SerializeField] private UIManager uiManager;
private void OnDisable()
{
if (uiManager != null) uiManager.HidePrompt();
}
private void Update()
{
// Пускаем луч из центра экрана
Ray ray = new Ray(transform.position, transform.forward);
if (Physics.Raycast(ray, out RaycastHit hit, interactRange, interactableLayer, QueryTriggerInteraction.Collide))
{
// Ищем интерактивную деталь (дверь, капот, крыло)
IInteractable interactable = hit.collider.GetComponentInParent<IInteractable>();
if (interactable != null)
// Ищем скрипт автомобиля в родительских объектах
VehicleInteraction vehicle = hit.collider.GetComponentInParent<VehicleInteraction>();
if (interactable != null || vehicle != null)
{
if (!string.IsNullOrEmpty(interactable.GetPrompt()) && uiManager!=null)
// Формируем комбинированную подсказку
string prompt = "";
if (vehicle != null && !vehicle.isPlayerInside)
{
uiManager.ShowPrompt(interactable.GetPrompt());
prompt += "[F] Сесть в авто ";
}
else if (uiManager != null)
if (interactable != null)
{
uiManager.HidePrompt();
string partPrompt = interactable.GetPrompt();
if (!string.IsNullOrEmpty(partPrompt))
{
prompt += partPrompt;
}
}
if (Input.GetKeyDown(primaryKey))
if (!string.IsNullOrEmpty(prompt) && uiManager != null)
{
uiManager.ShowPrompt(prompt);
}
// 1. Посадка в авто на F
if (Input.GetKeyDown(enterVehicleKey) && vehicle != null)
{
vehicle.Interact(transform.root.gameObject);
if (uiManager != null) uiManager.HidePrompt();
return;
}
// 2. Основное действие с деталью на E (Открыть/Закрыть)
if (Input.GetKeyDown(primaryKey) && interactable != null)
{
interactable.Interact(transform.root.gameObject);
}
// 3. Вторичное действие с деталью на R (Снять в руки)
if (Input.GetKeyDown(secondaryKey))
{
ISecondaryInteractable secondary = hit.collider.GetComponentInParent<ISecondaryInteractable>();
secondary?.SecondaryInteract(transform.root.gameObject);
}
return;
}
}
@ -50,12 +85,4 @@ public class PlayerInteractor : MonoBehaviour
uiManager.HidePrompt();
}
}
private void OnDisable()
{
if (uiManager != null)
{
uiManager.HidePrompt();
}
}
}