feat: initial commit — modified sdsandbox scripts for donkeycar RL training

Key changes vs upstream tawnkramer/sdsandbox:
- Car.cs: per-wheel OverlapSphere barrier detection, CCD mode
- TcpCarHandler.cs: regen_road with RoadBuilder+PathManager fallback,
  set_ai_text overlay, BrakeOnUpdate support
- PathManager.cs: self-intersection fix with XZ segment retry loop
- RoadBuilder.cs: BoxCollider per segment, showBarrierMeshes flag
- MapOverlay.cs: minimap refresh on road node position change

Unity version: 6000.4.4f1

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Paul Huliganga 2026-05-15 10:41:41 -04:00
commit fcdcb14e57
216 changed files with 15246 additions and 0 deletions

20
.gitattributes vendored Normal file
View File

@ -0,0 +1,20 @@
# Normalize line endings: store as LF, checkout as native
* text=auto
# Force text for C# and Unity text files
*.cs text eol=lf
*.unity text eol=lf
*.prefab text eol=lf
*.asset text eol=lf
*.asmdef text eol=lf
*.json text eol=lf
*.yaml text eol=lf
*.md text eol=lf
# Binary files — never diff or mangle
*.tga binary
*.png binary
*.jpg binary
*.fbx binary
*.wav binary
*.mp3 binary

12
.gitignore vendored Normal file
View File

@ -0,0 +1,12 @@
# Unity generated
*.csproj
*.sln
*.user
*.suo
*.tmp
# OS
.DS_Store
Thumbs.db
# Meta files are intentionally tracked (Unity needs them for GUIDs)

48
Packages/manifest.json Executable file
View File

@ -0,0 +1,48 @@
{
"dependencies": {
"com.unity.ai.navigation": "2.0.12",
"com.unity.collab-proxy": "2.12.4",
"com.unity.ide.rider": "3.0.39",
"com.unity.ide.visualstudio": "2.0.27",
"com.unity.ide.vscode": "1.2.5",
"com.unity.multiplayer.center": "1.0.1",
"com.unity.probuilder": "6.0.9",
"com.unity.test-framework": "1.6.0",
"com.unity.timeline": "1.8.12",
"com.unity.ugui": "2.0.0",
"com.unity.modules.accessibility": "1.0.0",
"com.unity.modules.adaptiveperformance": "1.0.0",
"com.unity.modules.ai": "1.0.0",
"com.unity.modules.androidjni": "1.0.0",
"com.unity.modules.animation": "1.0.0",
"com.unity.modules.assetbundle": "1.0.0",
"com.unity.modules.audio": "1.0.0",
"com.unity.modules.cloth": "1.0.0",
"com.unity.modules.director": "1.0.0",
"com.unity.modules.imageconversion": "1.0.0",
"com.unity.modules.imgui": "1.0.0",
"com.unity.modules.jsonserialize": "1.0.0",
"com.unity.modules.particlesystem": "1.0.0",
"com.unity.modules.physics": "1.0.0",
"com.unity.modules.physics2d": "1.0.0",
"com.unity.modules.screencapture": "1.0.0",
"com.unity.modules.terrain": "1.0.0",
"com.unity.modules.terrainphysics": "1.0.0",
"com.unity.modules.tilemap": "1.0.0",
"com.unity.modules.ui": "1.0.0",
"com.unity.modules.uielements": "1.0.0",
"com.unity.modules.umbra": "1.0.0",
"com.unity.modules.unityanalytics": "1.0.0",
"com.unity.modules.unitywebrequest": "1.0.0",
"com.unity.modules.unitywebrequestassetbundle": "1.0.0",
"com.unity.modules.unitywebrequestaudio": "1.0.0",
"com.unity.modules.unitywebrequesttexture": "1.0.0",
"com.unity.modules.unitywebrequestwww": "1.0.0",
"com.unity.modules.vectorgraphics": "1.0.0",
"com.unity.modules.vehicles": "1.0.0",
"com.unity.modules.video": "1.0.0",
"com.unity.modules.vr": "1.0.0",
"com.unity.modules.wind": "1.0.0",
"com.unity.modules.xr": "1.0.0"
}
}

459
Packages/packages-lock.json Executable file
View File

@ -0,0 +1,459 @@
{
"dependencies": {
"com.unity.ai.navigation": {
"version": "2.0.12",
"depth": 0,
"source": "registry",
"dependencies": {
"com.unity.modules.ai": "1.0.0"
},
"url": "https://packages.unity.com"
},
"com.unity.burst": {
"version": "1.8.29",
"depth": 3,
"source": "registry",
"dependencies": {
"com.unity.mathematics": "1.2.1",
"com.unity.modules.jsonserialize": "1.0.0"
},
"url": "https://packages.unity.com"
},
"com.unity.collab-proxy": {
"version": "2.12.4",
"depth": 0,
"source": "registry",
"dependencies": {},
"url": "https://packages.unity.com"
},
"com.unity.collections": {
"version": "6.4.0",
"depth": 3,
"source": "builtin",
"dependencies": {
"com.unity.burst": "1.8.23",
"com.unity.mathematics": "1.3.2",
"com.unity.nuget.mono-cecil": "1.11.5",
"com.unity.test-framework": "1.4.6",
"com.unity.test-framework.performance": "3.0.3"
}
},
"com.unity.ext.nunit": {
"version": "2.0.5",
"depth": 1,
"source": "builtin",
"dependencies": {}
},
"com.unity.ide.rider": {
"version": "3.0.39",
"depth": 0,
"source": "registry",
"dependencies": {
"com.unity.ext.nunit": "1.0.6"
},
"url": "https://packages.unity.com"
},
"com.unity.ide.visualstudio": {
"version": "2.0.27",
"depth": 0,
"source": "registry",
"dependencies": {
"com.unity.test-framework": "1.1.33"
},
"url": "https://packages.unity.com"
},
"com.unity.ide.vscode": {
"version": "1.2.5",
"depth": 0,
"source": "registry",
"dependencies": {},
"url": "https://packages.unity.com"
},
"com.unity.mathematics": {
"version": "1.3.3",
"depth": 3,
"source": "registry",
"dependencies": {},
"url": "https://packages.unity.com"
},
"com.unity.multiplayer.center": {
"version": "1.0.1",
"depth": 0,
"source": "builtin",
"dependencies": {
"com.unity.modules.uielements": "1.0.0"
}
},
"com.unity.nuget.mono-cecil": {
"version": "1.11.6",
"depth": 4,
"source": "registry",
"dependencies": {},
"url": "https://packages.unity.com"
},
"com.unity.probuilder": {
"version": "6.0.9",
"depth": 0,
"source": "registry",
"dependencies": {
"com.unity.shadergraph": "17.0.3",
"com.unity.modules.imgui": "1.0.0",
"com.unity.modules.physics": "1.0.0",
"com.unity.settings-manager": "1.0.3"
},
"url": "https://packages.unity.com"
},
"com.unity.render-pipelines.core": {
"version": "17.4.0",
"depth": 2,
"source": "builtin",
"dependencies": {
"com.unity.burst": "1.8.14",
"com.unity.mathematics": "1.3.2",
"com.unity.ugui": "2.0.0",
"com.unity.collections": "2.4.3",
"com.unity.modules.terrain": "1.0.0",
"com.unity.modules.jsonserialize": "1.0.0"
}
},
"com.unity.searcher": {
"version": "4.9.4",
"depth": 2,
"source": "registry",
"dependencies": {},
"url": "https://packages.unity.com"
},
"com.unity.settings-manager": {
"version": "2.1.1",
"depth": 1,
"source": "registry",
"dependencies": {},
"url": "https://packages.unity.com"
},
"com.unity.shadergraph": {
"version": "17.4.0",
"depth": 1,
"source": "builtin",
"dependencies": {
"com.unity.render-pipelines.core": "17.4.0",
"com.unity.searcher": "4.9.3"
}
},
"com.unity.test-framework": {
"version": "1.6.0",
"depth": 0,
"source": "builtin",
"dependencies": {
"com.unity.ext.nunit": "2.0.3",
"com.unity.modules.imgui": "1.0.0",
"com.unity.modules.jsonserialize": "1.0.0"
}
},
"com.unity.test-framework.performance": {
"version": "3.4.0",
"depth": 4,
"source": "registry",
"dependencies": {
"com.unity.test-framework": "1.1.33",
"com.unity.modules.jsonserialize": "1.0.0"
},
"url": "https://packages.unity.com"
},
"com.unity.timeline": {
"version": "1.8.12",
"depth": 0,
"source": "registry",
"dependencies": {
"com.unity.modules.audio": "1.0.0",
"com.unity.modules.director": "1.0.0",
"com.unity.modules.animation": "1.0.0",
"com.unity.modules.particlesystem": "1.0.0"
},
"url": "https://packages.unity.com"
},
"com.unity.ugui": {
"version": "2.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {
"com.unity.modules.ui": "1.0.0",
"com.unity.modules.imgui": "1.0.0"
}
},
"com.unity.modules.accessibility": {
"version": "1.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {}
},
"com.unity.modules.adaptiveperformance": {
"version": "1.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {
"com.unity.modules.subsystems": "1.0.0"
}
},
"com.unity.modules.ai": {
"version": "1.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {}
},
"com.unity.modules.androidjni": {
"version": "1.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {}
},
"com.unity.modules.animation": {
"version": "1.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {}
},
"com.unity.modules.assetbundle": {
"version": "1.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {}
},
"com.unity.modules.audio": {
"version": "1.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {}
},
"com.unity.modules.cloth": {
"version": "1.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {
"com.unity.modules.physics": "1.0.0"
}
},
"com.unity.modules.director": {
"version": "1.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {
"com.unity.modules.audio": "1.0.0",
"com.unity.modules.animation": "1.0.0"
}
},
"com.unity.modules.hierarchycore": {
"version": "1.0.0",
"depth": 1,
"source": "builtin",
"dependencies": {}
},
"com.unity.modules.imageconversion": {
"version": "1.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {}
},
"com.unity.modules.imgui": {
"version": "1.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {}
},
"com.unity.modules.jsonserialize": {
"version": "1.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {}
},
"com.unity.modules.particlesystem": {
"version": "1.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {}
},
"com.unity.modules.physics": {
"version": "1.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {}
},
"com.unity.modules.physics2d": {
"version": "1.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {}
},
"com.unity.modules.screencapture": {
"version": "1.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {
"com.unity.modules.imageconversion": "1.0.0"
}
},
"com.unity.modules.subsystems": {
"version": "1.0.0",
"depth": 1,
"source": "builtin",
"dependencies": {
"com.unity.modules.jsonserialize": "1.0.0"
}
},
"com.unity.modules.terrain": {
"version": "1.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {}
},
"com.unity.modules.terrainphysics": {
"version": "1.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {
"com.unity.modules.physics": "1.0.0",
"com.unity.modules.terrain": "1.0.0"
}
},
"com.unity.modules.tilemap": {
"version": "1.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {
"com.unity.modules.physics2d": "1.0.0"
}
},
"com.unity.modules.ui": {
"version": "1.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {}
},
"com.unity.modules.uielements": {
"version": "1.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {
"com.unity.modules.ui": "1.0.0",
"com.unity.modules.imgui": "1.0.0",
"com.unity.modules.jsonserialize": "1.0.0",
"com.unity.modules.hierarchycore": "1.0.0",
"com.unity.modules.physics": "1.0.0"
}
},
"com.unity.modules.umbra": {
"version": "1.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {}
},
"com.unity.modules.unityanalytics": {
"version": "1.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {
"com.unity.modules.unitywebrequest": "1.0.0",
"com.unity.modules.jsonserialize": "1.0.0"
}
},
"com.unity.modules.unitywebrequest": {
"version": "1.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {}
},
"com.unity.modules.unitywebrequestassetbundle": {
"version": "1.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {
"com.unity.modules.assetbundle": "1.0.0",
"com.unity.modules.unitywebrequest": "1.0.0"
}
},
"com.unity.modules.unitywebrequestaudio": {
"version": "1.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {
"com.unity.modules.unitywebrequest": "1.0.0",
"com.unity.modules.audio": "1.0.0"
}
},
"com.unity.modules.unitywebrequesttexture": {
"version": "1.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {
"com.unity.modules.unitywebrequest": "1.0.0",
"com.unity.modules.imageconversion": "1.0.0"
}
},
"com.unity.modules.unitywebrequestwww": {
"version": "1.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {
"com.unity.modules.unitywebrequest": "1.0.0",
"com.unity.modules.unitywebrequestassetbundle": "1.0.0",
"com.unity.modules.unitywebrequestaudio": "1.0.0",
"com.unity.modules.audio": "1.0.0",
"com.unity.modules.assetbundle": "1.0.0",
"com.unity.modules.imageconversion": "1.0.0"
}
},
"com.unity.modules.vectorgraphics": {
"version": "1.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {
"com.unity.modules.uielements": "1.0.0",
"com.unity.modules.imageconversion": "1.0.0",
"com.unity.modules.imgui": "1.0.0"
}
},
"com.unity.modules.vehicles": {
"version": "1.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {
"com.unity.modules.physics": "1.0.0"
}
},
"com.unity.modules.video": {
"version": "1.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {
"com.unity.modules.audio": "1.0.0",
"com.unity.modules.ui": "1.0.0",
"com.unity.modules.unitywebrequest": "1.0.0"
}
},
"com.unity.modules.vr": {
"version": "1.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {
"com.unity.modules.jsonserialize": "1.0.0",
"com.unity.modules.physics": "1.0.0",
"com.unity.modules.xr": "1.0.0"
}
},
"com.unity.modules.wind": {
"version": "1.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {}
},
"com.unity.modules.xr": {
"version": "1.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {
"com.unity.modules.physics": "1.0.0",
"com.unity.modules.jsonserialize": "1.0.0",
"com.unity.modules.subsystems": "1.0.0"
}
}
}
}

View File

@ -0,0 +1,19 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!11 &1
AudioManager:
m_ObjectHideFlags: 0
serializedVersion: 2
m_Volume: 1
Rolloff Scale: 1
Doppler Factor: 1
Default Speaker Mode: 2
m_SampleRate: 0
m_DSPBufferSize: 1024
m_VirtualVoiceCount: 512
m_RealVoiceCount: 32
m_SpatializerPlugin:
m_AmbisonicDecoderPlugin:
m_DisableAudio: 0
m_VirtualizeEffects: 1
m_RequestedDSPBufferSize: 0

View File

@ -0,0 +1,6 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!236 &1
ClusterInputManager:
m_ObjectHideFlags: 0
m_Inputs: []

View File

@ -0,0 +1,37 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!55 &1
PhysicsManager:
m_ObjectHideFlags: 0
serializedVersion: 13
m_Gravity: {x: 0, y: -78.48, z: 0}
m_DefaultMaterial: {fileID: 0}
m_BounceThreshold: 1
m_DefaultMaxDepenetrationVelocity: 10
m_SleepThreshold: 0.005
m_DefaultContactOffset: 0.01
m_DefaultSolverIterations: 10
m_DefaultSolverVelocityIterations: 1
m_QueriesHitBackfaces: 0
m_QueriesHitTriggers: 1
m_EnableAdaptiveForce: 0
m_ClothInterCollisionDistance: 0.1
m_ClothInterCollisionStiffness: 0.2
m_ContactsGeneration: 0
m_LayerCollisionMatrix: ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
m_AutoSimulation: 1
m_AutoSyncTransforms: 0
m_ReuseCollisionCallbacks: 0
m_ClothInterCollisionSettingsToggle: 0
m_ClothGravity: {x: 0, y: -9.81, z: 0}
m_ContactPairsMode: 0
m_BroadphaseType: 0
m_WorldBounds:
m_Center: {x: 0, y: 0, z: 0}
m_Extent: {x: 250, y: 250, z: 250}
m_WorldSubdivisions: 8
m_FrictionType: 0
m_EnableEnhancedDeterminism: 0
m_EnableUnifiedHeightmaps: 1
m_SolverType: 0
m_DefaultMaxAngularSpeed: 50

View File

@ -0,0 +1,41 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!1045 &1
EditorBuildSettings:
m_ObjectHideFlags: 0
serializedVersion: 2
m_Scenes:
- enabled: 1
path: Assets/Scenes/menu.unity
guid: 1ac0872dcad57c44496bb684aa1998f8
- enabled: 1
path: Assets/Scenes/generated_road.unity
guid: 80ac5eef166784810a0ab8e6742f8a30
- enabled: 1
path: Assets/Scenes/warehouse.unity
guid: 4483f94080df5d84f9e98fdae085f167
- enabled: 1
path: Assets/Scenes/sparkfun_avc.unity
guid: b362fdcb28a444fa5b719f21d5115c5a
- enabled: 1
path: Assets/Scenes/generated_track.unity
guid: b003bdd73179fe046b15d779a91c20e8
- enabled: 1
path: Assets/Scenes/roboracingleague_1.unity
guid: b37ac42fbc7419143a38115aec8b91ba
- enabled: 1
path: Assets/Scenes/waveshare.unity
guid: c5d126de1fd7ec9468c8765592f5f783
- enabled: 1
path: Assets/Scenes/mini_monaco.unity
guid: 66f33ad92e768c045a184401f8a0fd4c
- enabled: 1
path: Assets/Scenes/warren.unity
guid: a65aa29f80d4f97458c095f4838a8d36
- enabled: 1
path: Assets/Scenes/circuit_launch.unity
guid: 574a0b2d2b3bf6641bf9a81ed0cb3e1d
- enabled: 1
path: Assets/Scenes/mountain_track.unity
guid: fa958af1d4fc8ef449b0c7b710692aad
m_configObjects: {}

View File

@ -0,0 +1,35 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!159 &1
EditorSettings:
m_ObjectHideFlags: 0
serializedVersion: 9
m_ExternalVersionControlSupport: Hidden Meta Files
m_SerializationMode: 2
m_LineEndingsForNewScripts: 1
m_DefaultBehaviorMode: 0
m_PrefabRegularEnvironment: {fileID: 0}
m_PrefabUIEnvironment: {fileID: 0}
m_SpritePackerMode: 0
m_SpritePackerPaddingPower: 1
m_EtcTextureCompressorBehavior: 1
m_EtcTextureFastCompressor: 1
m_EtcTextureNormalCompressor: 2
m_EtcTextureBestCompressor: 4
m_ProjectGenerationIncludedExtensions: txt;xml;fnt;cd;asmdef;asmref;rsp
m_ProjectGenerationRootNamespace:
m_CollabEditorSettings:
inProgressEnabled: 1
m_EnableTextureStreamingInEditMode: 1
m_EnableTextureStreamingInPlayMode: 1
m_AsyncShaderCompilation: 1
m_EnterPlayModeOptionsEnabled: 0
m_EnterPlayModeOptions: 3
m_ShowLightmapResolutionOverlay: 1
m_UseLegacyProbeSampleCount: 1
m_AssetPipelineMode: 1
m_CacheServerMode: 0
m_CacheServerEndpoint:
m_CacheServerNamespacePrefix: default
m_CacheServerEnableDownload: 1
m_CacheServerEnableUpload: 1

View File

@ -0,0 +1,69 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!30 &1
GraphicsSettings:
m_ObjectHideFlags: 0
serializedVersion: 13
m_Deferred:
m_Mode: 1
m_Shader: {fileID: 69, guid: 0000000000000000f000000000000000, type: 0}
m_DeferredReflections:
m_Mode: 1
m_Shader: {fileID: 74, guid: 0000000000000000f000000000000000, type: 0}
m_ScreenSpaceShadows:
m_Mode: 1
m_Shader: {fileID: 64, guid: 0000000000000000f000000000000000, type: 0}
m_LegacyDeferred:
m_Mode: 1
m_Shader: {fileID: 63, guid: 0000000000000000f000000000000000, type: 0}
m_DepthNormals:
m_Mode: 1
m_Shader: {fileID: 62, guid: 0000000000000000f000000000000000, type: 0}
m_MotionVectors:
m_Mode: 1
m_Shader: {fileID: 75, guid: 0000000000000000f000000000000000, type: 0}
m_LightHalo:
m_Mode: 1
m_Shader: {fileID: 105, guid: 0000000000000000f000000000000000, type: 0}
m_LensFlare:
m_Mode: 1
m_Shader: {fileID: 102, guid: 0000000000000000f000000000000000, type: 0}
m_VideoShadersIncludeMode: 2
m_AlwaysIncludedShaders:
- {fileID: 7, guid: 0000000000000000f000000000000000, type: 0}
- {fileID: 15104, guid: 0000000000000000f000000000000000, type: 0}
- {fileID: 15105, guid: 0000000000000000f000000000000000, type: 0}
- {fileID: 15106, guid: 0000000000000000f000000000000000, type: 0}
- {fileID: 10753, guid: 0000000000000000f000000000000000, type: 0}
- {fileID: 10770, guid: 0000000000000000f000000000000000, type: 0}
- {fileID: 10783, guid: 0000000000000000f000000000000000, type: 0}
- {fileID: 16000, guid: 0000000000000000f000000000000000, type: 0}
- {fileID: 16001, guid: 0000000000000000f000000000000000, type: 0}
- {fileID: 17000, guid: 0000000000000000f000000000000000, type: 0}
- {fileID: 16002, guid: 0000000000000000f000000000000000, type: 0}
m_PreloadedShaders: []
m_SpritesDefaultMaterial: {fileID: 10754, guid: 0000000000000000f000000000000000,
type: 0}
m_CustomRenderPipeline: {fileID: 0}
m_TransparencySortMode: 0
m_TransparencySortAxis: {x: 0, y: 0, z: 1}
m_DefaultRenderingPath: 1
m_DefaultMobileRenderingPath: 1
m_TierSettings: []
m_LightmapStripping: 0
m_FogStripping: 0
m_InstancingStripping: 0
m_LightmapKeepPlain: 1
m_LightmapKeepDirCombined: 1
m_LightmapKeepDynamicPlain: 1
m_LightmapKeepDynamicDirCombined: 1
m_LightmapKeepShadowMask: 1
m_LightmapKeepSubtractive: 1
m_FogKeepLinear: 1
m_FogKeepExp: 1
m_FogKeepExp2: 1
m_AlbedoSwatchInfos: []
m_LightsUseLinearIntensity: 0
m_LightsUseColorTemperature: 0
m_DefaultRenderingLayerMask: 1
m_LogWhenShaderIsCompiled: 0

View File

