Добавил скрипты для более реалистичной физики, но они шляпа полная.
This commit is contained in:
parent
f9eb14868d
commit
5f25a8eab4
@ -25,6 +25,9 @@ Material:
|
|||||||
m_Parent: {fileID: 0}
|
m_Parent: {fileID: 0}
|
||||||
m_ModifiedSerializedProperties: 0
|
m_ModifiedSerializedProperties: 0
|
||||||
m_ValidKeywords:
|
m_ValidKeywords:
|
||||||
|
- _METALLICSPECGLOSSMAP
|
||||||
|
- _NORMALMAP
|
||||||
|
- _PARALLAXMAP
|
||||||
- _SPECGLOSSMAP
|
- _SPECGLOSSMAP
|
||||||
- _SPECULAR_SETUP
|
- _SPECULAR_SETUP
|
||||||
m_InvalidKeywords: []
|
m_InvalidKeywords: []
|
||||||
@ -65,7 +68,7 @@ Material:
|
|||||||
m_Scale: {x: 1, y: 1}
|
m_Scale: {x: 1, y: 1}
|
||||||
m_Offset: {x: 0, y: 0}
|
m_Offset: {x: 0, y: 0}
|
||||||
- _MainTex:
|
- _MainTex:
|
||||||
m_Texture: {fileID: 0}
|
m_Texture: {fileID: 2800000, guid: a9a0a885c2eede34587e12cd1414003c, type: 3}
|
||||||
m_Scale: {x: 1, y: 1}
|
m_Scale: {x: 1, y: 1}
|
||||||
m_Offset: {x: 0, y: 0}
|
m_Offset: {x: 0, y: 0}
|
||||||
- _MetallicGlossMap:
|
- _MetallicGlossMap:
|
||||||
|
|||||||
@ -25,6 +25,9 @@ Material:
|
|||||||
m_Parent: {fileID: 0}
|
m_Parent: {fileID: 0}
|
||||||
m_ModifiedSerializedProperties: 0
|
m_ModifiedSerializedProperties: 0
|
||||||
m_ValidKeywords:
|
m_ValidKeywords:
|
||||||
|
- _METALLICSPECGLOSSMAP
|
||||||
|
- _NORMALMAP
|
||||||
|
- _PARALLAXMAP
|
||||||
- _SPECGLOSSMAP
|
- _SPECGLOSSMAP
|
||||||
- _SPECULAR_SETUP
|
- _SPECULAR_SETUP
|
||||||
m_InvalidKeywords: []
|
m_InvalidKeywords: []
|
||||||
@ -65,7 +68,7 @@ Material:
|
|||||||
m_Scale: {x: 1, y: 1}
|
m_Scale: {x: 1, y: 1}
|
||||||
m_Offset: {x: 0, y: 0}
|
m_Offset: {x: 0, y: 0}
|
||||||
- _MainTex:
|
- _MainTex:
|
||||||
m_Texture: {fileID: 0}
|
m_Texture: {fileID: 2800000, guid: f63b585b494c19e408adc8374a32ff38, type: 3}
|
||||||
m_Scale: {x: 1, y: 1}
|
m_Scale: {x: 1, y: 1}
|
||||||
m_Offset: {x: 0, y: 0}
|
m_Offset: {x: 0, y: 0}
|
||||||
- _MetallicGlossMap:
|
- _MetallicGlossMap:
|
||||||
|
|||||||
@ -12,6 +12,9 @@ Material:
|
|||||||
m_Parent: {fileID: 0}
|
m_Parent: {fileID: 0}
|
||||||
m_ModifiedSerializedProperties: 0
|
m_ModifiedSerializedProperties: 0
|
||||||
m_ValidKeywords:
|
m_ValidKeywords:
|
||||||
|
- _METALLICSPECGLOSSMAP
|
||||||
|
- _NORMALMAP
|
||||||
|
- _PARALLAXMAP
|
||||||
- _SPECGLOSSMAP
|
- _SPECGLOSSMAP
|
||||||
- _SPECULAR_SETUP
|
- _SPECULAR_SETUP
|
||||||
m_InvalidKeywords: []
|
m_InvalidKeywords: []
|
||||||
@ -52,7 +55,7 @@ Material:
|
|||||||
m_Scale: {x: 1, y: 1}
|
m_Scale: {x: 1, y: 1}
|
||||||
m_Offset: {x: 0, y: 0}
|
m_Offset: {x: 0, y: 0}
|
||||||
- _MainTex:
|
- _MainTex:
|
||||||
m_Texture: {fileID: 0}
|
m_Texture: {fileID: 2800000, guid: d898f1952a888e5459ca4fa61f69aacb, type: 3}
|
||||||
m_Scale: {x: 1, y: 1}
|
m_Scale: {x: 1, y: 1}
|
||||||
m_Offset: {x: 0, y: 0}
|
m_Offset: {x: 0, y: 0}
|
||||||
- _MetallicGlossMap:
|
- _MetallicGlossMap:
|
||||||
|
|||||||
@ -12,6 +12,9 @@ Material:
|
|||||||
m_Parent: {fileID: 0}
|
m_Parent: {fileID: 0}
|
||||||
m_ModifiedSerializedProperties: 0
|
m_ModifiedSerializedProperties: 0
|
||||||
m_ValidKeywords:
|
m_ValidKeywords:
|
||||||
|
- _METALLICSPECGLOSSMAP
|
||||||
|
- _NORMALMAP
|
||||||
|
- _PARALLAXMAP
|
||||||
- _SPECGLOSSMAP
|
- _SPECGLOSSMAP
|
||||||
- _SPECULAR_SETUP
|
- _SPECULAR_SETUP
|
||||||
m_InvalidKeywords: []
|
m_InvalidKeywords: []
|
||||||
@ -52,7 +55,7 @@ Material:
|
|||||||
m_Scale: {x: 1, y: 1}
|
m_Scale: {x: 1, y: 1}
|
||||||
m_Offset: {x: 0, y: 0}
|
m_Offset: {x: 0, y: 0}
|
||||||
- _MainTex:
|
- _MainTex:
|
||||||
m_Texture: {fileID: 0}
|
m_Texture: {fileID: 2800000, guid: 190b08caee9510e4094d8fb85df30e6a, type: 3}
|
||||||
m_Scale: {x: 1, y: 1}
|
m_Scale: {x: 1, y: 1}
|
||||||
m_Offset: {x: 0, y: 0}
|
m_Offset: {x: 0, y: 0}
|
||||||
- _MetallicGlossMap:
|
- _MetallicGlossMap:
|
||||||
|
|||||||
@ -25,6 +25,9 @@ Material:
|
|||||||
m_Parent: {fileID: 0}
|
m_Parent: {fileID: 0}
|
||||||
m_ModifiedSerializedProperties: 0
|
m_ModifiedSerializedProperties: 0
|
||||||
m_ValidKeywords:
|
m_ValidKeywords:
|
||||||
|
- _METALLICSPECGLOSSMAP
|
||||||
|
- _NORMALMAP
|
||||||
|
- _PARALLAXMAP
|
||||||
- _SPECGLOSSMAP
|
- _SPECGLOSSMAP
|
||||||
- _SPECULAR_SETUP
|
- _SPECULAR_SETUP
|
||||||
m_InvalidKeywords: []
|
m_InvalidKeywords: []
|
||||||
@ -65,7 +68,7 @@ Material:
|
|||||||
m_Scale: {x: 1, y: 1}
|
m_Scale: {x: 1, y: 1}
|
||||||
m_Offset: {x: 0, y: 0}
|
m_Offset: {x: 0, y: 0}
|
||||||
- _MainTex:
|
- _MainTex:
|
||||||
m_Texture: {fileID: 0}
|
m_Texture: {fileID: 2800000, guid: 348b7b1e9b718254eb222c50d2f1b370, type: 3}
|
||||||
m_Scale: {x: 1, y: 1}
|
m_Scale: {x: 1, y: 1}
|
||||||
m_Offset: {x: 0, y: 0}
|
m_Offset: {x: 0, y: 0}
|
||||||
- _MetallicGlossMap:
|
- _MetallicGlossMap:
|
||||||
|
|||||||
@ -64,7 +64,7 @@ Material:
|
|||||||
m_Scale: {x: 1, y: 1}
|
m_Scale: {x: 1, y: 1}
|
||||||
m_Offset: {x: 0, y: 0}
|
m_Offset: {x: 0, y: 0}
|
||||||
- _MainTex:
|
- _MainTex:
|
||||||
m_Texture: {fileID: 0}
|
m_Texture: {fileID: 2800000, guid: 24ae1851ee4bd6b40903851f84596cc5, type: 3}
|
||||||
m_Scale: {x: 1, y: 1}
|
m_Scale: {x: 1, y: 1}
|
||||||
m_Offset: {x: 0, y: 0}
|
m_Offset: {x: 0, y: 0}
|
||||||
- _MetallicGlossMap:
|
- _MetallicGlossMap:
|
||||||
|
|||||||
@ -12,6 +12,7 @@ Material:
|
|||||||
m_Parent: {fileID: 0}
|
m_Parent: {fileID: 0}
|
||||||
m_ModifiedSerializedProperties: 0
|
m_ModifiedSerializedProperties: 0
|
||||||
m_ValidKeywords:
|
m_ValidKeywords:
|
||||||
|
- _METALLICSPECGLOSSMAP
|
||||||
- _SPECGLOSSMAP
|
- _SPECGLOSSMAP
|
||||||
- _SPECULAR_SETUP
|
- _SPECULAR_SETUP
|
||||||
m_InvalidKeywords:
|
m_InvalidKeywords:
|
||||||
@ -53,7 +54,7 @@ Material:
|
|||||||
m_Scale: {x: 1, y: 1}
|
m_Scale: {x: 1, y: 1}
|
||||||
m_Offset: {x: 0, y: 0}
|
m_Offset: {x: 0, y: 0}
|
||||||
- _MainTex:
|
- _MainTex:
|
||||||
m_Texture: {fileID: 0}
|
m_Texture: {fileID: 2800000, guid: 027ee668c37651046b8fcc1de158d11b, type: 3}
|
||||||
m_Scale: {x: 1, y: 1}
|
m_Scale: {x: 1, y: 1}
|
||||||
m_Offset: {x: 0, y: 0}
|
m_Offset: {x: 0, y: 0}
|
||||||
- _MetallicGlossMap:
|
- _MetallicGlossMap:
|
||||||
|
|||||||
@ -25,6 +25,7 @@ Material:
|
|||||||
m_Parent: {fileID: 0}
|
m_Parent: {fileID: 0}
|
||||||
m_ModifiedSerializedProperties: 0
|
m_ModifiedSerializedProperties: 0
|
||||||
m_ValidKeywords:
|
m_ValidKeywords:
|
||||||
|
- _METALLICSPECGLOSSMAP
|
||||||
- _SPECGLOSSMAP
|
- _SPECGLOSSMAP
|
||||||
- _SPECULAR_SETUP
|
- _SPECULAR_SETUP
|
||||||
m_InvalidKeywords: []
|
m_InvalidKeywords: []
|
||||||
@ -65,7 +66,7 @@ Material:
|
|||||||
m_Scale: {x: 1, y: 1}
|
m_Scale: {x: 1, y: 1}
|
||||||
m_Offset: {x: 0, y: 0}
|
m_Offset: {x: 0, y: 0}
|
||||||
- _MainTex:
|
- _MainTex:
|
||||||
m_Texture: {fileID: 0}
|
m_Texture: {fileID: 2800000, guid: 62da88ce44d49764b91100a52cc54548, type: 3}
|
||||||
m_Scale: {x: 1, y: 1}
|
m_Scale: {x: 1, y: 1}
|
||||||
m_Offset: {x: 0, y: 0}
|
m_Offset: {x: 0, y: 0}
|
||||||
- _MetallicGlossMap:
|
- _MetallicGlossMap:
|
||||||
|
|||||||
@ -12,6 +12,7 @@ Material:
|
|||||||
m_Parent: {fileID: 0}
|
m_Parent: {fileID: 0}
|
||||||
m_ModifiedSerializedProperties: 0
|
m_ModifiedSerializedProperties: 0
|
||||||
m_ValidKeywords:
|
m_ValidKeywords:
|
||||||
|
- _METALLICSPECGLOSSMAP
|
||||||
- _SPECGLOSSMAP
|
- _SPECGLOSSMAP
|
||||||
- _SPECULAR_SETUP
|
- _SPECULAR_SETUP
|
||||||
m_InvalidKeywords:
|
m_InvalidKeywords:
|
||||||
@ -53,7 +54,7 @@ Material:
|
|||||||
m_Scale: {x: 1, y: 1}
|
m_Scale: {x: 1, y: 1}
|
||||||
m_Offset: {x: 0, y: 0}
|
m_Offset: {x: 0, y: 0}
|
||||||
- _MainTex:
|
- _MainTex:
|
||||||
m_Texture: {fileID: 0}
|
m_Texture: {fileID: 2800000, guid: efce089419136f94492f8f54bf755a5c, type: 3}
|
||||||
m_Scale: {x: 1, y: 1}
|
m_Scale: {x: 1, y: 1}
|
||||||
m_Offset: {x: 0, y: 0}
|
m_Offset: {x: 0, y: 0}
|
||||||
- _MetallicGlossMap:
|
- _MetallicGlossMap:
|
||||||
|
|||||||
8
Assets/Data/CarPhysicsData.meta
Normal file
8
Assets/Data/CarPhysicsData.meta
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: a3efdaab9fd94774aa80108ad4e02503
|
||||||
|
folderAsset: yes
|
||||||
|
DefaultImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
98
Assets/Data/CarPhysicsData/Hirochi_Physics.asset
Normal file
98
Assets/Data/CarPhysicsData/Hirochi_Physics.asset
Normal 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
|
||||||
8
Assets/Data/CarPhysicsData/Hirochi_Physics.asset.meta
Normal file
8
Assets/Data/CarPhysicsData/Hirochi_Physics.asset.meta
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 1865251594a045046b5f77e23e0cb2c6
|
||||||
|
NativeFormatImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
mainObjectFileID: 11400000
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
@ -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!");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,2 +0,0 @@
|
|||||||
fileFormatVersion: 2
|
|
||||||
guid: 403983d9c86a19f4a85074eba6aed3fd
|
|
||||||
File diff suppressed because it is too large
Load Diff
@ -7,13 +7,13 @@ public class VehicleInteraction : MonoBehaviour, IInteractable
|
|||||||
[SerializeField] private UIManager uiManager;
|
[SerializeField] private UIManager uiManager;
|
||||||
|
|
||||||
private CarOrbitCamera globalCarCamera; // Ссылка на глобальную камеру
|
private CarOrbitCamera globalCarCamera; // Ссылка на глобальную камеру
|
||||||
private CarController carController;
|
private AdvancedCarController carController;
|
||||||
private GameObject playerInstance;
|
private GameObject playerInstance;
|
||||||
private bool isPlayerInside = false;
|
public bool isPlayerInside = false;
|
||||||
|
|
||||||
private void Awake()
|
private void Awake()
|
||||||
{
|
{
|
||||||
carController = GetComponent<CarController>();
|
carController = GetComponent<AdvancedCarController>();
|
||||||
|
|
||||||
// Автоматически находим камеру на сцене, даже если она выключена
|
// Автоматически находим камеру на сцене, даже если она выключена
|
||||||
globalCarCamera = FindAnyObjectByType<CarOrbitCamera>(FindObjectsInactive.Include);
|
globalCarCamera = FindAnyObjectByType<CarOrbitCamera>(FindObjectsInactive.Include);
|
||||||
|
|||||||
3
Assets/Scripts/Car/Part/Data.meta
Normal file
3
Assets/Scripts/Car/Part/Data.meta
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: d1396ff771764dc2bcb7e90faac08815
|
||||||
|
timeCreated: 1791809673
|
||||||
170
Assets/Scripts/Car/Physics/AdvancedCarController.cs
Normal file
170
Assets/Scripts/Car/Physics/AdvancedCarController.cs
Normal 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);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
3
Assets/Scripts/Car/Physics/AdvancedCarController.cs.meta
Normal file
3
Assets/Scripts/Car/Physics/AdvancedCarController.cs.meta
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: c02b03f912164de9ae5c7659d886fae9
|
||||||
|
timeCreated: 1791809782
|
||||||
3
Assets/Scripts/Car/Physics/Data.meta
Normal file
3
Assets/Scripts/Car/Physics/Data.meta
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 50a1732ad7494d0ab29474ca2bc918c1
|
||||||
|
timeCreated: 1791809613
|
||||||
28
Assets/Scripts/Car/Physics/Data/CarPhysicsData.cs
Normal file
28
Assets/Scripts/Car/Physics/Data/CarPhysicsData.cs
Normal 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; // Насколько скользкой становится задняя ось
|
||||||
|
}
|
||||||
3
Assets/Scripts/Car/Physics/Data/CarPhysicsData.cs.meta
Normal file
3
Assets/Scripts/Car/Physics/Data/CarPhysicsData.cs.meta
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 396086e692304e97aab2b9b09066d2b5
|
||||||
|
timeCreated: 1791809619
|
||||||
29
Assets/Scripts/Car/Physics/WheelVisuals.cs
Normal file
29
Assets/Scripts/Car/Physics/WheelVisuals.cs
Normal 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
3
Assets/Scripts/Car/Physics/WheelVisuals.cs.meta
Normal file
3
Assets/Scripts/Car/Physics/WheelVisuals.cs.meta
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: ce1b65bf09494194a68749d417b0e17a
|
||||||
|
timeCreated: 1791809850
|
||||||
@ -2,39 +2,74 @@ using UnityEngine;
|
|||||||
|
|
||||||
public class PlayerInteractor : MonoBehaviour
|
public class PlayerInteractor : MonoBehaviour
|
||||||
{
|
{
|
||||||
|
[Header("Настройки луча")]
|
||||||
[SerializeField] private float interactRange = 3f;
|
[SerializeField] private float interactRange = 3f;
|
||||||
[SerializeField] private LayerMask interactableLayer; // Создайте слой "Interactable" в Unity
|
[SerializeField] private LayerMask interactableLayer;
|
||||||
[SerializeField] private KeyCode primaryKey = KeyCode.E;
|
|
||||||
[SerializeField] private KeyCode secondaryKey = KeyCode.R;
|
|
||||||
|
|
||||||
[Header("References")]
|
[Header("Клавиши управления")]
|
||||||
|
[SerializeField] private KeyCode primaryKey = KeyCode.E; // Работа с деталью (открыть/взять)
|
||||||
|
[SerializeField] private KeyCode secondaryKey = KeyCode.R; // Снять деталь
|
||||||
|
[SerializeField] private KeyCode enterVehicleKey = KeyCode.F; // Сесть в машину
|
||||||
|
|
||||||
|
[Header("Ссылки")]
|
||||||
[SerializeField] private UIManager uiManager;
|
[SerializeField] private UIManager uiManager;
|
||||||
|
|
||||||
|
private void OnDisable()
|
||||||
|
{
|
||||||
|
if (uiManager != null) uiManager.HidePrompt();
|
||||||
|
}
|
||||||
|
|
||||||
private void Update()
|
private void Update()
|
||||||
{
|
{
|
||||||
// Пускаем луч из центра экрана
|
|
||||||
Ray ray = new Ray(transform.position, transform.forward);
|
Ray ray = new Ray(transform.position, transform.forward);
|
||||||
|
|
||||||
if (Physics.Raycast(ray, out RaycastHit hit, interactRange, interactableLayer, QueryTriggerInteraction.Collide))
|
if (Physics.Raycast(ray, out RaycastHit hit, interactRange, interactableLayer, QueryTriggerInteraction.Collide))
|
||||||
{
|
{
|
||||||
|
// Ищем интерактивную деталь (дверь, капот, крыло)
|
||||||
IInteractable interactable = hit.collider.GetComponentInParent<IInteractable>();
|
IInteractable interactable = hit.collider.GetComponentInParent<IInteractable>();
|
||||||
|
|
||||||
|
// Ищем скрипт автомобиля в родительских объектах
|
||||||
|
VehicleInteraction vehicle = hit.collider.GetComponentInParent<VehicleInteraction>();
|
||||||
|
|
||||||
|
if (interactable != null || vehicle != null)
|
||||||
|
{
|
||||||
|
// Формируем комбинированную подсказку
|
||||||
|
string prompt = "";
|
||||||
|
|
||||||
|
if (vehicle != null && !vehicle.isPlayerInside)
|
||||||
|
{
|
||||||
|
prompt += "[F] Сесть в авто ";
|
||||||
|
}
|
||||||
|
|
||||||
if (interactable != null)
|
if (interactable != null)
|
||||||
{
|
{
|
||||||
if (!string.IsNullOrEmpty(interactable.GetPrompt()) && uiManager!=null)
|
string partPrompt = interactable.GetPrompt();
|
||||||
|
if (!string.IsNullOrEmpty(partPrompt))
|
||||||
{
|
{
|
||||||
uiManager.ShowPrompt(interactable.GetPrompt());
|
prompt += partPrompt;
|
||||||
}
|
}
|
||||||
else if (uiManager != null)
|
|
||||||
{
|
|
||||||
uiManager.HidePrompt();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!string.IsNullOrEmpty(prompt) && uiManager != null)
|
||||||
|
{
|
||||||
|
uiManager.ShowPrompt(prompt);
|
||||||
|
}
|
||||||
|
|
||||||
if (Input.GetKeyDown(primaryKey))
|
// 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);
|
interactable.Interact(transform.root.gameObject);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 3. Вторичное действие с деталью на R (Снять в руки)
|
||||||
if (Input.GetKeyDown(secondaryKey))
|
if (Input.GetKeyDown(secondaryKey))
|
||||||
{
|
{
|
||||||
ISecondaryInteractable secondary = hit.collider.GetComponentInParent<ISecondaryInteractable>();
|
ISecondaryInteractable secondary = hit.collider.GetComponentInParent<ISecondaryInteractable>();
|
||||||
@ -50,12 +85,4 @@ public class PlayerInteractor : MonoBehaviour
|
|||||||
uiManager.HidePrompt();
|
uiManager.HidePrompt();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnDisable()
|
|
||||||
{
|
|
||||||
if (uiManager != null)
|
|
||||||
{
|
|
||||||
uiManager.HidePrompt();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
Loading…
Reference in New Issue
Block a user