@ -0,0 +1,487 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!13 &1
InputManager:
m_ObjectHideFlags: 0
serializedVersion: 2
m_Axes:
- serializedVersion: 3
m_Name: Horizontal
descriptiveName:
descriptiveNegativeName:
negativeButton: left
positiveButton: right
altNegativeButton: a
altPositiveButton: d
gravity: 3
dead: 0.001
sensitivity: 3
snap: 1
invert: 0
type: 0
axis: 0
joyNum: 0
- serializedVersion: 3
m_Name: Vertical
descriptiveName:
descriptiveNegativeName:
negativeButton: down
positiveButton: up
altNegativeButton: s
altPositiveButton: w
gravity: 3
dead: 0.001
sensitivity: 3
snap: 1
invert: 0
type: 0
axis: 0
joyNum: 0
- serializedVersion: 3
m_Name: Fire1
descriptiveName:
descriptiveNegativeName:
negativeButton:
positiveButton: left ctrl
altNegativeButton:
altPositiveButton: mouse 0
gravity: 1000
dead: 0.001
sensitivity: 1000
snap: 0
invert: 0
type: 0
axis: 0
joyNum: 0
- serializedVersion: 3
m_Name: Fire2
descriptiveName:
descriptiveNegativeName:
negativeButton:
positiveButton: left alt
altNegativeButton:
altPositiveButton: mouse 1
gravity: 1000
dead: 0.001
sensitivity: 1000
snap: 0
invert: 0
type: 0
axis: 0
joyNum: 0
- serializedVersion: 3
m_Name: Fire3
descriptiveName:
descriptiveNegativeName:
negativeButton:
positiveButton: left shift
altNegativeButton:
altPositiveButton: mouse 2
gravity: 1000
dead: 0.001
sensitivity: 1000
snap: 0
invert: 0
type: 0
axis: 0
joyNum: 0
- serializedVersion: 3
m_Name: Jump
descriptiveName:
descriptiveNegativeName:
negativeButton:
positiveButton: space
altNegativeButton:
altPositiveButton:
gravity: 1000
dead: 0.001
sensitivity: 1000
snap: 0
invert: 0
type: 0
axis: 0
joyNum: 0
- serializedVersion: 3
m_Name: Mouse X
descriptiveName:
descriptiveNegativeName:
negativeButton:
positiveButton:
altNegativeButton:
altPositiveButton:
gravity: 0
dead: 0
sensitivity: 0.1
snap: 0
invert: 0
type: 1
axis: 0
joyNum: 0
- serializedVersion: 3
m_Name: Mouse Y
descriptiveName:
descriptiveNegativeName:
negativeButton:
positiveButton:
altNegativeButton:
altPositiveButton:
gravity: 0
dead: 0
sensitivity: 0.1
snap: 0
invert: 0
type: 1
axis: 1
joyNum: 0
- serializedVersion: 3
m_Name: Mouse ScrollWheel
descriptiveName:
descriptiveNegativeName:
negativeButton:
positiveButton:
altNegativeButton:
altPositiveButton:
gravity: 0
dead: 0
sensitivity: 0.1
snap: 0
invert: 0
type: 1
axis: 2
joyNum: 0
- serializedVersion: 3
m_Name: Horizontal
descriptiveName:
descriptiveNegativeName:
negativeButton:
positiveButton:
altNegativeButton:
altPositiveButton:
gravity: 0
dead: 0.19
sensitivity: 1
snap: 0
invert: 0
type: 2
axis: 0
joyNum: 0
- serializedVersion: 3
m_Name: Vertical
descriptiveName:
descriptiveNegativeName:
negativeButton:
positiveButton:
altNegativeButton:
altPositiveButton:
gravity: 0
dead: 0.19
sensitivity: 1
snap: 0
invert: 1
type: 2
axis: 1
joyNum: 0
- serializedVersion: 3
m_Name: Fire1
descriptiveName:
descriptiveNegativeName:
negativeButton:
positiveButton: joystick button 0
altNegativeButton:
altPositiveButton:
gravity: 1000
dead: 0.001
sensitivity: 1000
snap: 0
invert: 0
type: 0
axis: 0
joyNum: 0
- serializedVersion: 3
m_Name: Fire2
descriptiveName:
descriptiveNegativeName:
negativeButton:
positiveButton: joystick button 1
altNegativeButton:
altPositiveButton:
gravity: 1000
dead: 0.001
sensitivity: 1000
snap: 0
invert: 0
type: 0
axis: 0
joyNum: 0
- serializedVersion: 3
m_Name: Fire3
descriptiveName:
descriptiveNegativeName:
negativeButton:
positiveButton: joystick button 2
altNegativeButton:
altPositiveButton:
gravity: 1000
dead: 0.001
sensitivity: 1000
snap: 0
invert: 0
type: 0
axis: 0
joyNum: 0
- serializedVersion: 3
m_Name: Jump
descriptiveName:
descriptiveNegativeName:
negativeButton:
positiveButton: joystick button 3
altNegativeButton:
altPositiveButton:
gravity: 1000
dead: 0.001
sensitivity: 1000
snap: 0
invert: 0
type: 0
axis: 0
joyNum: 0
- serializedVersion: 3
m_Name: Submit
descriptiveName:
descriptiveNegativeName:
negativeButton:
positiveButton: return
altNegativeButton:
altPositiveButton: joystick button 0
gravity: 1000
dead: 0.001
sensitivity: 1000
snap: 0
invert: 0
type: 0
axis: 0
joyNum: 0
- serializedVersion: 3
m_Name: Submit
descriptiveName:
descriptiveNegativeName:
negativeButton:
positiveButton: enter
altNegativeButton:
altPositiveButton: space
gravity: 1000
dead: 0.001
sensitivity: 1000
snap: 0
invert: 0
type: 0
axis: 0
joyNum: 0
- serializedVersion: 3
m_Name: Cancel
descriptiveName:
descriptiveNegativeName:
negativeButton:
positiveButton: escape
altNegativeButton:
altPositiveButton: joystick button 1
gravity: 1000
dead: 0.001
sensitivity: 1000
snap: 0
invert: 0
type: 0
axis: 0
joyNum: 0
- serializedVersion: 3
m_Name: Enable Debug Button 1
descriptiveName:
descriptiveNegativeName:
negativeButton:
positiveButton: left ctrl
altNegativeButton:
altPositiveButton: joystick button 8
gravity: 0
dead: 0
sensitivity: 0
snap: 0
invert: 0
type: 0
axis: 0
joyNum: 0
- serializedVersion: 3
m_Name: Enable Debug Button 2
descriptiveName:
descriptiveNegativeName:
negativeButton:
positiveButton: backspace
altNegativeButton:
altPositiveButton: joystick button 9
gravity: 0
dead: 0
sensitivity: 0
snap: 0
invert: 0
type: 0
axis: 0
joyNum: 0
- serializedVersion: 3
m_Name: Debug Reset
descriptiveName:
descriptiveNegativeName:
negativeButton:
positiveButton: left alt
altNegativeButton:
altPositiveButton: joystick button 1
gravity: 0
dead: 0
sensitivity: 0
snap: 0
invert: 0
type: 0
axis: 0
joyNum: 0
- serializedVersion: 3
m_Name: Debug Next
descriptiveName:
descriptiveNegativeName:
negativeButton:
positiveButton: page down
altNegativeButton:
altPositiveButton: joystick button 5
gravity: 0
dead: 0
sensitivity: 0
snap: 0
invert: 0
type: 0
axis: 0
joyNum: 0
- serializedVersion: 3
m_Name: Debug Previous
descriptiveName:
descriptiveNegativeName:
negativeButton:
positiveButton: page up
altNegativeButton:
altPositiveButton: joystick button 4
gravity: 0
dead: 0
sensitivity: 0
snap: 0
invert: 0
type: 0
axis: 0
joyNum: 0
- serializedVersion: 3
m_Name: Debug Validate
descriptiveName:
descriptiveNegativeName:
negativeButton:
positiveButton: return
altNegativeButton:
altPositiveButton: joystick button 0
gravity: 0
dead: 0
sensitivity: 0
snap: 0
invert: 0
type: 0
axis: 0
joyNum: 0
- serializedVersion: 3
m_Name: Debug Persistent
descriptiveName:
descriptiveNegativeName:
negativeButton:
positiveButton: right shift
altNegativeButton:
altPositiveButton: joystick button 2
gravity: 0
dead: 0
sensitivity: 0
snap: 0
invert: 0
type: 0
axis: 0
joyNum: 0
- serializedVersion: 3
m_Name: Debug Multiplier
descriptiveName:
descriptiveNegativeName:
negativeButton:
positiveButton: left shift
altNegativeButton:
altPositiveButton: joystick button 3
gravity: 0
dead: 0
sensitivity: 0
snap: 0
invert: 0
type: 0
axis: 0
joyNum: 0
- serializedVersion: 3
m_Name: Debug Horizontal
descriptiveName:
descriptiveNegativeName:
negativeButton: left
positiveButton: right
altNegativeButton:
altPositiveButton:
gravity: 1000
dead: 0.001
sensitivity: 1000
snap: 0
invert: 0
type: 0
axis: 0
joyNum: 0
- serializedVersion: 3
m_Name: Debug Vertical
descriptiveName:
descriptiveNegativeName:
negativeButton: down
positiveButton: up
altNegativeButton:
altPositiveButton:
gravity: 1000
dead: 0.001
sensitivity: 1000
snap: 0
invert: 0
type: 0
axis: 0
joyNum: 0
- serializedVersion: 3
m_Name: Debug Vertical
descriptiveName:
descriptiveNegativeName:
negativeButton: down
positiveButton: up
altNegativeButton:
altPositiveButton:
gravity: 1000
dead: 0.001
sensitivity: 1000
snap: 0
invert: 0
type: 2
axis: 6
joyNum: 0
- serializedVersion: 3
m_Name: Debug Horizontal
descriptiveName:
descriptiveNegativeName:
negativeButton: left
positiveButton: right
altNegativeButton:
altPositiveButton:
gravity: 1000
dead: 0.001
sensitivity: 1000
snap: 0
invert: 0
type: 2
axis: 5
joyNum: 0

View File

@ -0,0 +1,35 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!387306366 &1
MemorySettings:
m_ObjectHideFlags: 0
m_EditorMemorySettings:
m_MainAllocatorBlockSize: -1
m_ThreadAllocatorBlockSize: -1
m_MainGfxBlockSize: -1
m_ThreadGfxBlockSize: -1
m_CacheBlockSize: -1
m_TypetreeBlockSize: -1
m_ProfilerBlockSize: -1
m_ProfilerEditorBlockSize: -1
m_BucketAllocatorGranularity: -1
m_BucketAllocatorBucketsCount: -1
m_BucketAllocatorBlockSize: -1
m_BucketAllocatorBlockCount: -1
m_ProfilerBucketAllocatorGranularity: -1
m_ProfilerBucketAllocatorBucketsCount: -1
m_ProfilerBucketAllocatorBlockSize: -1
m_ProfilerBucketAllocatorBlockCount: -1
m_TempAllocatorSizeMain: -1
m_JobTempAllocatorBlockSize: -1
m_BackgroundJobTempAllocatorBlockSize: -1
m_JobTempAllocatorReducedBlockSize: -1
m_TempAllocatorSizeGIBakingWorker: -1
m_TempAllocatorSizeNavMeshWorker: -1
m_TempAllocatorSizeAudioWorker: -1
m_TempAllocatorSizeCloudWorker: -1
m_TempAllocatorSizeGfx: -1
m_TempAllocatorSizeJobWorker: -1
m_TempAllocatorSizeBackgroundWorker: -1
m_TempAllocatorSizePreloadManager: -1
m_PlatformMemorySettings: []

View File

@ -0,0 +1,9 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!655991488 &1
MultiplayerManager:
m_ObjectHideFlags: 0
m_EnableMultiplayerRoles: 0
m_EnablePlayModeLocalDeployment: 0
m_EnablePlayModeRemoteDeployment: 0
m_StrippingTypes: {}

View File

@ -0,0 +1,91 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!126 &1
NavMeshProjectSettings:
m_ObjectHideFlags: 0
serializedVersion: 2
areas:
- name: Walkable
cost: 1
- name: Not Walkable
cost: 1
- name: Jump
cost: 2
- name:
cost: 1
- name:
cost: 1
- name:
cost: 1
- name:
cost: 1
- name:
cost: 1
- name:
cost: 1
- name:
cost: 1
- name:
cost: 1
- name:
cost: 1
- name:
cost: 1
- name:
cost: 1
- name:
cost: 1
- name:
cost: 1
- name:
cost: 1
- name:
cost: 1
- name:
cost: 1
- name:
cost: 1
- name:
cost: 1
- name:
cost: 1
- name:
cost: 1
- name:
cost: 1
- name:
cost: 1
- name:
cost: 1
- name:
cost: 1
- name:
cost: 1
- name:
cost: 1
- name:
cost: 1
- name:
cost: 1
- name:
cost: 1
m_LastAgentTypeID: -887442657
m_Settings:
- serializedVersion: 2
agentTypeID: 0
agentRadius: 2
agentHeight: 1
agentSlope: 60
agentClimb: 0.2
ledgeDropHeight: 0
maxJumpAcrossDistance: 0
minRegionArea: 2
manualCellSize: 0
cellSize: 0.16666667
manualTileSize: 0
tileSize: 256
accuratePlacement: 0
debug:
m_Flags: 0
m_SettingNames:
- Car

View File

@ -0,0 +1,43 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!114 &1
MonoBehaviour:
m_ObjectHideFlags: 61
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: 13964, guid: 0000000000000000e000000000000000, type: 0}
m_Name:
m_EditorClassIdentifier:
m_EnablePreviewPackages: 0
m_EnablePackageDependencies: 0
m_AdvancedSettingsExpanded: 1
m_ScopedRegistriesSettingsExpanded: 1
oneTimeWarningShown: 0
m_Registries:
- m_Id: main
m_Name:
m_Url: https://packages.unity.com
m_Scopes: []
m_IsDefault: 1
m_Capabilities: 7
m_UserSelectedRegistryName:
m_UserAddingNewScopedRegistry: 0
m_RegistryInfoDraft:
m_ErrorMessage:
m_Original:
m_Id:
m_Name:
m_Url:
m_Scopes: []
m_IsDefault: 0
m_Capabilities: 0
m_Modified: 0
m_Name:
m_Url:
m_Scopes:
-
m_SelectedScopeIndex: 0

View File

@ -0,0 +1,306 @@
{
"m_Dictionary": {
"m_DictionaryValues": [
{
"type": "UnityEngine.ProBuilder.LogLevel, Unity.ProBuilder, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null",
"key": "log.level",
"value": "{\"m_Value\":3}"
},
{
"type": "UnityEngine.ProBuilder.LogOutput, Unity.ProBuilder, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null",
"key": "log.output",
"value": "{\"m_Value\":1}"
},
{
"type": "System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089",
"key": "log.path",
"value": "{\"m_Value\":\"ProBuilderLog.txt\"}"
},
{
"type": "System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089",
"key": "editor.materialPalettePath",
"value": "{\"m_Value\":\"Assets/ProBuilder Data/Default Material Palette.asset\"}"
},
{
"type": "System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089",
"key": "VertexColorPalette.previousColorPalette",
"value": "{\"m_Value\":\"Assets/ProBuilder Data/Default Color Palette.asset\"}"
},
{
"type": "UnityEngine.ProBuilder.SemVer, Unity.ProBuilder, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null",
"key": "about.identifier",
"value": "{\"m_Value\":{\"m_Major\":6,\"m_Minor\":0,\"m_Patch\":9,\"m_Build\":-1,\"m_Type\":\"\",\"m_Metadata\":\"\",\"m_Date\":\"\"}}"
},
{
"type": "UnityEngine.ProBuilder.SemVer, Unity.ProBuilder, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null",
"key": "preferences.version",
"value": "{\"m_Value\":{\"m_Major\":6,\"m_Minor\":0,\"m_Patch\":9,\"m_Build\":-1,\"m_Type\":\"\",\"m_Metadata\":\"\",\"m_Date\":\"\"}}"
},
{
"type": "System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089",
"key": "UnityEngine.ProBuilder.ProBuilderEditor-isUtilityWindow",
"value": "{\"m_Value\":false}"
},
{
"type": "System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089",
"key": "editor.backFaceSelectEnabled",
"value": "{\"m_Value\":false}"
},
{
"type": "System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089",
"key": "editor.toolbarIconGUI",
"value": "{\"m_Value\":false}"
},
{
"type": "System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089",
"key": "editor.showSceneInfo",
"value": "{\"m_Value\":false}"
},
{
"type": "System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089",
"key": "editor.showEditorNotifications",
"value": "{\"m_Value\":false}"
},
{
"type": "System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089",
"key": "meshImporter.quads",
"value": "{\"m_Value\":true}"
},
{
"type": "System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089",
"key": "meshImporter.smoothing",
"value": "{\"m_Value\":true}"
},
{
"type": "System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089",
"key": "UVEditor.showPreviewMaterial",
"value": "{\"m_Value\":true}"
},
{
"type": "System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089",
"key": "lightmapping.autoUnwrapLightmapUV",
"value": "{\"m_Value\":true}"
},
{
"type": "System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089",
"key": "mesh.newShapesSnapToGrid",
"value": "{\"m_Value\":true}"
},
{
"type": "System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089",
"key": "editor.autoRecalculateCollisions",
"value": "{\"m_Value\":false}"
},
{
"type": "System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089",
"key": "mesh.meshColliderIsConvex",
"value": "{\"m_Value\":false}"
},
{
"type": "System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089",
"key": "export.exportRecursive",
"value": "{\"m_Value\":false}"
},
{
"type": "System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089",
"key": "export.exportAsGroup",
"value": "{\"m_Value\":false}"
},
{
"type": "System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089",
"key": "export.objApplyTransform",
"value": "{\"m_Value\":false}"
},
{
"type": "System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089",
"key": "export.objExportRightHanded",
"value": "{\"m_Value\":true}"
},
{
"type": "System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089",
"key": "export.objExportCopyTextures",
"value": "{\"m_Value\":true}"
},
{
"type": "System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089",
"key": "export.objExportVertexColors",
"value": "{\"m_Value\":false}"
},
{
"type": "System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089",
"key": "export.objTextureOffsetScale",
"value": "{\"m_Value\":false}"
},
{
"type": "System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089",
"key": "export.objQuads",
"value": "{\"m_Value\":true}"
},
{
"type": "System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089",
"key": "editor.closeWindowAfterShapeCreation",
"value": "{\"m_Value\":false}"
},
{
"type": "System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089",
"key": "UnityEditor.ProBuilder.UVEditor-isUtilityWindow",
"value": "{\"m_Value\":false}"
},
{
"type": "System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089",
"key": "smoothing.showSettings",
"value": "{\"m_Value\":false}"
},
{
"type": "System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089",
"key": "smoothing.showPreview",
"value": "{\"m_Value\":false}"
},
{
"type": "System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089",
"key": "smoothing.showNormals",
"value": "{\"m_Value\":false}"
},
{
"type": "System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089",
"key": "smoothing.showHelp",
"value": "{\"m_Value\":false}"
},
{
"type": "System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089",
"key": "editor.stripProBuilderScriptsOnBuild",
"value": "{\"m_Value\":true}"
},
{
"type": "System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089",
"key": "FillHole.selectEntirePath",
"value": "{\"m_Value\":true}"
},
{
"type": "System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089",
"key": "GrowSelection.useAngle",
"value": "{\"m_Value\":true}"
},
{
"type": "System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089",
"key": "GrowSelection.iterativeGrow",
"value": "{\"m_Value\":false}"
},
{
"type": "System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089",
"key": "SelectEdgeLoop.selectIterative",
"value": "{\"m_Value\":false}"
},
{
"type": "System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089",
"key": "SelectEdgeRing.selectIterative",
"value": "{\"m_Value\":false}"
},
{
"type": "System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089",
"key": "editor.extrudeEdgesAsGroup",
"value": "{\"m_Value\":true}"
},
{
"type": "System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089",
"key": "experimental.enabled",
"value": "{\"m_Value\":false}"
},
{
"type": "UnityEngine.ProBuilder.SelectionModifierBehavior, Unity.ProBuilder, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null",
"key": "editor.rectSelectModifier",
"value": "{\"m_Value\":0}"
},
{
"type": "UnityEngine.ProBuilder.RectSelectMode, Unity.ProBuilder, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null",
"key": "editor.dragSelectRectMode",
"value": "{\"m_Value\":0}"
},
{
"type": "UnityEngine.ProBuilder.SelectMode, Unity.ProBuilder, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null",
"key": "editor.selectMode",
"value": "{\"m_Value\":1}"
},
{
"type": "System.Single, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089",
"key": "meshImporter.smoothingAngle",
"value": "{\"m_Value\":4.199999809265137}"
},
{
"type": "System.Single, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089",
"key": "uv.uvEditorGridSnapIncrement",
"value": "{\"m_Value\":0.125}"
},
{
"type": "System.Single, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089",
"key": "GrowSelection.angleValue",
"value": "{\"m_Value\":15.0}"
},
{
"type": "System.Single, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089",
"key": "ExtrudeFaces.distance",
"value": "{\"m_Value\":0.5}"
},
{
"type": "System.Single, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089",
"key": "ExtrudeEdges.distance",
"value": "{\"m_Value\":0.5}"
},
{
"type": "UnityEngine.ProBuilder.PivotLocation, Unity.ProBuilder, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null",
"key": "mesh.newShapePivotLocation",
"value": "{\"m_Value\":1}"
},
{
"type": "UnityEngine.Rendering.ShadowCastingMode, UnityEngine.CoreModule, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null",
"key": "mesh.shadowCastingMode",
"value": "{\"m_Value\":1}"
},
{
"type": "UnityEngine.Material, UnityEngine.CoreModule, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null",
"key": "mesh.userMaterial",
"value": "{\"m_Value\":{\"instanceID\":0}}"
},
{
"type": "UnityEditor.StaticEditorFlags, UnityEditor.CoreModule, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null",
"key": "mesh.defaultStaticEditorFlags",
"value": "{\"m_Value\":0}"
},
{
"type": "UnityEngine.ProBuilder.ColliderType, Unity.ProBuilder, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null",
"key": "mesh.newShapeColliderType",
"value": "{\"m_Value\":2}"
},
{
"type": "UnityEngine.ProBuilder.UnwrapParameters, Unity.ProBuilder, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null",
"key": "lightmapping.defaultLightmapUnwrapParameters",
"value": "{\"m_Value\":{\"m_HardAngle\":88.0,\"m_PackMargin\":20.0,\"m_AngleError\":8.0,\"m_AreaError\":15.0}}"
},
{
"type": "UnityEditor.ProBuilder.Actions.Export+ExportFormat, Unity.ProBuilder.Editor, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null",
"key": "export.format",
"value": "{\"m_Value\":0}"
},
{
"type": "UnityEditor.ProBuilder.Actions.ExportAssetOptions, Unity.ProBuilder.Editor, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null",
"key": "export.assetOptions",
"value": "{\"m_Value\":{\"makePrefab\":false,\"replaceOriginal\":false}}"
},
{
"type": "UnityEngine.Vector3, UnityEngine.CoreModule, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null",
"key": "MoveElements.s_Translation",
"value": "{\"m_Value\":{\"x\":0.0,\"y\":1.0,\"z\":0.0}}"
},
{
"type": "UnityEditor.ProBuilder.Actions.OffsetElements+CoordinateSpace, Unity.ProBuilder.Editor, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null",
"key": "MoveElements.s_CoordinateSpace",
"value": "{\"m_Value\":0}"
},
{
"type": "UnityEngine.ProBuilder.ExtrudeMethod, Unity.ProBuilder, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null",
"key": "editor.extrudeMethod",
"value": "{\"m_Value\":2}"
}
]
}
}

View File

@ -0,0 +1,7 @@
{
"m_Name": "Settings",
"m_Path": "ProjectSettings/Packages/com.unity.settings-manager/Settings.json",
"m_Dictionary": {
"m_DictionaryValues": []
}
}

View File

@ -0,0 +1,56 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!19 &1
Physics2DSettings:
m_ObjectHideFlags: 0
serializedVersion: 5
m_Gravity: {x: 0, y: -9.81}
m_DefaultMaterial: {fileID: 0}
m_VelocityIterations: 8
m_PositionIterations: 3
m_VelocityThreshold: 1
m_MaxLinearCorrection: 0.2
m_MaxAngularCorrection: 8
m_MaxTranslationSpeed: 100
m_MaxRotationSpeed: 360
m_BaumgarteScale: 0.2
m_BaumgarteTimeOfImpactScale: 0.75
m_TimeToSleep: 0.5
m_LinearSleepTolerance: 0.01
m_AngularSleepTolerance: 2
m_DefaultContactOffset: 0.01
m_JobOptions:
serializedVersion: 2
useMultithreading: 1
useConsistencySorting: 0
m_InterpolationPosesPerJob: 100
m_NewContactsPerJob: 30
m_CollideContactsPerJob: 100
m_ClearFlagsPerJob: 200
m_ClearBodyForcesPerJob: 200
m_SyncDiscreteFixturesPerJob: 50
m_SyncContinuousFixturesPerJob: 50
m_FindNearestContactsPerJob: 100
m_UpdateTriggerContactsPerJob: 100
m_IslandSolverCostThreshold: 100
m_IslandSolverBodyCostScale: 1
m_IslandSolverContactCostScale: 10
m_IslandSolverJointCostScale: 10
m_IslandSolverBodiesPerJob: 50
m_IslandSolverContactsPerJob: 50
m_SimulationMode: 0
m_QueriesHitTriggers: 1
m_QueriesStartInColliders: 1
m_CallbacksOnDisable: 1
m_ReuseCollisionCallbacks: 0
m_AutoSyncTransforms: 0
m_AlwaysShowColliders: 0
m_ShowColliderSleep: 1
m_ShowColliderContacts: 0
m_ShowColliderAABB: 0
m_ContactArrowScale: 0.2
m_ColliderAwakeColor: {r: 0.5686275, g: 0.95686275, b: 0.54509807, a: 0.7529412}
m_ColliderAsleepColor: {r: 0.5686275, g: 0.95686275, b: 0.54509807, a: 0.36078432}
m_ColliderContactColor: {r: 1, g: 0, b: 1, a: 0.6862745}
m_ColliderAABBColor: {r: 1, g: 1, b: 0, a: 0.2509804}
m_LayerCollisionMatrix: ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff

View File

@ -0,0 +1,7 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!1386491679 &1
PresetManager:
m_ObjectHideFlags: 0
serializedVersion: 2
m_DefaultPresets: {}

View File

@ -0,0 +1,766 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!129 &1
PlayerSettings:
m_ObjectHideFlags: 0
serializedVersion: 28
productGUID: 14389bd05b800ddd78609991ec8e5684
AndroidProfiler: 0
AndroidFilterTouchesWhenObscured: 0
AndroidEnableSustainedPerformanceMode: 0
defaultScreenOrientation: 4
targetDevice: 2
useOnDemandResources: 0
accelerometerFrequency: 60
companyName: DonkeyCar
productName: donkey_sim
defaultCursor: {fileID: 0}
cursorHotspot: {x: 0, y: 0}
m_SplashScreenBackgroundColor: {r: 0.13725491, g: 0.12156863, b: 0.1254902, a: 1}
m_ShowUnitySplashScreen: 1
m_ShowUnitySplashLogo: 1
m_SplashScreenOverlayOpacity: 1
m_SplashScreenAnimation: 1
m_SplashScreenLogoStyle: 1
m_SplashScreenDrawMode: 0
m_SplashScreenBackgroundAnimationZoom: 1
m_SplashScreenLogoAnimationZoom: 1
m_SplashScreenBackgroundLandscapeAspect: 1
m_SplashScreenBackgroundPortraitAspect: 1
m_SplashScreenBackgroundLandscapeUvs:
serializedVersion: 2
x: 0
y: 0
width: 1
height: 1
m_SplashScreenBackgroundPortraitUvs:
serializedVersion: 2
x: 0
y: 0
width: 1
height: 1
m_SplashScreenLogos: []
m_VirtualRealitySplashScreen: {fileID: 0}
defaultScreenWidth: 1920
defaultScreenHeight: 1127
defaultScreenWidthWeb: 960
defaultScreenHeightWeb: 600
m_StereoRenderingPath: 0
m_ActiveColorSpace: 1
unsupportedMSAAFallback: 0
m_SpriteBatchMaxVertexCount: 65535
m_SpriteBatchVertexThreshold: 300
m_MTRendering: 1
mipStripping: 0
numberOfMipsStripped: 0
numberOfMipsStrippedPerMipmapLimitGroup: {}
m_StackTraceTypes: 010000000100000001000000010000000100000001000000
iosShowActivityIndicatorOnLoading: -1
androidShowActivityIndicatorOnLoading: -1
iosUseCustomAppBackgroundBehavior: 0
allowedAutorotateToPortrait: 1
allowedAutorotateToPortraitUpsideDown: 1
allowedAutorotateToLandscapeRight: 1
allowedAutorotateToLandscapeLeft: 1
useOSAutorotation: 1
use32BitDisplayBuffer: 1
preserveFramebufferAlpha: 0
disableDepthAndStencilBuffers: 0
androidStartInFullscreen: 1
androidRenderOutsideSafeArea: 1
androidUseSwappy: 0
androidDisplayOptions: 1
androidBlitType: 0
androidResizeableActivity: 1
androidDefaultWindowWidth: 1920
androidDefaultWindowHeight: 1080
androidMinimumWindowWidth: 400
androidMinimumWindowHeight: 300
androidFullscreenMode: 1
androidAutoRotationBehavior: 1
androidPredictiveBackSupport: 1
androidApplicationEntry: 1
defaultIsNativeResolution: 1
macRetinaSupport: 1
runInBackground: 1
muteOtherAudioSources: 0
Prepare IOS For Recording: 0
Force IOS Speakers When Recording: 0
audioSpatialExperience: 0
deferSystemGesturesMode: 0
hideHomeButton: 0
submitAnalytics: 1
usePlayerLog: 1
dedicatedServerOptimizations: 1
bakeCollisionMeshes: 0
forceSingleInstance: 0
useFlipModelSwapchain: 1
resizableWindow: 1
useMacAppStoreValidation: 0
macAppStoreCategory: public.app-category.games
gpuSkinning: 0
meshDeformation: 0
xboxPIXTextureCapture: 0
xboxEnableAvatar: 0
xboxEnableKinect: 0
xboxEnableKinectAutoTracking: 0
xboxEnableFitness: 0
visibleInBackground: 1
allowFullscreenSwitch: 1
fullscreenMode: 3
xboxSpeechDB: 0
xboxEnableHeadOrientation: 0
xboxEnableGuest: 0
xboxEnablePIXSampling: 0
metalFramebufferOnly: 0
metalUseMetalDisplayLink: 0
xboxOneResolution: 0
xboxOneSResolution: 0
xboxOneXResolution: 3
xboxOneMonoLoggingLevel: 0
xboxOneLoggingLevel: 1
xboxOneDisableEsram: 0
xboxOneEnableTypeOptimization: 0
xboxOnePresentImmediateThreshold: 0
switchQueueCommandMemory: 1048576
switchQueueControlMemory: 16384
switchQueueComputeMemory: 262144
switchNVNShaderPoolsGranularity: 33554432
switchNVNDefaultPoolsGranularity: 16777216
switchNVNOtherPoolsGranularity: 16777216
switchGpuScratchPoolGranularity: 2097152
switchAllowGpuScratchShrinking: 0
switchNVNMaxPublicTextureIDCount: 0
switchNVNMaxPublicSamplerIDCount: 0
switchMaxWorkerMultiple: 8
switchNVNGraphicsFirmwareMemory: 32
switchGraphicsJobsSyncAfterKick: 1
vulkanNumSwapchainBuffers: 3
vulkanEnableSetSRGBWrite: 0
vulkanEnablePreTransform: 0
vulkanEnableLateAcquireNextImage: 0
vulkanEnableCommandBufferRecycling: 1
loadStoreDebugModeEnabled: 0
visionOSBundleVersion: 1.0
tvOSBundleVersion: 1.0
bundleVersion: 1.0
preloadedAssets: []
metroInputSource: 0
wsaTransparentSwapchain: 0
xboxOneDisableKinectGpuReservation: 1
xboxOneEnable7thCore: 1
vrSettings:
enable360StereoCapture: 0
enableFrameTimingStats: 0
enableOpenGLProfilerGPURecorders: 1
allowHDRDisplaySupport: 0
useHDRDisplay: 0
hdrBitDepth: 0
m_ColorGamuts: 00000000
targetPixelDensity: 30
resolutionScalingMode: 0
resetResolutionOnWindowResize: 0
androidSupportedAspectRatio: 1
androidMaxAspectRatio: 2.1
androidMinAspectRatio: 1
applicationIdentifier:
Standalone: com.DonkeyCar.donkeysim
buildNumber:
Standalone: 0
VisionOS: 0
iPhone: 0
tvOS: 0
overrideDefaultApplicationIdentifier: 0
AndroidBundleVersionCode: 1
AndroidMinSdkVersion: 25
AndroidTargetSdkVersion: 0
AndroidPreferredInstallLocation: 1
AndroidPreferredDataLocation: 1
aotOptions:
stripEngineCode: 1
iPhoneStrippingLevel: 0
iPhoneScriptCallOptimization: 0
ForceInternetPermission: 0
ForceSDCardPermission: 0
CreateWallpaper: 0
androidSplitApplicationBinary: 0
keepLoadedShadersAlive: 0
StripUnusedMeshComponents: 0
strictShaderVariantMatching: 0
VertexChannelCompressionMask: 4054
iPhoneSdkVersion: 988
iOSSimulatorArchitecture: 0
iOSTargetOSVersionString: 15.0
tvOSSdkVersion: 0
tvOSSimulatorArchitecture: 0
tvOSRequireExtendedGameController: 0
tvOSTargetOSVersionString: 15.0
VisionOSSdkVersion: 0
VisionOSTargetOSVersionString: 1.0
uIPrerenderedIcon: 0
uIRequiresPersistentWiFi: 0
uIRequiresFullScreen: 1
uIStatusBarHidden: 1
uIExitOnSuspend: 0
uIStatusBarStyle: 0
appleTVSplashScreen: {fileID: 0}
appleTVSplashScreen2x: {fileID: 0}
tvOSSmallIconLayers: []
tvOSSmallIconLayers2x: []
tvOSLargeIconLayers: []
tvOSLargeIconLayers2x: []
tvOSTopShelfImageLayers: []
tvOSTopShelfImageLayers2x: []
tvOSTopShelfImageWideLayers: []
tvOSTopShelfImageWideLayers2x: []
iOSLaunchScreenType: 0
iOSLaunchScreenPortrait: {fileID: 0}
iOSLaunchScreenLandscape: {fileID: 0}
iOSLaunchScreenBackgroundColor:
serializedVersion: 2
rgba: 0
iOSLaunchScreenFillPct: 100
iOSLaunchScreenSize: 100
iOSLaunchScreeniPadType: 0
iOSLaunchScreeniPadImage: {fileID: 0}
iOSLaunchScreeniPadBackgroundColor:
serializedVersion: 2
rgba: 0
iOSLaunchScreeniPadFillPct: 100
iOSLaunchScreeniPadSize: 100
iOSLaunchScreenCustomStoryboardPath:
iOSLaunchScreeniPadCustomStoryboardPath:
iOSDeviceRequirements: []
iOSURLSchemes: []
macOSURLSchemes: []
iOSBackgroundModes: 0
iOSMetalForceHardShadows: 0
metalEditorSupport: 1
metalAPIValidation: 1
metalCompileShaderBinary: 0
iOSRenderExtraFrameOnPause: 0
iosCopyPluginsCodeInsteadOfSymlink: 0
appleDeveloperTeamID:
iOSManualSigningProvisioningProfileID:
tvOSManualSigningProvisioningProfileID:
VisionOSManualSigningProvisioningProfileID:
iOSManualSigningProvisioningProfileType: 0
tvOSManualSigningProvisioningProfileType: 0
VisionOSManualSigningProvisioningProfileType: 0
appleEnableAutomaticSigning: 0
iOSRequireARKit: 0
iOSAutomaticallyDetectAndAddCapabilities: 1
appleEnableProMotion: 0
shaderPrecisionModel: 0
clonedFromGUID: 00000000000000000000000000000000
templatePackageId:
templateDefaultScene:
useCustomMainManifest: 0
useCustomLauncherManifest: 0
useCustomMainGradleTemplate: 0
useCustomLauncherGradleManifest: 0
useCustomBaseGradleTemplate: 0
useCustomGradlePropertiesTemplate: 0
useCustomGradleSettingsTemplate: 0
useCustomProguardFile: 0
AndroidTargetArchitectures: 1
AndroidAllowedArchitectures: -1
AndroidSplashScreenScale: 0
androidSplashScreen: {fileID: 0}
AndroidKeystoreName:
AndroidKeyaliasName:
AndroidEnableArmv9SecurityFeatures: 0
AndroidEnableArm64MTE: 0
AndroidBuildApkPerCpuArchitecture: 0
AndroidTVCompatibility: 0
AndroidIsGame: 1
androidAppCategory: 3
useAndroidAppCategory: 1
androidAppCategoryOther:
AndroidEnableTango: 0
androidEnableBanner: 1
androidUseLowAccuracyLocation: 0
androidUseCustomKeystore: 0
m_AndroidBanners:
- width: 320
height: 180
banner: {fileID: 0}
androidGamepadSupportLevel: 0
AndroidMinifyRelease: 0
AndroidMinifyDebug: 0
AndroidValidateAppBundleSize: 1
AndroidAppBundleSizeToValidate: 150
AndroidReportGooglePlayAppDependencies: 1
androidSymbolsSizeThreshold: 800
m_BuildTargetIcons:
- m_BuildTarget:
m_Icons:
- serializedVersion: 2
m_Icon: {fileID: 2800000, guid: 5a980be9821c24f4ba4fd728e5fa23e3, type: 3}
m_Width: 128
m_Height: 128
m_Kind: 0
m_BuildTargetPlatformIcons: []
m_BuildTargetBatching: []
m_BuildTargetShaderSettings: []
m_BuildTargetGraphicsJobs:
- m_BuildTarget: MacStandaloneSupport
m_GraphicsJobs: 1
- m_BuildTarget: Switch
m_GraphicsJobs: 0
- m_BuildTarget: MetroSupport
m_GraphicsJobs: 0
- m_BuildTarget: AppleTVSupport
m_GraphicsJobs: 0
- m_BuildTarget: BJMSupport
m_GraphicsJobs: 0
- m_BuildTarget: LinuxStandaloneSupport
m_GraphicsJobs: 1
- m_BuildTarget: PS4Player
m_GraphicsJobs: 0
- m_BuildTarget: iOSSupport
m_GraphicsJobs: 0
- m_BuildTarget: WindowsStandaloneSupport
m_GraphicsJobs: 1
- m_BuildTarget: XboxOnePlayer
m_GraphicsJobs: 0
- m_BuildTarget: LuminSupport
m_GraphicsJobs: 0
- m_BuildTarget: AndroidPlayer
m_GraphicsJobs: 0
- m_BuildTarget: WebGLSupport
m_GraphicsJobs: 0
m_BuildTargetGraphicsJobMode:
- m_BuildTarget: PS4Player
m_GraphicsJobMode: 0
- m_BuildTarget: XboxOnePlayer
m_GraphicsJobMode: 0
m_BuildTargetGraphicsAPIs:
- m_BuildTarget: iOSSupport
m_APIs: 10000000
m_Automatic: 1
- m_BuildTarget: AndroidPlayer
m_APIs: 0b000000
m_Automatic: 0
- m_BuildTarget: WindowsStandaloneSupport
m_APIs: 0200000012000000
m_Automatic: 0
m_BuildTargetVRSettings: []
m_DefaultShaderChunkSizeInMB: 16
m_DefaultShaderChunkCount: 0
openGLRequireES31: 0
openGLRequireES31AEP: 0
openGLRequireES32: 0
m_TemplateCustomTags: {}
mobileMTRendering:
Android: 1
iPhone: 1
tvOS: 1
m_BuildTargetGroupLightmapEncodingQuality: []
m_BuildTargetGroupHDRCubemapEncodingQuality: []
m_BuildTargetGroupLightmapSettings: []
m_BuildTargetGroupLoadStoreDebugModeSettings: []
m_BuildTargetNormalMapEncoding: []
m_BuildTargetDefaultTextureCompressionFormat: []
playModeTestRunnerEnabled: 0
runPlayModeTestAsEditModeTest: 0
actionOnDotNetUnhandledException: 1
editorGfxJobOverride: 1
enableInternalProfiler: 0
logObjCUncaughtExceptions: 1
enableCrashReportAPI: 0
cameraUsageDescription:
locationUsageDescription:
microphoneUsageDescription:
bluetoothUsageDescription:
macOSTargetOSVersion: 12.0
switchNMETAOverride:
switchNetLibKey:
switchSocketMemoryPoolSize: 6144
switchSocketAllocatorPoolSize: 128
switchSocketConcurrencyLimit: 14
switchScreenResolutionBehavior: 2
switchUseCPUProfiler: 0
switchEnableFileSystemTrace: 0
switchLTOSetting: 0
switchApplicationID: 0x01004b9000490000
switchNSODependencies:
switchCompilerFlags:
switchTitleNames_0:
switchTitleNames_1:
switchTitleNames_2:
switchTitleNames_3:
switchTitleNames_4:
switchTitleNames_5:
switchTitleNames_6:
switchTitleNames_7:
switchTitleNames_8:
switchTitleNames_9:
switchTitleNames_10:
switchTitleNames_11:
switchTitleNames_12:
switchTitleNames_13:
switchTitleNames_14:
switchTitleNames_15:
switchPublisherNames_0:
switchPublisherNames_1:
switchPublisherNames_2:
switchPublisherNames_3:
switchPublisherNames_4:
switchPublisherNames_5:
switchPublisherNames_6:
switchPublisherNames_7:
switchPublisherNames_8:
switchPublisherNames_9:
switchPublisherNames_10:
switchPublisherNames_11:
switchPublisherNames_12:
switchPublisherNames_13:
switchPublisherNames_14:
switchPublisherNames_15:
switchIcons_0: {fileID: 0}
switchIcons_1: {fileID: 0}
switchIcons_2: {fileID: 0}
switchIcons_3: {fileID: 0}
switchIcons_4: {fileID: 0}
switchIcons_5: {fileID: 0}
switchIcons_6: {fileID: 0}
switchIcons_7: {fileID: 0}
switchIcons_8: {fileID: 0}
switchIcons_9: {fileID: 0}
switchIcons_10: {fileID: 0}
switchIcons_11: {fileID: 0}
switchIcons_12: {fileID: 0}
switchIcons_13: {fileID: 0}
switchIcons_14: {fileID: 0}
switchIcons_15: {fileID: 0}
switchSmallIcons_0: {fileID: 0}
switchSmallIcons_1: {fileID: 0}
switchSmallIcons_2: {fileID: 0}
switchSmallIcons_3: {fileID: 0}
switchSmallIcons_4: {fileID: 0}
switchSmallIcons_5: {fileID: 0}
switchSmallIcons_6: {fileID: 0}
switchSmallIcons_7: {fileID: 0}
switchSmallIcons_8: {fileID: 0}
switchSmallIcons_9: {fileID: 0}
switchSmallIcons_10: {fileID: 0}
switchSmallIcons_11: {fileID: 0}
switchSmallIcons_12: {fileID: 0}
switchSmallIcons_13: {fileID: 0}
switchSmallIcons_14: {fileID: 0}
switchSmallIcons_15: {fileID: 0}
switchManualHTML:
switchAccessibleURLs:
switchLegalInformation:
switchMainThreadStackSize: 1048576
switchPresenceGroupId:
switchLogoHandling: 0
switchReleaseVersion: 0
switchDisplayVersion: 1.0.0
switchStartupUserAccount: 0
switchSupportedLanguagesMask: 0
switchLogoType: 0
switchApplicationErrorCodeCategory:
switchUserAccountSaveDataSize: 0
switchUserAccountSaveDataJournalSize: 0
switchApplicationAttribute: 0
switchCardSpecSize: -1
switchCardSpecClock: -1
switchRatingsMask: 0
switchRatingsInt_0: 0
switchRatingsInt_1: 0
switchRatingsInt_2: 0
switchRatingsInt_3: 0
switchRatingsInt_4: 0
switchRatingsInt_5: 0
switchRatingsInt_6: 0
switchRatingsInt_7: 0
switchRatingsInt_8: 0
switchRatingsInt_9: 0
switchRatingsInt_10: 0
switchRatingsInt_11: 0
switchRatingsInt_12: 0
switchLocalCommunicationIds_0:
switchLocalCommunicationIds_1:
switchLocalCommunicationIds_2:
switchLocalCommunicationIds_3:
switchLocalCommunicationIds_4:
switchLocalCommunicationIds_5:
switchLocalCommunicationIds_6:
switchLocalCommunicationIds_7:
switchParentalControl: 0
switchAllowsScreenshot: 1
switchAllowsVideoCapturing: 1
switchAllowsRuntimeAddOnContentInstall: 0
switchDataLossConfirmation: 0
switchUserAccountLockEnabled: 0
switchSystemResourceMemory: 16777216
switchSupportedNpadStyles: 22
switchNativeFsCacheSize: 32
switchIsHoldTypeHorizontal: 0
switchSupportedNpadCount: 8
switchEnableTouchScreen: 1
switchSocketConfigEnabled: 0
switchTcpInitialSendBufferSize: 32
switchTcpInitialReceiveBufferSize: 64
switchTcpAutoSendBufferSizeMax: 256
switchTcpAutoReceiveBufferSizeMax: 256
switchUdpSendBufferSize: 9
switchUdpReceiveBufferSize: 42
switchSocketBufferEfficiency: 4
switchSocketInitializeEnabled: 1
switchNetworkInterfaceManagerInitializeEnabled: 1
switchDisableHTCSPlayerConnection: 0
switchUseNewStyleFilepaths: 0
switchUseLegacyFmodPriorities: 0
switchUseMicroSleepForYield: 1
switchEnableRamDiskSupport: 0
switchMicroSleepForYieldTime: 25
switchRamDiskSpaceSize: 12
switchUpgradedPlayerSettingsToNMETA: 0
ps4NPAgeRating: 12
ps4NPTitleSecret:
ps4NPTrophyPackPath:
ps4ParentalLevel: 11
ps4ContentID: ED1633-NPXX51362_00-0000000000000000
ps4Category: 0
ps4MasterVersion: 01.00
ps4AppVersion: 01.00
ps4AppType: 0
ps4ParamSfxPath:
ps4VideoOutPixelFormat: 0
ps4VideoOutInitialWidth: 1920
ps4VideoOutBaseModeInitialWidth: 1920
ps4VideoOutReprojectionRate: 60
ps4PronunciationXMLPath:
ps4PronunciationSIGPath:
ps4BackgroundImagePath:
ps4StartupImagePath:
ps4StartupImagesFolder:
ps4IconImagesFolder:
ps4SaveDataImagePath:
ps4SdkOverride:
ps4BGMPath:
ps4ShareFilePath:
ps4ShareOverlayImagePath:
ps4PrivacyGuardImagePath:
ps4ExtraSceSysFile:
ps4NPtitleDatPath:
ps4RemotePlayKeyAssignment: -1
ps4RemotePlayKeyMappingDir:
ps4PlayTogetherPlayerCount: 0
ps4EnterButtonAssignment: 2
ps4ApplicationParam1: 0
ps4ApplicationParam2: 0
ps4ApplicationParam3: 0
ps4ApplicationParam4: 0
ps4DownloadDataSize: 0
ps4GarlicHeapSize: 2048
ps4ProGarlicHeapSize: 2560
playerPrefsMaxSize: 32768
ps4Passcode: fa37JncCHryDsbzayy4cBWDxS22JjzhM
ps4pnSessions: 1
ps4pnPresence: 1
ps4pnFriends: 1
ps4pnGameCustomData: 1
playerPrefsSupport: 0
enableApplicationExit: 0
resetTempFolder: 1
restrictedAudioUsageRights: 0
ps4UseResolutionFallback: 0
ps4ReprojectionSupport: 0
ps4UseAudio3dBackend: 0
ps4UseLowGarlicFragmentationMode: 1
ps4SocialScreenEnabled: 0
ps4ScriptOptimizationLevel: 2
ps4Audio3dVirtualSpeakerCount: 14
ps4attribCpuUsage: 0
ps4PatchPkgPath:
ps4PatchLatestPkgPath:
ps4PatchChangeinfoPath:
ps4PatchDayOne: 0
ps4attribUserManagement: 0
ps4attribMoveSupport: 0
ps4attrib3DSupport: 0
ps4attribShareSupport: 0
ps4attribExclusiveVR: 0
ps4disableAutoHideSplash: 0
ps4videoRecordingFeaturesUsed: 0
ps4contentSearchFeaturesUsed: 0
ps4CompatibilityPS5: 0
ps4AllowPS5Detection: 0
ps4GPU800MHz: 1
ps4attribEyeToEyeDistanceSettingVR: 0
ps4IncludedModules: []
ps4attribVROutputEnabled: 0
monoEnv:
splashScreenBackgroundSourceLandscape: {fileID: 0}
splashScreenBackgroundSourcePortrait: {fileID: 0}
blurSplashScreenBackground: 1
spritePackerPolicy:
webGLMemorySize: 32
webGLExceptionSupport: 1
webGLNameFilesAsHashes: 0
webGLShowDiagnostics: 0
webGLDataCaching: 1
webGLDebugSymbols: 0
webGLEmscriptenArgs:
webGLModulesDirectory:
webGLTemplate: APPLICATION:Default
webGLAnalyzeBuildSize: 0
webGLUseEmbeddedResources: 0
webGLCompressionFormat: 0
webGLWasmArithmeticExceptions: 0
webGLLinkerTarget: 1
webGLThreadsSupport: 0
webGLDecompressionFallback: 0
webGLInitialMemorySize: 32
webGLMaximumMemorySize: 2048
webGLMemoryGrowthMode: 2
webGLMemoryLinearGrowthStep: 16
webGLMemoryGeometricGrowthStep: 0.2
webGLMemoryGeometricGrowthCap: 96
webGLPowerPreference: 2
webGLWebAssemblyTable: 0
webGLWebAssemblyBigInt: 0
webGLCloseOnQuit: 0
webWasm2023: 0
webEnableSubmoduleStrippingCompatibility: 0
scriptingDefineSymbols:
Android: CROSS_PLATFORM_INPUT;MOBILE_INPUT
Standalone: CROSS_PLATFORM_INPUT
Windows Store Apps: MOBILE_INPUT
iPhone: CROSS_PLATFORM_INPUT;MOBILE_INPUT
additionalCompilerArguments: {}
platformArchitecture: {}
scriptingBackend:
Android: 0
il2cppCompilerConfiguration: {}
il2cppCodeGeneration: {}
il2cppStacktraceInformation: {}
managedStrippingLevel:
Android: 1
EmbeddedLinux: 1
GameCoreScarlett: 1
GameCoreXboxOne: 1
Kepler: 1
Nintendo Switch: 1
Nintendo Switch 2: 1
PS4: 1
PS5: 1
QNX: 1
VisionOS: 1
WebGL: 1
Windows Store Apps: 1
XboxOne: 1
iPhone: 1
tvOS: 1
incrementalIl2cppBuild: {}
suppressCommonWarnings: 1
allowUnsafeCode: 0
useDeterministicCompilation: 1
additionalIl2CppArgs:
scriptingRuntimeVersion: 1
gcIncremental: 0
gcWBarrierValidation: 0
apiCompatibilityLevelPerPlatform: {}
editorAssembliesCompatibilityLevel: 1
m_RenderingPath: 1
m_MobileRenderingPath: 1
metroPackageName: sdsim
metroPackageVersion:
metroCertificatePath:
metroCertificatePassword:
metroCertificateSubject:
metroCertificateIssuer:
metroCertificateNotAfter: 0000000000000000
metroApplicationDescription: sdsim
wsaImages: {}
metroTileShortName:
metroTileShowName: 0
metroMediumTileShowName: 0
metroLargeTileShowName: 0
metroWideTileShowName: 0
metroSupportStreamingInstall: 0
metroLastRequiredScene: 0
metroDefaultTileSize: 1
metroTileForegroundText: 2
metroTileBackgroundColor: {r: 0.13333334, g: 0.17254902, b: 0.21568628, a: 0}
metroSplashScreenBackgroundColor: {r: 0.12941177, g: 0.17254902, b: 0.21568628,
a: 1}
metroSplashScreenUseBackgroundColor: 0
syncCapabilities: 0
platformCapabilities: {}
metroTargetDeviceFamilies: {}
metroFTAName:
metroFTAFileTypes: []
metroProtocolName:
vcxProjDefaultLanguage:
XboxOneProductId:
XboxOneUpdateKey:
XboxOneSandboxId:
XboxOneContentId:
XboxOneTitleId:
XboxOneSCId:
XboxOneGameOsOverridePath:
XboxOnePackagingOverridePath:
XboxOneAppManifestOverridePath:
XboxOneVersion: 1.0.0.0
XboxOnePackageEncryption: 0
XboxOnePackageUpdateGranularity: 2
XboxOneDescription:
XboxOneLanguage:
- enus
XboxOneCapability: []
XboxOneGameRating: {}
XboxOneIsContentPackage: 0
XboxOneEnhancedXboxCompatibilityMode: 0
XboxOneEnableGPUVariability: 1
XboxOneSockets: {}
XboxOneSplashScreen: {fileID: 0}
XboxOneAllowedProductIds: []
XboxOnePersistentLocalStorageSize: 0
XboxOneXTitleMemory: 8
XboxOneOverrideIdentityName:
XboxOneOverrideIdentityPublisher:
vrEditorSettings: {}
cloudServicesEnabled: {}
luminIcon:
m_Name:
m_ModelFolderPath:
m_PortalFolderPath:
luminCert:
m_CertPath:
m_SignPackage: 1
luminIsChannelApp: 0
luminVersion:
m_VersionCode: 1
m_VersionName:
hmiPlayerDataPath:
hmiForceSRGBBlit: 0
embeddedLinuxEnableGamepadInput: 0
hmiCpuConfiguration:
hmiLogStartupTiming: 0
qnxGraphicConfPath:
apiCompatibilityLevel: 6
captureStartupLogs: {}
activeInputHandler: 0
windowsGamepadBackendHint: 0
enableDirectStorage: 0
cloudProjectId:
framebufferDepthMemorylessMode: 0
qualitySettingsNames: []
projectName:
organizationId:
cloudEnabled: 0
legacyClampBlendShapeWeights: 0
hmiLoadingImage: {fileID: 0}
platformRequiresReadableAssets: 0
virtualTexturingSupportEnabled: 0
insecureHttpOption: 0
androidVulkanDenyFilterList: []
androidVulkanAllowFilterList: []
androidVulkanDeviceFilterListAsset: {fileID: 0}
d3d12DeviceFilterListAsset: {fileID: 0}
allowedHttpConnections: 3

View File

@ -0,0 +1,2 @@
m_EditorVersion: 6000.4.4f1
m_EditorVersionWithRevision: 6000.4.4f1 (360f97ecca93)

View File

@ -0,0 +1,236 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!47 &1
QualitySettings:
m_ObjectHideFlags: 0
serializedVersion: 5
m_CurrentQuality: 5
m_QualitySettings:
- serializedVersion: 2
name: Very Low
pixelLightCount: 0
shadows: 0
shadowResolution: 0
shadowProjection: 1
shadowCascades: 1
shadowDistance: 15
shadowNearPlaneOffset: 3
shadowCascade2Split: 0.33333334
shadowCascade4Split: {x: 0.06666667, y: 0.2, z: 0.46666667}
shadowmaskMode: 0
skinWeights: 1
textureQuality: 1
anisotropicTextures: 0
antiAliasing: 0
softParticles: 0
softVegetation: 0
realtimeReflectionProbes: 0
billboardsFaceCameraPosition: 0
vSyncCount: 0
lodBias: 0.3
maximumLODLevel: 0
streamingMipmapsActive: 0
streamingMipmapsAddAllCameras: 1
streamingMipmapsMemoryBudget: 512
streamingMipmapsRenderersPerFrame: 512
streamingMipmapsMaxLevelReduction: 2
streamingMipmapsMaxFileIORequests: 1024
particleRaycastBudget: 4
asyncUploadTimeSlice: 2
asyncUploadBufferSize: 16
asyncUploadPersistentBuffer: 1
resolutionScalingFixedDPIFactor: 1
customRenderPipeline: {fileID: 0}
excludedTargetPlatforms: []
- serializedVersion: 2
name: Low
pixelLightCount: 0
shadows: 0
shadowResolution: 0
shadowProjection: 1
shadowCascades: 1
shadowDistance: 20
shadowNearPlaneOffset: 3
shadowCascade2Split: 0.33333334
shadowCascade4Split: {x: 0.06666667, y: 0.2, z: 0.46666667}
shadowmaskMode: 0
skinWeights: 2
textureQuality: 0
anisotropicTextures: 0
antiAliasing: 0
softParticles: 0
softVegetation: 0
realtimeReflectionProbes: 0
billboardsFaceCameraPosition: 0
vSyncCount: 0
lodBias: 0.4
maximumLODLevel: 0
streamingMipmapsActive: 0
streamingMipmapsAddAllCameras: 1
streamingMipmapsMemoryBudget: 512
streamingMipmapsRenderersPerFrame: 512
streamingMipmapsMaxLevelReduction: 2
streamingMipmapsMaxFileIORequests: 1024
particleRaycastBudget: 16
asyncUploadTimeSlice: 2
asyncUploadBufferSize: 16
asyncUploadPersistentBuffer: 1
resolutionScalingFixedDPIFactor: 1
customRenderPipeline: {fileID: 0}
excludedTargetPlatforms: []
- serializedVersion: 2
name: Medium
pixelLightCount: 1
shadows: 1
shadowResolution: 0
shadowProjection: 1
shadowCascades: 1
shadowDistance: 20
shadowNearPlaneOffset: 3
shadowCascade2Split: 0.33333334
shadowCascade4Split: {x: 0.06666667, y: 0.2, z: 0.46666667}
shadowmaskMode: 0
skinWeights: 2
textureQuality: 0
anisotropicTextures: 1
antiAliasing: 0
softParticles: 0
softVegetation: 0
realtimeReflectionProbes: 0
billboardsFaceCameraPosition: 0
vSyncCount: 1
lodBias: 0.7
maximumLODLevel: 0
streamingMipmapsActive: 0
streamingMipmapsAddAllCameras: 1
streamingMipmapsMemoryBudget: 512
streamingMipmapsRenderersPerFrame: 512
streamingMipmapsMaxLevelReduction: 2
streamingMipmapsMaxFileIORequests: 1024
particleRaycastBudget: 64
asyncUploadTimeSlice: 2
asyncUploadBufferSize: 16
asyncUploadPersistentBuffer: 1
resolutionScalingFixedDPIFactor: 1
customRenderPipeline: {fileID: 0}
excludedTargetPlatforms: []
- serializedVersion: 2
name: High
pixelLightCount: 2
shadows: 2
shadowResolution: 1
shadowProjection: 1
shadowCascades: 2
shadowDistance: 40
shadowNearPlaneOffset: 3
shadowCascade2Split: 0.33333334
shadowCascade4Split: {x: 0.06666667, y: 0.2, z: 0.46666667}
shadowmaskMode: 1
skinWeights: 2
textureQuality: 0
anisotropicTextures: 1
antiAliasing: 0
softParticles: 0
softVegetation: 1
realtimeReflectionProbes: 1
billboardsFaceCameraPosition: 1
vSyncCount: 1
lodBias: 1
maximumLODLevel: 0
streamingMipmapsActive: 0
streamingMipmapsAddAllCameras: 1
streamingMipmapsMemoryBudget: 512
streamingMipmapsRenderersPerFrame: 512
streamingMipmapsMaxLevelReduction: 2
streamingMipmapsMaxFileIORequests: 1024
particleRaycastBudget: 256
asyncUploadTimeSlice: 2
asyncUploadBufferSize: 16
asyncUploadPersistentBuffer: 1
resolutionScalingFixedDPIFactor: 1
customRenderPipeline: {fileID: 0}
excludedTargetPlatforms: []
- serializedVersion: 2
name: Very High
pixelLightCount: 3
shadows: 2
shadowResolution: 2
shadowProjection: 1
shadowCascades: 2
shadowDistance: 70
shadowNearPlaneOffset: 3
shadowCascade2Split: 0.33333334
shadowCascade4Split: {x: 0.06666667, y: 0.2, z: 0.46666667}
shadowmaskMode: 1
skinWeights: 4
textureQuality: 0
anisotropicTextures: 2
antiAliasing: 2
softParticles: 1
softVegetation: 1
realtimeReflectionProbes: 1
billboardsFaceCameraPosition: 1
vSyncCount: 1
lodBias: 1.5
maximumLODLevel: 0
streamingMipmapsActive: 0
streamingMipmapsAddAllCameras: 1
streamingMipmapsMemoryBudget: 512
streamingMipmapsRenderersPerFrame: 512
streamingMipmapsMaxLevelReduction: 2
streamingMipmapsMaxFileIORequests: 1024
particleRaycastBudget: 1024
asyncUploadTimeSlice: 2
asyncUploadBufferSize: 16
asyncUploadPersistentBuffer: 1
resolutionScalingFixedDPIFactor: 1
customRenderPipeline: {fileID: 0}
excludedTargetPlatforms: []
- serializedVersion: 2
name: Ultra
pixelLightCount: 4
shadows: 2
shadowResolution: 2
shadowProjection: 1
shadowCascades: 4
shadowDistance: 150
shadowNearPlaneOffset: 3
shadowCascade2Split: 0.33333334
shadowCascade4Split: {x: 0.06666667, y: 0.2, z: 0.46666667}
shadowmaskMode: 1
skinWeights: 255
textureQuality: 0
anisotropicTextures: 2
antiAliasing: 2
softParticles: 1
softVegetation: 1
realtimeReflectionProbes: 1
billboardsFaceCameraPosition: 1
vSyncCount: 0
lodBias: 2
maximumLODLevel: 0
streamingMipmapsActive: 0
streamingMipmapsAddAllCameras: 1
streamingMipmapsMemoryBudget: 512
streamingMipmapsRenderersPerFrame: 512
streamingMipmapsMaxLevelReduction: 2
streamingMipmapsMaxFileIORequests: 1024
particleRaycastBudget: 4096
asyncUploadTimeSlice: 2
asyncUploadBufferSize: 16
asyncUploadPersistentBuffer: 1
resolutionScalingFixedDPIFactor: 1
customRenderPipeline: {fileID: 0}
excludedTargetPlatforms: []
m_PerPlatformDefaultQuality:
Android: 2
BJM: 5
Lumin: 5
Nintendo Switch: 5
PS4: 5
Standalone: 5
WebGL: 3
Windows Store Apps: 5
XboxOne: 5
iPhone: 2
tvOS: 2

View File

@ -0,0 +1,167 @@
{
"templatePinStates": [],
"dependencyTypeInfos": [
{
"userAdded": false,
"type": "UnityEngine.AnimationClip",
"ignore": false,
"defaultInstantiationMode": 0,
"supportsModification": true
},
{
"userAdded": false,
"type": "UnityEditor.Animations.AnimatorController",
"ignore": false,
"defaultInstantiationMode": 0,
"supportsModification": true
},
{
"userAdded": false,
"type": "UnityEngine.AnimatorOverrideController",
"ignore": false,
"defaultInstantiationMode": 0,
"supportsModification": true
},
{
"userAdded": false,
"type": "UnityEditor.Audio.AudioMixerController",
"ignore": false,
"defaultInstantiationMode": 0,
"supportsModification": true
},
{
"userAdded": false,
"type": "UnityEngine.ComputeShader",
"ignore": true,
"defaultInstantiationMode": 1,
"supportsModification": true
},
{
"userAdded": false,
"type": "UnityEngine.Cubemap",
"ignore": false,
"defaultInstantiationMode": 0,
"supportsModification": true
},
{
"userAdded": false,
"type": "UnityEngine.GameObject",
"ignore": false,
"defaultInstantiationMode": 0,
"supportsModification": true
},
{
"userAdded": false,
"type": "UnityEditor.LightingDataAsset",
"ignore": false,
"defaultInstantiationMode": 0,
"supportsModification": false
},
{
"userAdded": false,
"type": "UnityEngine.LightingSettings",
"ignore": false,
"defaultInstantiationMode": 0,
"supportsModification": true
},
{
"userAdded": false,
"type": "UnityEngine.Material",
"ignore": false,
"defaultInstantiationMode": 0,
"supportsModification": true
},
{
"userAdded": false,
"type": "UnityEditor.MonoScript",
"ignore": true,
"defaultInstantiationMode": 1,
"supportsModification": true
},
{
"userAdded": false,
"type": "UnityEngine.PhysicMaterial",
"ignore": false,
"defaultInstantiationMode": 0,
"supportsModification": true
},
{
"userAdded": false,
"type": "UnityEngine.PhysicsMaterial2D",
"ignore": false,
"defaultInstantiationMode": 0,
"supportsModification": true
},
{
"userAdded": false,
"type": "UnityEngine.Rendering.PostProcessing.PostProcessProfile",
"ignore": false,
"defaultInstantiationMode": 0,
"supportsModification": true
},
{
"userAdded": false,
"type": "UnityEngine.Rendering.PostProcessing.PostProcessResources",
"ignore": false,
"defaultInstantiationMode": 0,
"supportsModification": true
},
{
"userAdded": false,
"type": "UnityEngine.Rendering.VolumeProfile",
"ignore": false,
"defaultInstantiationMode": 0,
"supportsModification": true
},
{
"userAdded": false,
"type": "UnityEditor.SceneAsset",
"ignore": false,
"defaultInstantiationMode": 0,
"supportsModification": false
},
{
"userAdded": false,
"type": "UnityEngine.Shader",
"ignore": true,
"defaultInstantiationMode": 1,
"supportsModification": true
},
{
"userAdded": false,
"type": "UnityEngine.ShaderVariantCollection",
"ignore": true,
"defaultInstantiationMode": 1,
"supportsModification": true
},
{
"userAdded": false,
"type": "UnityEngine.Texture",
"ignore": false,
"defaultInstantiationMode": 0,
"supportsModification": true
},
{
"userAdded": false,
"type": "UnityEngine.Texture2D",
"ignore": false,
"defaultInstantiationMode": 0,
"supportsModification": true
},
{
"userAdded": false,
"type": "UnityEngine.Timeline.TimelineAsset",
"ignore": false,
"defaultInstantiationMode": 0,
"supportsModification": true
}
],
"defaultDependencyTypeInfo": {
"userAdded": false,
"type": "<default_scene_template_dependencies>",
"ignore": false,
"defaultInstantiationMode": 1,
"supportsModification": true
},
"newSceneOverride": 0
}

View File

@ -0,0 +1,19 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!114 &1
MonoBehaviour:
m_ObjectHideFlags: 53
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: de02f9e1d18f588468e474319d09a723, type: 3}
m_Name:
m_EditorClassIdentifier: Unity.ShaderGraph.Editor::UnityEditor.ShaderGraph.ShaderGraphProjectSettings
shaderVariantLimit: 2048
overrideShaderVariantLimit: 0
customInterpolatorErrorThreshold: 32
customInterpolatorWarningThreshold: 16
customHeatmapValues: {fileID: 0}

View File

@ -0,0 +1,46 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!78 &1
TagManager:
serializedVersion: 2
tags:
- ground
- road_mesh
- pathNode
layers:
- Default
- TransparentFX
- Ignore Raycast
-
- Water
- UI
-
-
- CarName
- Ignore Lidar
- OverHead
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
m_SortingLayers:
- name: Default
uniqueID: 0
locked: 0

View File

@ -0,0 +1,9 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!5 &1
TimeManager:
m_ObjectHideFlags: 0
Fixed Timestep: 0.01
Maximum Allowed Timestep: 0.1
m_TimeScale: 1
Maximum Particle Timestep: 0.03

View File

@ -0,0 +1,15 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!114 &1
MonoBehaviour:
m_ObjectHideFlags: 61
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: a287be6c49135cd4f9b2b8666c39d999, type: 3}
m_Name:
m_EditorClassIdentifier:
assetDefaultFramerate: 60

View File

@ -0,0 +1,15 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!114 &1
MonoBehaviour:
m_ObjectHideFlags: 61
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: 247994e1f5a72c2419c26a37e9334c01, type: 3}
m_Name:
m_EditorClassIdentifier:
m_LastMaterialVersion: 4

View File

@ -0,0 +1,36 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!310 &1
UnityConnectSettings:
m_ObjectHideFlags: 0
serializedVersion: 1
m_Enabled: 0
m_TestMode: 0
m_EventOldUrl: https://api.uca.cloud.unity3d.com/v1/events
m_EventUrl: https://cdp.cloud.unity3d.com/v1/events
m_ConfigUrl: https://config.uca.cloud.unity3d.com
m_DashboardUrl: https://dashboard.unity3d.com
m_TestInitMode: 0
CrashReportingSettings:
m_EventUrl: https://perf-events.cloud.unity3d.com
m_Enabled: 0
m_LogBufferSize: 10
m_CaptureEditorExceptions: 1
UnityPurchasingSettings:
m_Enabled: 0
m_TestMode: 0
UnityAnalyticsSettings:
m_Enabled: 0
m_TestMode: 0
m_InitializeOnStartup: 1
m_PackageRequiringCoreStatsPresent: 0
UnityAdsSettings:
m_Enabled: 0
m_InitializeOnStartup: 1
m_TestMode: 0
m_IosGameId:
m_AndroidGameId:
m_GameIds: {}
m_GameId:
PerformanceReportingSettings:
m_Enabled: 0

View File

@ -0,0 +1,14 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!937362698 &1
VFXManager:
m_ObjectHideFlags: 0
m_IndirectShader: {fileID: 0}
m_CopyBufferShader: {fileID: 0}
m_SortShader: {fileID: 0}
m_StripUpdateShader: {fileID: 0}
m_RenderPipeSettingsPath:
m_FixedTimeStep: 0.016666668
m_MaxDeltaTime: 0.05
m_CompiledVersion: 0
m_RuntimeVersion: 0

View File

@ -0,0 +1,8 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!890905787 &1
VersionControlSettings:
m_ObjectHideFlags: 0
m_Mode: Visible Meta Files
m_CollabEditorSettings:
inProgressEnabled: 1

View File

@ -0,0 +1,10 @@
{
"m_SettingKeys": [
"VR Device Disabled",
"VR Device User Alert"
],
"m_SettingValues": [
"False",
"False"
]
}

45
README.md Normal file
View File

@ -0,0 +1,45 @@
# sdsandbox-rl-scripts
Modified C# scripts for the sdsandbox Unity simulator, used with the
[donkeycar-rl-autoresearch](https://paje.ca/git/paulh/donkeycar-rl-autoresearch) project.
## What's here
- `Scripts/` — all C# scripts from `sdsim/Assets/Scripts/`, including our RL training modifications
- `ProjectSettings/` — Unity project settings
- `Packages/` — Unity package manifest
## Key modifications (vs upstream tawnkramer/sdsandbox)
- **`Car.cs`** — per-wheel OverlapSphere barrier collision detection; CCD mode
- **`TcpCarHandler.cs`** — `regen_road` message support with direct RoadBuilder+PathManager fallback when no TrainingManager present; `set_ai_text` overlay message
- **`PathManager.cs`** — self-intersection fix: retry loop with XZ segment-segment math (up to 20 retries)
- **`RoadBuilder.cs`** — BoxCollider per segment with overlap; `showBarrierMeshes` flag
- **`MapOverlay.cs`** — minimap refresh on road node position change (not just count)
## Setup on a new machine
1. Clone the upstream sdsandbox (provides all binary assets Unity needs):
```bash
git clone https://github.com/tawnkramer/sdsandbox
```
2. Clone this repo:
```bash
git clone git@paje.ca:paulh/sdsandbox-rl-scripts.git
```
3. Overlay our scripts into the sdsandbox project:
```bash
cp -r sdsandbox-rl-scripts/Scripts/* sdsandbox/sdsim/Assets/Scripts/
cp -r sdsandbox-rl-scripts/ProjectSettings/* sdsandbox/sdsim/ProjectSettings/
cp -r sdsandbox-rl-scripts/Packages/* sdsandbox/sdsim/Packages/
```
4. Open `sdsandbox/sdsim` in Unity 6000.4.4f1. Unity will reimport assets on first open.
5. Build: **Edit → Project Settings → Player Builder → WinBuild** (or use the batch build command from the donkeycar-rl-autoresearch SESSION_HANDOFF.md).
## Unity version
**Unity 6000.4.4f1** — other versions are not tested and may have incompatible APIs.

379
Scripts/Car.cs Executable file
View File

@ -0,0 +1,379 @@
using UnityEngine;
using System.Collections;
public class Car : MonoBehaviour, ICar{
public CarSpawner carSpawner;
public WheelCollider[] wheelColliders;
public Transform[] wheelMeshes;
public float maxSpeed = 30f;
public float maxTorque = 50f;
public float maxBreakTorque = 50f;
public AnimationCurve torqueCurve;
public Transform centrOfMass;
public float requestTorque = 0f;
public float requestBrake = 0f;
public float requestSteering = 0f;
public Vector3 acceleration = Vector3.zero;
public Vector3 velocity = Vector3.zero;
public Vector3 prevVel = Vector3.zero;
public Vector3 startPos;
public Quaternion startRot;
private Quaternion rotation = Quaternion.identity;
private Vector3 gyro = Vector3.zero;
public Rigidbody rb;
//for logging
public float lastSteer = 0.0f;
public float lastAccel = 0.0f;
//when the car is doing multiple things, we sometimes want to sort out parts of the training
//use this label to pull partial training samples from a run
public string activity = "keep_lane";
public float maxSteer = 16.0f;
//name of the last object we hit.
public string last_collision = "none";
private float last_collision_time = -999f;
private const float collision_hold_seconds = 0.75f;
// Pre-allocated buffer for per-wheel barrier overlap checks (avoids GC per frame).
private Collider[] _wheelOverlapBuf = new Collider[8];
// Use this for initialization
void Awake ()
{
rb = GetComponent<Rigidbody>();
if(rb && centrOfMass)
{
rb.centerOfMass = centrOfMass.localPosition;
}
// Continuous collision detection prevents the car from tunnelling through
// thin or fast-moving colliders (including barrier walls) between frames.
if (rb)
rb.collisionDetectionMode = CollisionDetectionMode.Continuous;
requestTorque = 0f;
requestSteering = 0f;
SavePosRot();
// had to disable this because PID max steering was affecting the global max_steering
// maxSteer = PlayerPrefs.GetFloat("max_steer", 16.0f);
}
public void SavePosRot()
{
startPos = transform.position;
startRot = transform.rotation;
}
public void RestorePosRot()
{
Set(startPos, startRot);
}
public void RequestThrottle(float val)
{
requestTorque = val;
requestBrake = 0f;
//Debug.Log("request throttle: " + val);
}
public void SetMaxSteering(float val)
{
maxSteer = val;
// had to disable this because PID max steering was affecting the global max_steering
// PlayerPrefs.SetFloat("max_steer", maxSteer);
// PlayerPrefs.Save();
}
public float GetMaxSteering()
{
return maxSteer;
}
public void RequestSteering(float val)
{
requestSteering = Mathf.Clamp(val, -maxSteer, maxSteer);
//Debug.Log("request steering: " + val);
}
public void Set(Vector3 pos, Quaternion rot)
{
rb.position = pos;
rb.rotation = rot;
//just setting it once doesn't seem to work. Try setting it multiple times..
StartCoroutine(KeepSetting(pos, rot, 1));
}
IEnumerator KeepSetting(Vector3 pos, Quaternion rot, int numIter)
{
while(numIter > 0)
{
rb.isKinematic = true;
yield return new WaitForFixedUpdate();
rb.position = pos;
rb.rotation = rot;
transform.position = pos;
transform.rotation = rot;
numIter--;
rb.isKinematic = false;
}
}
public float GetSteering()
{
return requestSteering;
}
public float GetThrottle()
{
return requestTorque;
}
public float GetFootBrake()
{
return requestBrake;
}
public float GetHandBrake()
{
return 0.0f;
}
public Vector3 GetVelocity()
{
return velocity;
}
public Vector3 GetAccel()
{
return acceleration;
}
public Vector3 GetGyro()
{
return gyro;
}
public float GetOrient ()
{
Vector3 dir = transform.forward;
return Mathf.Atan2( dir.z, dir.x);
}
public Transform GetTransform()
{
return this.transform;
}
public bool IsStill()
{
return rb.IsSleeping();
}
public void RequestFootBrake(float val)
{
requestBrake = val;
}
public void RequestHandBrake(float val)
{
//todo
}
// Update is called once per frame
void Update () {
UpdateWheelPositions();
}
public string GetActivity()
{
return activity;
}
public void SetActivity(string act)
{
activity = act;
}
void FixedUpdate()
{
lastSteer = requestSteering;
lastAccel = requestTorque;
prevVel = velocity;
velocity = transform.InverseTransformDirection(rb.velocity);
acceleration = (velocity - prevVel)/Time.deltaTime;
gyro = rb.angularVelocity;
rotation = rb.rotation;
// use the torque curve
float throttle = torqueCurve.Evaluate(velocity.magnitude / maxSpeed) * requestTorque * maxTorque;
float steerAngle = requestSteering;
float brake = requestBrake * maxBreakTorque;
//front two tires.
wheelColliders[2].steerAngle = steerAngle;
wheelColliders[3].steerAngle = steerAngle;
//four wheel drive at the moment
foreach(WheelCollider wc in wheelColliders)
{
wc.motorTorque = throttle;
wc.brakeTorque = brake;
}
// WheelColliders don't fire OnCollisionStay on this MonoBehaviour. We use
// two complementary checks to catch barrier contact from any angle:
//
// 1) Forward raycast — probes ahead of the car even before contact occurs,
// so it fires quickly when driving into a barrier nose-first.
if (requestTorque > 0.05f)
{
Vector3 rayOrigin = transform.position + transform.up * 0.3f;
RaycastHit rhit;
if (Physics.Raycast(rayOrigin, transform.forward, out rhit, 0.8f))
{
if (!IsStartingLine(rhit.collider.gameObject.name))
RegisterCollision(rhit.collider.gameObject.name);
}
}
// 2) Per-wheel OverlapSphere — catches actual contact from any direction
// (side, rear, diagonal) regardless of throttle or car orientation.
// Uses barrier name filter to avoid false positives from the road surface.
foreach (WheelCollider wc in wheelColliders)
{
Vector3 wheelCenter;
Quaternion wheelRot;
wc.GetWorldPose(out wheelCenter, out wheelRot);
int n = Physics.OverlapSphereNonAlloc(wheelCenter, wc.radius + 0.05f, _wheelOverlapBuf);
for (int i = 0; i < n; i++)
{
if (_wheelOverlapBuf[i] == null) continue;
string hitName = _wheelOverlapBuf[i].gameObject.name;
if (hitName.Contains("barrier"))
{
RegisterCollision(hitName);
break;
}
}
}
}
void FlipUpright()
{
Quaternion rot = Quaternion.Euler(180f, 0f, 0f);
this.transform.rotation = transform.rotation * rot;
transform.position = transform.position + Vector3.up * 2;
}
void UpdateWheelPositions()
{
Quaternion rot;
Vector3 pos;
for(int i = 0; i < wheelColliders.Length; i++)
{
WheelCollider wc = wheelColliders[i];
Transform tm = wheelMeshes[i];
wc.GetWorldPose(out pos, out rot);
tm.position = pos;
tm.rotation = rot;
}
}
//get the name of the last object we collided with
public string GetLastCollision()
{
return last_collision;
}
public void ClearLastCollision()
{
if (Time.time - last_collision_time > collision_hold_seconds)
{
last_collision = "none";
}
}
bool ShouldPersistCollision(string collisionName, float speedMagnitude)
{
if (speedMagnitude < 1.5f)
{
return true;
}
string lowered = collisionName.ToLowerInvariant();
return lowered.Contains("barrier") || lowered.Contains("tree") || lowered.Contains("wall");
}
// The starting/finish line is a physical collider used for lap counting.
// It must not be treated as a barrier hit — lap counting is handled separately
// via the collision_with_starting_line TCP message in TcpCarHandler.
bool IsStartingLine(string objectName)
{
string lower = objectName.ToLowerInvariant();
return lower.Contains("starting_line") || lower.Contains("startingline") || lower.Contains("finishline");
}
void RegisterCollision(string collisionName)
{
last_collision = collisionName;
last_collision_time = Time.time;
}
void OnCollisionEnter(Collision col)
{
if (IsStartingLine(col.gameObject.name)) return;
RegisterCollision(col.gameObject.name);
}
void OnCollisionStay(Collision col)
{
if (IsStartingLine(col.gameObject.name)) return;
float speedMagnitude = (rb != null) ? rb.velocity.magnitude : 0.0f;
if (ShouldPersistCollision(col.gameObject.name, speedMagnitude))
{
RegisterCollision(col.gameObject.name);
}
}
// Trigger-based barriers (used by built-in tracks like mini-monaco) fire
// OnTriggerEnter rather than OnCollisionEnter. Handle them here so that
// out-of-bounds detection works on all tracks, not just our custom ones.
void OnTriggerEnter(Collider other)
{
if (IsStartingLine(other.gameObject.name)) return;
RegisterCollision(other.gameObject.name);
}
void OnTriggerStay(Collider other)
{
if (IsStartingLine(other.gameObject.name)) return;
float speedMagnitude = (rb != null) ? rb.velocity.magnitude : 0.0f;
if (ShouldPersistCollision(other.gameObject.name, speedMagnitude))
{
RegisterCollision(other.gameObject.name);
}
}
}

12
Scripts/Car.cs.meta Executable file
View File

@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: ab3484103f28341d0a2099af385e1610
timeCreated: 1448832312
licenseType: Free
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

48
Scripts/CarBodyStyle.cs Executable file
View File

@ -0,0 +1,48 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class CarBodyStyle : MonoBehaviour
{
public GameObject[] bodyParts;
// sometimes, object can have multiple material, here we are specifying witch one we want to modify
public string[] material_name;
private int mat_idx = 0;
public void ApplyColor(Color col)
{
for (int i = 0; i < bodyParts.Length; i++)
{
GameObject part = bodyParts[i];
Renderer rend = part.GetComponent<Renderer>();
Material[] materials = rend.materials;
if (i < material_name.Length && i < materials.Length)
{
mat_idx = SearchMaterial(materials, material_name[i]);
}
else
{
mat_idx = 0;
}
// Debug.Log("mat name: " + materials[mat_idx].name);
materials[mat_idx].SetColor("_Color", col);
}
}
public int SearchMaterial(Material[] materials, string name)
{
if (name == "default")
return 0;
// search for the material requested name
for (int idx = 0; idx < materials.Length; idx++)
{
// Debug.Log(materials[idx].name + " " + name);
if (materials[idx].name == name + " (Instance)")
return idx;
}
return 0;
}
}

11
Scripts/CarBodyStyle.cs.meta Executable file
View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 0fb12741290ca1d4998921501601a696
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

78
Scripts/CarConfig.cs Executable file
View File

@ -0,0 +1,78 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class CarConfig : MonoBehaviour
{
public GameObject bodyStyles;
public GameObject car_name_base;
public GameObject OverheadViewSphere;
public TextMesh car_name_text;
public Timer timer;
public void SetStyle(string body_style, int r, int g, int b, string car_name, int font_size)
{
Debug.Log("Setting car config.");
if (car_name.Length > 1)
{
car_name_base.SetActive(true);
car_name_text.text = car_name;
car_name_text.fontSize = font_size;
transform.name = car_name; // rename the gameobject name
}
if (timer != null)
{
timer.racerName = car_name;
}
else
{
Debug.LogError("timer not found while mapping racer name");
}
Color col = new Color();
col.r = r / 255.0f;
col.g = g / 255.0f;
col.b = b / 255.0f;
Renderer rend = OverheadViewSphere.GetComponent<Renderer>();
Material[] materials = rend.materials;
materials[0].SetColor("_Color", col);
GameObject bodyStyle;
for (int i = 0; i < bodyStyles.transform.childCount; i++) // go through each bodyStyles to find the desired body style
{
bodyStyle = bodyStyles.transform.GetChild(i).gameObject;
if (bodyStyle.name == body_style) // check if it's the requested body style
{
bodyStyle.SetActive(true);
var carBodyStyle = bodyStyle.GetComponent<CarBodyStyle>();
if (carBodyStyle != null)
{
carBodyStyle.ApplyColor(col);
}
else
{
Debug.LogWarning(bodyStyle.name + " doesn't have a CarBodyStyle component");
}
return;
}
else // else just make sure it's disabled
{
bodyStyle.SetActive(false);
}
}
Debug.LogWarning("body_style not in list of available bodyStyles, using default one instead");
GameObject defaultBodyStyle = bodyStyles.transform.GetChild(0).gameObject;
var defaultCarBodyStyle = defaultBodyStyle.GetComponent<CarBodyStyle>();
if (defaultCarBodyStyle != null)
{
defaultBodyStyle.SetActive(true);
defaultCarBodyStyle.ApplyColor(col);
}
}
}

11
Scripts/CarConfig.cs.meta Executable file
View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 18637ebcb2c9a94dc9974c66102fb75c
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

47
Scripts/CarModel.cs Executable file
View File

@ -0,0 +1,47 @@
using UnityEngine;
using System.Collections;
public class CarModel
{
public Vector3 pos = Vector3.zero;
public float length = 1f;
public float orientation = 0f; //radians rot about Y
public void SetLength(float val)
{
length = val;
}
public void Set(Vector3 p, float o)
{
pos = p;
orientation = o;
}
public CarModel move(float distMove, float angleTurn)
{
CarModel newMod = new CarModel();
newMod.pos = pos;
newMod.length = length;
newMod.orientation = orientation;
float theta = orientation;
if(angleTurn < 0.001f)
{
newMod.pos.x += distMove * Mathf.Cos(theta);
newMod.pos.z += distMove * Mathf.Sin(theta);
}
else
{
float Beta = distMove / length * Mathf.Tan( angleTurn );
float R = distMove / Beta;
float cx = pos.x - Mathf.Sin(theta) * R;
float cz = pos.z + Mathf.Cos(theta) * R;
newMod.pos.x = cx + Mathf.Sin(theta + Beta) * R;
newMod.pos.z = cz - Mathf.Cos(theta + Beta) * R;
newMod.orientation = theta + Beta;
}
return newMod;
}
}

12
Scripts/CarModel.cs.meta Executable file
View File

@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 2ad110fb87d4845daac10710224235c8
timeCreated: 1449523174
licenseType: Free
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

163
Scripts/CarPath.cs Executable file
View File

@ -0,0 +1,163 @@
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using UnityEngine.AI;
public class PathNode
{
public Vector3 pos;
public Quaternion rotation;
public string activity;
}
public class CarPath
{
public List<PathNode> nodes;
public List<PathNode> centerNodes;
public NavMeshPath navMeshPath;
public int iActiveSpan = 0;
public CarPath()
{
nodes = new List<PathNode>();
centerNodes = new List<PathNode>();
navMeshPath = new NavMeshPath();
}
public int GetClosestSpanIndex(Vector3 carPos)
{
float minDistance = float.MaxValue;
int minDistanceIndex = -1;
for (int i = 0; i < nodes.Count; i++)
{
float dist = Vector3.Distance(nodes[i].pos, carPos);
if (dist < minDistance)
{
minDistance = dist;
minDistanceIndex = i;
}
}
return minDistanceIndex;
}
public PathNode GetNode(int index)
{
if (index < nodes.Count)
return nodes[index];
return null;
}
public void SmoothPath(float factor = 0.5f)
{
LineSeg3d.SegResult segRes = new LineSeg3d.SegResult();
for (int iN = 1; iN < nodes.Count - 2; iN++)
{
PathNode p = nodes[iN - 1];
PathNode c = nodes[iN];
PathNode n = nodes[iN + 1];
LineSeg3d seg = new LineSeg3d(ref p.pos, ref n.pos);
Vector3 closestP = seg.ClosestPointOnSegmentTo(ref c.pos, ref segRes);
Vector3 dIntersect = closestP - c.pos;
c.pos += dIntersect.normalized * factor;
}
}
public double getDistance(Vector3 currentPosition, Vector3 target)
{
double distance = 0.0;
if (NavMesh.CalculatePath(currentPosition, target, NavMesh.AllAreas, this.navMeshPath))
{
if (this.navMeshPath.corners.Length > 5)
{
//ignore the first corners -> more stable
distance += (this.navMeshPath.corners[2] - currentPosition).magnitude;
for (int i = 3; i < this.navMeshPath.corners.Length; i++)
{
Vector3 start = this.navMeshPath.corners[i - 1];
Vector3 end = this.navMeshPath.corners[i];
distance += (end - start).magnitude;
}
}
}
return distance;
}
public bool GetCrossTrackErr(Vector3 pos, ref int iActiveSpan, ref float err, int lookAhead = 1)
{
int nextIActiveSpan = (iActiveSpan + 1) % (nodes.Count);
int aheadIActiveSpan = (iActiveSpan + lookAhead) % (nodes.Count);
PathNode a = nodes[iActiveSpan];
PathNode b = nodes[nextIActiveSpan];
PathNode c = nodes[aheadIActiveSpan];
//2d path.
pos.y = a.pos.y;
LineSeg3d pathSeg = new LineSeg3d(ref a.pos, ref c.pos);
LineSeg3d.SegResult segRes = new LineSeg3d.SegResult();
Vector3 closePt = pathSeg.ClosestPointOnSegmentTo(ref pos, ref segRes);
Vector3 errVec = pathSeg.ClosestVectorTo(ref pos);
pathSeg.Draw(Color.green);
Debug.DrawLine(a.pos, closePt, Color.blue);
Debug.DrawRay(closePt, errVec, Color.white);
float sign = 1.0f;
Vector3 cp = Vector3.Cross(pathSeg.m_dir.normalized, errVec.normalized);
if (cp.y > 0.0f)
sign = -1f;
err = errVec.magnitude * sign;
int oldActiveSpan = iActiveSpan ;
float dista = Vector3.Distance(a.pos, pos);
float distb = Vector3.Distance(b.pos, pos);
if (dista > distb)
{
iActiveSpan = (iActiveSpan + 1) % (nodes.Count);
}
// if (iActiveSpan - oldActiveSpan <= 0) { return true; } // we lapped
return false; // we are on the same lap
}
public (float xmin, float xmax, float ymin, float ymax, float zmin, float zmax) GetPathBounds()
{
(float xmin, float xmax, float ymin, float ymax, float zmin, float zmax) bounds;
bounds.xmin = bounds.ymin = bounds.zmin = float.MaxValue;
bounds.xmax = bounds.ymax = bounds.zmax = float.MinValue;
foreach (PathNode node in centerNodes)
{
Vector3 pos = node.pos;
float x = pos.x;
float y = pos.y;
float z = pos.z;
if (x < bounds.xmin)
bounds.xmin = x;
if (x > bounds.xmax)
bounds.xmax = x;
if (y < bounds.ymin)
bounds.ymin = y;
if (y > bounds.ymax)
bounds.ymax = y;
if (z < bounds.zmin)
bounds.zmin = z;
if (z > bounds.zmax)
bounds.zmax = z;
}
return bounds;
}
}

12
Scripts/CarPath.cs.meta Executable file
View File

@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 71b3d88cc247f4490bbdc990e9941183
timeCreated: 1449527982
licenseType: Free
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

51
Scripts/CarPusher.cs Executable file
View File

@ -0,0 +1,51 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class CarPusher : MonoBehaviour {
public Car car;
public float amountToPushSideways = 1.0f;
public float amountToRotate = 10.0f;
public float durationTillNextPush = 3.0f;
public bool doPush = true;
public bool doRotate = true;
float timer = 0.0f;
// Use this for initialization
void Start () {
timer = durationTillNextPush - 1.0f;
}
void PushCar()
{
Vector3 sideVec = car.gameObject.transform.right.normalized;
float randScale = Random.Range( -1f * amountToPushSideways, amountToPushSideways);
car.transform.position = car.transform.position + (sideVec * randScale);
}
void RotateCar()
{
float randRot = Random.Range( -1f * amountToRotate, amountToRotate);
Quaternion rotY = Quaternion.Euler(0.0f, randRot, 0.0f);
car.transform.rotation = car.transform.rotation * rotY;
}
// Update is called once per frame
void Update ()
{
timer += Time.deltaTime;
if(timer > durationTillNextPush)
{
timer = 0.0f;
if(doPush)
PushCar();
if(doRotate)
RotateCar();
}
}
}

12
Scripts/CarPusher.cs.meta Executable file
View File

@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 4a4f2387b0f594d808f4ade6f32da6ed
timeCreated: 1482953591
licenseType: Free
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

528
Scripts/CarSpawner.cs Executable file
View File

@ -0,0 +1,528 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using tk;
using System;
public class CarSpawner : MonoBehaviour
{
public PathManager pathManager;
public GameObject carPrefab;
public Transform[] startsTm; // list containing multiple starting points
public bool EnableTrainingManager = false;
public delegate void OnNewCar(GameObject carObj);
public OnNewCar OnNewCarCB;
public int numCarRows = 2;
public float distCarCols = 4.5f;
public float distCarRows = 5f;
public GameObject mainCamera;
public GameObject splitScreenCamPrefab;
public GameObject splitScreenOHCamPrefab;
public int SplitScreenWidth = 2;
public RaceCameras raceCameras;
public GameObject racerStatusPrefab;
public RectTransform raceStatusPanel;
int raceStatusWidth = 380;
int raceStatusHeight = 100;
int n_columns = 2; // number of columns in the RaceStatus panel
public List<GameObject> cars = new List<GameObject>();
public List<GameObject> cameras = new List<GameObject>();
static public GameObject getChildGameObject(GameObject fromGameObject, string withName)
{
//Author: Isaac Dart, June-13.
Transform[] ts = fromGameObject.transform.GetComponentsInChildren<Transform>(true);
foreach (Transform t in ts) if (t.gameObject.name == withName) return t.gameObject;
Debug.LogError("couldn't find: " + withName);
return null;
}
// Find the car for the given JsonTcpClient and remove it from the scene.
public bool RemoveCar(tk.JsonTcpClient client)
{
GameObject toRemove = null;
foreach (GameObject go in cars)
{
GameObject TcpClientObj = getChildGameObject(go, "TCPClient");
if (TcpClientObj != null)
{
tk.TcpCarHandler handler = TcpClientObj.GetComponent<tk.TcpCarHandler>();
if (handler != null && handler.GetClient() == client)
{
toRemove = go;
}
}
}
if (toRemove != null)
{
int iSplitScreenCam = cars.IndexOf(toRemove);
if (GlobalState.overheadCamera) { iSplitScreenCam += 1; }
if (raceCameras != null)
{
int carID = toRemove.GetInstanceID() - 4;
if (raceCameras.carProgress.ContainsKey(carID))
{
raceCameras.carProgress.Remove(carID);
}
}
RemoveTimer(toRemove);
cars.Remove(toRemove);
if (cameras.Count > iSplitScreenCam)
{
GameObject SplitScreenCamGo = cameras[iSplitScreenCam];
RemoveSplitScreenCam(SplitScreenCamGo);
}
GameObject.Destroy(toRemove);
Debug.Log("Removed car");
return true;
}
else
{
Debug.LogError("failed to remove car");
return false;
}
}
public void RemoveGhostCars()
{
foreach (GameObject car in cars)
{
tk.TcpCarHandler tcpCarHandler = car.GetComponentInChildren<tk.TcpCarHandler>();
if (tcpCarHandler != null && tcpCarHandler.IsGhostCar())
{
tcpCarHandler.Boot();
}
}
}
public void RemoveAllCars()
{
// Remove each car one by one
foreach (GameObject car in cars)
{
int i = cars.IndexOf(car);
if (raceCameras != null)
{
int carID = car.GetInstanceID() - 4;
if (raceCameras.carProgress.ContainsKey(carID))
{
raceCameras.carProgress.Remove(carID);
}
}
RemoveTimer(car);
cars.Remove(car);
if (cameras.Count > i)
{
GameObject SplitScreenCamGo = cameras[i + 1];
RemoveSplitScreenCam(SplitScreenCamGo);
}
GameObject.Destroy(car);
}
RemoveUiReferences();
}
void UpdateRaceStatusPannel()
{
int n_children = raceStatusPanel.transform.childCount;
int row = n_children;
if (row > n_columns)
row = n_columns;
int col = (n_children / n_columns) + (n_children % n_columns);
float width = row * raceStatusWidth;
float height = col * raceStatusHeight;
raceStatusPanel.SetSizeWithCurrentAnchors(RectTransform.Axis.Horizontal, width);
raceStatusPanel.SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical, height);
raceStatusPanel.anchoredPosition = new Vector3(8.0f, -1 * height, 0.0f);
}
public void AddTimer(Timer t, tk.JsonTcpClient client)
{
if (racerStatusPrefab == null)
return;
GameObject go = Instantiate(racerStatusPrefab) as GameObject;
RaceStatus rs = go.GetComponent<RaceStatus>();
rs.Init(t, client);
go.transform.SetParent(raceStatusPanel.transform);
go.transform.GetComponent<RectTransform>().localScale = raceStatusPanel.transform.localScale;
UpdateRaceStatusPannel(); // update the UI with the new child count
Debug.Log("Added timer");
}
public void RemoveTimer(GameObject go)
{
Timer timer = getChildGameObject(go, "Timer").GetComponent<Timer>();
if (timer != null && raceStatusPanel != null)
{
int count = raceStatusPanel.transform.childCount;
for (int i = 0; i < count; i++)
{
Transform child = raceStatusPanel.transform.GetChild(i);
RaceStatus rs = child.GetComponent<RaceStatus>();
if (rs.timer == timer)
{
child.transform.SetParent(null); // detach from parent
Destroy(child.gameObject); // destroy child
UpdateRaceStatusPannel(); // update the UI with the new child count
Debug.Log("removed timer");
return;
}
}
Debug.LogError("failed to find timer while removing it");
return;
}
Debug.LogError("failed to remove timer");
}
public void AddSplitScreenCam(int index)
{
if (cameras.Count < GlobalState.maxSplitScreen && !GlobalState.raceCameras)
{
if (index == 0 && GlobalState.overheadCamera)
{
GameObject splitScreenOHCamGo = Instantiate(splitScreenOHCamPrefab);
OverHeadCamera OHCam = splitScreenOHCamGo.GetComponent<OverHeadCamera>();
OHCam.pathManager = pathManager;
OHCam.Init();
cameras.Add(splitScreenOHCamGo);
}
else
{
GameObject splitScreenCamGo = Instantiate(splitScreenCamPrefab);
cameras.Add(splitScreenCamGo);
}
}
}
public void RemoveSplitScreenCam(GameObject splitScreenCamGo)
{
GameObject.Destroy(splitScreenCamGo);
cameras.Remove(splitScreenCamGo);
UpdateSplitScreenCams();
Debug.Log("removed split screen camera");
}
public void UpdateSplitScreenCams()
{
if (GlobalState.raceCameras)
{
if (mainCamera != null) { mainCamera.SetActive(false); }
return;
}
int num_cameras = cars.Count;
if (GlobalState.overheadCamera) { num_cameras += 1; }
if (num_cameras > GlobalState.maxSplitScreen) { num_cameras = GlobalState.maxSplitScreen; }
// check if the number of cameras match the number of cars
if ((cameras.Count != num_cameras))
{
// remove all cameras in there
foreach (GameObject splitScreenCamGo in cameras)
{
GameObject.Destroy(splitScreenCamGo);
}
cameras.Clear();
// and recreate some new ones
for (int i = 0; i < num_cameras; i++)
{
AddSplitScreenCam(i);
}
}
// for each camera, update the rect
for (int i = 0; i < num_cameras; i++)
{
if (i > 0 || !GlobalState.overheadCamera) // if the camera isn't overhead, assign a car to it
{
GameObject splitScreenCamGo = cameras[i];
GameObject car;
if (GlobalState.overheadCamera) { car = cars[i - 1]; }
else { car = cars[i]; }
// set target to the corresponding car
Camera splitScreenCam = splitScreenCamGo.GetComponent<Camera>();
DrawLidar dLidar = splitScreenCamGo.GetComponent<DrawLidar>();
dLidar.car = car;
CameraFollow cameraFollow = splitScreenCam.GetComponent<CameraFollow>();
cameraFollow.target = getChildGameObject(car, "CameraFollowTm").transform;
}
int x_index = i % SplitScreenWidth;
int y_index = i / SplitScreenWidth;
int number_in_row = Math.Min((cameras.Count - y_index * SplitScreenWidth), SplitScreenWidth);
int number_of_row = 1 + ((cameras.Count - 1) / SplitScreenWidth);
float w = 1 / (float)(number_in_row);
float h = 1 / (float)(number_of_row);
float x = (x_index) / (float)number_in_row;
float y = (y_index) / (float)number_of_row;
GameObject go = cameras[i];
Camera camera = go.GetComponent<Camera>();
camera.rect = new Rect(x, y, w, h);
if (GlobalState.overheadCamera && i == 0) { OverHeadCamera ohcam = go.GetComponent<OverHeadCamera>(); ohcam.Init(); }
}
if (cameras.Count == 0 && mainCamera != null && !GlobalState.raceCameras)
{
mainCamera.SetActive(true);
}
else if (mainCamera != null)
{
mainCamera.SetActive(false); // make sure we are disabling main camera to avoid background rendering
}
}
public void CarTextFacecamera(GameObject car, Transform target)
{
GameObject carNameObj = getChildGameObject(car, "CarName");
if (!carNameObj)
return;
FaceTarget ft = carNameObj.GetComponent<FaceTarget>();
if (!ft)
return;
ft.target = target;
}
public bool IsOccupied(Vector3 pos)
{
int carCount = cars.Count - 1;
for (int iCar = 0; iCar < carCount; iCar++)
{
GameObject go = cars[iCar];
Car car = go.GetComponent<Car>();
if (Vector3.Distance(car.startPos, pos) < 1.0f)
return true;
}
return false;
}
public (Vector3, Quaternion) GetStartPosRot(int iCar)
{
int iSpawn = iCar % startsTm.Length;
Transform spawn = startsTm[iSpawn];
Vector3 pos = spawn.position;
Quaternion rot = spawn.rotation;
int iCol = (iCar / startsTm.Length) % numCarRows;
int iRow = (iCar / startsTm.Length) / numCarRows;
Vector3 offset = Vector3.zero;
offset.z = -distCarRows * iRow;
offset.x = -distCarCols * iCol;
return (spawn.position + rot * offset, rot);
}
public (Vector3, Quaternion) GetCarStartPosRot()
{
Vector3 startPos = startsTm[0].position; // default position
Quaternion startRot = startsTm[0].rotation; // default rotation
if (IsOccupied(startPos))
{
int iCar = 0;
while (IsOccupied(startPos))
{
(startPos, startRot) = GetStartPosRot(iCar);
iCar++;
}
}
return (startPos, startRot);
}
public GameObject Spawn(tk.JsonTcpClient client, bool paceCar)
{
if (carPrefab == null)
{
Debug.LogError("No carPrefab set in CarSpawner!");
return null;
}
// Create a car object, and also hook up all the connections
// to various places in game that need to hook into the car.
GameObject go = GameObject.Instantiate(carPrefab) as GameObject;
if (go == null)
{
Debug.LogError("CarSpawner failed to instantiate prefab!");
return null;
}
cars.Add(go);
(Vector3 startPos, Quaternion startRot) = GetCarStartPosRot();
go.transform.SetPositionAndRotation(startPos, startRot);
go.GetComponent<Car>().SavePosRot();
UpdateSplitScreenCams();
GameObject TcpClientObj = getChildGameObject(go, "TCPClient");
// CarTextFacecamera(go, cam.transform);
if (TcpClientObj != null)
{
// without this it will not connect.
TcpClientObj.SetActive(true);
// now set the connection settings.
TcpCarHandler carHandler = TcpClientObj.GetComponent<TcpCarHandler>();
if (carHandler != null)
carHandler.Init(client);
}
if (OnNewCarCB != null)
OnNewCarCB.Invoke(go);
///////////////////////////////////////////////
// Search scene to find these.
MenuHandler menuHandler = GameObject.FindObjectOfType<MenuHandler>();
Canvas canvas = GameObject.FindObjectOfType<Canvas>();
GameObject panelMenu = getChildGameObject(canvas.gameObject, "Panel Menu");
GameObject pidPanel = getChildGameObject(canvas.gameObject, "PIDPanel");
///////////////////////////////////////////////
// set camera target follow tm
// Set menu handler hooks
if (menuHandler != null)
{
menuHandler.PIDContoller = getChildGameObject(go, "PIDController");
menuHandler.Logger = getChildGameObject(go, "Logger");
menuHandler.NetworkSteering = getChildGameObject(go, "TCPClient");
menuHandler.carJSControl = getChildGameObject(go, "JoyStickCarContoller");
menuHandler.trainingManager = getChildGameObject(go, "TrainingManager").GetComponent<TrainingManager>();
menuHandler.trainingManager.carObj = go;
if (EnableTrainingManager)
{
menuHandler.trainingManager.gameObject.SetActive(true);
getChildGameObject(go, "OverheadViewSphere").SetActive(true);
}
if (GlobalState.bAutoHideSceneMenu && panelMenu != null)
{
panelMenu.SetActive(false);
}
}
if (paceCar && !GlobalState.manualDriving)
{
GameObject pidController_go = getChildGameObject(go, "PIDController");
pidController_go.SetActive(true);
}
else if (paceCar && GlobalState.manualDriving)
{
GameObject jsController = getChildGameObject(go, "JoyStickCarContoller");
jsController.SetActive(true);
}
// Add race status, if possible.
GameObject to = getChildGameObject(go, "Timer");
if (to != null)
{
AddTimer(to.GetComponent<Timer>(), client);
}
else
{
Debug.LogError("failed to find Timer");
}
return go;
}
internal void EnsureOneCar()
{
// pace car doesn't always mean cars.Count = 0, so will need to refactor that
if (cars.Count == 0)
Spawn(null, GlobalState.paceCar);
}
public void RemoveUiReferences()
{
Camera cam = Camera.main;
///////////////////////////////////////////////
// Search scene to find these.
CameraFollow cameraFollow = cam.transform.GetComponent<CameraFollow>();
MenuHandler menuHandler = GameObject.FindObjectOfType<MenuHandler>();
Canvas canvas = GameObject.FindObjectOfType<Canvas>();
GameObject panelMenu = getChildGameObject(canvas.gameObject, "Panel Menu");
PID_UI pid_ui = null;
GameObject pidPanel = getChildGameObject(canvas.gameObject, "PIDPanel");
///////////////////////////////////////////////
if (pidPanel)
pid_ui = pidPanel.GetComponent<PID_UI>();
// set camera target follow tm
if (cameraFollow != null)
cameraFollow.target = null;
// Set menu handler hooks
if (menuHandler != null)
{
menuHandler.PIDContoller = null;
menuHandler.Logger = null;
menuHandler.NetworkSteering = null;
menuHandler.carJSControl = null;
menuHandler.trainingManager = null;
}
// Set the PID ui hooks
if (pid_ui != null)
{
pid_ui.pid = null;
pid_ui.logger = null;
}
}
}

11
Scripts/CarSpawner.cs.meta Executable file
View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: f7b37e7667e6449eb95452eb5655f48f
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

27
Scripts/CollisionSensor.cs Executable file
View File

@ -0,0 +1,27 @@
using UnityEngine;
using System.Collections;
public class CollisionSensor : MonoBehaviour {
public delegate void OnCollideCB(string objType);
public OnCollideCB collideCB;
public void OnCollisionEnter(Collision collision)
{
if(collideCB != null)
{
string objType = "none";
foreach (ContactPoint contact in collision.contacts)
{
objType = contact.otherCollider.gameObject.tag;
//Debug.DrawRay(contact.point, contact.normal, Color.white);
}
collideCB.Invoke(objType);
}
}
}

12
Scripts/CollisionSensor.cs.meta Executable file
View File

@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 3f04f1d47c6d243908093d88e03f355c
timeCreated: 1449512093
licenseType: Free
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

72
Scripts/DrawLidar.cs Executable file
View File

@ -0,0 +1,72 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class DrawLidar : MonoBehaviour
{
public Lidar lidar;
public GameObject car;
static Material lineMaterial;
void OnPostRender()
{
if (GlobalState.drawLidar == true)
{
if (car == null) { return; }
if (lidar == null)
{
lidar = car.GetComponentInChildren<Lidar>();
return;
}
else if (lidar.enabled == false) { return; }
Draw();
}
}
static void CreateLineMaterial()
{
if (!lineMaterial)
{
// Unity has a built-in shader that is useful for drawing
// simple colored things.
Shader shader = Shader.Find("Hidden/Internal-Colored");
lineMaterial = new Material(shader);
lineMaterial.hideFlags = HideFlags.HideAndDontSave;
// Turn on alpha blending
lineMaterial.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.SrcAlpha);
lineMaterial.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.OneMinusSrcAlpha);
// Turn backface culling off
lineMaterial.SetInt("_Cull", (int)UnityEngine.Rendering.CullMode.Off);
// Turn off depth writes
lineMaterial.SetInt("_ZWrite", 0);
}
}
public void Draw()
{
CreateLineMaterial();
lineMaterial.SetPass(0); // Apply the line material
GL.Begin(GL.LINES); // Draw lines
if (lidar.pointArr == null)
return;
Vector3 lidarPos = lidar.transform.position;
foreach (LidarPoint p in lidar.pointArr.points)
{
if (p == null)
continue;
GL.Color(new Color(1, 0, 0, 0.8F));
Vector3 ppoint = new Vector3(p.x, p.y, p.z) + lidarPos;
GL.Vertex3(lidarPos.x, lidarPos.y, lidarPos.z);
GL.Vertex3(ppoint.x, ppoint.y, ppoint.z);
}
GL.End();
}
}

11
Scripts/DrawLidar.cs.meta Executable file
View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: d34136b32b3d9f64fb84431d5f971b9e
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

9
Scripts/Editor.meta Executable file
View File

@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: 4873f492b6b4141b1be922502923dcee
folderAsset: yes
timeCreated: 1503686012
licenseType: Free
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:

38
Scripts/Editor/BundleBuilder.cs Executable file
View File

@ -0,0 +1,38 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
public class BundleBuilder : Editor
{
[MenuItem("Build/ Build All AssetsBundles")]
static void BuildAllAssetsBundles()
{
BuildTarget[] platforms = new BuildTarget[] { BuildTarget.StandaloneWindows64, BuildTarget.StandaloneLinux64, BuildTarget.StandaloneOSX };
foreach (BuildTarget platform in platforms)
{
BuildAssetBundles(platform);
}
}
[MenuItem("Build/ Build Active Target AssetsBundles")]
static void BuildCurrentTargetAssetsBundles()
{
BuildTarget platform = EditorUserBuildSettings.activeBuildTarget;
BuildAssetBundles(platform);
}
static void BuildAssetBundles(BuildTarget platform)
{
string path = System.IO.Path.Combine(System.IO.Directory.GetCurrentDirectory(), "Assets/AssetBundles/" + platform.ToString());
if (System.IO.Directory.Exists(path) == false)
{
System.IO.Directory.CreateDirectory(path);
Debug.LogFormat("creating directory {0}", path);
}
BuildPipeline.BuildAssetBundles(path, BuildAssetBundleOptions.ChunkBasedCompression, platform);
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 7ce8d5283b7d033478808c087bb7704d
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,19 @@
using UnityEngine;
using UnityEditor;
using System;
[CustomEditor(typeof(ConeChallenge))]
public class ConeChallengeEditor : Editor
{
public override void OnInspectorGUI()
{
DrawDefaultInspector();
ConeChallenge challenge = (ConeChallenge)target;
if (GUILayout.Button("Reset Challenge"))
{
challenge.ResetChallenge();
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 6d921735578446241a54a0dd088e0a5a
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,18 @@
using UnityEngine;
using UnityEditor;
using System;
[CustomEditor(typeof(LightChallenge))]
public class LightChallengeEditor : Editor
{
public override void OnInspectorGUI()
{
DrawDefaultInspector();
LightChallenge challenge = (LightChallenge)target;
if (GUILayout.Button("Reset Challenge"))
{
challenge.ResetChallenge();
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: fd73e76678e66e446ae14987ca82acc7
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

121
Scripts/Editor/PlayerBuilder.cs Executable file
View File

@ -0,0 +1,121 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
using UnityEditor.Build.Reporting;
public class PlayerBuilder : Editor
{
[MenuItem("Build/ Build Every Player")]
static void Build()
{
WinBuild();
MacBuild();
LinuxBuild();
}
[MenuItem("Build/ Build Windows Player")]
static void WinBuild()
{
EditorBuildSettingsScene[] scenes = EditorBuildSettings.scenes;
BuildReport report = BuildPipeline.BuildPlayer(scenes, "Builds/DonkeySimWin/donkey_sim.exe", BuildTarget.StandaloneWindows64, BuildOptions.None);
BuildSummary summary = report.summary;
if (summary.result == BuildResult.Succeeded)
{
Debug.Log("Build succeeded: " + summary.totalSize + " bytes");
string assetBundlePath = "Assets/AssetBundles/" + BuildTarget.StandaloneWindows64.ToString();
string destPath = "Builds/DonkeySimWin/donkey_sim_Data/StreamingAssets/";
if (System.IO.Directory.Exists(assetBundlePath))
{
CopyDirectory(assetBundlePath, destPath);
}
else
{
Debug.LogWarning("Asset bundle directory missing, skipping copy: " + assetBundlePath);
}
}
if (summary.result == BuildResult.Failed)
{
Debug.Log("Build failed");
}
}
[MenuItem("Build/ Build MacOS Player")]
static void MacBuild()
{
EditorBuildSettingsScene[] scenes = EditorBuildSettings.scenes;
BuildReport report = BuildPipeline.BuildPlayer(scenes, "Builds/DonkeySimMac/donkey_sim.app", BuildTarget.StandaloneOSX, BuildOptions.None);
BuildSummary summary = report.summary;
if (summary.result == BuildResult.Succeeded)
{
Debug.Log("Build succeeded: " + summary.totalSize + " bytes");
string assetBundlePath = "Assets/AssetBundles/" + BuildTarget.StandaloneOSX.ToString();
string destPath = "Builds/DonkeySimMac/donkey_sim.app/Contents/Resources/Data/StreamingAssets";
if (System.IO.Directory.Exists(assetBundlePath))
{
CopyDirectory(assetBundlePath, destPath);
}
else
{
Debug.LogWarning("Asset bundle directory missing, skipping copy: " + assetBundlePath);
}
}
if (summary.result == BuildResult.Failed)
{
Debug.Log("Build failed");
}
}
[MenuItem("Build/ Build Linux Player")]
static void LinuxBuild()
{
EditorBuildSettingsScene[] scenes = EditorBuildSettings.scenes;
BuildReport report = BuildPipeline.BuildPlayer(scenes, "Builds/DonkeySimLinux/donkey_sim.x86_64", BuildTarget.StandaloneLinux64, BuildOptions.None);
BuildSummary summary = report.summary;
if (summary.result == BuildResult.Succeeded)
{
Debug.Log("Build succeeded: " + summary.totalSize + " bytes");
string assetBundlePath = "Assets/AssetBundles/" + BuildTarget.StandaloneLinux64.ToString();
string destPath = "Builds/DonkeySimLinux/donkey_sim_Data/StreamingAssets";
if (System.IO.Directory.Exists(assetBundlePath))
{
CopyDirectory(assetBundlePath, destPath);
}
else
{
Debug.LogWarning("Asset bundle directory missing, skipping copy: " + assetBundlePath);
}
}
if (summary.result == BuildResult.Failed)
{
Debug.Log("Build failed");
}
}
static void CopyDirectory(string SourcePath, string DestinationPath)
{
if (!System.IO.Directory.Exists(DestinationPath)) { System.IO.Directory.CreateDirectory(DestinationPath); }
foreach (string dirPath in System.IO.Directory.GetDirectories(SourcePath, "*",
System.IO.SearchOption.AllDirectories))
System.IO.Directory.CreateDirectory(dirPath.Replace(SourcePath, DestinationPath));
foreach (string newPath in System.IO.Directory.GetFiles(SourcePath, "*.*",
System.IO.SearchOption.AllDirectories))
System.IO.File.Copy(newPath, newPath.Replace(SourcePath, DestinationPath), true);
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 0d217cd5ee5171749afe98509b2e1498
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,19 @@
using UnityEngine;
using UnityEditor;
using System;
[CustomEditor(typeof(RandAssetsChallenge))]
public class RandAssetsChallengeEditor : Editor
{
public override void OnInspectorGUI()
{
DrawDefaultInspector();
RandAssetsChallenge challenge = (RandAssetsChallenge)target;
if (GUILayout.Button("Reset Challenge"))
{
challenge.ResetChallenge();
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: f4ecfc59e1e41924a9e9d0ca85bb2cea
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,31 @@
using UnityEngine;
using UnityEditor;
using System;
[CustomEditor(typeof(RepeatObjectAlong))]
public class RepeatObjectAlongEditor : Editor
{
public override void OnInspectorGUI()
{
DrawDefaultInspector();
RepeatObjectAlong repeatObjectAlong = (RepeatObjectAlong)target;
if (GUILayout.Button("Generate Mesh (only at runtime)"))
{
repeatObjectAlong.Generate();
}
if (GUILayout.Button("Save Mesh"))
{
MeshFilter mf = repeatObjectAlong.GetComponent<MeshFilter>();
Mesh mesh = mf.sharedMesh;
if (mesh == null)
{
Debug.LogWarning("Mesh is null, creating a new one");
mesh = new Mesh();
}
AssetDatabase.CreateAsset(mesh, repeatObjectAlong.savePath);
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: ac720408aac926645a88c7df0f96e232
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,20 @@
using UnityEngine;
using UnityEditor;
using System;
[CustomEditor(typeof(RoadBuilder))]
public class RoadBuilderEditor : Editor
{
public override void OnInspectorGUI()
{
DrawDefaultInspector();
RoadBuilder roadBuilder = (RoadBuilder)target;
if (GUILayout.Button("Save Mesh") && roadBuilder.createdRoad != null)
{
MeshFilter mf = roadBuilder.createdRoad.GetComponent<MeshFilter>();
AssetDatabase.CreateAsset(mf.mesh, roadBuilder.savePath);
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 87400f6f678666347be1cbc8553f01c5
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

33
Scripts/Editor/UiTools.cs Executable file
View File

@ -0,0 +1,33 @@
using UnityEngine;
using System.Collections;
using UnityEditor;
public class UiTools : MonoBehaviour {
[MenuItem("UiHelpers/Anchors to Corners %[")]
static void AnchorsToCorners(){
RectTransform t = Selection.activeTransform as RectTransform;
RectTransform pt = Selection.activeTransform.parent as RectTransform;
if(t == null || pt == null) return;
Vector2 newAnchorsMin = new Vector2(t.anchorMin.x + t.offsetMin.x / pt.rect.width,
t.anchorMin.y + t.offsetMin.y / pt.rect.height);
Vector2 newAnchorsMax = new Vector2(t.anchorMax.x + t.offsetMax.x / pt.rect.width,
t.anchorMax.y + t.offsetMax.y / pt.rect.height);
t.anchorMin = newAnchorsMin;
t.anchorMax = newAnchorsMax;
t.offsetMin = t.offsetMax = new Vector2(0, 0);
}
[MenuItem("UiHelpers/Corners to Anchors %]")]
static void CornersToAnchors(){
RectTransform t = Selection.activeTransform as RectTransform;
if(t == null) return;
t.offsetMin = t.offsetMax = new Vector2(0, 0);
}
}

12
Scripts/Editor/UiTools.cs.meta Executable file
View File

@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: e7917617b75a2884d91c365a562495e0
timeCreated: 1498592895
licenseType: Free
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

59
Scripts/GenPathFromDriving.cs Executable file
View File

@ -0,0 +1,59 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.IO;
public class GenPathFromDriving : MonoBehaviour {
public GameObject carObj;
public ICar car;
private StreamWriter writer;
public string outputFilename;
public float sampleDist = 2.0f;
Vector3 lastSample = Vector3.zero;
void Awake()
{
car = carObj.GetComponent<ICar>();
if(car != null)
{
string filename = Application.dataPath + "/Resources/" + outputFilename;
writer = new StreamWriter(filename);
Debug.Log("Opening file for path at: " + filename);
}
}
// Update is called once per frame
void Update ()
{
if(writer != null)
{
Vector3 p = carObj.transform.position;
if((p - lastSample).magnitude > sampleDist)
{
lastSample = p;
writer.WriteLine(string.Format("{0},{1},{2}", p.x, p.y, p.z));
}
}
}
public void Shutdown()
{
if(writer != null)
{
writer.Close();
writer = null;
}
}
void OnDestroy()
{
Shutdown();
}
}

View File

@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 803f435a5637a4143b85fa3e1ad3f5cf
timeCreated: 1486432165
licenseType: Free
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

38
Scripts/GlobalState.cs Executable file
View File

@ -0,0 +1,38 @@
using System.Collections.Generic;
using UnityEngine;
public static class GlobalState
{
public static string version = "v25.06.10";
public static string host = "0.0.0.0";
public static int port = 9091;
public static int portPrivateAPI = 9092;
public static int fps = 60;
public static float timeScale = 1.0f;
public static int maxSplitScreen = 4;
public static bool bAutoHideSceneMenu = false;
// should we create a car even though we don't have a network client?
public static bool bCreateCarWithoutNetworkClient = false;
public static string log_path = "default";
public static bool extendedTelemetry = true;
public static bool generateTrees = true;
public static bool generateRandomCones = true;
public static bool randomLight = true;
public static bool overheadCamera = false;
public static bool raceCameras = false;
public static bool paceCar = false;
public static bool manualDriving = false;
public static float kp = 5.0f;
public static float kd = 5.0f;
public static float ki = 0.0f;
public static string privateKey = "";
public static bool useSeed = false;
public static int seed = 20432814;
public static string additionnalContentPath = "";
public static string[] sceneNames;
public static List<AssetBundle> bundleScenes = new List<AssetBundle>();
public static bool drawLidar = true;
public static float timeOut = 300f;
}

13
Scripts/GlobalState.cs.meta Executable file
View File

@ -0,0 +1,13 @@
fileFormatVersion: 2
guid: 91e0f36bb9310904886d185248b951c3
timeCreated: 1516308787
licenseType: Free
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

355
Scripts/GlobalStateEditor.cs Executable file
View File

@ -0,0 +1,355 @@
using UnityEngine;
public class GlobalStateEditor : MonoBehaviour
{
public Rect rect;
private Vector2 scrollPosition = Vector2.zero;
public int port
{
get { return GlobalState.port; }
set { GlobalState.port = value; }
}
public int portPrivateAPI
{
get { return GlobalState.portPrivateAPI; }
set { GlobalState.portPrivateAPI = value; }
}
public int fps
{
get { return GlobalState.fps; }
set { GlobalState.fps = value; }
}
public int maxSplitScreen
{
get { return GlobalState.maxSplitScreen; }
set { GlobalState.maxSplitScreen = value; }
}
public bool generateTrees
{
get { return GlobalState.generateTrees; }
set { GlobalState.generateTrees = value; }
}
public bool extendedTelemetry
{
get { return GlobalState.extendedTelemetry; }
set { GlobalState.extendedTelemetry = value; }
}
public bool generateRandomCones
{
get { return GlobalState.generateRandomCones; }
set { GlobalState.generateRandomCones = value; }
}
public bool randomLight
{
get { return GlobalState.randomLight; }
set { GlobalState.randomLight = value; }
}
public bool raceCameras
{
get { return GlobalState.raceCameras; }
set { GlobalState.raceCameras = value; }
}
public bool overheadCamera
{
get { return GlobalState.overheadCamera; }
set { GlobalState.overheadCamera = value; }
}
public bool drawLidar
{
get { return GlobalState.drawLidar; }
set { GlobalState.drawLidar = value; }
}
public bool paceCar
{
get { return GlobalState.paceCar; }
set { GlobalState.paceCar = value; }
}
public bool manualDriving
{
get { return GlobalState.manualDriving; }
set { GlobalState.manualDriving = value; }
}
public float kp
{
get { return GlobalState.kp; }
set { GlobalState.kp = value; }
}
public float kd
{
get { return GlobalState.kd; }
set { GlobalState.kd = value; }
}
public float ki
{
get { return GlobalState.ki; }
set { GlobalState.ki = value; }
}
public bool useSeed
{
get { return GlobalState.useSeed; }
set { GlobalState.useSeed = value; }
}
public int seed
{
get { return GlobalState.seed; }
set { GlobalState.seed = value; }
}
public string privateKey
{
get { return GlobalState.privateKey; }
set { GlobalState.privateKey = value; }
}
public string additionnalContentPath
{
get { return GlobalState.additionnalContentPath; }
set { GlobalState.additionnalContentPath = value; }
}
public float timeScale
{
get { return GlobalState.timeScale; }
set { GlobalState.timeScale = value; Time.timeScale = value; }
}
public float timeOut
{
get { return GlobalState.timeOut; }
set { GlobalState.timeOut = value; }
}
private bool showPrivateKey = false;
private VersionCheck versionCheck;
void Awake()
{
LoadPlayerPrefs();
SaveToPlayerPrefs();
versionCheck = gameObject.GetComponent<VersionCheck>();
//keep it processing even when not in focus.
Application.runInBackground = true;
//Set desired frame rate as high as possible.
Application.targetFrameRate = GlobalState.fps;
}
void OnGUI()
{
int pixXOffset = (int)(rect.x * Screen.width);
int pixYOffset = (int)(rect.y * Screen.height);
int width = (int)(rect.width * Screen.width);
int height = (int)(rect.height * Screen.height);
int LabelXOffset = 100;
int scrollHeight = 220;
int scrollWidth = 200;
int YOffset = 0;
int Ysteps = 20;
GUI.BeginGroup(new Rect(pixXOffset, pixYOffset, width, height));
scrollPosition = GUI.BeginScrollView(new Rect(0, 0, width, height), scrollPosition, new Rect(0, 0, scrollWidth, scrollHeight), false, false);
GUI.Label(new Rect(0, YOffset, LabelXOffset, 20), "port");
string portString = GUI.TextField(new Rect(LabelXOffset, YOffset, width-LabelXOffset, 20), port.ToString());
int tmp_port = port;
int.TryParse(portString, out tmp_port);
if (tmp_port != port)
port = tmp_port;
YOffset += Ysteps;
GUI.Label(new Rect(0, YOffset, LabelXOffset, 20), "portPrivateAPI");
string portPrivateAPIString = GUI.TextField(new Rect(LabelXOffset, YOffset, width-LabelXOffset, 20), portPrivateAPI.ToString());
int tmp_portPrivateAPI = portPrivateAPI;
int.TryParse(portPrivateAPIString, out tmp_portPrivateAPI);
if (tmp_portPrivateAPI != portPrivateAPI)
portPrivateAPI = tmp_portPrivateAPI;
YOffset += Ysteps;
GUI.Label(new Rect(0, YOffset, LabelXOffset, 20), "FPS limit");
string fpsString = GUI.TextField(new Rect(LabelXOffset, YOffset, width-LabelXOffset, 20), fps.ToString());
int tmp_fps = fps;
int.TryParse(fpsString, out tmp_fps);
if (tmp_fps != fps)
fps = tmp_fps;
YOffset += Ysteps;
GUI.Label(new Rect(0, YOffset, LabelXOffset, 20), "Time scale");
string timeScaleString = GUI.TextField(new Rect(LabelXOffset, YOffset, width-LabelXOffset, 20), timeScale.ToString());
float tmp_timeScale = timeScale;
float.TryParse(timeScaleString, out tmp_timeScale);
if (tmp_timeScale != timeScale)
timeScale = tmp_timeScale;
YOffset += Ysteps;
GUI.Label(new Rect(0, YOffset, LabelXOffset, 20), "Time out");
string timeOutString = GUI.TextField(new Rect(LabelXOffset, YOffset, width-LabelXOffset, 20), timeOut.ToString());
float tmp_timeOut = timeOut;
float.TryParse(timeOutString, out tmp_timeOut);
if (tmp_timeOut != timeOut)
timeOut = tmp_timeOut;
YOffset += Ysteps;
GUI.Label(new Rect(0, YOffset, LabelXOffset, 20), "Max SplitScreen");
string maxspString = GUI.TextField(new Rect(LabelXOffset, YOffset, width-LabelXOffset, 20), maxSplitScreen.ToString());
int tmp_maxsp = maxSplitScreen;
int.TryParse(maxspString, out tmp_maxsp);
if (tmp_maxsp != maxSplitScreen)
maxSplitScreen = tmp_maxsp;
YOffset += Ysteps;
extendedTelemetry = GUI.Toggle(new Rect(0, YOffset, width, 20), extendedTelemetry, "extendedTelemetry");
YOffset += Ysteps;
generateTrees = GUI.Toggle(new Rect(0, YOffset, width, 20), generateTrees, "generateTrees");
YOffset += Ysteps;
generateRandomCones = GUI.Toggle(new Rect(0, YOffset, width, 20), generateRandomCones, "generateRandomCones");
YOffset += Ysteps;
randomLight = GUI.Toggle(new Rect(0, YOffset, width, 20), randomLight, "randomLight");
YOffset += Ysteps;
raceCameras = GUI.Toggle(new Rect(0, YOffset, width, 20), raceCameras, "raceCameras");
YOffset += Ysteps;
overheadCamera = GUI.Toggle(new Rect(0, YOffset, width, 20), overheadCamera, "overheadCamera");
YOffset += Ysteps;
drawLidar = GUI.Toggle(new Rect(0, YOffset, width, 20), drawLidar, "drawLidar");
YOffset += Ysteps;
paceCar = GUI.Toggle(new Rect(0, YOffset, width, 20), paceCar, "paceCar");
YOffset += Ysteps;
if (paceCar)
{
manualDriving = GUI.Toggle(new Rect(Ysteps, YOffset, width, 20), manualDriving, "manualDriving");
YOffset += Ysteps;
if (!manualDriving)
{
GUI.Label(new Rect(Ysteps, YOffset, LabelXOffset, 20), "kp");
string kpString = GUI.TextField(new Rect(LabelXOffset+Ysteps, YOffset, width-LabelXOffset-Ysteps, 20), kp.ToString());
float tmp_kp = kp;
float.TryParse(kpString, out tmp_kp);
if (tmp_kp != kp)
kp = tmp_kp;
YOffset += Ysteps;
GUI.Label(new Rect(Ysteps, YOffset, LabelXOffset, 20), "kd");
string kdString = GUI.TextField(new Rect(LabelXOffset+Ysteps, YOffset, width-LabelXOffset-Ysteps, 20), kd.ToString());
float tmp_kd = kd;
float.TryParse(kdString, out tmp_kd);
if (tmp_kd != kd)
kd = tmp_kd;
YOffset += Ysteps;
GUI.Label(new Rect(Ysteps, YOffset, LabelXOffset, 20), "ki");
string kiString = GUI.TextField(new Rect(LabelXOffset+Ysteps, YOffset, width-LabelXOffset-Ysteps, 20), ki.ToString());
float tmp_ki = ki;
float.TryParse(kiString, out tmp_ki);
if (tmp_ki != ki)
ki = tmp_ki;
YOffset += Ysteps;
}
}
useSeed = GUI.Toggle(new Rect(0, YOffset, width, 20), useSeed, "useSeed");
YOffset += Ysteps;
if (useSeed)
{
GUI.Label(new Rect(0, YOffset, LabelXOffset, 20), "Seed");
string seedString = GUI.TextField(new Rect(LabelXOffset, YOffset, width, 20), seed.ToString());
YOffset += Ysteps;
int tmp_seed = seed;
int.TryParse(seedString, out tmp_seed);
if (tmp_seed != seed)
seed = tmp_seed;
}
YOffset += Ysteps;
bool doSave = GUI.Button(new Rect(0, YOffset, width, 20), "Save");
YOffset += Ysteps;
// Check if the version used is the latest version if not, notify the user !
if (versionCheck.latest != GlobalState.version)
{
YOffset += Ysteps;
bool getLatest = GUI.Button(new Rect(0, YOffset, width, Ysteps * 2), "A new version is available, \n click here to get latest version !");
YOffset += Ysteps * 2;
if (getLatest) { versionCheck.GetLatestVersion(); }
}
YOffset += Ysteps;
showPrivateKey = GUI.Toggle(new Rect(0, YOffset, width, 20), showPrivateKey, "showPrivateKey");
YOffset += Ysteps;
if (showPrivateKey)
{
GUI.Label(new Rect(0, YOffset, LabelXOffset, 20), "Private API Key");
privateKey = GUI.TextField(new Rect(LabelXOffset, YOffset, width, 20), privateKey);
YOffset += Ysteps;
bool doRandomize = GUI.Button(new Rect(0, YOffset, width, 20), "Randomize private key");
YOffset += Ysteps;
if (doRandomize) { RandomizePrivateKey(); }
}
if (doSave) { SaveToPlayerPrefs(); }
GUI.EndScrollView();
GUI.EndGroup();
}
void SaveToPlayerPrefs()
{
PlayerPrefs.SetInt("port", port);
PlayerPrefs.SetInt("portPrivateAPI", portPrivateAPI);
PlayerPrefs.SetInt("fps", fps);
PlayerPrefs.SetFloat("timeScale", timeScale);
PlayerPrefs.SetFloat("timeOut", timeOut);
PlayerPrefs.SetInt("maxSplitScreen", maxSplitScreen);
PlayerPrefs.SetInt("generateTrees", generateTrees ? 1 : 0);
PlayerPrefs.SetInt("extendedTelemetry", extendedTelemetry ? 1 : 0);
PlayerPrefs.SetInt("generateRandomCones", generateRandomCones ? 1 : 0);
PlayerPrefs.SetInt("randomLight", randomLight ? 1 : 0);
PlayerPrefs.SetInt("raceCameras", raceCameras ? 1 : 0);
PlayerPrefs.SetInt("overheadCamera", overheadCamera ? 1 : 0);
PlayerPrefs.SetInt("drawLidar", drawLidar ? 1 : 0);
PlayerPrefs.SetInt("paceCar", paceCar ? 1 : 0);
PlayerPrefs.SetInt("manualDriving", manualDriving ? 1 : 0);
PlayerPrefs.SetFloat("kp", kp);
PlayerPrefs.SetFloat("kd", kd);
PlayerPrefs.SetFloat("ki", ki);
PlayerPrefs.SetInt("useSeed", useSeed ? 1 : 0);
PlayerPrefs.SetString("privateKey", privateKey);
PlayerPrefs.Save();
}
void LoadPlayerPrefs()
{
port = PlayerPrefs.GetInt("port", port);
portPrivateAPI = PlayerPrefs.GetInt("portPrivateAPI", portPrivateAPI);
fps = PlayerPrefs.GetInt("fps", fps);
timeScale = PlayerPrefs.GetFloat("timeScale", timeScale);
timeOut = PlayerPrefs.GetFloat("timeOut", timeOut);
maxSplitScreen = PlayerPrefs.GetInt("maxSplitScreen", maxSplitScreen);
generateTrees = PlayerPrefs.GetInt("generateTrees", generateTrees ? 1 : 0) == 1 ? true : false;
extendedTelemetry = PlayerPrefs.GetInt("extendedTelemetry", extendedTelemetry ? 1 : 0) == 1 ? true : false;
generateRandomCones = PlayerPrefs.GetInt("generateRandomCones", generateRandomCones ? 1 : 0) == 1 ? true : false;
randomLight = PlayerPrefs.GetInt("randomLight", randomLight ? 1 : 0) == 1 ? true : false;
raceCameras = PlayerPrefs.GetInt("raceCameras", raceCameras ? 1 : 0) == 1 ? true : false;
overheadCamera = PlayerPrefs.GetInt("overheadCamera", overheadCamera ? 1 : 0) == 1 ? true : false;
drawLidar = PlayerPrefs.GetInt("drawLidar", drawLidar ? 1 : 0) == 1 ? true : false;
paceCar = PlayerPrefs.GetInt("paceCar", paceCar ? 1 : 0) == 1 ? true : false;
manualDriving = PlayerPrefs.GetInt("manualDriving", manualDriving ? 1 : 0) == 1 ? true : false;
kp = PlayerPrefs.GetFloat("kp", kp);
kd = PlayerPrefs.GetFloat("kd", kd);
ki = PlayerPrefs.GetFloat("ki", ki);
useSeed = PlayerPrefs.GetInt("useSeed", useSeed ? 1 : 0) == 1 ? true : false;
privateKey = PlayerPrefs.GetString("privateKey", Random.Range(10000000, 99999999).ToString());
additionnalContentPath = Application.streamingAssetsPath;
}
void RandomizePrivateKey()
{
privateKey = Random.Range(10000000, 99999999).ToString();
PlayerPrefs.SetString("privateKey", privateKey);
PlayerPrefs.Save();
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 1b637f9c31c45c549817af28ffef012a
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: -1100
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

23
Scripts/GlobalStateWatcher.cs Executable file
View File

@ -0,0 +1,23 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class GlobalStateWatcher : MonoBehaviour {
public GameObject menuObj;
public GameObject networkObj;
// Use this for initialization
void Start () {
/*
if (GlobalState.bAutoHideSceneMenu && menuObj != null)
menuObj.SetActive(false);
if (GlobalState.bAutoConnectToWebSocket && networkObj != null)
networkObj.SetActive(true);
*/
}
}

View File

@ -0,0 +1,13 @@
fileFormatVersion: 2
guid: 4efaaf7922b6daa4e9eafc08b1a175ba
timeCreated: 1516309168
licenseType: Free
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

55
Scripts/HUDFPS.cs Executable file
View File

@ -0,0 +1,55 @@
using UnityEngine;
using UnityEngine.UI;
//Credit Poless on http://wiki.unity3d.com/index.php?title=FramesPerSecond
public class HUDFPS : MonoBehaviour
{
// Attach this to a GUIText to make a frames/second indicator.
//
// It calculates frames/second over each updateInterval,
// so the display does not keep changing wildly.
//
// It is also fairly accurate at very low FPS counts (<10).
// We do this not by simply counting frames per interval, but
// by accumulating FPS for each frame. This way we end up with
// correct overall FPS even if the interval renders something like
// 5.5 frames.
public float updateInterval = 3.0F;
private float accum = 0; // time accumulated over the interval
private int frames = 0; // frames drawn over the interval
public Text status;
void Start()
{
if( !status)
{
Debug.Log("HUDFPS needs a Text component!");
enabled = false;
return;
}
}
void Update()
{
accum += Time.unscaledDeltaTime;
++frames;
// Interval ended - update GUI text and start new interval
if( accum > updateInterval && status != null)
{
// display two fractional digits (f2 format)
float fps = frames / accum;
string format = System.String.Format("FPS: {0:F1}",fps);
status.text = format;
accum = 0.0F;
frames = 0;
}
}
}

12
Scripts/HUDFPS.cs.meta Executable file
View File

@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 2f5d34ac169a493488e5978a3359d2ef
timeCreated: 1504629867
licenseType: Free
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

61
Scripts/ICar.cs Executable file
View File

@ -0,0 +1,61 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
//view scripts at Aug 17
//https://github.com/tawnkramer/sdsandbox/tree/7c88596a3fd8ffe32d11074ab1ff661d24602152/sdsim/Assets/Scripts
//https://github.com/tawnkramer/sdsandbox/commit/7c88596a3fd8ffe32d11074ab1ff661d24602152
//Create an interface class that the sdsim will expect. We can use this to wrap other car implementations
//like the Unity standard asset car.
public interface ICar
{
//all inputs require 0-1 input except steering which is in degrees, where 0 is center.
void RequestThrottle(float val);
void RequestSteering(float val);
void RequestFootBrake(float val);
void RequestHandBrake(float val);
//query last input given.
float GetSteering();
float GetThrottle();
float GetFootBrake();
float GetHandBrake();
//query state.
Transform GetTransform();
Vector3 GetVelocity();
Vector3 GetAccel();
Vector3 GetGyro();
//mark the current activity for partial selections when creating training sets later.
string GetActivity();
void SetActivity(string act);
//Save and restore State
void SavePosRot();
void RestorePosRot();
void SetMaxSteering(float val);
float GetMaxSteering();
//get the name of the last object we collided with
string GetLastCollision();
void ClearLastCollision();
}

12
Scripts/ICar.cs.meta Executable file
View File

@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: a6e9cc1b4fe7846dcbda44e6943a5132
timeCreated: 1484592740
licenseType: Free
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

36
Scripts/JoystickCarControl.cs Executable file
View File

@ -0,0 +1,36 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityStandardAssets.CrossPlatformInput;
public class JoystickCarControl : MonoBehaviour
{
public GameObject carObj;
private ICar car;
public float MaximumSteerAngle = 25.0f; //has to be kept in sync with the car, as that's a private var.
void Awake()
{
if(carObj != null)
car = carObj.GetComponent<ICar>();
}
private void OnDisable()
{
car.RequestThrottle(0.0f);
car.RequestHandBrake(1.0f);
car.RequestFootBrake(1.0f);
}
private void FixedUpdate()
{
// pass the input to the car!
float h = CrossPlatformInputManager.GetAxis("Horizontal");
float v = CrossPlatformInputManager.GetAxis("Vertical");
float handbrake = CrossPlatformInputManager.GetAxis("Jump");
car.RequestSteering(h * MaximumSteerAngle);
car.RequestThrottle(v);
//car.RequestFootBrake(v);
car.RequestHandBrake(handbrake);
}
}

View File

@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 23bb2fa9b8a0421478eb697c3a63f7f0
timeCreated: 1498591643
licenseType: Free
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

172
Scripts/LaneChangeTrainer.cs Executable file
View File

@ -0,0 +1,172 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class LaneChangeTrainer : MonoBehaviour {
//how many lanes in total to change to/from
public int numLanes = 5;
//how far side ways to the next lane
public float laneDist = 4.0f;
//which lane do we begin? Far right is zero.
public int currentLane = 0;
//over how long should we take to move to the next lane
public float transitionDist = 20.0f;
//How long to stay in this lane before changing
public float laneKeepDist = 20.0f;
//How much to smooth path. 0.0 - 1.0f
public float pathSmoothFactor = 0.5f;
public void ModifyPath(ref CarPath path)
{
float curLaneDist = 0.0f;
Vector3 start = path.nodes[0].pos;
int changeLaneDir = 1;
float curTransDist = 0.0f;
bool initLaneChange = false;
Vector3 offset = Vector3.zero;
Vector3 laneChangeDp = Vector3.zero;
string activity = "keep_lane";
for(int iN = 1; iN < path.nodes.Count; iN++)
{
PathNode n = path.nodes[iN];
Vector3 dp = n.pos - path.nodes[iN - 1].pos;
if(curLaneDist < laneKeepDist)
{
n.activity = activity;
activity = "keep_lane";
//stay in current lane.
curLaneDist += dp.magnitude;
initLaneChange = false;
}
else if(!initLaneChange)
{
initLaneChange = true;
laneChangeDp = new Vector3(-1 * NewLaneDir(changeLaneDir) * laneDist, 0.0f, laneKeepDist);
GetActivity(ref changeLaneDir, ref activity);
offset = laneChangeDp.normalized * dp.magnitude;
offset.z = 0.0f;
OffsetRemainingPath(ref path, iN, offset);
curTransDist += dp.magnitude;
n.activity = activity;
}
else
{
offset = laneChangeDp.normalized * dp.magnitude;
offset.z = 0.0f;
OffsetRemainingPath(ref path, iN, offset);
curTransDist += dp.magnitude;
n.activity = activity;
if(curTransDist > transitionDist)
{
OnEnterNewLane(ref changeLaneDir);
n = path.nodes[iN];
//do a small correction to make sure we are in the absolute center of the lane.
float lanePosAbsoluteX = (-1 * currentLane * laneDist) + start.x;
float errorX = lanePosAbsoluteX - n.pos.x;
Vector3 error = new Vector3(errorX, 0.0f, 0.0f);
OffsetRemainingPath(ref path, iN, error);
//switch back to driving in the lane.
curLaneDist = 0.0f;
curTransDist = 0.0f;
}
}
}
OffsetLabelsBack(ref path);
OffsetLabelsBack(ref path);
path.SmoothPath(pathSmoothFactor);
}
void OffsetLabelsBack(ref CarPath path)
{
//we are setting our activity labels one node too late. Try setting them a bit early. And removing them one early too.
for(int iN = 1; iN < path.nodes.Count; iN++)
{
PathNode p = path.nodes[iN - 1];
PathNode c = path.nodes[iN];
if(p.activity == null || c.activity == null)
continue;
if(c.activity != p.activity)
{
if(c.activity.StartsWith("cl_"))
{
p.activity = c.activity;
}
else if(p.activity.StartsWith("cl_"))
{
p.activity = c.activity;
}
}
}
}
void OffsetRemainingPath(ref CarPath path, int iStart, Vector3 offset)
{
for(int iN = iStart; iN < path.nodes.Count; iN++)
{
PathNode n = path.nodes[iN];
n.pos += offset;
}
}
int NewLaneDir(int changeLaneDir)
{
if(currentLane == numLanes - 1)
{
return -1;
}
else if(currentLane == 0)
{
return 1;
}
return changeLaneDir;
}
void GetActivity(ref int changeLaneDir, ref string activity)
{
if(changeLaneDir > 0)
activity = "cl_left";
else
activity = "cl_right";
}
void OnEnterNewLane(ref int changeLaneDir)
{
//choose a dir, left or right.
currentLane += changeLaneDir;
if(currentLane == numLanes - 1)
{
changeLaneDir = -1;
}
else if(currentLane == 0)
{
changeLaneDir = 1;
}
}
}

View File

@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 489eab0f2e6a3422f9b8ff53d6251c46
timeCreated: 1484765183
licenseType: Free
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

232
Scripts/Lidar.cs Executable file
View File

@ -0,0 +1,232 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;
[Serializable]
public class LidarPoint
{
public float x;
public float y;
public float z;
public float d;
public float rx;
public float ry;
public LidarPoint(Vector3 p, float distance, float _rx, float _ry)
{
x = p.x;
y = p.y;
z = p.z;
d = distance;
rx = _rx;
ry = _ry;
}
}
[Serializable]
public class V3
{
public float x;
public float y;
public float z;
public V3(Vector3 p)
{
x = p.x;
y = p.y;
z = p.z;
}
}
[Serializable]
public class LidarPointArray
{
//All coordinates in World coordinate system
public LidarPoint[] points;
public void Init(int numPoints)
{
points = new LidarPoint[numPoints];
}
}
public class Lidar : MonoBehaviour
{
public LidarPointArray pointArr;
//as the ray sweeps around, how many degrees does it advance per sample
public float degPerSweepInc = 2f;
//what is the starting angle for the initial sweep compared to the forward vector
public float degAngDown = 25f;
//what angle change between sweeps
public float degAngDelta = -1f;
//how many complete 360 sweeps
public int numSweepsLevels = 25;
//what it max distance we will register a hit
public float maxRange = 50f;
//how large radius to use when rendering debug display
public float gizmoSize = 0.1f;
//what is the scalar on the perlin noise applied to point position
public float noise = 0.2f;
public bool DisplayDebugInScene = false;
// are there layers we don't want to collide with?
public string[] layerMaskNames;
int collMask = 0;
void Awake()
{
pointArr = new LidarPointArray();
pointArr.Init((int)(360 / degPerSweepInc * numSweepsLevels));
int v = 0;
foreach (string layerName in layerMaskNames)
{
int layer = LayerMask.NameToLayer(layerName);
v |= 1 << layer;
}
collMask |= ~v;
}
public void SetConfig(float offset_x, float offset_y, float offset_z, float rot_x,
float _degPerSweepInc, float _degAngDown, float _degAngDelta, float _maxRange, float _noise, int _numSweepsLevels)
{
degPerSweepInc = _degPerSweepInc;
degAngDown = _degAngDown;
degAngDelta = _degAngDelta;
maxRange = _maxRange;
noise = _noise;
numSweepsLevels = _numSweepsLevels;
if (offset_x != 0.0f || offset_y != 0.0f || offset_z != 0.0f)
transform.localPosition = new Vector3(offset_x, offset_y, offset_z);
if (rot_x != 0.0f)
transform.localEulerAngles = new Vector3(rot_x, 0.0f, 0.0f);
pointArr = new LidarPointArray();
pointArr.Init((int)(360 / degPerSweepInc * numSweepsLevels));
}
public JSONObject GetOutputAsJson()
{
LidarPointArray points = GetOutput();
JSONObject json = JSONObject.Create();
foreach (LidarPoint p in points.points)
{
JSONObject vec = JSONObject.Create();
try
{
vec.AddField("d", (float)Math.Round(p.d, 2));
vec.AddField("rx", p.rx);
vec.AddField("ry", p.ry);
json.Add(vec);
}
catch
{
// just ignore points that don't resolve.
}
}
return json;
}
public LidarPointArray GetOutput()
{
int numSweep = (int)(360 / degPerSweepInc);
pointArr = new LidarPointArray();
pointArr.Init(numSweep * numSweepsLevels);
Ray ray = new Ray(transform.position, transform.forward);
RaycastHit hit;
// Vertical rotation
Quaternion rotUp = Quaternion.AngleAxis(degAngDelta, transform.right);
// Horizontal rotation
Quaternion rotSide = Quaternion.AngleAxis(degPerSweepInc, transform.up);
//Sample the output texture to create rays.
int iP = 0;
float rx = 0.0f;
float ry = 0.0f;
for (int iS = 0; iS < numSweepsLevels; iS++)
{
// reset the orientation of the ray
Quaternion rotDown = Quaternion.AngleAxis(degAngDown + iS * degAngDelta, transform.right);
ray.direction = rotDown * transform.forward;
rx = 0.0f;
for (int iA = 0; iA < numSweep; iA++)
{
if (Physics.Raycast(ray, out hit, maxRange, collMask))
{
//sample that ray at the depth given by the pixel.
Vector3 pos = hit.point - transform.position;
float distance = hit.distance;
//shouldn't hit this unless user is messing around in the interface with things running.
if (iP >= pointArr.points.Length)
break;
// add some noise to the point position
float noiseX = Mathf.PerlinNoise(UnityEngine.Random.Range(-1f, 1f), UnityEngine.Random.Range(-1f, 1f));
float noiseY = Mathf.PerlinNoise(UnityEngine.Random.Range(-1f, 1f), UnityEngine.Random.Range(-1f, 1f));
float noiseZ = Mathf.PerlinNoise(UnityEngine.Random.Range(-1f, 1f), UnityEngine.Random.Range(-1f, 1f));
pos.x += noise * noiseX;
pos.y += noise * noiseY;
pos.z += noise * noiseZ;
//set iPoint
pointArr.points[iP] = new LidarPoint(pos, distance, rx, ry);
iP++;
}
ray.direction = rotSide * ray.direction;
rx += degPerSweepInc;
}
ray.direction = rotUp * ray.direction;
ry += degAngDelta;
}
return pointArr;
}
void OnDrawGizmosSelected()
{
Gizmos.color = Color.red;
pointArr = GetOutput(); // not really efficient but won't be called in the app, just for visualization purpose
Vector3 pos = Vector3.zero;
foreach (LidarPoint p in pointArr.points)
{
if (p == null)
continue;
pos.x = p.x;
pos.y = p.y;
pos.z = p.z;
//make points global space for drawing
pos += transform.position;
Gizmos.DrawSphere(pos, gizmoSize);
}
}
}

12
Scripts/Lidar.cs.meta Executable file
View File

@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 271bfe211179846878a1f16e517b854d
timeCreated: 1489425632
licenseType: Free
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

101
Scripts/Lines.cs Executable file
View File

@ -0,0 +1,101 @@
using UnityEngine;
using System.Collections;
//3d line
public class Line3d
{
public Line3d() {}
public Line3d(ref Vector3 a, ref Vector3 b)
{
ConstructLine(ref a, ref b);
}
//allow a line to be recomputed
public void ConstructLine(ref Vector3 a, ref Vector3 b)
{
m_origin = a;
m_dir = a - b;
m_dir.Normalize();
}
//produce a vector normal to this line passing through this point.
public Vector3 ClosestVectorTo(ref Vector3 point)
{
Vector3 deltaPoint = m_origin - point;
float dot = Vector3.Dot(deltaPoint, m_dir);
return (m_dir * dot) - deltaPoint;
}
//transform the point by the normal vector that places it on the line
public Vector3 ClosestPointOnLineTo(ref Vector3 point)
{
Vector3 vectorTo = ClosestVectorTo(ref point);
return point - vectorTo;
}
public float AbsAngleBetween(ref Line3d l)
{
return Mathf.Abs(Vector3.Angle( m_dir, l.m_dir));
}
public Vector3 m_origin, m_dir;
};
public class LineSeg3d : Line3d
{
public LineSeg3d(){}
public LineSeg3d(ref Vector3 a, ref Vector3 b)
{
ConstructLineSeg(ref a, ref b);
}
public void ConstructLineSeg(ref Vector3 a, ref Vector3 b)
{
ConstructLine(ref a, ref b);
m_end = b;
m_length = (a - b).magnitude;
}
public enum SegResult
{
OnSpan,
LessThanOrigin,
GreaterThanEnd,
}
//find the closest point, clamping it to the ends
public Vector3 ClosestPointOnSegmentTo(ref Vector3 point, ref SegResult res)
{
Vector3 deltaPoint = m_origin - point;
float dot = Vector3.Dot(deltaPoint, m_dir);
//clamp to the ends of the line segment
if(dot <= 0.0f)
{
res = SegResult.LessThanOrigin;
return m_origin;
}
if(dot >= m_length)
{
res = SegResult.GreaterThanEnd;
return m_end;
}
res = SegResult.OnSpan;
Vector3 vectorTo = (m_dir * dot) - deltaPoint;
return point - vectorTo;
}
public void Draw(Color c)
{
Debug.DrawLine(m_origin, m_end, c);
}
public float m_length;
public Vector3 m_end;
};

12
Scripts/Lines.cs.meta Executable file
View File

@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 9f193da27afc443cab7d171c78f63a1b
timeCreated: 1449593992
licenseType: Free
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

439
Scripts/Localizer.cs Executable file
View File

@ -0,0 +1,439 @@
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
[System.Serializable]
public class Measurement
{
public int id;
public int offsetX;
public int offsetZ;
public Measurement(int _id, int offX, int offZ)
{
id = _id;
offsetX = offX;
offsetZ = offZ;
}
}
[System.Serializable]
public class Measurements
{
public List<Measurement> m;
public void Init(int count)
{
m = new List<Measurement>(count);
}
}
[System.Serializable]
public class ProbMap
{
public float[,] cells;
public int numX;
public int numZ;
public void Init(int numXCells, int numZCells)
{
numX = numXCells;
numZ = numZCells;
cells = new float[numXCells, numZCells];
}
public void AllEqualProb()
{
int totalCells = numX * numZ;
//At first we are equally likely to be in any cell.
//And since we like the probability to add to 1, we
///divide by total cells.
float iniProb = 1.0f / totalCells;
for(int iX = 0; iX < numX; iX++)
{
for(int iZ = 0; iZ < numZ; iZ++)
{
cells[iX, iZ] = iniProb;
}
}
}
public void Zero()
{
for(int iX = 0; iX < numX; iX++)
{
for(int iZ = 0; iZ < numZ; iZ++)
{
cells[iX, iZ] = 0.0f;
}
}
}
}
public class ProbMapVisualizer
{
public List<GameObject> cellMarkers;
public List<Vector2> topCells;
public void Init(int numToVisualize, GameObject prefab)
{
cellMarkers = new List<GameObject>(numToVisualize);
topCells = new List<Vector2>(numToVisualize);
for(int i = 0; i < numToVisualize; i++)
{
GameObject go = GameObject.Instantiate(prefab) as GameObject;
cellMarkers.Add(go);
}
}
public void Visualize(ProbMap pm, Map world)
{
topCells.Clear();
int numX = pm.numX;
int numZ = pm.numZ;
float thresh = 0.05f;
int iCM = 0;
for(int iX = 0; iX < numX; iX++)
{
for(int iZ = 0; iZ < numZ; iZ++)
{
float p = pm.cells[iX, iZ];
if(p > thresh)
{
Vector3 pos = Vector3.zero;
pos = world.startPos;
pos.x += world.dX * iX;
pos.z += world.dZ * iZ;
cellMarkers[iCM].transform.position = pos;
Vector3 s = Vector3.one;
s.y = p * 100f;
s.x = world.dX;
s.z = world.dZ;
cellMarkers[iCM].transform.localScale = s;
iCM++;
if(iCM == cellMarkers.Count)
break;
}
}
}
for(int iM = iCM; iM < cellMarkers.Count; iM++)
{
cellMarkers[iM].transform.position = Vector3.zero;
cellMarkers[iM].transform.localScale = Vector3.zero;
}
}
}
public class MonteCarloLocalizer
{
public Map world;
public ProbMap probMap;
//for memory efficiency, we will allocate
//two maps and swap between them.
bool useMapA;
ProbMap mapA;
ProbMap mapB;
public void Init(Map worldMap)
{
world = worldMap;
mapA = new ProbMap();
mapA.Init(world.numX, world.numZ);
mapA.AllEqualProb();
useMapA = true;
probMap = mapA;
mapB = new ProbMap();
mapB.Init(world.numX, world.numZ);
}
public void Move(int iMoveX, int iMoveZ, float probExact)
{
if(iMoveX == 0 && iMoveZ == 0)
return;
ProbMap newMap = useMapA ? mapB : mapA;
newMap.Zero();
int numX = probMap.numX;
int numZ = probMap.numZ;
for(int iX = 0; iX < numX; iX++)
{
for(int iZ = 0; iZ < numZ; iZ++)
{
int iTargetX = iX + iMoveX;
int iTargetZ = iZ + iMoveZ;
if(iTargetX < 0 || iTargetX >= numX)
continue;
if(iTargetZ < 0 || iTargetZ >= numZ)
continue;
//int trailX = iMoveX > 0 ? - 1 : (iMoveX == 0 ? 0 : 1);
//int trailZ = iMoveZ > 0 ? - 1 : (iMoveZ == 0 ? 0 : 1);
//most of old value moves to new
float probTarget = probMap.cells[iX, iZ] * probExact;
//some probablity that we are still in old cell.
//float probTrail = probMap.cells[iX, iZ] * (1.0f - probExact);
newMap.cells[iTargetX, iTargetZ] += probTarget;
//newMap.cells[iTargetX + trailX, iTargetZ + trailZ] += probTrail;
}
}
probMap = newMap;
useMapA = !useMapA;
}
public void Sense(Measurements m, float probExact)
{
for(int iM = 0; iM < m.m.Count; iM++)
{
Measurement _m = m.m[iM];
Sense(_m, probExact);
}
}
public void Sense(Measurement m, float probHit)
{
int numX = probMap.numX;
int numZ = probMap.numZ;
float probMiss = 1.0f - probHit;
float t = 0f;
for(int iX = 0; iX < numX; iX++)
{
for(int iZ = 0; iZ < numZ; iZ++)
{
float hit = 0f;
int iSenseX = iX + m.offsetX;
int iSenseZ = iZ + m.offsetZ;
if(iSenseZ >= 0 && iSenseZ < numZ &&
iSenseX >= 0 && iSenseX < numX)
{
hit = (m.id == world.cells[iSenseX, iSenseZ]) ? 1.0f : 0.0f;
}
float p = probMap.cells[iX, iZ];
float np = p * (hit * probHit + (1.0f - hit) * probMiss);
probMap.cells[iX, iZ] = np;
t += np;
}
}
//Normalize.
for(int iX = 0; iX < numX; iX++)
{
for(int iZ = 0; iZ < numZ; iZ++)
{
probMap.cells[iX, iZ] = probMap.cells[iX, iZ] / t;
}
}
}
public void MostLikelyCell(out int cellX, out int cellZ)
{
float p = 0f;
int numX = probMap.numX;
int numZ = probMap.numZ;
cellX = 0;
cellZ = 0;
for(int iX = 0; iX < numX; iX++)
{
for(int iZ = 0; iZ < numZ; iZ++)
{
float pc = probMap.cells[iX, iZ];
if(pc > p)
{
p = pc;
cellX = iX;
cellZ = iZ;
}
}
}
}
public void MostLikelyPos(out Vector3 pos)
{
int iX = 0;
int iZ = 0;
MostLikelyCell(out iX, out iZ);
pos = world.startPos;
pos.x += world.dX * iX;
pos.z += world.dZ * iZ;
}
}
public class LocUnitTester
{
public void Test(Map map, Measurements measurements, List<Vector2> moves,
int iExpectedX, int iExpectedZ)
{
MonteCarloLocalizer loc = new MonteCarloLocalizer();
loc.Init(map);
int iX = (int)moves[0].x;
int iY = (int)moves[0].y;
loc.Move(iX, iY, 1f);
loc.Sense(measurements, 1f);
int mlX, mlZ;
loc.MostLikelyCell(out mlX, out mlZ);
if(iExpectedX == mlX && iExpectedZ == mlZ)
{
Debug.Log("Correct!");
}
else
{
Debug.LogError("Oops");
}
}
public void TestA()
{
Map map = new Map();
map.Init(3, 3);
map.cells [1,1] = 1; //all the rest are zero.
Measurement m = new Measurement(1, 0, 0);
Measurements ma = new Measurements();
ma.Init(1);
ma.m.Add(m);
List<Vector2> moves = new List<Vector2>();
moves.Add(Vector2.zero);
Test (map, ma, moves, 1, 1);
}
public void TestB()
{
Map map = new Map();
map.Init(3, 3);
map.cells [1,1] = 1; //all the rest are zero.
Measurement m = new Measurement(1, 0, -1);
Measurements ma = new Measurements();
ma.Init(1);
ma.m.Add(m);
List<Vector2> moves = new List<Vector2>();
moves.Add(Vector2.zero);
Test (map, ma, moves, 1, 2);
}
}
public class Localizer : MonoBehaviour
{
MonteCarloLocalizer loc;
ProbMapVisualizer vis;
public MapManager mm;
int iPrevX = 0;
int iPrevZ = 0;
Vector3 prevPos;
public float radiusSense = 100f;
public float threshMove = 0.1f;
public float probMoveExact = 0.8f;
public float probSenseExact = 0.8f;
public Transform likelyTM;
// Use this for initialization
void Start ()
{
LocUnitTester tester = new LocUnitTester();
tester.TestB();
loc = new MonteCarloLocalizer();
loc.Init(mm.map);
vis = new ProbMapVisualizer();
vis.Init(25, likelyTM.gameObject );
//when we move at least full a cell dist, then sense again.
threshMove = mm.map.dX;
prevPos = Vector3.zero;
}
// Update is called once per frame
void Update ()
{
Vector3 newPos = transform.position;
int inewX = Mathf.RoundToInt(newPos.x / mm.map.dX);
int inewZ = Mathf.RoundToInt(newPos.z / mm.map.dZ);
if(inewX != iPrevX || inewZ != iPrevZ)
{
int iMoveX = inewX - iPrevX;
int iMoveZ = inewZ - iPrevZ;
SenseEnv(iMoveX, iMoveZ);
iPrevX = inewX;
iPrevZ = inewZ;
prevPos = newPos;
}
vis.Visualize(loc.probMap, loc.world);
}
void SenseEnv(int iMoveX, int iMoveZ)
{
Marker[] allMarkers = GameObject.FindObjectsOfType<Marker>();
Vector3 pos = transform.position;
Measurements ma = new Measurements();
ma.Init(100);
foreach(Marker marker in allMarkers)
{
Vector3 delta = (marker.transform.position - pos);
if(delta.magnitude < radiusSense)
{
int offX = Mathf.RoundToInt(delta.x / mm.map.dX);
int offZ = Mathf.RoundToInt(delta.z / mm.map.dZ);
Measurement m = new Measurement(marker.id, offX, offZ);
ma.m.Add(m);
}
}
//first move is huge and not needed.
if(prevPos != Vector3.zero)
loc.Move(iMoveX, iMoveZ, probMoveExact);
loc.Sense(ma, probSenseExact);
Vector3 likelyPos = Vector3.zero;
likelyTM.position = likelyPos;
}
}

12
Scripts/Localizer.cs.meta Executable file
View File

@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 019bba83519c94d9e80c79b1b54e2b59
timeCreated: 1449074642
licenseType: Free
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

29
Scripts/LocationMarker.cs Executable file
View File

@ -0,0 +1,29 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class LocationMarker : MonoBehaviour {
public int id;
public static int GetNearestLocMarker(Vector3 pos)
{
int closest = -1;
float dist = float.PositiveInfinity;
var markers = GameObject.FindObjectsOfType<LocationMarker>();
foreach(var marker in markers)
{
float d = (marker.transform.position - pos).magnitude;
if(d < dist)
{
closest = marker.id;
dist = d;
}
}
return closest;
}
}

11
Scripts/LocationMarker.cs.meta Executable file
View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 362da7465d0da47f7981adc02f1fcc80
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

373
Scripts/Logger.cs Executable file
View File

@ -0,0 +1,373 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.IO;
using System.Threading;
using System;
using UnityEngine.UI;
[Serializable]
public class MetaJson
{
public string[] inputs;
public string[] types;
public void Init(string[] _inputs, string[] _types)
{
inputs = _inputs;
types = _types;
}
}
[Serializable]
public class DonkeyRecord
{
public string cam_image_array;
public float user_throttle;
public float user_angle;
public string user_mode;
public int track_lap;
public int track_loc;
public void Init(string image_name, float throttle, float angle, string mode, int lap, int loc)
{
cam_image_array = image_name;
user_throttle = throttle;
user_angle = angle;
user_mode = mode;
track_lap = lap;
track_loc = loc;
}
public string AsString()
{
string json = JsonUtility.ToJson(this);
//Can't name the variable names with a slash, so replace on output
json = json.Replace("cam_image", "cam/image");
json = json.Replace("user_throttle", "user/throttle");
json = json.Replace("user_angle", "user/angle");
json = json.Replace("user_mode", "user/mode");
json = json.Replace("track_lap", "track/lap");
json = json.Replace("track_lap", "track/lap");
json = json.Replace("track_loc", "track/loc");
return json;
}
}
public class Logger : MonoBehaviour {
public GameObject carObj;
public ICar car;
public CameraSensor camSensor;
public CameraSensor optionlB_CamSensor;
public Lidar lidar;
//what's the current frame index
public int frameCounter = 0;
//which lap
public int lapCounter = 0;
//is there an upper bound on the number of frames to log
public int maxFramesToLog = 14000;
//should we log when we are enabled
public bool bDoLog = true;
public int limitFPS = 30;
float timeSinceLastCapture = 0.0f;
//We can output our logs in the style that matched the output from the shark robot car platform - github/tawnkramer/shark
public bool SharkStyle = false;
//We can output our logs in the style that matched the output from the udacity simulator
public bool UdacityStyle = false;
//We can output our logs in the style that matched the output from the donkey robot car platform - donkeycar.com
public bool DonkeyStyle = false;
//Tub style as prefered by Donkey2
public bool DonkeyStyle2 = true;
public Text logDisplay;
string outputFilename = "log_car_controls.txt";
private StreamWriter writer;
class ImageSaveJob {
public string filename;
public byte[] bytes;
}
List<ImageSaveJob> imagesToSave;
Thread thread;
string GetLogPath()
{
if(GlobalState.log_path != "default")
return GlobalState.log_path + "/";
return Application.dataPath + "/../log/";
}
void Awake()
{
car = carObj.GetComponent<ICar>();
if(bDoLog && car != null)
{
if(UdacityStyle)
{
outputFilename = "driving_log.csv";
}
string filename = GetLogPath() + outputFilename;
writer = new StreamWriter(filename);
Debug.Log("Opening file for log at: " + filename);
if(UdacityStyle)
{
writer.WriteLine("center,left,right,steering,throttle,brake,speed");
}
if(DonkeyStyle2)
{
MetaJson mjson = new MetaJson();
string[] inputs = {"cam/image_array", "user/angle", "user/throttle", "user/mode", "track/lap", "track/loc"};
string[] types = {"image_array", "float", "float", "str", "int", "int"};
mjson.Init(inputs, types);
string json = JsonUtility.ToJson(mjson);
var f = File.CreateText(GetLogPath() + "meta.json");
f.Write(json);
f.Close();
}
}
Canvas canvas = GameObject.FindObjectOfType<Canvas>();
GameObject go = CarSpawner.getChildGameObject(canvas.gameObject, "LogCount");
if (go != null)
logDisplay = go.GetComponent<Text>();
imagesToSave = new List<ImageSaveJob>();
thread = new Thread(SaverThread);
thread.Start();
}
// Update is called once per frame
void Update ()
{
if(!bDoLog)
return;
timeSinceLastCapture += Time.deltaTime;
if (timeSinceLastCapture < 1.0f / limitFPS)
return;
timeSinceLastCapture -= (1.0f / limitFPS);
string activity = car.GetActivity();
if(writer != null)
{
if(UdacityStyle)
{
string image_filename = GetUdacityStyleImageFilename();
float steering = car.GetSteering() / car.GetMaxSteering();
writer.WriteLine(string.Format("{0},{1},{2},{3},{4},{5},{6},{7}", image_filename,
"none", "none", steering.ToString(),
car.GetThrottle().ToString(), "0", "0", lapCounter));
}
else if(DonkeyStyle || SharkStyle)
{
}
else if(DonkeyStyle2)
{
DonkeyRecord mjson = new DonkeyRecord();
float steering = car.GetSteering() / car.GetMaxSteering();
float throttle = car.GetThrottle();
int loc = LocationMarker.GetNearestLocMarker(carObj.transform.position);
//training code like steering clamped between -1, 1
steering = Mathf.Clamp(steering, -1.0f, 1.0f);
mjson.Init(string.Format("{0}_cam-image_array_.jpg", frameCounter),
throttle, steering, "user", lapCounter, loc);
string json = mjson.AsString();
string filename = string.Format("record_{0}.json", frameCounter);
var f = File.CreateText(GetLogPath() + filename);
f.Write(json);
f.Close();
}
else
{
writer.WriteLine(string.Format("{0},{1},{2},{3}", frameCounter.ToString(), activity, car.GetSteering().ToString(), car.GetThrottle().ToString()));
}
}
if(lidar != null && lidar.gameObject.activeInHierarchy)
{
LidarPointArray pa = lidar.GetOutput();
if(pa != null)
{
string json = JsonUtility.ToJson(pa);
var filename = string.Format("lidar_{0}_{1}.txt", frameCounter.ToString(), activity);
var f = File.CreateText(GetLogPath() + filename);
f.Write(json);
f.Close();
}
}
if (optionlB_CamSensor != null && optionlB_CamSensor.gameObject.activeInHierarchy)
{
SaveCamSensor(camSensor, activity, "_a");
SaveCamSensor(optionlB_CamSensor, activity, "_b");
}
else
{
SaveCamSensor(camSensor, activity, "");
}
if (maxFramesToLog != -1 && frameCounter >= maxFramesToLog)
{
Shutdown();
this.gameObject.SetActive(false);
}
frameCounter = frameCounter + 1;
if (logDisplay != null)
logDisplay.text = "Log:" + frameCounter;
}
string GetUdacityStyleImageFilename()
{
return GetLogPath() + string.Format("IMG/center_{0,8:D8}.jpg", frameCounter);
}
string GetDonkeyStyleImageFilename()
{
float steering = car.GetSteering() / 25.0f;
float throttle = car.GetThrottle();
return GetLogPath() + string.Format("frame_{0,6:D6}_ttl_{1}_agl_{2}_mil_0.0.jpg",
frameCounter, throttle, steering);
}
string GetSharkStyleImageFilename()
{
int steering = (int)(car.GetSteering() / 25.0f * 32768.0f);
int throttle = (int)(car.GetThrottle() * 32768.0f);
return GetLogPath() + string.Format("frame_{0,6:D6}_st_{1}_th_{2}.jpg",
frameCounter, steering, throttle);
}
string GetDonkey2StyleImageFilename()
{
return GetLogPath() + string.Format("{0}_cam-image_array_.jpg", frameCounter);
}
//Save the camera sensor to an image. Use the suffix to distinguish between cameras.
void SaveCamSensor(CameraSensor cs, string prefix, string suffix)
{
if (cs != null)
{
Texture2D image = cs.GetImage();
ImageSaveJob ij = new ImageSaveJob();
if(UdacityStyle)
{
ij.filename = GetUdacityStyleImageFilename();
ij.bytes = image.EncodeToJPG();
}
else if (DonkeyStyle)
{
ij.filename = GetDonkeyStyleImageFilename();
ij.bytes = image.EncodeToJPG();
}
else if (DonkeyStyle2)
{
ij.filename = GetDonkey2StyleImageFilename();
ij.bytes = image.EncodeToJPG();
}
else if(SharkStyle)
{
ij.filename = GetSharkStyleImageFilename();
ij.bytes = image.EncodeToJPG();
}
else
{
ij.filename = GetLogPath() + string.Format("{0}_{1,8:D8}{2}.png", prefix, frameCounter, suffix);
ij.bytes = image.EncodeToPNG();
}
lock (this)
{
imagesToSave.Add(ij);
}
}
}
public void SaverThread()
{
while(true)
{
int count = 0;
lock(this)
{
count = imagesToSave.Count;
}
if(count > 0)
{
ImageSaveJob ij = imagesToSave[0];
//Debug.Log("saving: " + ij.filename);
File.WriteAllBytes(ij.filename, ij.bytes);
lock(this)
{
imagesToSave.RemoveAt(0);
}
}
}
}
public void Shutdown()
{
if(writer != null)
{
writer.Close();
writer = null;
}
if(thread != null)
{
thread.Abort();
thread = null;
}
bDoLog = false;
}
void OnDestroy()
{
Shutdown();
}
}

12
Scripts/Logger.cs.meta Executable file
View File

@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: d99138db4ad8544028a31fd0a13333ef
timeCreated: 1481994783
licenseType: Free
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

82
Scripts/MapManager.cs Executable file
View File

@ -0,0 +1,82 @@
using UnityEngine;
using System.Collections;
[System.Serializable]
public class Map
{
public int[,] cells;
public Vector3 startPos; //of 0,0 cell.
public float dX; //the delta X position to the next cell
public float dZ; //the delta Z position to the next cell
public int numX;
public int numZ;
public void Init(int numXCells, int numZCells)
{
numX = numXCells;
numZ = numZCells;
cells = new int[numXCells, numZCells];
}
}
public class MapManager : MonoBehaviour
{
//two node giving the extent of the map.
public Transform minLimit;
public Transform maxLimit;
public float cellSize = 1f; //how big is the cell in world units
public int numXCells = 1;
public int numZCells = 1;
public GameObject markerPrefab;
public int numMarkers = 1;
public int numMarkerIds = 10;
public Map map;
// Use this for initialization
void Awake () {
GenerateMap();
}
// Update is called once per frame
void GenerateMap ()
{
Vector3 minPos = minLimit.position;
Vector3 maxPos = maxLimit.position;
numXCells = (int)((maxPos.x - minPos.x) / cellSize);
numZCells = (int)((maxPos.z - minPos.z) / cellSize);
float dx = (maxPos.x - minPos.x) / (numXCells);
float dz = (maxPos.z - minPos.z) / (numZCells);
map = new Map();
map.Init(numXCells, numZCells);
map.startPos = minPos;
map.dX = dx;
map.dZ = dz;
for(int iM = 0; iM < numMarkers; iM++)
{
int iX = Random.Range(0, numXCells);
int iZ = Random.Range(0, numZCells);
Vector3 pos = Vector3.zero;
pos.x = iX * dx + minPos.x;
pos.z = iZ * dz + minPos.z;
GameObject go = Instantiate(markerPrefab, pos, Quaternion.identity) as GameObject;
Marker m = go.GetComponent<Marker>();
//go.transform.parent = this.transform;
if(m)
{
m.id = Random.Range(1, numMarkerIds);
//map cell has this id now.
map.cells[iX, iZ] = m.id;
}
}
}
}

12
Scripts/MapManager.cs.meta Executable file
View File

@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: f40a26aa70ad4435bb2d66bf90c1e3d6
timeCreated: 1484267705
licenseType: Free
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

156
Scripts/MapOverlay.cs Executable file
View File

@ -0,0 +1,156 @@
using System.Collections.Generic;
using UnityEngine;
// Draws a minimap of the generated road as a 2D overlay in the top-left corner,
// positioned just below the NN steering/throttle text. Shows white path lines
// and a red dot for the current car position. Auto-refreshes when the road changes.
public class MapOverlay : MonoBehaviour
{
public PathManager pathManager;
public Transform carTransform;
const int MAP_X = 5;
const int MAP_Y = 42; // below the one-line NN text (~25px tall + padding)
const int MAP_SIZE = 160;
static Texture2D _whiteTex;
static Texture2D _bgTex;
static Texture2D _dotTex;
static Texture2D WhiteTex
{
get
{
if (_whiteTex == null)
{
_whiteTex = new Texture2D(1, 1);
_whiteTex.SetPixel(0, 0, Color.white);
_whiteTex.Apply();
}
return _whiteTex;
}
}
List<Vector3> _nodes = new List<Vector3>();
float _minX, _maxX, _minZ, _maxZ;
int _lastNodeCount = -1;
float _lastFirstNodeX = float.MaxValue; // catches regen with same node count
float _lastFirstNodeZ = float.MaxValue;
bool _hasPath = false;
void Awake()
{
if (pathManager == null)
pathManager = FindObjectOfType<PathManager>();
_bgTex = new Texture2D(1, 1);
_bgTex.SetPixel(0, 0, new Color(0f, 0f, 0f, 0.55f));
_bgTex.Apply();
_dotTex = new Texture2D(4, 4);
for (int y = 0; y < 4; y++)
for (int x = 0; x < 4; x++)
_dotTex.SetPixel(x, y, Color.red);
_dotTex.Apply();
}
void Update()
{
// Find car transform once it exists
if (carTransform == null)
{
Car c = FindObjectOfType<Car>();
if (c != null) carTransform = c.transform;
}
// Re-cache path whenever it changes (road regen).
// Check both count and the 10th node position — regen always produces the same
// count (numSpans=100) but different positions for different seeds.
if (pathManager != null && pathManager.carPath != null)
{
var nodes = pathManager.carPath.centerNodes;
int n = nodes.Count;
float fx = n > 10 ? nodes[10].pos.x : float.MaxValue;
float fz = n > 10 ? nodes[10].pos.z : float.MaxValue;
if (n != _lastNodeCount || fx != _lastFirstNodeX || fz != _lastFirstNodeZ)
{
_lastFirstNodeX = fx;
_lastFirstNodeZ = fz;
RefreshPath();
}
}
}
void RefreshPath()
{
_nodes.Clear();
_minX = float.MaxValue; _maxX = float.MinValue;
_minZ = float.MaxValue; _maxZ = float.MinValue;
foreach (PathNode node in pathManager.carPath.centerNodes)
{
_nodes.Add(node.pos);
if (node.pos.x < _minX) _minX = node.pos.x;
if (node.pos.x > _maxX) _maxX = node.pos.x;
if (node.pos.z < _minZ) _minZ = node.pos.z;
if (node.pos.z > _maxZ) _maxZ = node.pos.z;
}
_lastNodeCount = _nodes.Count;
_hasPath = _nodes.Count > 1;
}
Vector2 WorldToMap(Vector3 world)
{
float rangeX = _maxX - _minX;
float rangeZ = _maxZ - _minZ;
float range = Mathf.Max(rangeX, rangeZ, 1f);
float pad = 6f;
float inner = MAP_SIZE - pad * 2f;
float px = MAP_X + pad + (world.x - _minX) / range * inner;
float pz = MAP_Y + pad + (1f - (world.z - _minZ) / range) * inner; // flip Z → screen Y
return new Vector2(px, pz);
}
static void DrawLine(Vector2 a, Vector2 b, Color color, float thickness = 1.5f)
{
Vector2 delta = b - a;
if (delta.sqrMagnitude < 0.01f) return;
float angle = Mathf.Atan2(delta.y, delta.x) * Mathf.Rad2Deg;
float length = delta.magnitude;
Color prev = GUI.color;
GUI.color = color;
Matrix4x4 saved = GUI.matrix;
GUIUtility.RotateAroundPivot(angle, a);
GUI.DrawTexture(new Rect(a.x, a.y - thickness * 0.5f, length, thickness), WhiteTex);
GUI.matrix = saved;
GUI.color = prev;
}
void OnGUI()
{
if (!_hasPath) return;
// Dark background
GUI.DrawTexture(new Rect(MAP_X - 1, MAP_Y - 1, MAP_SIZE + 2, MAP_SIZE + 2), _bgTex);
// Path lines
for (int i = 0; i < _nodes.Count - 1; i++)
{
Vector2 a = WorldToMap(_nodes[i]);
Vector2 b = WorldToMap(_nodes[i + 1]);
DrawLine(a, b, Color.white, 1.5f);
}
// Car dot
if (carTransform != null)
{
Vector2 cp = WorldToMap(carTransform.position);
GUI.DrawTexture(new Rect(cp.x - 3f, cp.y - 3f, 6f, 6f), _dotTex);
}
}
}

2
Scripts/MapOverlay.cs.meta Executable file
View File

@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 20dd129af531d464c9226ba59011e113

7
Scripts/Marker.cs Executable file
View File

@ -0,0 +1,7 @@
using UnityEngine;
using System.Collections;
public class Marker : MonoBehaviour
{
public int id;
}

12
Scripts/Marker.cs.meta Executable file
View File

@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: b0bd2d647423d4a38b51dd85df5e0bbc
timeCreated: 1449072422
licenseType: Free
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

Some files were not shown because too many files have changed in this diff Show More