├── .gitignore ├── Assets ├── Concrete_Albedo.tga ├── Concrete_Albedo.tga.meta ├── Plugins.meta ├── Plugins │ ├── Editor.meta │ └── Editor │ │ ├── JetBrains.meta │ │ └── JetBrains │ │ ├── Unity3DRider.cs │ │ └── Unity3DRider.cs.meta ├── Scenes.meta ├── Scenes │ ├── SampleScene.meta │ ├── SampleScene.unity │ ├── SampleScene.unity.meta │ └── SampleScene │ │ ├── LightingData.asset │ │ ├── LightingData.asset.meta │ │ ├── ReflectionProbe-0.exr │ │ └── ReflectionProbe-0.exr.meta ├── SimpleJobifiedPhysics.cs ├── SimpleJobifiedPhysics.cs.meta ├── SimpleMaterial.mat ├── SimpleMaterial.mat.meta ├── Wall.mat └── Wall.mat.meta ├── Docs └── phys.gif ├── LICENSE ├── Packages └── manifest.json ├── ProjectSettings ├── AudioManager.asset ├── ClusterInputManager.asset ├── DynamicsManager.asset ├── EditorBuildSettings.asset ├── EditorSettings.asset ├── GraphicsSettings.asset ├── InputManager.asset ├── NavMeshAreas.asset ├── NetworkManager.asset ├── Physics2DSettings.asset ├── PresetManager.asset ├── ProjectSettings.asset ├── ProjectVersion.txt ├── QualitySettings.asset ├── TagManager.asset ├── TimeManager.asset └── UnityConnectSettings.asset └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | /[Ll]ibrary/ 2 | /[Tt]emp/ 3 | /[Oo]bj/ 4 | /[Bb]uild/ 5 | /[Bb]uilds/ 6 | /Assets/AssetStoreTools* 7 | 8 | # Visual Studio 2015 cache directory 9 | /.vs/ 10 | 11 | # Autogenerated VS/MD/Consulo solution and project files 12 | ExportedObj/ 13 | .consulo/ 14 | *.csproj 15 | *.unityproj 16 | *.sln 17 | *.suo 18 | *.tmp 19 | *.user 20 | *.userprefs 21 | *.pidb 22 | *.booproj 23 | *.svd 24 | *.pdb 25 | 26 | # Unity3D generated meta files 27 | *.pidb.meta 28 | 29 | # Unity3D Generated File On Crash Reports 30 | sysinfo.txt 31 | 32 | # Builds 33 | *.apk 34 | *.unitypackage 35 | /.idea 36 | -------------------------------------------------------------------------------- /Assets/Concrete_Albedo.tga: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LotteMakesStuff/SimplePhysicsDemo/77bc1aada2847529018ad2f0b05357c3bf6551f3/Assets/Concrete_Albedo.tga -------------------------------------------------------------------------------- /Assets/Concrete_Albedo.tga.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 12cbdb496dafb464097861bafa9ea5f0 3 | TextureImporter: 4 | fileIDToRecycleName: {} 5 | externalObjects: {} 6 | serializedVersion: 5 7 | mipmaps: 8 | mipMapMode: 0 9 | enableMipMap: 1 10 | sRGBTexture: 1 11 | linearTexture: 0 12 | fadeOut: 0 13 | borderMipMap: 0 14 | mipMapsPreserveCoverage: 0 15 | alphaTestReferenceValue: 0.5 16 | mipMapFadeDistanceStart: 1 17 | mipMapFadeDistanceEnd: 3 18 | bumpmap: 19 | convertToNormalMap: 0 20 | externalNormalMap: 0 21 | heightScale: 0.25 22 | normalMapFilter: 0 23 | isReadable: 0 24 | grayScaleToAlpha: 0 25 | generateCubemap: 6 26 | cubemapConvolution: 0 27 | seamlessCubemap: 0 28 | textureFormat: 1 29 | maxTextureSize: 2048 30 | textureSettings: 31 | serializedVersion: 2 32 | filterMode: -1 33 | aniso: -1 34 | mipBias: -1 35 | wrapU: -1 36 | wrapV: -1 37 | wrapW: -1 38 | nPOTScale: 1 39 | lightmap: 0 40 | compressionQuality: 50 41 | spriteMode: 0 42 | spriteExtrude: 1 43 | spriteMeshType: 1 44 | alignment: 0 45 | spritePivot: {x: 0.5, y: 0.5} 46 | spriteBorder: {x: 0, y: 0, z: 0, w: 0} 47 | spritePixelsToUnits: 100 48 | alphaUsage: 1 49 | alphaIsTransparency: 0 50 | spriteTessellationDetail: -1 51 | textureType: 0 52 | textureShape: 1 53 | singleChannelComponent: 0 54 | maxTextureSizeSet: 0 55 | compressionQualitySet: 0 56 | textureFormatSet: 0 57 | platformSettings: 58 | - serializedVersion: 2 59 | buildTarget: DefaultTexturePlatform 60 | maxTextureSize: 2048 61 | resizeAlgorithm: 0 62 | textureFormat: -1 63 | textureCompression: 1 64 | compressionQuality: 50 65 | crunchedCompression: 0 66 | allowsAlphaSplitting: 0 67 | overridden: 0 68 | androidETC2FallbackOverride: 0 69 | spriteSheet: 70 | serializedVersion: 2 71 | sprites: [] 72 | outline: [] 73 | physicsShape: [] 74 | bones: [] 75 | spriteID: 76 | vertices: [] 77 | indices: 78 | edges: [] 79 | weights: [] 80 | spritePackingTag: 81 | userData: 82 | assetBundleName: 83 | assetBundleVariant: 84 | -------------------------------------------------------------------------------- /Assets/Plugins.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: b26a534f8461957418a78eae55db93b9 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Assets/Plugins/Editor.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: c1beccf47593aeb429766c5a1b350a62 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Assets/Plugins/Editor/JetBrains.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 2c3b5297b4837b142a5eaeb02cb1fee3 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Assets/Plugins/Editor/JetBrains/Unity3DRider.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // This code was generated by a tool. 4 | // Version: 2.1.3.5034 5 | // 6 | // Changes to this file may cause incorrect behavior and will be lost if 7 | // the code is regenerated. 8 | // 9 | //------------------------------------------------------------------------------ 10 | using Application = UnityEngine.Application; 11 | using Debug = UnityEngine.Debug; 12 | using System.Collections.Generic; 13 | using System.Diagnostics; 14 | using System.IO; 15 | using System.Linq; 16 | using System.Net; 17 | using System.Reflection; 18 | using System.Runtime.CompilerServices; 19 | using System.Runtime.InteropServices; 20 | using System.Text.RegularExpressions; 21 | using System.Text; 22 | using System.Xml.Linq; 23 | using System; 24 | using UnityEditor; 25 | using UnityEngine; 26 | 27 | namespace Plugins.Editor.JetBrains 28 | { 29 | public class RiderAssetPostprocessor : AssetPostprocessor 30 | { 31 | public static void OnGeneratedCSProjectFiles() 32 | { 33 | if (!RiderPlugin.Enabled) 34 | return; 35 | var currentDirectory = Directory.GetCurrentDirectory(); 36 | var projectFiles = Directory.GetFiles(currentDirectory, "*.csproj"); 37 | 38 | foreach (var file in projectFiles) 39 | { 40 | UpgradeProjectFile(file); 41 | } 42 | 43 | var slnFile = RiderPlugin.SlnFile; 44 | if (string.IsNullOrEmpty(slnFile)) 45 | return; 46 | 47 | RiderPlugin.Log(RiderPlugin.LoggingLevel.Verbose, string.Format("Post-processing {0}", slnFile)); 48 | string slnAllText = File.ReadAllText(slnFile); 49 | const string unityProjectGuid = @"Project(""{E097FAD1-6243-4DAD-9C02-E9B9EFC3FFC1}"")"; 50 | if (!slnAllText.Contains(unityProjectGuid)) 51 | { 52 | string matchGUID = @"Project\(\""\{[A-Z0-9]{8}-[A-Z0-9]{4}-[A-Z0-9]{4}-[A-Z0-9]{4}-[A-Z0-9]{12}\}\""\)"; 53 | // Unity may put a random guid, unityProjectGuid will help VSTU recognize Rider-generated projects 54 | slnAllText = Regex.Replace(slnAllText, matchGUID, unityProjectGuid); 55 | } 56 | 57 | var lines = slnAllText.Split(new[] {Environment.NewLine}, StringSplitOptions.RemoveEmptyEntries); 58 | var sb = new StringBuilder(); 59 | foreach (var line in lines) 60 | { 61 | if (line.StartsWith("Project(")) 62 | { 63 | MatchCollection mc = Regex.Matches(line, "\"([^\"]*)\""); 64 | //RiderPlugin.Log(RiderPlugin.LoggingLevel.Info, "mc[1]: "+mc[1].Value); 65 | //RiderPlugin.Log(RiderPlugin.LoggingLevel.Info, "mc[2]: "+mc[2].Value); 66 | var to = GetFileNameWithoutExtension(mc[2].Value.Substring(1, mc[2].Value.Length-1)); // remove quotes 67 | //RiderPlugin.Log(RiderPlugin.LoggingLevel.Info, "to:" + to); 68 | //RiderPlugin.Log(RiderPlugin.LoggingLevel.Info, line); 69 | var newLine = line.Substring(0, mc[1].Index + 1) + to + line.Substring(mc[1].Index + mc[1].Value.Length - 1); 70 | sb.Append(newLine); 71 | //RiderPlugin.Log(RiderPlugin.LoggingLevel.Info, newLine); 72 | } 73 | else 74 | { 75 | sb.Append(line); 76 | } 77 | sb.Append(Environment.NewLine); 78 | } 79 | File.WriteAllText(slnFile, sb.ToString()); 80 | } 81 | 82 | private static string GetFileNameWithoutExtension(string path) 83 | { 84 | if (string.IsNullOrEmpty(path)) 85 | return null; 86 | int length; 87 | return (length = path.LastIndexOf('.')) == -1 ? path : path.Substring(0, length); 88 | } 89 | 90 | private static void UpgradeProjectFile(string projectFile) 91 | { 92 | RiderPlugin.Log(RiderPlugin.LoggingLevel.Verbose, string.Format("Post-processing {0}", projectFile)); 93 | var doc = XDocument.Load(projectFile); 94 | var projectContentElement = doc.Root; 95 | XNamespace xmlns = projectContentElement.Name.NamespaceName; // do not use var 96 | 97 | FixTargetFrameworkVersion(projectContentElement, xmlns); 98 | FixSystemXml(projectContentElement, xmlns); 99 | SetLangVersion(projectContentElement, xmlns); 100 | // Unity_5_6_OR_NEWER switched to nunit 3.5 101 | #if UNITY_5_6_OR_NEWER 102 | ChangeNunitReference(projectContentElement, xmlns); 103 | #endif 104 | 105 | #if !UNITY_2017_1_OR_NEWER // Unity 2017.1 and later has this features by itself 106 | SetManuallyDefinedComilingSettings(projectFile, projectContentElement, xmlns); 107 | #endif 108 | SetXCodeDllReference("UnityEditor.iOS.Extensions.Xcode.dll", xmlns, projectContentElement); 109 | SetXCodeDllReference("UnityEditor.iOS.Extensions.Common.dll", xmlns, projectContentElement); 110 | ApplyManualCompilingSettingsReferences(projectContentElement, xmlns); 111 | doc.Save(projectFile); 112 | } 113 | 114 | private static void FixSystemXml(XElement projectContentElement, XNamespace xmlns) 115 | { 116 | var el = projectContentElement 117 | .Elements(xmlns+"ItemGroup") 118 | .Elements(xmlns+"Reference") 119 | .FirstOrDefault(a => a.Attribute("Include").Value=="System.XML"); 120 | if (el != null) 121 | { 122 | el.Attribute("Include").Value = "System.Xml"; 123 | } 124 | } 125 | 126 | private static void ChangeNunitReference(XElement projectContentElement, XNamespace xmlns) 127 | { 128 | var el = projectContentElement 129 | .Elements(xmlns+"ItemGroup") 130 | .Elements(xmlns+"Reference") 131 | .FirstOrDefault(a => a.Attribute("Include").Value=="nunit.framework"); 132 | if (el != null) 133 | { 134 | var hintPath = el.Elements(xmlns + "HintPath").FirstOrDefault(); 135 | if (hintPath != null) 136 | { 137 | var path = Path.GetFullPath("Library/resharper-unity-libs/nunit3.5.0/nunit.framework.dll"); 138 | if (new FileInfo(path).Exists) 139 | hintPath.Value = path; 140 | } 141 | } 142 | } 143 | 144 | private static readonly string PROJECT_MANUAL_CONFIG_ABSOLUTE_FILE_PATH = Path.GetFullPath("Assets/mcs.rsp"); 145 | #if !UNITY_2017_1_OR_NEWER // Unity 2017.1 and later has this features by itself 146 | private const string UNITY_PLAYER_PROJECT_NAME = "Assembly-CSharp.csproj"; 147 | private const string UNITY_EDITOR_PROJECT_NAME = "Assembly-CSharp-Editor.csproj"; 148 | private const string UNITY_UNSAFE_KEYWORD = "-unsafe"; 149 | private const string UNITY_DEFINE_KEYWORD = "-define:"; 150 | private static readonly string PLAYER_PROJECT_MANUAL_CONFIG_ABSOLUTE_FILE_PATH = Path.GetFullPath("Assets/smcs.rsp"); 151 | private static readonly string EDITOR_PROJECT_MANUAL_CONFIG_ABSOLUTE_FILE_PATH = Path.GetFullPath("Assets/gmcs.rsp"); 152 | 153 | private static void SetManuallyDefinedComilingSettings(string projectFile, XElement projectContentElement, XNamespace xmlns) 154 | { 155 | string configPath = null; 156 | 157 | if (IsPlayerProjectFile(projectFile) || IsEditorProjectFile(projectFile)) 158 | { 159 | //Prefer mcs.rsp if it exists 160 | if (File.Exists(PROJECT_MANUAL_CONFIG_ABSOLUTE_FILE_PATH)) 161 | { 162 | configPath = PROJECT_MANUAL_CONFIG_ABSOLUTE_FILE_PATH; 163 | } 164 | else 165 | { 166 | if (IsPlayerProjectFile(projectFile)) 167 | configPath = PLAYER_PROJECT_MANUAL_CONFIG_ABSOLUTE_FILE_PATH; 168 | else if (IsEditorProjectFile(projectFile)) 169 | configPath = EDITOR_PROJECT_MANUAL_CONFIG_ABSOLUTE_FILE_PATH; 170 | } 171 | } 172 | 173 | if(!string.IsNullOrEmpty(configPath)) 174 | ApplyManualCompilingSettings(configPath 175 | , projectContentElement 176 | , xmlns); 177 | } 178 | 179 | private static void ApplyManualCompilingSettings(string configFilePath, XElement projectContentElement, XNamespace xmlns) 180 | { 181 | if (File.Exists(configFilePath)) 182 | { 183 | var configText = File.ReadAllText(configFilePath); 184 | if (configText.Contains(UNITY_UNSAFE_KEYWORD)) 185 | { 186 | // Add AllowUnsafeBlocks to the .csproj. Unity doesn't generate it (although VSTU does). 187 | // Strictly necessary to compile unsafe code 188 | ApplyAllowUnsafeBlocks(projectContentElement, xmlns); 189 | } 190 | if (configText.Contains(UNITY_DEFINE_KEYWORD)) 191 | { 192 | // defines could be 193 | // 1) -define:DEFINE1,DEFINE2 194 | // 2) -define:DEFINE1;DEFINE2 195 | // 3) -define:DEFINE1 -define:DEFINE2 196 | // 4) -define:DEFINE1,DEFINE2;DEFINE3 197 | // tested on "-define:DEF1;DEF2 -define:DEF3,DEF4;DEFFFF \n -define:DEF5" 198 | // result: DEF1, DEF2, DEF3, DEF4, DEFFFF, DEF5 199 | 200 | var definesList = new List(); 201 | var compileFlags = configText.Split(' ', '\n'); 202 | foreach (var flag in compileFlags) 203 | { 204 | var f = flag.Trim(); 205 | if (f.Contains(UNITY_DEFINE_KEYWORD)) 206 | { 207 | var defineEndPos = f.IndexOf(UNITY_DEFINE_KEYWORD) + UNITY_DEFINE_KEYWORD.Length; 208 | var definesSubString = f.Substring(defineEndPos,f.Length - defineEndPos); 209 | definesSubString = definesSubString.Replace(";", ","); 210 | definesList.AddRange(definesSubString.Split(',')); 211 | } 212 | } 213 | 214 | ApplyCustomDefines(definesList.ToArray(), projectContentElement, xmlns); 215 | } 216 | } 217 | } 218 | 219 | private static void ApplyCustomDefines(string[] customDefines, XElement projectContentElement, XNamespace xmlns) 220 | { 221 | var definesString = string.Join(";", customDefines); 222 | 223 | var DefineConstants = projectContentElement 224 | .Elements(xmlns+"PropertyGroup") 225 | .Elements(xmlns+"DefineConstants") 226 | .FirstOrDefault(definesConsts=> !string.IsNullOrEmpty(definesConsts.Value)); 227 | 228 | if (DefineConstants != null) 229 | { 230 | DefineConstants.SetValue(DefineConstants.Value + ";" + definesString); 231 | } 232 | } 233 | 234 | private static void ApplyAllowUnsafeBlocks(XElement projectContentElement, XNamespace xmlns) 235 | { 236 | projectContentElement.AddFirst( 237 | new XElement(xmlns + "PropertyGroup", new XElement(xmlns + "AllowUnsafeBlocks", true))); 238 | } 239 | 240 | private static bool IsPlayerProjectFile(string projectFile) 241 | { 242 | return Path.GetFileName(projectFile) == UNITY_PLAYER_PROJECT_NAME; 243 | } 244 | 245 | private static bool IsEditorProjectFile(string projectFile) 246 | { 247 | return Path.GetFileName(projectFile) == UNITY_EDITOR_PROJECT_NAME; 248 | } 249 | #endif 250 | private static void SetXCodeDllReference(string name, XNamespace xmlns, XElement projectContentElement) 251 | { 252 | string unityAppBaseFolder = Path.GetDirectoryName(EditorApplication.applicationPath); 253 | 254 | var xcodeDllPath = Path.Combine(unityAppBaseFolder, Path.Combine("Data/PlaybackEngines/iOSSupport", name)); 255 | if (!File.Exists(xcodeDllPath)) 256 | xcodeDllPath = Path.Combine(unityAppBaseFolder, Path.Combine("PlaybackEngines/iOSSupport", name)); 257 | 258 | if (File.Exists(xcodeDllPath)) 259 | { 260 | var itemGroup = new XElement(xmlns + "ItemGroup"); 261 | var reference = new XElement(xmlns + "Reference"); 262 | reference.Add(new XAttribute("Include", Path.GetFileNameWithoutExtension(xcodeDllPath))); 263 | reference.Add(new XElement(xmlns + "HintPath", xcodeDllPath)); 264 | itemGroup.Add(reference); 265 | projectContentElement.Add(itemGroup); 266 | } 267 | } 268 | 269 | private const string UNITY_REFERENCE_KEYWORD = "-r:"; 270 | /// 271 | /// Handles custom references -r: in "mcs.rsp" 272 | /// 273 | /// 274 | /// 275 | private static void ApplyManualCompilingSettingsReferences(XElement projectContentElement, XNamespace xmlns) 276 | { 277 | if (!File.Exists(PROJECT_MANUAL_CONFIG_ABSOLUTE_FILE_PATH)) 278 | return; 279 | 280 | var configFilePath = PROJECT_MANUAL_CONFIG_ABSOLUTE_FILE_PATH; 281 | 282 | if (File.Exists(configFilePath)) 283 | { 284 | var configText = File.ReadAllText(configFilePath); 285 | if (configText.Contains(UNITY_REFERENCE_KEYWORD)) 286 | { 287 | var referenceList = new List(); 288 | var compileFlags = configText.Split(' ', '\n'); 289 | foreach (var flag in compileFlags) 290 | { 291 | var f = flag.Trim(); 292 | if (f.Contains(UNITY_REFERENCE_KEYWORD)) 293 | { 294 | var defineEndPos = f.IndexOf(UNITY_REFERENCE_KEYWORD) + UNITY_REFERENCE_KEYWORD.Length; 295 | var definesSubString = f.Substring(defineEndPos,f.Length - defineEndPos); 296 | definesSubString = definesSubString.Replace(";", ","); 297 | referenceList.AddRange(definesSubString.Split(',')); 298 | } 299 | } 300 | 301 | foreach (var referenceName in referenceList) 302 | { 303 | ApplyCustomReference(referenceName, projectContentElement, xmlns); 304 | } 305 | } 306 | } 307 | } 308 | 309 | private static void ApplyCustomReference(string name, XElement projectContentElement, XNamespace xmlns) 310 | { 311 | var itemGroup = new XElement(xmlns + "ItemGroup"); 312 | var reference = new XElement(xmlns + "Reference"); 313 | reference.Add(new XAttribute("Include", Path.GetFileNameWithoutExtension(name))); 314 | itemGroup.Add(reference); 315 | projectContentElement.Add(itemGroup); 316 | } 317 | 318 | // Set appropriate version 319 | private static void FixTargetFrameworkVersion(XElement projectElement, XNamespace xmlns) 320 | { 321 | var targetFrameworkVersion = projectElement.Elements(xmlns + "PropertyGroup") 322 | .Elements(xmlns + "TargetFrameworkVersion") 323 | .FirstOrDefault(); // Processing csproj files, which are not Unity-generated #56 324 | if (targetFrameworkVersion != null) 325 | { 326 | int scriptingRuntime = 0; // legacy runtime 327 | try 328 | { 329 | var property = typeof(EditorApplication).GetProperty("scriptingRuntimeVersion"); 330 | scriptingRuntime = (int)property.GetValue(null, null); 331 | if (scriptingRuntime>0) 332 | RiderPlugin.Log(RiderPlugin.LoggingLevel.Verbose, "Latest runtime detected."); 333 | } 334 | catch(Exception){} 335 | 336 | if (scriptingRuntime>0) 337 | targetFrameworkVersion.SetValue("v"+RiderPlugin.TargetFrameworkVersion); 338 | else 339 | targetFrameworkVersion.SetValue("v"+RiderPlugin.TargetFrameworkVersionOldMono); 340 | } 341 | } 342 | 343 | private static void SetLangVersion(XElement projectElement, XNamespace xmlns) 344 | { 345 | // Add LangVersion to the .csproj. Unity doesn't generate it (although VSTU does). 346 | // Not strictly necessary, as the Unity plugin for Rider will work it out, but setting 347 | // it makes Rider work if it's not installed. 348 | var langVersion = projectElement.Elements(xmlns + "PropertyGroup").Elements(xmlns + "LangVersion") 349 | .FirstOrDefault(); // Processing csproj files, which are not Unity-generated #56 350 | if (langVersion != null) 351 | { 352 | langVersion.SetValue(GetLanguageLevel()); 353 | } 354 | else 355 | { 356 | projectElement.AddFirst(new XElement(xmlns + "PropertyGroup", 357 | new XElement(xmlns + "LangVersion", GetLanguageLevel()))); 358 | } 359 | } 360 | 361 | private static string GetLanguageLevel() 362 | { 363 | // https://bitbucket.org/alexzzzz/unity-c-5.0-and-6.0-integration/src 364 | if (Directory.Exists(Path.GetFullPath("CSharp70Support"))) 365 | return "7"; 366 | if (Directory.Exists(Path.GetFullPath("CSharp60Support"))) 367 | return "6"; 368 | 369 | // Unity 5.5 supports C# 6, but only when targeting .NET 4.6. The enum doesn't exist pre Unity 5.5 370 | #if !UNITY_5_6_OR_NEWER 371 | if ((int)PlayerSettings.apiCompatibilityLevel >= 3) 372 | #else 373 | if ((int) PlayerSettings.GetApiCompatibilityLevel(EditorUserBuildSettings.selectedBuildTargetGroup) >= 3) 374 | #endif 375 | return "6"; 376 | 377 | return "4"; 378 | } 379 | 380 | private static Type ourPdb2MdbDriver; 381 | private static Type Pdb2MdbDriver 382 | { 383 | get 384 | { 385 | if (ourPdb2MdbDriver != null) 386 | return ourPdb2MdbDriver; 387 | Assembly assembly; 388 | try 389 | { 390 | var path = Path.GetFullPath(@"Library\resharper-unity-libs\pdb2mdb.exe"); 391 | var bytes = File.ReadAllBytes(path); 392 | assembly = Assembly.Load(bytes); 393 | } 394 | catch (Exception) 395 | { 396 | RiderPlugin.Log(RiderPlugin.LoggingLevel.Verbose, "Loading pdb2mdb failed."); 397 | assembly = null; 398 | } 399 | 400 | if (assembly == null) 401 | return null; 402 | var type = assembly.GetType("Pdb2Mdb.Driver"); 403 | if (type == null) 404 | return null; 405 | return ourPdb2MdbDriver = type; 406 | } 407 | } 408 | 409 | public static void OnPostprocessAllAssets(string[] importedAssets, string[] deletedAssets, string[] movedAssets, string[] movedFromPath) 410 | { 411 | if (!RiderPlugin.Enabled) 412 | return; 413 | var toBeConverted = importedAssets.Where(a => 414 | a.EndsWith(".dll", StringComparison.OrdinalIgnoreCase) && 415 | importedAssets.Any(a1 => a1 == Path.ChangeExtension(a, ".pdb")) && 416 | importedAssets.All(b => b != Path.ChangeExtension(a, ".dll.mdb"))) 417 | .ToArray(); 418 | foreach (var asset in toBeConverted) 419 | { 420 | var pdb = Path.ChangeExtension(asset, ".pdb"); 421 | if (!IsPortablePdb(pdb)) 422 | ConvertSymbolsForAssembly(asset); 423 | else 424 | RiderPlugin.Log(RiderPlugin.LoggingLevel.Verbose, string.Format("mdb generation for Portable pdb is not supported. {0}", pdb)); 425 | } 426 | } 427 | 428 | private static void ConvertSymbolsForAssembly(string asset) 429 | { 430 | if (Pdb2MdbDriver == null) 431 | { 432 | RiderPlugin.Log(RiderPlugin.LoggingLevel.Verbose, "FailedToConvertDebugSymbolsNoPdb2mdb."); 433 | return; 434 | } 435 | 436 | var method = Pdb2MdbDriver.GetMethod("Main", BindingFlags.Static | BindingFlags.NonPublic); 437 | if (method == null) 438 | { 439 | RiderPlugin.Log(RiderPlugin.LoggingLevel.Verbose, "WarningFailedToConvertDebugSymbolsPdb2mdbMainIsNull."); 440 | return; 441 | } 442 | 443 | var strArray = new[] { Path.GetFullPath(asset) }; 444 | method.Invoke(null, new object[] { strArray }); 445 | } 446 | 447 | //https://github.com/xamarin/xamarin-android/commit/4e30546f 448 | const uint ppdb_signature = 0x424a5342; 449 | public static bool IsPortablePdb(string filename) 450 | { 451 | try 452 | { 453 | using (var fs = new FileStream(filename, FileMode.Open, FileAccess.Read)) 454 | { 455 | using (var br = new BinaryReader(fs)) 456 | { 457 | return br.ReadUInt32() == ppdb_signature; 458 | } 459 | } 460 | } 461 | catch 462 | { 463 | return false; 464 | } 465 | } 466 | } 467 | } 468 | 469 | namespace Plugins.Editor.JetBrains 470 | { 471 | [InitializeOnLoad] 472 | public static class RiderPlugin 473 | { 474 | private static bool Initialized; 475 | internal static string SlnFile; 476 | 477 | public static void Log(LoggingLevel level, string initialText) 478 | { 479 | if (level < SelectedLoggingLevel) return; 480 | 481 | var text = "[Rider] "+DateTime.Now.ToString("HH:mm:ss:ff")+" [" + level + "] " + initialText; 482 | 483 | switch (level) 484 | { 485 | case LoggingLevel.Warning: 486 | Debug.LogWarning(text); 487 | break; 488 | default: 489 | Debug.Log(text); 490 | break; 491 | } 492 | } 493 | 494 | private static string GetDefaultApp() 495 | { 496 | var allFoundPaths = GetAllRiderPaths().Select(a=>new FileInfo(a).FullName).ToArray(); 497 | var externalEditor = GetExternalScriptEditor(); 498 | if (!string.IsNullOrEmpty(externalEditor)) 499 | { 500 | var alreadySetPath = new FileInfo(externalEditor).FullName; 501 | if (RiderPathExist(alreadySetPath)) 502 | { 503 | if (!allFoundPaths.Any() || allFoundPaths.Any() && allFoundPaths.Contains(alreadySetPath)) 504 | { 505 | RiderPath = alreadySetPath; 506 | return alreadySetPath; 507 | } 508 | } 509 | } 510 | if (!string.IsNullOrEmpty(RiderPath) && allFoundPaths.Contains(new FileInfo(RiderPath).FullName)) {} 511 | else 512 | RiderPath = allFoundPaths.FirstOrDefault(); 513 | 514 | return RiderPath; 515 | } 516 | 517 | private static string[] GetAllRiderPaths() 518 | { 519 | switch (SystemInfoRiderPlugin.operatingSystemFamily) 520 | { 521 | case OperatingSystemFamily.Windows: 522 | string[] folders = 523 | { 524 | @"C:\ProgramData\Microsoft\Windows\Start Menu\Programs\JetBrains", Path.Combine( 525 | Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), 526 | @"Microsoft\Windows\Start Menu\Programs\JetBrains Toolbox") 527 | }; 528 | 529 | var newPathLnks = folders.Select(b => new DirectoryInfo(b)).Where(a => a.Exists) 530 | .SelectMany(c => c.GetFiles("*Rider*.lnk")).ToArray(); 531 | if (newPathLnks.Any()) 532 | { 533 | var newPaths = newPathLnks 534 | .Select(newPathLnk => new FileInfo(ShortcutResolver.Resolve(newPathLnk.FullName))) 535 | .Where(fi => File.Exists(fi.FullName)) 536 | .ToArray() 537 | .OrderByDescending(fi => FileVersionInfo.GetVersionInfo(fi.FullName).ProductVersion) 538 | .Select(a => a.FullName).ToArray(); 539 | 540 | return newPaths; 541 | } 542 | break; 543 | 544 | case OperatingSystemFamily.MacOSX: 545 | // "/Applications/*Rider*.app" 546 | //"~/Applications/JetBrains Toolbox/*Rider*.app" 547 | string[] foldersMac = 548 | { 549 | "/Applications", Path.Combine(Environment.GetEnvironmentVariable("HOME"), "Applications/JetBrains Toolbox") 550 | }; 551 | var newPathsMac = foldersMac.Select(b => new DirectoryInfo(b)).Where(a => a.Exists) 552 | .SelectMany(c => c.GetDirectories("*Rider*.app")) 553 | .Select(a => a.FullName).ToArray(); 554 | return newPathsMac; 555 | } 556 | return new string[0]; 557 | } 558 | 559 | private static string GetTargetFrameworkVersionDefault(string defaultValue) 560 | { 561 | if (SystemInfoRiderPlugin.operatingSystemFamily == OperatingSystemFamily.Windows) 562 | { 563 | var dir = new DirectoryInfo(@"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework"); 564 | if (dir.Exists) 565 | { 566 | var availableVersions = dir.GetDirectories("v*").Select(a => a.Name.Substring(1)) 567 | .Where(v => TryCatch(v, s => { })).ToArray(); 568 | if (availableVersions.Any() && !availableVersions.Contains(defaultValue)) 569 | { 570 | defaultValue = availableVersions.OrderBy(a => new Version(a)).Last(); 571 | } 572 | } 573 | } 574 | return defaultValue; 575 | } 576 | 577 | 578 | public static string TargetFrameworkVersion 579 | { 580 | get 581 | { 582 | return EditorPrefs.GetString("Rider_TargetFrameworkVersion", GetTargetFrameworkVersionDefault("4.6")); 583 | } 584 | set 585 | { 586 | TryCatch(value, val => 587 | { 588 | EditorPrefs.SetString("Rider_TargetFrameworkVersion", val); 589 | }); 590 | } 591 | } 592 | 593 | public static string TargetFrameworkVersionOldMono 594 | { 595 | get 596 | { 597 | return EditorPrefs.GetString("Rider_TargetFrameworkVersionOldMono", GetTargetFrameworkVersionDefault("3.5")); 598 | } 599 | set 600 | { 601 | TryCatch(value, val => 602 | { 603 | EditorPrefs.SetString("Rider_TargetFrameworkVersionOldMono", val); 604 | }); 605 | } 606 | } 607 | 608 | private static bool TryCatch(string value, Action action) 609 | { 610 | try 611 | { 612 | new Version(value); // mono 2.6 doesn't support Version.TryParse 613 | action(value); 614 | return true; 615 | } 616 | catch (ArgumentException) 617 | { 618 | } // can't put loggin here because ot fire on every symbol 619 | catch (FormatException) 620 | { 621 | } 622 | return false; 623 | } 624 | 625 | public static string RiderPath 626 | { 627 | get { return EditorPrefs.GetString("Rider_RiderPath", GetAllRiderPaths().FirstOrDefault()); } 628 | set { EditorPrefs.SetString("Rider_RiderPath", value); } 629 | } 630 | 631 | public enum LoggingLevel 632 | { 633 | Verbose = 0, 634 | Info = 1, 635 | Warning = 2 636 | } 637 | 638 | public static LoggingLevel SelectedLoggingLevel 639 | { 640 | get { return (LoggingLevel) EditorPrefs.GetInt("Rider_SelectedLoggingLevel", 1); } 641 | set { EditorPrefs.SetInt("Rider_SelectedLoggingLevel", (int) value); } 642 | } 643 | 644 | public static bool RiderInitializedOnce 645 | { 646 | get { return EditorPrefs.GetBool("RiderInitializedOnce", false); } 647 | set { EditorPrefs.SetBool("RiderInitializedOnce", value); } 648 | } 649 | 650 | internal static bool Enabled 651 | { 652 | get 653 | { 654 | var defaultApp = GetExternalScriptEditor(); 655 | return !string.IsNullOrEmpty(defaultApp) && Path.GetFileName(defaultApp).ToLower().Contains("rider"); 656 | } 657 | } 658 | 659 | static RiderPlugin() 660 | { 661 | var riderPath = GetDefaultApp(); 662 | if (!RiderPathExist(riderPath)) 663 | return; 664 | 665 | AddRiderToRecentlyUsedScriptApp(riderPath, "RecentlyUsedScriptApp"); 666 | if (!RiderInitializedOnce) 667 | { 668 | SetExternalScriptEditor(riderPath); 669 | RiderInitializedOnce = true; 670 | } 671 | if (Enabled) 672 | { 673 | InitRiderPlugin(); 674 | } 675 | } 676 | 677 | private static void InitRiderPlugin() 678 | { 679 | var projectDirectory = Directory.GetParent(Application.dataPath).FullName; 680 | 681 | var projectName = Path.GetFileName(projectDirectory); 682 | SlnFile = Path.GetFullPath(string.Format("{0}.sln", projectName)); 683 | 684 | InitializeEditorInstanceJson(); 685 | 686 | RiderAssetPostprocessor.OnGeneratedCSProjectFiles(); 687 | 688 | Log(LoggingLevel.Info, "Rider plugin initialized. You may change the amount of Rider Debug output via Edit -> Preferences -> Rider -> Logging Level"); 689 | Initialized = true; 690 | } 691 | 692 | private static void AddRiderToRecentlyUsedScriptApp(string userAppPath, string recentAppsKey) 693 | { 694 | for (int index = 0; index < 10; ++index) 695 | { 696 | string path = EditorPrefs.GetString(recentAppsKey + (object) index); 697 | if (File.Exists(path) && Path.GetFileName(path).ToLower().Contains("rider")) 698 | return; 699 | } 700 | EditorPrefs.SetString(recentAppsKey + 9, userAppPath); 701 | } 702 | 703 | private static string GetExternalScriptEditor() 704 | { 705 | return EditorPrefs.GetString("kScriptsDefaultApp"); 706 | } 707 | 708 | private static void SetExternalScriptEditor(string path) 709 | { 710 | EditorPrefs.SetString("kScriptsDefaultApp", path); 711 | } 712 | 713 | private static bool RiderPathExist(string path) 714 | { 715 | if (string.IsNullOrEmpty(path)) 716 | return false; 717 | // windows or mac 718 | var fileInfo = new FileInfo(path); 719 | if (!fileInfo.Name.ToLower().Contains("rider")) 720 | return false; 721 | var directoryInfo = new DirectoryInfo(path); 722 | return fileInfo.Exists || (SystemInfoRiderPlugin.operatingSystemFamily == OperatingSystemFamily.MacOSX && 723 | directoryInfo.Exists); 724 | } 725 | 726 | /// 727 | /// Creates and deletes Library/EditorInstance.json containing info about unity instance 728 | /// 729 | private static void InitializeEditorInstanceJson() 730 | { 731 | Log(LoggingLevel.Verbose, "Writing Library/EditorInstance.json"); 732 | 733 | var editorInstanceJsonPath = Path.GetFullPath("Library/EditorInstance.json"); 734 | 735 | File.WriteAllText(editorInstanceJsonPath, string.Format(@"{{ 736 | ""process_id"": {0}, 737 | ""version"": ""{1}"", 738 | ""app_path"": ""{2}"", 739 | ""app_contents_path"": ""{3}"", 740 | ""attach_allowed"": ""{4}"" 741 | }}", Process.GetCurrentProcess().Id, Application.unityVersion, 742 | EditorApplication.applicationPath, 743 | EditorApplication.applicationContentsPath, 744 | EditorPrefs.GetBool("AllowAttachedDebuggingOfEditor", true) 745 | )); 746 | 747 | AppDomain.CurrentDomain.DomainUnload += (sender, args) => 748 | { 749 | Log(LoggingLevel.Verbose, "Deleting Library/EditorInstance.json"); 750 | File.Delete(editorInstanceJsonPath); 751 | }; 752 | } 753 | 754 | /// 755 | /// Asset Open Callback (from Unity) 756 | /// 757 | /// 758 | /// Called when Unity is about to open an asset. 759 | /// 760 | [UnityEditor.Callbacks.OnOpenAssetAttribute()] 761 | static bool OnOpenedAsset(int instanceID, int line) 762 | { 763 | if (Enabled) 764 | { 765 | if (!Initialized) 766 | { 767 | // make sure the plugin was initialized first. 768 | // this can happen in case "Rider" was set as the default scripting app only after this plugin was imported. 769 | InitRiderPlugin(); 770 | } 771 | 772 | // determine asset that has been double clicked in the project view 773 | var selected = EditorUtility.InstanceIDToObject(instanceID); 774 | 775 | var assetFilePath = Path.GetFullPath(AssetDatabase.GetAssetPath(selected)); 776 | if (!(selected.GetType().ToString() == "UnityEditor.MonoScript" || 777 | selected.GetType().ToString() == "UnityEngine.Shader" || 778 | (selected.GetType().ToString() == "UnityEngine.TextAsset" && 779 | #if UNITY_5 || UNITY_5_5_OR_NEWER 780 | EditorSettings.projectGenerationUserExtensions.Contains(Path.GetExtension(assetFilePath).Substring(1)) 781 | #else 782 | EditorSettings.externalVersionControl.Contains(Path.GetExtension(assetFilePath).Substring(1)) 783 | #endif 784 | ))) 785 | return false; 786 | 787 | SyncSolution(); // added to handle opening file, which was just recently created. 788 | if (DetectPortAndOpenFile(line, assetFilePath, SystemInfoRiderPlugin.operatingSystemFamily == OperatingSystemFamily.Windows)) 789 | return true; 790 | var args = string.Format("{0}{1}{0} --line {2} {0}{3}{0}", "\"", SlnFile, line, assetFilePath); 791 | return CallRider(args); 792 | } 793 | 794 | return false; 795 | } 796 | 797 | 798 | private static bool DetectPortAndOpenFile(int line, string filePath, bool isWindows) 799 | { 800 | if (SystemInfoRiderPlugin.operatingSystemFamily == OperatingSystemFamily.Windows) 801 | { 802 | var process = GetRiderProcess(); 803 | if (process == null) 804 | return false; 805 | } 806 | 807 | var ports = Enumerable.Range(63342, 20); 808 | var res = ports.Any(port => 809 | { 810 | var aboutUrl = string.Format("http://localhost:{0}/api/about/", port); 811 | var aboutUri = new Uri(aboutUrl); 812 | 813 | using (var client = new WebClient()) 814 | { 815 | client.Headers.Add("origin", string.Format("http://localhost:{0}", port)); 816 | client.Headers[HttpRequestHeader.ContentType] = "application/x-www-form-urlencoded"; 817 | 818 | try 819 | { 820 | var responce = CallHttpApi(aboutUri, client); 821 | if (responce.ToLower().Contains("rider")) 822 | { 823 | return HttpOpenFile(line, filePath, isWindows, port, client); 824 | } 825 | } 826 | catch (Exception e) 827 | { 828 | Log(LoggingLevel.Verbose, string.Format("Exception in DetectPortAndOpenFile: {0}", e)); 829 | } 830 | } 831 | return false; 832 | }); 833 | return res; 834 | } 835 | 836 | private static bool HttpOpenFile(int line, string filePath, bool isWindows, int port, WebClient client) 837 | { 838 | var url = string.Format("http://localhost:{0}/api/file?file={1}{2}", port, filePath, 839 | line < 0 840 | ? "&p=0" 841 | : "&line=" + line); // &p is needed to workaround https://youtrack.jetbrains.com/issue/IDEA-172350 842 | if (isWindows) 843 | url = string.Format(@"http://localhost:{0}/api/file/{1}{2}", port, filePath, line < 0 ? "" : ":" + line); 844 | 845 | var uri = new Uri(url); 846 | Log(LoggingLevel.Verbose, string.Format("HttpRequestOpenFile({0})", uri.AbsoluteUri)); 847 | 848 | CallHttpApi(uri, client); 849 | ActivateWindow(); 850 | return true; 851 | } 852 | 853 | private static string CallHttpApi(Uri uri, WebClient client) 854 | { 855 | var responseString = client.DownloadString(uri.AbsoluteUri); 856 | Log(LoggingLevel.Verbose, string.Format("CallHttpApi {0} response: {1}", uri.AbsoluteUri, responseString)); 857 | return responseString; 858 | } 859 | 860 | private static bool CallRider(string args) 861 | { 862 | var defaultApp = GetDefaultApp(); 863 | if (!RiderPathExist(defaultApp)) 864 | { 865 | return false; 866 | } 867 | 868 | var proc = new Process(); 869 | if (SystemInfoRiderPlugin.operatingSystemFamily == OperatingSystemFamily.MacOSX) 870 | { 871 | proc.StartInfo.FileName = "open"; 872 | proc.StartInfo.Arguments = string.Format("-n {0}{1}{0} --args {2}", "\"", "/" + defaultApp, args); 873 | Log(LoggingLevel.Verbose, string.Format("{0} {1}", proc.StartInfo.FileName, proc.StartInfo.Arguments)); 874 | } 875 | else 876 | { 877 | proc.StartInfo.FileName = defaultApp; 878 | proc.StartInfo.Arguments = args; 879 | Log(LoggingLevel.Verbose, string.Format("{2}{0}{2}" + " {1}", proc.StartInfo.FileName, proc.StartInfo.Arguments, "\"")); 880 | } 881 | 882 | proc.StartInfo.UseShellExecute = false; 883 | proc.StartInfo.WindowStyle = ProcessWindowStyle.Hidden; 884 | proc.StartInfo.CreateNoWindow = true; 885 | proc.StartInfo.RedirectStandardOutput = true; 886 | proc.Start(); 887 | 888 | ActivateWindow(); 889 | return true; 890 | } 891 | 892 | private static void ActivateWindow() 893 | { 894 | if (SystemInfoRiderPlugin.operatingSystemFamily == OperatingSystemFamily.Windows) 895 | { 896 | try 897 | { 898 | var process = GetRiderProcess(); 899 | if (process != null) 900 | { 901 | // Collect top level windows 902 | var topLevelWindows = User32Dll.GetTopLevelWindowHandles(); 903 | // Get process main window title 904 | var windowHandle = topLevelWindows.FirstOrDefault(hwnd => User32Dll.GetWindowProcessId(hwnd) == process.Id); 905 | Log(LoggingLevel.Info, string.Format("ActivateWindow: {0} {1}", process.Id, windowHandle)); 906 | if (windowHandle != IntPtr.Zero) 907 | { 908 | //User32Dll.ShowWindow(windowHandle, 9); //SW_RESTORE = 9 909 | User32Dll.SetForegroundWindow(windowHandle); 910 | } 911 | } 912 | } 913 | catch (Exception e) 914 | { 915 | Log(LoggingLevel.Warning, "Exception on ActivateWindow: " + e); 916 | } 917 | } 918 | } 919 | 920 | private static Process GetRiderProcess() 921 | { 922 | var process = Process.GetProcesses().FirstOrDefault(p => 923 | { 924 | string processName; 925 | try 926 | { 927 | processName = 928 | p.ProcessName; // some processes like kaspersky antivirus throw exception on attempt to get ProcessName 929 | } 930 | catch (Exception) 931 | { 932 | return false; 933 | } 934 | 935 | return !p.HasExited && processName.ToLower().Contains("rider"); 936 | }); 937 | return process; 938 | } 939 | 940 | // The default "Open C# Project" menu item will use the external script editor to load the .sln 941 | // file, but unless Unity knows the external script editor can properly load solutions, it will 942 | // also launch MonoDevelop (or the OS registered app for .sln files). This menu item side steps 943 | // that issue, and opens the solution in Rider without opening MonoDevelop as well. 944 | // Unity 2017.1 and later recognise Rider as an app that can load solutions, so this menu isn't 945 | // needed in newer versions. 946 | [MenuItem("Assets/Open C# Project in Rider", false, 1000)] 947 | static void MenuOpenProject() 948 | { 949 | // Force the project files to be sync 950 | SyncSolution(); 951 | 952 | // Load Project 953 | CallRider(string.Format("{0}{1}{0}", "\"", SlnFile)); 954 | } 955 | 956 | [MenuItem("Assets/Open C# Project in Rider", true, 1000)] 957 | static bool ValidateMenuOpenProject() 958 | { 959 | return Enabled; 960 | } 961 | 962 | /// 963 | /// Force Unity To Write Project File 964 | /// 965 | private static void SyncSolution() 966 | { 967 | System.Type T = System.Type.GetType("UnityEditor.SyncVS,UnityEditor"); 968 | System.Reflection.MethodInfo SyncSolution = T.GetMethod("SyncSolution", 969 | System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Static); 970 | SyncSolution.Invoke(null, null); 971 | } 972 | 973 | /// 974 | /// JetBrains Rider Integration Preferences Item 975 | /// 976 | /// 977 | /// Contains all 3 toggles: Enable/Disable; Debug On/Off; Writing Launch File On/Off 978 | /// 979 | [PreferenceItem("Rider")] 980 | static void RiderPreferencesItem() 981 | { 982 | EditorGUILayout.BeginVertical(); 983 | EditorGUI.BeginChangeCheck(); 984 | 985 | var alternatives = GetAllRiderPaths(); 986 | if (alternatives.Any()) 987 | { 988 | int index = Array.IndexOf(alternatives, RiderPath); 989 | var alts = alternatives.Select(s => s.Replace("/", ":")) 990 | .ToArray(); // hack around https://fogbugz.unity3d.com/default.asp?940857_tirhinhe3144t4vn 991 | RiderPath = alternatives[EditorGUILayout.Popup("Rider executable:", index == -1 ? 0 : index, alts)]; 992 | if (EditorGUILayout.Toggle(new GUIContent("Rider is default editor"), Enabled)) 993 | { 994 | SetExternalScriptEditor(RiderPath); 995 | EditorGUILayout.HelpBox("Unckecking will restore default external editor.", MessageType.None); 996 | } 997 | else 998 | { 999 | SetExternalScriptEditor(string.Empty); 1000 | EditorGUILayout.HelpBox("Checking will set Rider as default external editor", MessageType.None); 1001 | } 1002 | } 1003 | 1004 | GUILayout.BeginVertical(); 1005 | string status = "TargetFrameworkVersion for Runtime"; 1006 | EditorGUILayout.TextArea(status, EditorStyles.boldLabel); 1007 | var help = @"TargetFramework >= 4.5 is recommended."; 1008 | TargetFrameworkVersion = 1009 | EditorGUILayout.TextField( 1010 | new GUIContent("NET 4.6", 1011 | help), TargetFrameworkVersion); 1012 | EditorGUILayout.HelpBox(help, MessageType.None); 1013 | var helpOldMono = @"TargetFramework = 3.5 is recommended. 1014 | - With 4.5 Rider may show ambiguous references in UniRx."; 1015 | 1016 | TargetFrameworkVersionOldMono = 1017 | EditorGUILayout.TextField( 1018 | new GUIContent("NET 3.5", 1019 | helpOldMono), TargetFrameworkVersionOldMono); 1020 | EditorGUILayout.HelpBox(helpOldMono, MessageType.None); 1021 | 1022 | GUILayout.EndVertical(); 1023 | 1024 | EditorGUI.EndChangeCheck(); 1025 | 1026 | EditorGUI.BeginChangeCheck(); 1027 | 1028 | var loggingMsg = 1029 | @"Sets the amount of Rider Debug output. If you are about to report an issue, please select Verbose logging level and attach Unity console output to the issue."; 1030 | SelectedLoggingLevel = (LoggingLevel) EditorGUILayout.EnumPopup(new GUIContent("Logging Level", loggingMsg), SelectedLoggingLevel); 1031 | EditorGUILayout.HelpBox(loggingMsg, MessageType.None); 1032 | 1033 | EditorGUI.EndChangeCheck(); 1034 | 1035 | var url = "https://github.com/JetBrains/resharper-unity"; 1036 | LinkButton(url, url); 1037 | 1038 | /* if (GUILayout.Button("reset RiderInitializedOnce = false")) 1039 | { 1040 | RiderInitializedOnce = false; 1041 | }*/ 1042 | 1043 | EditorGUILayout.EndVertical(); 1044 | } 1045 | 1046 | private static void LinkButton(string caption, string url) 1047 | { 1048 | var style = GUI.skin.label; 1049 | style.richText = true; 1050 | caption = string.Format("{0}", caption); 1051 | 1052 | bool bClicked = GUILayout.Button(caption, style); 1053 | 1054 | var rect = GUILayoutUtility.GetLastRect(); 1055 | rect.width = style.CalcSize(new GUIContent(caption)).x; 1056 | EditorGUIUtility.AddCursorRect(rect, MouseCursor.Link); 1057 | 1058 | if (bClicked) 1059 | Application.OpenURL(url); 1060 | } 1061 | 1062 | #region SystemInfoRiderPlugin 1063 | 1064 | private static class SystemInfoRiderPlugin 1065 | { 1066 | public static OperatingSystemFamily operatingSystemFamily 1067 | { 1068 | get 1069 | { 1070 | #if UNITY_5_5_OR_NEWER 1071 | return SystemInfo.operatingSystemFamily; 1072 | #else 1073 | if (SystemInfo.operatingSystem.StartsWith("Mac", StringComparison.InvariantCultureIgnoreCase)) 1074 | { 1075 | return OperatingSystemFamily.MacOSX; 1076 | } 1077 | if (SystemInfo.operatingSystem.StartsWith("Win", StringComparison.InvariantCultureIgnoreCase)) 1078 | { 1079 | return OperatingSystemFamily.Windows; 1080 | } 1081 | if (SystemInfo.operatingSystem.StartsWith("Lin", StringComparison.InvariantCultureIgnoreCase)) 1082 | { 1083 | return OperatingSystemFamily.Linux; 1084 | } 1085 | return OperatingSystemFamily.Other; 1086 | #endif 1087 | } 1088 | } 1089 | } 1090 | #if !UNITY_5_5_OR_NEWER 1091 | enum OperatingSystemFamily 1092 | { 1093 | Other, 1094 | MacOSX, 1095 | Windows, 1096 | Linux, 1097 | } 1098 | #endif 1099 | #endregion 1100 | 1101 | static class User32Dll 1102 | { 1103 | 1104 | /// 1105 | /// Gets the ID of the process that owns the window. 1106 | /// Note that creating a wrapper for that is very expensive because it causes an enumeration of all the system processes to happen. 1107 | /// 1108 | public static int GetWindowProcessId(IntPtr hwnd) 1109 | { 1110 | uint dwProcessId; 1111 | GetWindowThreadProcessId(hwnd, out dwProcessId); 1112 | return unchecked((int) dwProcessId); 1113 | } 1114 | 1115 | /// 1116 | /// Lists the handles of all the top-level windows currently available in the system. 1117 | /// 1118 | public static List GetTopLevelWindowHandles() 1119 | { 1120 | var retval = new List(); 1121 | EnumWindowsProc callback = (hwnd, param) => 1122 | { 1123 | retval.Add(hwnd); 1124 | return 1; 1125 | }; 1126 | EnumWindows(Marshal.GetFunctionPointerForDelegate(callback), IntPtr.Zero); 1127 | GC.KeepAlive(callback); 1128 | return retval; 1129 | } 1130 | 1131 | public delegate Int32 EnumWindowsProc(IntPtr hwnd, IntPtr lParam); 1132 | 1133 | [DllImport("user32.dll", CharSet = CharSet.Unicode, PreserveSig = true, SetLastError = true, 1134 | ExactSpelling = true)] 1135 | public static extern Int32 EnumWindows(IntPtr lpEnumFunc, IntPtr lParam); 1136 | 1137 | [DllImport("user32.dll", SetLastError = true)] 1138 | static extern uint GetWindowThreadProcessId(IntPtr hWnd, out uint lpdwProcessId); 1139 | 1140 | [DllImport("user32.dll", CharSet = CharSet.Unicode, PreserveSig = true, SetLastError = true, 1141 | ExactSpelling = true)] 1142 | public static extern Int32 SetForegroundWindow(IntPtr hWnd); 1143 | 1144 | [DllImport("user32.dll", CharSet = CharSet.Unicode, PreserveSig = true, SetLastError = true, 1145 | ExactSpelling = true)] 1146 | public static extern UInt32 ShowWindow(IntPtr hWnd, Int32 nCmdShow); 1147 | } 1148 | 1149 | static class ShortcutResolver 1150 | { 1151 | #region Signitures imported from http://pinvoke.net 1152 | 1153 | [DllImport("shfolder.dll", CharSet = CharSet.Auto)] 1154 | internal static extern int SHGetFolderPath(IntPtr hwndOwner, int nFolder, IntPtr hToken, int dwFlags, StringBuilder lpszPath); 1155 | 1156 | [Flags()] 1157 | enum SLGP_FLAGS 1158 | { 1159 | /// Retrieves the standard short (8.3 format) file name 1160 | SLGP_SHORTPATH = 0x1, 1161 | 1162 | /// Retrieves the Universal Naming Convention (UNC) path name of the file 1163 | SLGP_UNCPRIORITY = 0x2, 1164 | 1165 | /// Retrieves the raw path name. A raw path is something that might not exist and may include environment variables that need to be expanded 1166 | SLGP_RAWPATH = 0x4 1167 | } 1168 | 1169 | [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)] 1170 | struct WIN32_FIND_DATAW 1171 | { 1172 | public uint dwFileAttributes; 1173 | public long ftCreationTime; 1174 | public long ftLastAccessTime; 1175 | public long ftLastWriteTime; 1176 | public uint nFileSizeHigh; 1177 | public uint nFileSizeLow; 1178 | public uint dwReserved0; 1179 | public uint dwReserved1; 1180 | [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)] public string cFileName; 1181 | [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 14)] public string cAlternateFileName; 1182 | } 1183 | 1184 | [Flags()] 1185 | enum SLR_FLAGS 1186 | { 1187 | /// 1188 | /// Do not display a dialog box if the link cannot be resolved. When SLR_NO_UI is set, 1189 | /// the high-order word of fFlags can be set to a time-out value that specifies the 1190 | /// maximum amount of time to be spent resolving the link. The function returns if the 1191 | /// link cannot be resolved within the time-out duration. If the high-order word is set 1192 | /// to zero, the time-out duration will be set to the default value of 3,000 milliseconds 1193 | /// (3 seconds). To specify a value, set the high word of fFlags to the desired time-out 1194 | /// duration, in milliseconds. 1195 | /// 1196 | SLR_NO_UI = 0x1, 1197 | 1198 | /// Obsolete and no longer used 1199 | SLR_ANY_MATCH = 0x2, 1200 | 1201 | /// If the link object has changed, update its path and list of identifiers. 1202 | /// If SLR_UPDATE is set, you do not need to call IPersistFile::IsDirty to determine 1203 | /// whether or not the link object has changed. 1204 | SLR_UPDATE = 0x4, 1205 | 1206 | /// Do not update the link information 1207 | SLR_NOUPDATE = 0x8, 1208 | 1209 | /// Do not execute the search heuristics 1210 | SLR_NOSEARCH = 0x10, 1211 | 1212 | /// Do not use distributed link tracking 1213 | SLR_NOTRACK = 0x20, 1214 | 1215 | /// Disable distributed link tracking. By default, distributed link tracking tracks 1216 | /// removable media across multiple devices based on the volume name. It also uses the 1217 | /// Universal Naming Convention (UNC) path to track remote file systems whose drive letter 1218 | /// has changed. Setting SLR_NOLINKINFO disables both types of tracking. 1219 | SLR_NOLINKINFO = 0x40, 1220 | 1221 | /// Call the Microsoft Windows Installer 1222 | SLR_INVOKE_MSI = 0x80 1223 | } 1224 | 1225 | 1226 | /// The IShellLink interface allows Shell links to be created, modified, and resolved 1227 | [ComImport(), InterfaceType(ComInterfaceType.InterfaceIsIUnknown), Guid("000214F9-0000-0000-C000-000000000046")] 1228 | interface IShellLinkW 1229 | { 1230 | /// Retrieves the path and file name of a Shell link object 1231 | [MethodImpl (MethodImplOptions.InternalCall | MethodImplOptions.PreserveSig, MethodCodeType = MethodCodeType.Runtime)] 1232 | void GetPath([Out(), MarshalAs(UnmanagedType.LPWStr)] StringBuilder pszFile, int cchMaxPath, out WIN32_FIND_DATAW pfd, SLGP_FLAGS fFlags); 1233 | 1234 | /// Retrieves the list of item identifiers for a Shell link object 1235 | [MethodImpl (MethodImplOptions.InternalCall | MethodImplOptions.PreserveSig, MethodCodeType = MethodCodeType.Runtime)] 1236 | void GetIDList(out IntPtr ppidl); 1237 | 1238 | /// Sets the pointer to an item identifier list (PIDL) for a Shell link object. 1239 | [MethodImpl (MethodImplOptions.InternalCall | MethodImplOptions.PreserveSig, MethodCodeType = MethodCodeType.Runtime)] 1240 | void SetIDList(IntPtr pidl); 1241 | 1242 | /// Retrieves the description string for a Shell link object 1243 | [MethodImpl (MethodImplOptions.InternalCall | MethodImplOptions.PreserveSig, MethodCodeType = MethodCodeType.Runtime)] 1244 | void GetDescription([Out(), MarshalAs(UnmanagedType.LPWStr)] StringBuilder pszName, int cchMaxName); 1245 | 1246 | /// Sets the description for a Shell link object. The description can be any application-defined string 1247 | [MethodImpl (MethodImplOptions.InternalCall | MethodImplOptions.PreserveSig, MethodCodeType = MethodCodeType.Runtime)] 1248 | void SetDescription([MarshalAs(UnmanagedType.LPWStr)] string pszName); 1249 | 1250 | /// Retrieves the name of the working directory for a Shell link object 1251 | [MethodImpl (MethodImplOptions.InternalCall | MethodImplOptions.PreserveSig, MethodCodeType = MethodCodeType.Runtime)] 1252 | void GetWorkingDirectory([Out(), MarshalAs(UnmanagedType.LPWStr)] StringBuilder pszDir, int cchMaxPath); 1253 | 1254 | /// Sets the name of the working directory for a Shell link object 1255 | [MethodImpl (MethodImplOptions.InternalCall | MethodImplOptions.PreserveSig, MethodCodeType = MethodCodeType.Runtime)] 1256 | void SetWorkingDirectory([MarshalAs(UnmanagedType.LPWStr)] string pszDir); 1257 | 1258 | /// Retrieves the command-line arguments associated with a Shell link object 1259 | [MethodImpl (MethodImplOptions.InternalCall | MethodImplOptions.PreserveSig, MethodCodeType = MethodCodeType.Runtime)] 1260 | void GetArguments([Out(), MarshalAs(UnmanagedType.LPWStr)] StringBuilder pszArgs, int cchMaxPath); 1261 | 1262 | /// Sets the command-line arguments for a Shell link object 1263 | [MethodImpl (MethodImplOptions.InternalCall | MethodImplOptions.PreserveSig, MethodCodeType = MethodCodeType.Runtime)] 1264 | void SetArguments([MarshalAs(UnmanagedType.LPWStr)] string pszArgs); 1265 | 1266 | /// Retrieves the hot key for a Shell link object 1267 | [MethodImpl (MethodImplOptions.InternalCall | MethodImplOptions.PreserveSig, MethodCodeType = MethodCodeType.Runtime)] 1268 | void GetHotkey(out short pwHotkey); 1269 | 1270 | /// Sets a hot key for a Shell link object 1271 | [MethodImpl (MethodImplOptions.InternalCall | MethodImplOptions.PreserveSig, MethodCodeType = MethodCodeType.Runtime)] 1272 | void SetHotkey(short wHotkey); 1273 | 1274 | /// Retrieves the show command for a Shell link object 1275 | [MethodImpl (MethodImplOptions.InternalCall | MethodImplOptions.PreserveSig, MethodCodeType = MethodCodeType.Runtime)] 1276 | void GetShowCmd(out int piShowCmd); 1277 | 1278 | /// Sets the show command for a Shell link object. The show command sets the initial show state of the window. 1279 | [MethodImpl (MethodImplOptions.InternalCall | MethodImplOptions.PreserveSig, MethodCodeType = MethodCodeType.Runtime)] 1280 | void SetShowCmd(int iShowCmd); 1281 | 1282 | /// Retrieves the location (path and index) of the icon for a Shell link object 1283 | [MethodImpl (MethodImplOptions.InternalCall | MethodImplOptions.PreserveSig, MethodCodeType = MethodCodeType.Runtime)] 1284 | void GetIconLocation([Out(), MarshalAs(UnmanagedType.LPWStr)] StringBuilder pszIconPath, int cchIconPath, out int piIcon); 1285 | 1286 | /// Sets the location (path and index) of the icon for a Shell link object 1287 | [MethodImpl (MethodImplOptions.InternalCall | MethodImplOptions.PreserveSig, MethodCodeType = MethodCodeType.Runtime)] 1288 | void SetIconLocation([MarshalAs(UnmanagedType.LPWStr)] string pszIconPath, int iIcon); 1289 | 1290 | /// Sets the relative path to the Shell link object 1291 | [MethodImpl (MethodImplOptions.InternalCall | MethodImplOptions.PreserveSig, MethodCodeType = MethodCodeType.Runtime)] 1292 | void SetRelativePath([MarshalAs(UnmanagedType.LPWStr)] string pszPathRel, int dwReserved); 1293 | 1294 | /// Attempts to find the target of a Shell link, even if it has been moved or renamed 1295 | [MethodImpl (MethodImplOptions.InternalCall | MethodImplOptions.PreserveSig, MethodCodeType = MethodCodeType.Runtime)] 1296 | void Resolve(IntPtr hwnd, SLR_FLAGS fFlags); 1297 | 1298 | /// Sets the path and file name of a Shell link object 1299 | [MethodImpl (MethodImplOptions.InternalCall | MethodImplOptions.PreserveSig, MethodCodeType = MethodCodeType.Runtime)] 1300 | void SetPath([MarshalAs(UnmanagedType.LPWStr)] string pszFile); 1301 | } 1302 | 1303 | [ComImport, Guid("0000010c-0000-0000-c000-000000000046"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] 1304 | public interface IPersist 1305 | { 1306 | [MethodImpl (MethodImplOptions.InternalCall | MethodImplOptions.PreserveSig, MethodCodeType = MethodCodeType.Runtime)] 1307 | void GetClassID(out Guid pClassID); 1308 | } 1309 | 1310 | 1311 | [ComImport, Guid("0000010b-0000-0000-C000-000000000046"), 1312 | InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] 1313 | public interface IPersistFile : IPersist 1314 | { 1315 | [MethodImpl(MethodImplOptions.InternalCall | MethodImplOptions.PreserveSig, MethodCodeType = MethodCodeType.Runtime)] 1316 | new void GetClassID(out Guid pClassID); 1317 | 1318 | [MethodImpl(MethodImplOptions.InternalCall | MethodImplOptions.PreserveSig, MethodCodeType = MethodCodeType.Runtime)] 1319 | int IsDirty(); 1320 | 1321 | [MethodImpl(MethodImplOptions.InternalCall | MethodImplOptions.PreserveSig, MethodCodeType = MethodCodeType.Runtime)] 1322 | void Load([In, MarshalAs(UnmanagedType.LPWStr)] string pszFileName, uint dwMode); 1323 | 1324 | [MethodImpl (MethodImplOptions.InternalCall | MethodImplOptions.PreserveSig, MethodCodeType = MethodCodeType.Runtime)] 1325 | void Save([In, MarshalAs(UnmanagedType.LPWStr)] string pszFileName, [In, MarshalAs(UnmanagedType.Bool)] bool fRemember); 1326 | 1327 | [MethodImpl (MethodImplOptions.InternalCall | MethodImplOptions.PreserveSig, MethodCodeType = MethodCodeType.Runtime)] 1328 | void SaveCompleted([In, MarshalAs(UnmanagedType.LPWStr)] string pszFileName); 1329 | 1330 | [MethodImpl (MethodImplOptions.InternalCall | MethodImplOptions.PreserveSig, MethodCodeType = MethodCodeType.Runtime)] 1331 | void GetCurFile([In, MarshalAs(UnmanagedType.LPWStr)] string ppszFileName); 1332 | } 1333 | 1334 | const uint STGM_READ = 0; 1335 | const int MAX_PATH = 260; 1336 | 1337 | // CLSID_ShellLink from ShlGuid.h 1338 | [ 1339 | ComImport(), 1340 | Guid("00021401-0000-0000-C000-000000000046") 1341 | ] 1342 | public class ShellLink 1343 | { 1344 | } 1345 | 1346 | #endregion 1347 | 1348 | public static string Resolve(string filename) 1349 | { 1350 | ShellLink link = new ShellLink(); 1351 | ((IPersistFile) link).Load(filename, STGM_READ); 1352 | // If I can get hold of the hwnd call resolve first. This handles moved and renamed files. 1353 | // ((IShellLinkW)link).Resolve(hwnd, 0) 1354 | StringBuilder sb = new StringBuilder(MAX_PATH); 1355 | WIN32_FIND_DATAW data = new WIN32_FIND_DATAW(); 1356 | ((IShellLinkW) link).GetPath(sb, sb.Capacity, out data, 0); 1357 | return sb.ToString(); 1358 | } 1359 | } 1360 | } 1361 | } 1362 | 1363 | // Developed using JetBrains Rider =) 1364 | -------------------------------------------------------------------------------- /Assets/Plugins/Editor/JetBrains/Unity3DRider.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 58a04b915a9b6644f96b9553804eb3f1 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Assets/Scenes.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 4f704ae4b4f98ae41a0bce26658850c1 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Assets/Scenes/SampleScene.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: e841a5b52e809584382e3b3f7979cae1 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Assets/Scenes/SampleScene.unity: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!29 &1 4 | OcclusionCullingSettings: 5 | m_ObjectHideFlags: 0 6 | serializedVersion: 2 7 | m_OcclusionBakeSettings: 8 | smallestOccluder: 5 9 | smallestHole: 0.25 10 | backfaceThreshold: 100 11 | m_SceneGUID: 00000000000000000000000000000000 12 | m_OcclusionCullingData: {fileID: 0} 13 | --- !u!104 &2 14 | RenderSettings: 15 | m_ObjectHideFlags: 0 16 | serializedVersion: 9 17 | m_Fog: 0 18 | m_FogColor: {r: 0.5, g: 0.5, b: 0.5, a: 1} 19 | m_FogMode: 3 20 | m_FogDensity: 0.01 21 | m_LinearFogStart: 0 22 | m_LinearFogEnd: 300 23 | m_AmbientSkyColor: {r: 0.212, g: 0.227, b: 0.259, a: 1} 24 | m_AmbientEquatorColor: {r: 0.114, g: 0.125, b: 0.133, a: 1} 25 | m_AmbientGroundColor: {r: 0.047, g: 0.043, b: 0.035, a: 1} 26 | m_AmbientIntensity: 1 27 | m_AmbientMode: 0 28 | m_SubtractiveShadowColor: {r: 0.42, g: 0.478, b: 0.627, a: 1} 29 | m_SkyboxMaterial: {fileID: 10304, guid: 0000000000000000f000000000000000, type: 0} 30 | m_HaloStrength: 0.5 31 | m_FlareStrength: 1 32 | m_FlareFadeSpeed: 3 33 | m_HaloTexture: {fileID: 0} 34 | m_SpotCookie: {fileID: 10001, guid: 0000000000000000e000000000000000, type: 0} 35 | m_DefaultReflectionMode: 0 36 | m_DefaultReflectionResolution: 128 37 | m_ReflectionBounces: 1 38 | m_ReflectionIntensity: 1 39 | m_CustomReflection: {fileID: 0} 40 | m_Sun: {fileID: 1526980366} 41 | m_IndirectSpecularColor: {r: 0.18028334, g: 0.2257134, b: 0.30692226, a: 1} 42 | m_UseRadianceAmbientProbe: 0 43 | --- !u!157 &3 44 | LightmapSettings: 45 | m_ObjectHideFlags: 0 46 | serializedVersion: 11 47 | m_GIWorkflowMode: 1 48 | m_GISettings: 49 | serializedVersion: 2 50 | m_BounceScale: 1 51 | m_IndirectOutputScale: 1 52 | m_AlbedoBoost: 1 53 | m_TemporalCoherenceThreshold: 1 54 | m_EnvironmentLightingMode: 0 55 | m_EnableBakedLightmaps: 1 56 | m_EnableRealtimeLightmaps: 1 57 | m_LightmapEditorSettings: 58 | serializedVersion: 10 59 | m_Resolution: 2 60 | m_BakeResolution: 10 61 | m_AtlasSize: 512 62 | m_AO: 0 63 | m_AOMaxDistance: 1 64 | m_CompAOExponent: 1 65 | m_CompAOExponentDirect: 0 66 | m_Padding: 2 67 | m_LightmapParameters: {fileID: 0} 68 | m_LightmapsBakeMode: 1 69 | m_TextureCompression: 1 70 | m_FinalGather: 0 71 | m_FinalGatherFiltering: 1 72 | m_FinalGatherRayCount: 256 73 | m_ReflectionCompression: 2 74 | m_MixedBakeMode: 2 75 | m_BakeBackend: 1 76 | m_PVRSampling: 1 77 | m_PVRDirectSampleCount: 32 78 | m_PVRSampleCount: 256 79 | m_PVRBounces: 2 80 | m_PVRFilterTypeDirect: 0 81 | m_PVRFilterTypeIndirect: 0 82 | m_PVRFilterTypeAO: 0 83 | m_PVRFilteringMode: 1 84 | m_PVRCulling: 1 85 | m_PVRFilteringGaussRadiusDirect: 1 86 | m_PVRFilteringGaussRadiusIndirect: 5 87 | m_PVRFilteringGaussRadiusAO: 2 88 | m_PVRFilteringAtrousPositionSigmaDirect: 0.5 89 | m_PVRFilteringAtrousPositionSigmaIndirect: 2 90 | m_PVRFilteringAtrousPositionSigmaAO: 1 91 | m_ShowResolutionOverlay: 1 92 | m_LightingDataAsset: {fileID: 112000002, guid: 75f33e997dee73d4fbe39db1cd2bb23a, 93 | type: 2} 94 | m_UseShadowmask: 1 95 | --- !u!196 &4 96 | NavMeshSettings: 97 | serializedVersion: 2 98 | m_ObjectHideFlags: 0 99 | m_BuildSettings: 100 | serializedVersion: 2 101 | agentTypeID: 0 102 | agentRadius: 0.5 103 | agentHeight: 2 104 | agentSlope: 45 105 | agentClimb: 0.4 106 | ledgeDropHeight: 0 107 | maxJumpAcrossDistance: 0 108 | minRegionArea: 2 109 | manualCellSize: 0 110 | cellSize: 0.16666667 111 | manualTileSize: 0 112 | tileSize: 256 113 | accuratePlacement: 0 114 | debug: 115 | m_Flags: 0 116 | m_NavMeshData: {fileID: 0} 117 | --- !u!1 &239344962 118 | GameObject: 119 | m_ObjectHideFlags: 0 120 | m_PrefabParentObject: {fileID: 0} 121 | m_PrefabInternal: {fileID: 0} 122 | serializedVersion: 5 123 | m_Component: 124 | - component: {fileID: 239344964} 125 | - component: {fileID: 239344963} 126 | - component: {fileID: 239344966} 127 | - component: {fileID: 239344965} 128 | m_Layer: 0 129 | m_Name: Physics Spawner 130 | m_TagString: Untagged 131 | m_Icon: {fileID: 0} 132 | m_NavMeshLayer: 0 133 | m_StaticEditorFlags: 0 134 | m_IsActive: 1 135 | --- !u!114 &239344963 136 | MonoBehaviour: 137 | m_ObjectHideFlags: 0 138 | m_PrefabParentObject: {fileID: 0} 139 | m_PrefabInternal: {fileID: 0} 140 | m_GameObject: {fileID: 239344962} 141 | m_Enabled: 1 142 | m_EditorHideFlags: 0 143 | m_Script: {fileID: 11500000, guid: a771d3ce55ccaa1408dd353e4f7327a3, type: 3} 144 | m_Name: 145 | m_EditorClassIdentifier: 146 | mesh: {fileID: 10202, guid: 0000000000000000e000000000000000, type: 0} 147 | material: {fileID: 2100000, guid: c8000df3fbe738942adfb8603476934b, type: 2} 148 | spawnDirection: {fileID: 737408400} 149 | --- !u!4 &239344964 150 | Transform: 151 | m_ObjectHideFlags: 0 152 | m_PrefabParentObject: {fileID: 0} 153 | m_PrefabInternal: {fileID: 0} 154 | m_GameObject: {fileID: 239344962} 155 | m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} 156 | m_LocalPosition: {x: 25, y: 15, z: 0} 157 | m_LocalScale: {x: 2, y: 2, z: 2} 158 | m_Children: [] 159 | m_Father: {fileID: 0} 160 | m_RootOrder: 3 161 | m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} 162 | --- !u!23 &239344965 163 | MeshRenderer: 164 | m_ObjectHideFlags: 0 165 | m_PrefabParentObject: {fileID: 0} 166 | m_PrefabInternal: {fileID: 0} 167 | m_GameObject: {fileID: 239344962} 168 | m_Enabled: 1 169 | m_CastShadows: 1 170 | m_ReceiveShadows: 1 171 | m_DynamicOccludee: 1 172 | m_MotionVectors: 1 173 | m_LightProbeUsage: 1 174 | m_ReflectionProbeUsage: 1 175 | m_RenderingLayerMask: 4294967295 176 | m_Materials: 177 | - {fileID: 10303, guid: 0000000000000000f000000000000000, type: 0} 178 | m_StaticBatchInfo: 179 | firstSubMesh: 0 180 | subMeshCount: 0 181 | m_StaticBatchRoot: {fileID: 0} 182 | m_ProbeAnchor: {fileID: 0} 183 | m_LightProbeVolumeOverride: {fileID: 0} 184 | m_ScaleInLightmap: 1 185 | m_PreserveUVs: 0 186 | m_IgnoreNormalsForChartDetection: 0 187 | m_ImportantGI: 0 188 | m_StitchLightmapSeams: 0 189 | m_SelectedEditorRenderState: 3 190 | m_MinimumChartSize: 4 191 | m_AutoUVMaxDistance: 0.5 192 | m_AutoUVMaxAngle: 89 193 | m_LightmapParameters: {fileID: 0} 194 | m_SortingLayerID: 0 195 | m_SortingLayer: 0 196 | m_SortingOrder: 0 197 | --- !u!33 &239344966 198 | MeshFilter: 199 | m_ObjectHideFlags: 0 200 | m_PrefabParentObject: {fileID: 0} 201 | m_PrefabInternal: {fileID: 0} 202 | m_GameObject: {fileID: 239344962} 203 | m_Mesh: {fileID: 10207, guid: 0000000000000000e000000000000000, type: 0} 204 | --- !u!1 &282840810 205 | GameObject: 206 | m_ObjectHideFlags: 0 207 | m_PrefabParentObject: {fileID: 0} 208 | m_PrefabInternal: {fileID: 0} 209 | serializedVersion: 5 210 | m_Component: 211 | - component: {fileID: 282840814} 212 | - component: {fileID: 282840813} 213 | - component: {fileID: 282840811} 214 | m_Layer: 0 215 | m_Name: Main Camera 216 | m_TagString: MainCamera 217 | m_Icon: {fileID: 0} 218 | m_NavMeshLayer: 0 219 | m_StaticEditorFlags: 0 220 | m_IsActive: 1 221 | --- !u!81 &282840811 222 | AudioListener: 223 | m_ObjectHideFlags: 0 224 | m_PrefabParentObject: {fileID: 0} 225 | m_PrefabInternal: {fileID: 0} 226 | m_GameObject: {fileID: 282840810} 227 | m_Enabled: 1 228 | --- !u!20 &282840813 229 | Camera: 230 | m_ObjectHideFlags: 0 231 | m_PrefabParentObject: {fileID: 0} 232 | m_PrefabInternal: {fileID: 0} 233 | m_GameObject: {fileID: 282840810} 234 | m_Enabled: 1 235 | serializedVersion: 2 236 | m_ClearFlags: 1 237 | m_BackGroundColor: {r: 0.19215687, g: 0.3019608, b: 0.4745098, a: 0} 238 | m_NormalizedViewPortRect: 239 | serializedVersion: 2 240 | x: 0 241 | y: 0 242 | width: 1 243 | height: 1 244 | near clip plane: 0.3 245 | far clip plane: 1000 246 | field of view: 60 247 | orthographic: 0 248 | orthographic size: 5 249 | m_Depth: -1 250 | m_CullingMask: 251 | serializedVersion: 2 252 | m_Bits: 4294967295 253 | m_RenderingPath: -1 254 | m_TargetTexture: {fileID: 0} 255 | m_TargetDisplay: 0 256 | m_TargetEye: 3 257 | m_HDR: 1 258 | m_AllowMSAA: 0 259 | m_AllowDynamicResolution: 0 260 | m_ForceIntoRT: 1 261 | m_OcclusionCulling: 1 262 | m_StereoConvergence: 10 263 | m_StereoSeparation: 0.022 264 | --- !u!4 &282840814 265 | Transform: 266 | m_ObjectHideFlags: 0 267 | m_PrefabParentObject: {fileID: 0} 268 | m_PrefabInternal: {fileID: 0} 269 | m_GameObject: {fileID: 282840810} 270 | m_LocalRotation: {x: 0.064249724, y: -0.9222669, z: 0.1749807, w: 0.33864087} 271 | m_LocalPosition: {x: 28.162617, y: 21.180996, z: 27.708668} 272 | m_LocalScale: {x: 1, y: 1, z: 1} 273 | m_Children: [] 274 | m_Father: {fileID: 0} 275 | m_RootOrder: 0 276 | m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} 277 | --- !u!1 &737408396 278 | GameObject: 279 | m_ObjectHideFlags: 0 280 | m_PrefabParentObject: {fileID: 0} 281 | m_PrefabInternal: {fileID: 0} 282 | serializedVersion: 5 283 | m_Component: 284 | - component: {fileID: 737408400} 285 | - component: {fileID: 737408399} 286 | - component: {fileID: 737408398} 287 | - component: {fileID: 737408397} 288 | m_Layer: 0 289 | m_Name: Wall 290 | m_TagString: Untagged 291 | m_Icon: {fileID: 0} 292 | m_NavMeshLayer: 0 293 | m_StaticEditorFlags: 0 294 | m_IsActive: 1 295 | --- !u!65 &737408397 296 | BoxCollider: 297 | m_ObjectHideFlags: 0 298 | m_PrefabParentObject: {fileID: 0} 299 | m_PrefabInternal: {fileID: 0} 300 | m_GameObject: {fileID: 737408396} 301 | m_Material: {fileID: 0} 302 | m_IsTrigger: 0 303 | m_Enabled: 1 304 | serializedVersion: 2 305 | m_Size: {x: 1, y: 1, z: 1} 306 | m_Center: {x: 0, y: 0, z: 0} 307 | --- !u!23 &737408398 308 | MeshRenderer: 309 | m_ObjectHideFlags: 0 310 | m_PrefabParentObject: {fileID: 0} 311 | m_PrefabInternal: {fileID: 0} 312 | m_GameObject: {fileID: 737408396} 313 | m_Enabled: 1 314 | m_CastShadows: 1 315 | m_ReceiveShadows: 1 316 | m_DynamicOccludee: 1 317 | m_MotionVectors: 1 318 | m_LightProbeUsage: 1 319 | m_ReflectionProbeUsage: 1 320 | m_RenderingLayerMask: 4294967295 321 | m_Materials: 322 | - {fileID: 2100000, guid: 302e301269ab4924f8f15ff9e3ca22cb, type: 2} 323 | m_StaticBatchInfo: 324 | firstSubMesh: 0 325 | subMeshCount: 0 326 | m_StaticBatchRoot: {fileID: 0} 327 | m_ProbeAnchor: {fileID: 0} 328 | m_LightProbeVolumeOverride: {fileID: 0} 329 | m_ScaleInLightmap: 1 330 | m_PreserveUVs: 0 331 | m_IgnoreNormalsForChartDetection: 0 332 | m_ImportantGI: 0 333 | m_StitchLightmapSeams: 0 334 | m_SelectedEditorRenderState: 3 335 | m_MinimumChartSize: 4 336 | m_AutoUVMaxDistance: 0.5 337 | m_AutoUVMaxAngle: 89 338 | m_LightmapParameters: {fileID: 0} 339 | m_SortingLayerID: 0 340 | m_SortingLayer: 0 341 | m_SortingOrder: 0 342 | --- !u!33 &737408399 343 | MeshFilter: 344 | m_ObjectHideFlags: 0 345 | m_PrefabParentObject: {fileID: 0} 346 | m_PrefabInternal: {fileID: 0} 347 | m_GameObject: {fileID: 737408396} 348 | m_Mesh: {fileID: 10202, guid: 0000000000000000e000000000000000, type: 0} 349 | --- !u!4 &737408400 350 | Transform: 351 | m_ObjectHideFlags: 0 352 | m_PrefabParentObject: {fileID: 0} 353 | m_PrefabInternal: {fileID: 0} 354 | m_GameObject: {fileID: 737408396} 355 | m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} 356 | m_LocalPosition: {x: 0, y: 11.55, z: 0} 357 | m_LocalScale: {x: 1, y: 25, z: 50} 358 | m_Children: [] 359 | m_Father: {fileID: 0} 360 | m_RootOrder: 4 361 | m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} 362 | --- !u!1 &1526980365 363 | GameObject: 364 | m_ObjectHideFlags: 0 365 | m_PrefabParentObject: {fileID: 0} 366 | m_PrefabInternal: {fileID: 0} 367 | serializedVersion: 5 368 | m_Component: 369 | - component: {fileID: 1526980367} 370 | - component: {fileID: 1526980366} 371 | m_Layer: 0 372 | m_Name: Directional Light 373 | m_TagString: Untagged 374 | m_Icon: {fileID: 0} 375 | m_NavMeshLayer: 0 376 | m_StaticEditorFlags: 0 377 | m_IsActive: 1 378 | --- !u!108 &1526980366 379 | Light: 380 | m_ObjectHideFlags: 0 381 | m_PrefabParentObject: {fileID: 0} 382 | m_PrefabInternal: {fileID: 0} 383 | m_GameObject: {fileID: 1526980365} 384 | m_Enabled: 1 385 | serializedVersion: 8 386 | m_Type: 1 387 | m_Color: {r: 1, g: 0.95686275, b: 0.8392157, a: 1} 388 | m_Intensity: 1 389 | m_Range: 10 390 | m_SpotAngle: 30 391 | m_CookieSize: 10 392 | m_Shadows: 393 | m_Type: 1 394 | m_Resolution: 2 395 | m_CustomResolution: -1 396 | m_Strength: 1 397 | m_Bias: 0.005 398 | m_NormalBias: 0.1 399 | m_NearPlane: 5 400 | m_Cookie: {fileID: 0} 401 | m_DrawHalo: 0 402 | m_Flare: {fileID: 0} 403 | m_RenderMode: 0 404 | m_CullingMask: 405 | serializedVersion: 2 406 | m_Bits: 4294967295 407 | m_Lightmapping: 4 408 | m_AreaSize: {x: 1, y: 1} 409 | m_BounceIntensity: 1.7 410 | m_ColorTemperature: 6570 411 | m_UseColorTemperature: 0 412 | m_ShadowRadius: 0 413 | m_ShadowAngle: 0 414 | --- !u!4 &1526980367 415 | Transform: 416 | m_ObjectHideFlags: 0 417 | m_PrefabParentObject: {fileID: 0} 418 | m_PrefabInternal: {fileID: 0} 419 | m_GameObject: {fileID: 1526980365} 420 | m_LocalRotation: {x: 0.40821788, y: -0.23456968, z: 0.10938163, w: 0.8754261} 421 | m_LocalPosition: {x: 0, y: 3, z: 0} 422 | m_LocalScale: {x: 1, y: 1, z: 1} 423 | m_Children: [] 424 | m_Father: {fileID: 0} 425 | m_RootOrder: 1 426 | m_LocalEulerAnglesHint: {x: 50, y: -30, z: 0} 427 | --- !u!1 &2137533645 428 | GameObject: 429 | m_ObjectHideFlags: 0 430 | m_PrefabParentObject: {fileID: 0} 431 | m_PrefabInternal: {fileID: 0} 432 | serializedVersion: 5 433 | m_Component: 434 | - component: {fileID: 2137533646} 435 | - component: {fileID: 2137533649} 436 | - component: {fileID: 2137533648} 437 | - component: {fileID: 2137533647} 438 | m_Layer: 0 439 | m_Name: Floor 440 | m_TagString: Untagged 441 | m_Icon: {fileID: 0} 442 | m_NavMeshLayer: 0 443 | m_StaticEditorFlags: 0 444 | m_IsActive: 1 445 | --- !u!4 &2137533646 446 | Transform: 447 | m_ObjectHideFlags: 0 448 | m_PrefabParentObject: {fileID: 0} 449 | m_PrefabInternal: {fileID: 0} 450 | m_GameObject: {fileID: 2137533645} 451 | m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} 452 | m_LocalPosition: {x: -0.6430855, y: -50.33, z: 3.0220134} 453 | m_LocalScale: {x: 500, y: 100, z: 500} 454 | m_Children: [] 455 | m_Father: {fileID: 0} 456 | m_RootOrder: 2 457 | m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} 458 | --- !u!65 &2137533647 459 | BoxCollider: 460 | m_ObjectHideFlags: 0 461 | m_PrefabParentObject: {fileID: 0} 462 | m_PrefabInternal: {fileID: 0} 463 | m_GameObject: {fileID: 2137533645} 464 | m_Material: {fileID: 0} 465 | m_IsTrigger: 0 466 | m_Enabled: 1 467 | serializedVersion: 2 468 | m_Size: {x: 1, y: 1, z: 1} 469 | m_Center: {x: 0, y: 0, z: 0} 470 | --- !u!23 &2137533648 471 | MeshRenderer: 472 | m_ObjectHideFlags: 0 473 | m_PrefabParentObject: {fileID: 0} 474 | m_PrefabInternal: {fileID: 0} 475 | m_GameObject: {fileID: 2137533645} 476 | m_Enabled: 1 477 | m_CastShadows: 1 478 | m_ReceiveShadows: 1 479 | m_DynamicOccludee: 1 480 | m_MotionVectors: 1 481 | m_LightProbeUsage: 1 482 | m_ReflectionProbeUsage: 1 483 | m_RenderingLayerMask: 4294967295 484 | m_Materials: 485 | - {fileID: 10303, guid: 0000000000000000f000000000000000, type: 0} 486 | m_StaticBatchInfo: 487 | firstSubMesh: 0 488 | subMeshCount: 0 489 | m_StaticBatchRoot: {fileID: 0} 490 | m_ProbeAnchor: {fileID: 0} 491 | m_LightProbeVolumeOverride: {fileID: 0} 492 | m_ScaleInLightmap: 1 493 | m_PreserveUVs: 0 494 | m_IgnoreNormalsForChartDetection: 0 495 | m_ImportantGI: 0 496 | m_StitchLightmapSeams: 0 497 | m_SelectedEditorRenderState: 3 498 | m_MinimumChartSize: 4 499 | m_AutoUVMaxDistance: 0.5 500 | m_AutoUVMaxAngle: 89 501 | m_LightmapParameters: {fileID: 0} 502 | m_SortingLayerID: 0 503 | m_SortingLayer: 0 504 | m_SortingOrder: 0 505 | --- !u!33 &2137533649 506 | MeshFilter: 507 | m_ObjectHideFlags: 0 508 | m_PrefabParentObject: {fileID: 0} 509 | m_PrefabInternal: {fileID: 0} 510 | m_GameObject: {fileID: 2137533645} 511 | m_Mesh: {fileID: 10202, guid: 0000000000000000e000000000000000, type: 0} 512 | -------------------------------------------------------------------------------- /Assets/Scenes/SampleScene.unity.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 99c9720ab356a0642a771bea13969a05 3 | DefaultImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /Assets/Scenes/SampleScene/LightingData.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LotteMakesStuff/SimplePhysicsDemo/77bc1aada2847529018ad2f0b05357c3bf6551f3/Assets/Scenes/SampleScene/LightingData.asset -------------------------------------------------------------------------------- /Assets/Scenes/SampleScene/LightingData.asset.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 75f33e997dee73d4fbe39db1cd2bb23a 3 | NativeFormatImporter: 4 | externalObjects: {} 5 | mainObjectFileID: 25800000 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Assets/Scenes/SampleScene/ReflectionProbe-0.exr: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LotteMakesStuff/SimplePhysicsDemo/77bc1aada2847529018ad2f0b05357c3bf6551f3/Assets/Scenes/SampleScene/ReflectionProbe-0.exr -------------------------------------------------------------------------------- /Assets/Scenes/SampleScene/ReflectionProbe-0.exr.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: ae50ada776c0fc64b81572891f15bd63 3 | TextureImporter: 4 | fileIDToRecycleName: 5 | 8900000: generatedCubemap 6 | externalObjects: {} 7 | serializedVersion: 5 8 | mipmaps: 9 | mipMapMode: 0 10 | enableMipMap: 1 11 | sRGBTexture: 1 12 | linearTexture: 0 13 | fadeOut: 0 14 | borderMipMap: 0 15 | mipMapsPreserveCoverage: 0 16 | alphaTestReferenceValue: 0.5 17 | mipMapFadeDistanceStart: 1 18 | mipMapFadeDistanceEnd: 3 19 | bumpmap: 20 | convertToNormalMap: 0 21 | externalNormalMap: 0 22 | heightScale: 0.25 23 | normalMapFilter: 0 24 | isReadable: 0 25 | grayScaleToAlpha: 0 26 | generateCubemap: 6 27 | cubemapConvolution: 1 28 | seamlessCubemap: 1 29 | textureFormat: 1 30 | maxTextureSize: 2048 31 | textureSettings: 32 | serializedVersion: 2 33 | filterMode: 2 34 | aniso: 0 35 | mipBias: 0 36 | wrapU: 1 37 | wrapV: 1 38 | wrapW: 1 39 | nPOTScale: 1 40 | lightmap: 0 41 | compressionQuality: 50 42 | spriteMode: 0 43 | spriteExtrude: 1 44 | spriteMeshType: 1 45 | alignment: 0 46 | spritePivot: {x: 0.5, y: 0.5} 47 | spriteBorder: {x: 0, y: 0, z: 0, w: 0} 48 | spritePixelsToUnits: 100 49 | alphaUsage: 1 50 | alphaIsTransparency: 0 51 | spriteTessellationDetail: -1 52 | textureType: 0 53 | textureShape: 2 54 | singleChannelComponent: 0 55 | maxTextureSizeSet: 0 56 | compressionQualitySet: 0 57 | textureFormatSet: 0 58 | platformSettings: 59 | - serializedVersion: 2 60 | buildTarget: DefaultTexturePlatform 61 | maxTextureSize: 2048 62 | resizeAlgorithm: 0 63 | textureFormat: -1 64 | textureCompression: 1 65 | compressionQuality: 100 66 | crunchedCompression: 0 67 | allowsAlphaSplitting: 0 68 | overridden: 0 69 | androidETC2FallbackOverride: 0 70 | spriteSheet: 71 | serializedVersion: 2 72 | sprites: [] 73 | outline: [] 74 | physicsShape: [] 75 | bones: [] 76 | spriteID: 77 | vertices: [] 78 | indices: 79 | edges: [] 80 | weights: [] 81 | spritePackingTag: 82 | userData: 83 | assetBundleName: 84 | assetBundleVariant: 85 | -------------------------------------------------------------------------------- /Assets/SimpleJobifiedPhysics.cs: -------------------------------------------------------------------------------- 1 | using System.CodeDom.Compiler; 2 | using System.Collections; 3 | using System.Collections.Generic; 4 | using System.Runtime.InteropServices; 5 | using Unity.Collections; 6 | using Unity.Jobs; 7 | using UnityEngine; 8 | using UnityEngine.Profiling; 9 | 10 | public class SimpleJobifiedPhysics : MonoBehaviour 11 | { 12 | // When passing a data collection into a Unity Job it has to be one of the new Unity Native types. 13 | // .net genrics (like List) and plain arrays (like T[]) wil not work in jobs! 14 | private NativeArray velocities; 15 | private NativeArray positions; 16 | private NativeArray renderMatrices; 17 | private Matrix4x4[] renderMatrixArray; 18 | private NativeArray sleepingTimer; 19 | private NativeQueue asleep; 20 | private Vector3 gravity; 21 | private int objectCount = 1023; // the most we can fit into a single call to Graphics.DrawInstance 22 | 23 | public Mesh mesh; 24 | public Material material; 25 | 26 | public Transform spawnDirection; 27 | 28 | // This job applies gravity to each objects vecocity in the simulation 29 | struct GravityJob : IJobParallelFor 30 | { 31 | public float DeltaTime; 32 | 33 | public Vector3 Gravity; 34 | public NativeArray Velocities; 35 | public NativeArray Sleeping; 36 | 37 | public void Execute(int i) 38 | { 39 | // has the object been marked as sleeping? 40 | // sleeping objects are object that have settled, so they dont 41 | // move at all in this case we skip adding gravity to make them 42 | // appear more stable 43 | if (Sleeping[i] > 0) 44 | { 45 | Velocities[i] = new Vector3(0, 0, 0); 46 | return; 47 | } 48 | 49 | // simply integrate gravity based on time since last step. 50 | Velocities[i] += Gravity * DeltaTime; 51 | } 52 | } 53 | 54 | // this job creates a batch of RaycastCommands we are going to use for 55 | // collision detection against the world. these can be sent to PhysX 56 | // as a batch that will be executed in a job, rather than us having to 57 | // call Physics.Raycast in a loop just on the main thread! 58 | struct PrepareRaycastCommands : IJobParallelFor 59 | { 60 | public float DeltaTime; 61 | 62 | public NativeArray Raycasts; 63 | [ReadOnly] 64 | public NativeArray Velocities; 65 | [ReadOnly] 66 | public NativeArray Positions; 67 | 68 | 69 | public void Execute(int i) 70 | { 71 | // figure out how far the object we are testing collision for 72 | // wants to move in total. Our collision raycast only needs to be 73 | // that far. 74 | float distance = (Velocities[i] * DeltaTime).magnitude; 75 | Raycasts[i] = new RaycastCommand(Positions[i], Velocities[i], distance); 76 | } 77 | } 78 | 79 | // Integrate the velocity into all the objects positions. We use the 80 | // Raycast hit data to decide how much of the velocity to integrate - 81 | // we dont want to tunnel though the colliders in the scene! 82 | struct IntegratePhysics : IJobParallelFor 83 | { 84 | public float DeltaTime; 85 | [ReadOnly] 86 | public NativeArray Velocities; 87 | [ReadOnly] 88 | public NativeArray Hits; 89 | public NativeArray Sleeping; 90 | public NativeArray Positions; 91 | 92 | public void Execute(int i) 93 | { 94 | if (Sleeping[i] > 0) // if the object is sleeping, we dont have to integrate anything 95 | { 96 | Sleeping[i]++; 97 | return; 98 | } 99 | 100 | if (Hits[i].normal == Vector3.zero) 101 | { 102 | // if there has been no colision, intergrate all of the velocity we want for this frame 103 | Positions[i] += Velocities[i] * (Velocities[i] * DeltaTime).magnitude; 104 | } 105 | else 106 | { 107 | // there has been a collision! just move up to the point of the collion with a tiny offset for stability 108 | Positions[i] = Hits[i].point + new Vector3(0, 0.1f, 0); 109 | } 110 | } 111 | } 112 | 113 | // Respond to collisions 114 | struct CalculateCollisionResponse : IJobParallelFor 115 | { 116 | [ReadOnly] 117 | public NativeArray Hits; 118 | 119 | public NativeArray Velocities; 120 | public NativeArray Sleeping; 121 | 122 | public void Execute(int i) 123 | { 124 | // If there has been a collision, the RaycastHit normal will be 125 | // non zero. When we know there has been a collisoin we can 126 | // respond to it. 127 | if (Hits[i].normal != Vector3.zero) 128 | { 129 | // first, lets check if the velocity has got very low before this collision. if so 130 | // we are going to put the object to sleep. this will stop it from 131 | // reciveing gravity and will make the simulation appear more stable 132 | if (Velocities[i].magnitude <= 2f) 133 | { 134 | Velocities[i] = Vector3.zero; 135 | Sleeping[i]++; // increment the sleeping counter. any value over 1 is sleeping. We can use this to respawn objects after they have been static for while 136 | } 137 | // lets implement a very simple bounce effect - just be reflecting the velocity by the 138 | // collison normal (the normal is a vector pointing perpendicular away from the surface 139 | // that we have hit). 140 | // were also going to apply a damping effect to the velocity by removing force from the resulting 141 | // reflected velocity. You can think of this as a really simple simulation of force lost 142 | // due to friction against the surface we have collided with. 143 | else 144 | { 145 | Velocities[i] = Vector3.Reflect(Velocities[i], Hits[i].normal); 146 | 147 | var angleBetweenNormalAndUp = Vector3.Angle(Hits[i].normal, Vector3.up); // returns a value between 0-180 148 | var lerp = angleBetweenNormalAndUp / 180f; 149 | Velocities[i] = Velocities[i] * Mathf.Lerp(0.5f, 1f, lerp); 150 | } 151 | } 152 | } 153 | } 154 | 155 | // Calculate and store a matrix we can use to draw each object. As we dont support rotation in this demo, we pretty 156 | // much only supply the position. A fixed scale is also applied to make sure the meshes we draw arnt giant. 157 | struct CalculateDrawMatricies : IJobParallelFor 158 | { 159 | [ReadOnly] 160 | public NativeArray positions; 161 | public NativeArray renderMatrices; 162 | 163 | public void Execute(int i) 164 | { 165 | renderMatrices[i] = Matrix4x4.TRS(positions[i], Quaternion.identity, new Vector3(0.5f, 0.5f, 0.5f)); 166 | } 167 | } 168 | 169 | struct FindSleepingObjects : IJobParallelFor 170 | { 171 | public NativeQueue.Concurrent SleepQueue; 172 | [ReadOnly] 173 | public NativeArray Sleeping; 174 | 175 | public void Execute(int index) 176 | { 177 | if (Sleeping[index] > 15) 178 | { 179 | SleepQueue.Enqueue(index); 180 | } 181 | } 182 | } 183 | 184 | CustomSampler sampler; 185 | IEnumerator Start() 186 | { 187 | // lets wait for half a second before we set off the system -- just to avoid any stutters 188 | yield return new WaitForSeconds(0.5f); 189 | 190 | // create a sampler so we can mesure performance 191 | sampler = CustomSampler.Create("SimplePhysics"); 192 | 193 | // lets define an rough approximation for gravity 194 | gravity = new Vector3(0, -9f, 0); 195 | 196 | // and set up all our NativeArrays with initial values 197 | velocities = new NativeArray(objectCount, Allocator.Persistent); 198 | positions = new NativeArray(objectCount, Allocator.Persistent); 199 | sleepingTimer = new NativeArray(objectCount, Allocator.Persistent); 200 | renderMatrices = new NativeArray(objectCount, Allocator.Persistent); 201 | renderMatrixArray = new Matrix4x4[objectCount]; 202 | asleep = new NativeQueue(Allocator.Persistent); 203 | 204 | for (int i = 0; i < objectCount; i++) 205 | { 206 | Respawn(i); 207 | } 208 | } 209 | 210 | private void Respawn(int i) 211 | { 212 | // Random cannot be used from jobs so this always has to execute on the main thread. 213 | 214 | //velocities[i] = Random.onUnitSphere * Random.Range(2, 10); // spawn objects with velocities spreading them out in a sphere 215 | velocities[i] = (Random.onUnitSphere + (((spawnDirection.position - transform.position).normalized).normalized)*1.3f).normalized * Random.Range(2f, 10f); // spawn with velocities arching towards a target object 216 | positions[i] = transform.position; 217 | sleepingTimer[i] = 0; 218 | renderMatrices[i] = Matrix4x4.identity; 219 | } 220 | 221 | void Update() 222 | { 223 | // only do an update if the data has been initialized 224 | if (!positions.IsCreated) 225 | return; 226 | 227 | sampler.Begin(); 228 | 229 | var deltaTime = Time.deltaTime; 230 | 231 | // FORCE ACCUMILATION 232 | 233 | // First off lets apply gravity to all the object in our scene that arnt currently asleep 234 | var gravityJob = new GravityJob() 235 | { 236 | DeltaTime = deltaTime, 237 | Gravity = gravity, 238 | Velocities = velocities, 239 | Sleeping = sleepingTimer 240 | }; 241 | var gravityDependency = gravityJob.Schedule(objectCount, 32); 242 | 243 | // TODO accumilate other forces here! gravity is just the simplest force to apply to our objects, 244 | // but theres no limit on the kind of forces we can simulate. We could add friction, air resistnace, 245 | // constant acceleration, joints and constrainsts, boyancy.. anything we can think of that can effect 246 | // the velocity of an object can have its own job scheduled here. 247 | 248 | // INTERGRATION AND COLLISION 249 | 250 | // Create temporary arrays for the raycast info. Lets use the TempJob allocator, 251 | // this means we have to dispose them when the job has finished - its short lived data 252 | var raycastCommands = new NativeArray(objectCount, Allocator.TempJob); 253 | var raycastHits = new NativeArray(objectCount, Allocator.TempJob); 254 | 255 | // Lets schedule jobs to do a collision raycast for each object. One job Prepare s all the raycast commands, 256 | // the second actually does the raycasts. 257 | var setupRaycastsJob = new PrepareRaycastCommands() 258 | { 259 | DeltaTime = deltaTime, 260 | Positions = positions, 261 | Raycasts = raycastCommands, 262 | Velocities = velocities 263 | }; 264 | 265 | var setupDependency = setupRaycastsJob.Schedule(objectCount, 32, gravityDependency ); 266 | 267 | var raycastDependency = RaycastCommand.ScheduleBatch(raycastCommands, raycastHits, 32, setupDependency ); 268 | 269 | // Now we know if there is a collision along our velocity vector, its time to integrate the velocity into 270 | // our objects for the current timeset. 271 | var integrateJob = new IntegratePhysics() 272 | { 273 | DeltaTime = deltaTime, 274 | Positions = positions, 275 | Velocities = velocities, 276 | Sleeping = sleepingTimer, 277 | Hits = raycastHits 278 | }; 279 | var integrateDependency = integrateJob.Schedule(objectCount, 32, raycastDependency ); 280 | 281 | // finally, respond to any collisions that happened in the lsat update step. 282 | var collisionResponeJob = new CalculateCollisionResponse() 283 | { 284 | Hits = raycastHits, 285 | Velocities = velocities, 286 | Sleeping = sleepingTimer 287 | }; 288 | var collisionDependency = collisionResponeJob.Schedule(objectCount, 32, integrateDependency ); 289 | 290 | // Now the physics is done, we need to create a drawing matrix for every object. This simple demo dosnt 291 | // implment roation, so only the translation values in the matrix reallllly matter. 292 | var renderMatrixJob = new CalculateDrawMatricies() 293 | { 294 | positions = positions, 295 | renderMatrices = renderMatrices 296 | }; 297 | var matrixDependency = renderMatrixJob.Schedule(objectCount, 32, collisionDependency ); 298 | 299 | // All the jobs we want to execute have been scheduled! By calling .Complete() on the last job in the 300 | // chain, Unity makes the main thread help out with scheduled jobs untill they are all complete. 301 | // then we can move on and use the data caluclated in the jobs safely, without worry about data being changed 302 | // by other threads as we try to use it - we *know* all the work is done 303 | matrixDependency.Complete(); 304 | 305 | // make sure we dispose of the temporary NativeArrays we used for raycasting 306 | raycastCommands.Dispose(); 307 | raycastHits.Dispose(); 308 | 309 | // lets schedule a job to figure out which objects are sleeping - this can run in the background whilst 310 | // we dispach the drawing commands for this frame. 311 | var sleepJob = new FindSleepingObjects() 312 | { 313 | Sleeping = sleepingTimer, 314 | SleepQueue = asleep 315 | }; 316 | var sleepDependancy = sleepJob.Schedule(objectCount, 32, matrixDependency); 317 | 318 | // lets actually issue a draw! 319 | renderMatrices.CopyTo(renderMatrixArray); // copy to a preallocated array, we would get garbage from ToArray() 320 | Graphics.DrawMeshInstanced(mesh, 0, material, renderMatrixArray); 321 | 322 | // DEBUG 1 - draw red lines showing object velocity 323 | //for (int i = 0; i < objectCount; i++) 324 | //{ 325 | /// Debug.DrawLine(positions[i], positions[i] + velocities[i], Color.red, 0.016f, true); 326 | //} 327 | 328 | // DEBUG 2 - draw a trail for a few objects, really helps to visualize the bounce! 329 | //var duration = 01f; 330 | //Debug.DrawLine(positions[0], positions[0] + velocities[0], Color.red, duration, true); 331 | //Debug.DrawLine(positions[200], positions[200] + velocities[200], Color.cyan, duration, true); 332 | //Debug.DrawLine(positions[400], positions[400] + velocities[400], Color.green, duration, true); 333 | //Debug.DrawLine(positions[600], positions[600] + velocities[600], Color.magenta, duration, true); 334 | //Debug.DrawLine(positions[800], positions[800] + velocities[800], Color.yellow, duration, true); 335 | //Debug.DrawLine(positions[1000], positions[1000] + velocities[1000], Color.blue, duration, true); 336 | //Debug.DrawLine(positions[100], positions[100] + velocities[100], Color.red, duration, true); 337 | //Debug.DrawLine(positions[300], positions[300] + velocities[300], Color.cyan, duration, true); 338 | //Debug.DrawLine(positions[500], positions[500] + velocities[500], Color.green, duration, true); 339 | //Debug.DrawLine(positions[700], positions[700] + velocities[700], Color.magenta, duration, true); 340 | //Debug.DrawLine(positions[900], positions[900] + velocities[900], Color.yellow, duration, true); 341 | 342 | // finally lets respawn any object that has been found to be asleep (ie not moved for 15 frames) 343 | // were going to respawn that object so there is a constant flow 344 | sleepDependancy.Complete(); 345 | for (int i = asleep.Count; i != 0; i--) 346 | { 347 | int index = asleep.Dequeue(); 348 | Respawn(index); 349 | } 350 | 351 | 352 | 353 | sampler.End(); 354 | } 355 | 356 | private void OnDisable() 357 | { 358 | velocities.Dispose(); 359 | positions.Dispose(); 360 | renderMatrices.Dispose(); 361 | sleepingTimer.Dispose(); 362 | asleep.Dispose(); 363 | } 364 | } 365 | -------------------------------------------------------------------------------- /Assets/SimpleJobifiedPhysics.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: a771d3ce55ccaa1408dd353e4f7327a3 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Assets/SimpleMaterial.mat: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!21 &2100000 4 | Material: 5 | serializedVersion: 6 6 | m_ObjectHideFlags: 0 7 | m_PrefabParentObject: {fileID: 0} 8 | m_PrefabInternal: {fileID: 0} 9 | m_Name: SimpleMaterial 10 | m_Shader: {fileID: 46, guid: 0000000000000000f000000000000000, type: 0} 11 | m_ShaderKeywords: _GLOSSYREFLECTIONS_OFF 12 | m_LightmapFlags: 4 13 | m_EnableInstancingVariants: 1 14 | m_DoubleSidedGI: 0 15 | m_CustomRenderQueue: -1 16 | stringTagMap: {} 17 | disabledShaderPasses: [] 18 | m_SavedProperties: 19 | serializedVersion: 3 20 | m_TexEnvs: 21 | - _BumpMap: 22 | m_Texture: {fileID: 0} 23 | m_Scale: {x: 1, y: 1} 24 | m_Offset: {x: 0, y: 0} 25 | - _DetailAlbedoMap: 26 | m_Texture: {fileID: 0} 27 | m_Scale: {x: 1, y: 1} 28 | m_Offset: {x: 0, y: 0} 29 | - _DetailMask: 30 | m_Texture: {fileID: 0} 31 | m_Scale: {x: 1, y: 1} 32 | m_Offset: {x: 0, y: 0} 33 | - _DetailNormalMap: 34 | m_Texture: {fileID: 0} 35 | m_Scale: {x: 1, y: 1} 36 | m_Offset: {x: 0, y: 0} 37 | - _EmissionMap: 38 | m_Texture: {fileID: 0} 39 | m_Scale: {x: 1, y: 1} 40 | m_Offset: {x: 0, y: 0} 41 | - _MainTex: 42 | m_Texture: {fileID: 0} 43 | m_Scale: {x: 1, y: 1} 44 | m_Offset: {x: 0, y: 0} 45 | - _MetallicGlossMap: 46 | m_Texture: {fileID: 0} 47 | m_Scale: {x: 1, y: 1} 48 | m_Offset: {x: 0, y: 0} 49 | - _OcclusionMap: 50 | m_Texture: {fileID: 0} 51 | m_Scale: {x: 1, y: 1} 52 | m_Offset: {x: 0, y: 0} 53 | - _ParallaxMap: 54 | m_Texture: {fileID: 0} 55 | m_Scale: {x: 1, y: 1} 56 | m_Offset: {x: 0, y: 0} 57 | m_Floats: 58 | - _BumpScale: 1 59 | - _Cutoff: 0.5 60 | - _DetailNormalMapScale: 1 61 | - _DstBlend: 0 62 | - _GlossMapScale: 1 63 | - _Glossiness: 0.834 64 | - _GlossyReflections: 0 65 | - _Metallic: 0 66 | - _Mode: 0 67 | - _OcclusionStrength: 1 68 | - _Parallax: 0.02 69 | - _SmoothnessTextureChannel: 0 70 | - _SpecularHighlights: 1 71 | - _SrcBlend: 1 72 | - _UVSec: 0 73 | - _ZWrite: 1 74 | m_Colors: 75 | - _Color: {r: 1, g: 0.3726415, b: 0.6195378, a: 1} 76 | - _EmissionColor: {r: 1.018868, g: 0.05744694, b: 0, a: 1} 77 | -------------------------------------------------------------------------------- /Assets/SimpleMaterial.mat.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: c8000df3fbe738942adfb8603476934b 3 | NativeFormatImporter: 4 | externalObjects: {} 5 | mainObjectFileID: 2100000 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Assets/Wall.mat: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!21 &2100000 4 | Material: 5 | serializedVersion: 6 6 | m_ObjectHideFlags: 0 7 | m_PrefabParentObject: {fileID: 0} 8 | m_PrefabInternal: {fileID: 0} 9 | m_Name: Wall 10 | m_Shader: {fileID: 46, guid: 0000000000000000f000000000000000, type: 0} 11 | m_ShaderKeywords: _EMISSION 12 | m_LightmapFlags: 1 13 | m_EnableInstancingVariants: 0 14 | m_DoubleSidedGI: 0 15 | m_CustomRenderQueue: -1 16 | stringTagMap: {} 17 | disabledShaderPasses: [] 18 | m_SavedProperties: 19 | serializedVersion: 3 20 | m_TexEnvs: 21 | - _BumpMap: 22 | m_Texture: {fileID: 0} 23 | m_Scale: {x: 1, y: 1} 24 | m_Offset: {x: 0, y: 0} 25 | - _DetailAlbedoMap: 26 | m_Texture: {fileID: 0} 27 | m_Scale: {x: 1, y: 1} 28 | m_Offset: {x: 0, y: 0} 29 | - _DetailMask: 30 | m_Texture: {fileID: 0} 31 | m_Scale: {x: 1, y: 1} 32 | m_Offset: {x: 0, y: 0} 33 | - _DetailNormalMap: 34 | m_Texture: {fileID: 0} 35 | m_Scale: {x: 1, y: 1} 36 | m_Offset: {x: 0, y: 0} 37 | - _EmissionMap: 38 | m_Texture: {fileID: 0} 39 | m_Scale: {x: 1, y: 1} 40 | m_Offset: {x: 0, y: 0} 41 | - _MainTex: 42 | m_Texture: {fileID: 2800000, guid: 12cbdb496dafb464097861bafa9ea5f0, type: 3} 43 | m_Scale: {x: 1, y: 1} 44 | m_Offset: {x: 0, y: 0} 45 | - _MetallicGlossMap: 46 | m_Texture: {fileID: 0} 47 | m_Scale: {x: 1, y: 1} 48 | m_Offset: {x: 0, y: 0} 49 | - _OcclusionMap: 50 | m_Texture: {fileID: 0} 51 | m_Scale: {x: 1, y: 1} 52 | m_Offset: {x: 0, y: 0} 53 | - _ParallaxMap: 54 | m_Texture: {fileID: 0} 55 | m_Scale: {x: 1, y: 1} 56 | m_Offset: {x: 0, y: 0} 57 | m_Floats: 58 | - _BumpScale: 1 59 | - _Cutoff: 0.5 60 | - _DetailNormalMapScale: 1 61 | - _DstBlend: 0 62 | - _GlossMapScale: 1 63 | - _Glossiness: 0.5 64 | - _GlossyReflections: 1 65 | - _Metallic: 0 66 | - _Mode: 0 67 | - _OcclusionStrength: 1 68 | - _Parallax: 0.02 69 | - _SmoothnessTextureChannel: 0 70 | - _SpecularHighlights: 1 71 | - _SrcBlend: 1 72 | - _UVSec: 0 73 | - _ZWrite: 1 74 | m_Colors: 75 | - _Color: {r: 1, g: 1, b: 1, a: 1} 76 | - _EmissionColor: {r: 0.13137256, g: 0.009803922, b: 0.023529412, a: 1} 77 | -------------------------------------------------------------------------------- /Assets/Wall.mat.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 302e301269ab4924f8f15ff9e3ca22cb 3 | NativeFormatImporter: 4 | externalObjects: {} 5 | mainObjectFileID: 2100000 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Docs/phys.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LotteMakesStuff/SimplePhysicsDemo/77bc1aada2847529018ad2f0b05357c3bf6551f3/Docs/phys.gif -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 LotteMakesStuff 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Packages/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "dependencies": { 3 | "com.unity.standardevents": "exclude", 4 | "com.unity.purchasing": "exclude", 5 | "com.unity.ads": "exclude", 6 | "com.unity.analytics": "exclude", 7 | "com.unity.package-manager-ui": "1.8.2", 8 | "com.unity.collections":"0.0.8", 9 | "com.unity.mathematics":"0.0.7" 10 | }, 11 | "registry": "https://staging-packages.unity.com" 12 | } 13 | -------------------------------------------------------------------------------- /ProjectSettings/AudioManager.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!11 &1 4 | AudioManager: 5 | m_ObjectHideFlags: 0 6 | m_Volume: 1 7 | Rolloff Scale: 1 8 | Doppler Factor: 1 9 | Default Speaker Mode: 2 10 | m_SampleRate: 0 11 | m_DSPBufferSize: 1024 12 | m_VirtualVoiceCount: 512 13 | m_RealVoiceCount: 32 14 | m_SpatializerPlugin: 15 | m_AmbisonicDecoderPlugin: 16 | m_DisableAudio: 0 17 | m_VirtualizeEffects: 1 18 | -------------------------------------------------------------------------------- /ProjectSettings/ClusterInputManager.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!236 &1 4 | ClusterInputManager: 5 | m_ObjectHideFlags: 0 6 | m_Inputs: [] 7 | -------------------------------------------------------------------------------- /ProjectSettings/DynamicsManager.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!55 &1 4 | PhysicsManager: 5 | m_ObjectHideFlags: 0 6 | serializedVersion: 7 7 | m_Gravity: {x: 0, y: -9.81, z: 0} 8 | m_DefaultMaterial: {fileID: 0} 9 | m_BounceThreshold: 2 10 | m_SleepThreshold: 0.005 11 | m_DefaultContactOffset: 0.01 12 | m_DefaultSolverIterations: 6 13 | m_DefaultSolverVelocityIterations: 1 14 | m_QueriesHitBackfaces: 0 15 | m_QueriesHitTriggers: 1 16 | m_EnableAdaptiveForce: 0 17 | m_ClothInterCollisionDistance: 0 18 | m_ClothInterCollisionStiffness: 0 19 | m_ContactsGeneration: 1 20 | m_LayerCollisionMatrix: ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 21 | m_AutoSimulation: 1 22 | m_AutoSyncTransforms: 1 23 | m_ClothInterCollisionSettingsToggle: 0 24 | m_ContactPairsMode: 0 25 | m_BroadphaseType: 0 26 | m_WorldBounds: 27 | m_Center: {x: 0, y: 0, z: 0} 28 | m_Extent: {x: 250, y: 250, z: 250} 29 | m_WorldSubdivisions: 8 30 | -------------------------------------------------------------------------------- /ProjectSettings/EditorBuildSettings.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!1045 &1 4 | EditorBuildSettings: 5 | m_ObjectHideFlags: 0 6 | serializedVersion: 2 7 | m_Scenes: 8 | - enabled: 1 9 | path: Assets/Scenes/SampleScene.unity 10 | guid: 99c9720ab356a0642a771bea13969a05 11 | m_configObjects: {} 12 | -------------------------------------------------------------------------------- /ProjectSettings/EditorSettings.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!159 &1 4 | EditorSettings: 5 | m_ObjectHideFlags: 0 6 | serializedVersion: 7 7 | m_ExternalVersionControlSupport: Visible Meta Files 8 | m_SerializationMode: 2 9 | m_LineEndingsForNewScripts: 2 10 | m_DefaultBehaviorMode: 0 11 | m_SpritePackerMode: 0 12 | m_SpritePackerPaddingPower: 1 13 | m_EtcTextureCompressorBehavior: 1 14 | m_EtcTextureFastCompressor: 1 15 | m_EtcTextureNormalCompressor: 2 16 | m_EtcTextureBestCompressor: 4 17 | m_ProjectGenerationIncludedExtensions: txt;xml;fnt;cd 18 | m_ProjectGenerationRootNamespace: 19 | m_UserGeneratedProjectSuffix: 20 | m_CollabEditorSettings: 21 | inProgressEnabled: 1 22 | -------------------------------------------------------------------------------- /ProjectSettings/GraphicsSettings.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!30 &1 4 | GraphicsSettings: 5 | m_ObjectHideFlags: 0 6 | serializedVersion: 12 7 | m_Deferred: 8 | m_Mode: 1 9 | m_Shader: {fileID: 69, guid: 0000000000000000f000000000000000, type: 0} 10 | m_DeferredReflections: 11 | m_Mode: 1 12 | m_Shader: {fileID: 74, guid: 0000000000000000f000000000000000, type: 0} 13 | m_ScreenSpaceShadows: 14 | m_Mode: 1 15 | m_Shader: {fileID: 64, guid: 0000000000000000f000000000000000, type: 0} 16 | m_LegacyDeferred: 17 | m_Mode: 1 18 | m_Shader: {fileID: 63, guid: 0000000000000000f000000000000000, type: 0} 19 | m_DepthNormals: 20 | m_Mode: 1 21 | m_Shader: {fileID: 62, guid: 0000000000000000f000000000000000, type: 0} 22 | m_MotionVectors: 23 | m_Mode: 1 24 | m_Shader: {fileID: 75, guid: 0000000000000000f000000000000000, type: 0} 25 | m_LightHalo: 26 | m_Mode: 1 27 | m_Shader: {fileID: 105, guid: 0000000000000000f000000000000000, type: 0} 28 | m_LensFlare: 29 | m_Mode: 1 30 | m_Shader: {fileID: 102, guid: 0000000000000000f000000000000000, type: 0} 31 | m_AlwaysIncludedShaders: 32 | - {fileID: 7, guid: 0000000000000000f000000000000000, type: 0} 33 | - {fileID: 15104, guid: 0000000000000000f000000000000000, type: 0} 34 | - {fileID: 15105, guid: 0000000000000000f000000000000000, type: 0} 35 | - {fileID: 15106, guid: 0000000000000000f000000000000000, type: 0} 36 | - {fileID: 10753, guid: 0000000000000000f000000000000000, type: 0} 37 | - {fileID: 10770, guid: 0000000000000000f000000000000000, type: 0} 38 | - {fileID: 17000, guid: 0000000000000000f000000000000000, type: 0} 39 | - {fileID: 16000, guid: 0000000000000000f000000000000000, type: 0} 40 | m_PreloadedShaders: [] 41 | m_SpritesDefaultMaterial: {fileID: 10754, guid: 0000000000000000f000000000000000, 42 | type: 0} 43 | m_CustomRenderPipeline: {fileID: 0} 44 | m_TransparencySortMode: 0 45 | m_TransparencySortAxis: {x: 0, y: 0, z: 1} 46 | m_DefaultRenderingPath: 1 47 | m_DefaultMobileRenderingPath: 1 48 | m_TierSettings: [] 49 | m_LightmapStripping: 0 50 | m_FogStripping: 0 51 | m_InstancingStripping: 0 52 | m_LightmapKeepPlain: 1 53 | m_LightmapKeepDirCombined: 1 54 | m_LightmapKeepDynamicPlain: 1 55 | m_LightmapKeepDynamicDirCombined: 1 56 | m_LightmapKeepShadowMask: 1 57 | m_LightmapKeepSubtractive: 1 58 | m_FogKeepLinear: 1 59 | m_FogKeepExp: 1 60 | m_FogKeepExp2: 1 61 | m_AlbedoSwatchInfos: [] 62 | m_LightsUseLinearIntensity: 0 63 | m_LightsUseColorTemperature: 0 64 | -------------------------------------------------------------------------------- /ProjectSettings/InputManager.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!13 &1 4 | InputManager: 5 | m_ObjectHideFlags: 0 6 | serializedVersion: 2 7 | m_Axes: 8 | - serializedVersion: 3 9 | m_Name: Horizontal 10 | descriptiveName: 11 | descriptiveNegativeName: 12 | negativeButton: left 13 | positiveButton: right 14 | altNegativeButton: a 15 | altPositiveButton: d 16 | gravity: 3 17 | dead: 0.001 18 | sensitivity: 3 19 | snap: 1 20 | invert: 0 21 | type: 0 22 | axis: 0 23 | joyNum: 0 24 | - serializedVersion: 3 25 | m_Name: Vertical 26 | descriptiveName: 27 | descriptiveNegativeName: 28 | negativeButton: down 29 | positiveButton: up 30 | altNegativeButton: s 31 | altPositiveButton: w 32 | gravity: 3 33 | dead: 0.001 34 | sensitivity: 3 35 | snap: 1 36 | invert: 0 37 | type: 0 38 | axis: 0 39 | joyNum: 0 40 | - serializedVersion: 3 41 | m_Name: Fire1 42 | descriptiveName: 43 | descriptiveNegativeName: 44 | negativeButton: 45 | positiveButton: left ctrl 46 | altNegativeButton: 47 | altPositiveButton: mouse 0 48 | gravity: 1000 49 | dead: 0.001 50 | sensitivity: 1000 51 | snap: 0 52 | invert: 0 53 | type: 0 54 | axis: 0 55 | joyNum: 0 56 | - serializedVersion: 3 57 | m_Name: Fire2 58 | descriptiveName: 59 | descriptiveNegativeName: 60 | negativeButton: 61 | positiveButton: left alt 62 | altNegativeButton: 63 | altPositiveButton: mouse 1 64 | gravity: 1000 65 | dead: 0.001 66 | sensitivity: 1000 67 | snap: 0 68 | invert: 0 69 | type: 0 70 | axis: 0 71 | joyNum: 0 72 | - serializedVersion: 3 73 | m_Name: Fire3 74 | descriptiveName: 75 | descriptiveNegativeName: 76 | negativeButton: 77 | positiveButton: left shift 78 | altNegativeButton: 79 | altPositiveButton: mouse 2 80 | gravity: 1000 81 | dead: 0.001 82 | sensitivity: 1000 83 | snap: 0 84 | invert: 0 85 | type: 0 86 | axis: 0 87 | joyNum: 0 88 | - serializedVersion: 3 89 | m_Name: Jump 90 | descriptiveName: 91 | descriptiveNegativeName: 92 | negativeButton: 93 | positiveButton: space 94 | altNegativeButton: 95 | altPositiveButton: 96 | gravity: 1000 97 | dead: 0.001 98 | sensitivity: 1000 99 | snap: 0 100 | invert: 0 101 | type: 0 102 | axis: 0 103 | joyNum: 0 104 | - serializedVersion: 3 105 | m_Name: Mouse X 106 | descriptiveName: 107 | descriptiveNegativeName: 108 | negativeButton: 109 | positiveButton: 110 | altNegativeButton: 111 | altPositiveButton: 112 | gravity: 0 113 | dead: 0 114 | sensitivity: 0.1 115 | snap: 0 116 | invert: 0 117 | type: 1 118 | axis: 0 119 | joyNum: 0 120 | - serializedVersion: 3 121 | m_Name: Mouse Y 122 | descriptiveName: 123 | descriptiveNegativeName: 124 | negativeButton: 125 | positiveButton: 126 | altNegativeButton: 127 | altPositiveButton: 128 | gravity: 0 129 | dead: 0 130 | sensitivity: 0.1 131 | snap: 0 132 | invert: 0 133 | type: 1 134 | axis: 1 135 | joyNum: 0 136 | - serializedVersion: 3 137 | m_Name: Mouse ScrollWheel 138 | descriptiveName: 139 | descriptiveNegativeName: 140 | negativeButton: 141 | positiveButton: 142 | altNegativeButton: 143 | altPositiveButton: 144 | gravity: 0 145 | dead: 0 146 | sensitivity: 0.1 147 | snap: 0 148 | invert: 0 149 | type: 1 150 | axis: 2 151 | joyNum: 0 152 | - serializedVersion: 3 153 | m_Name: Horizontal 154 | descriptiveName: 155 | descriptiveNegativeName: 156 | negativeButton: 157 | positiveButton: 158 | altNegativeButton: 159 | altPositiveButton: 160 | gravity: 0 161 | dead: 0.19 162 | sensitivity: 1 163 | snap: 0 164 | invert: 0 165 | type: 2 166 | axis: 0 167 | joyNum: 0 168 | - serializedVersion: 3 169 | m_Name: Vertical 170 | descriptiveName: 171 | descriptiveNegativeName: 172 | negativeButton: 173 | positiveButton: 174 | altNegativeButton: 175 | altPositiveButton: 176 | gravity: 0 177 | dead: 0.19 178 | sensitivity: 1 179 | snap: 0 180 | invert: 1 181 | type: 2 182 | axis: 1 183 | joyNum: 0 184 | - serializedVersion: 3 185 | m_Name: Fire1 186 | descriptiveName: 187 | descriptiveNegativeName: 188 | negativeButton: 189 | positiveButton: joystick button 0 190 | altNegativeButton: 191 | altPositiveButton: 192 | gravity: 1000 193 | dead: 0.001 194 | sensitivity: 1000 195 | snap: 0 196 | invert: 0 197 | type: 0 198 | axis: 0 199 | joyNum: 0 200 | - serializedVersion: 3 201 | m_Name: Fire2 202 | descriptiveName: 203 | descriptiveNegativeName: 204 | negativeButton: 205 | positiveButton: joystick button 1 206 | altNegativeButton: 207 | altPositiveButton: 208 | gravity: 1000 209 | dead: 0.001 210 | sensitivity: 1000 211 | snap: 0 212 | invert: 0 213 | type: 0 214 | axis: 0 215 | joyNum: 0 216 | - serializedVersion: 3 217 | m_Name: Fire3 218 | descriptiveName: 219 | descriptiveNegativeName: 220 | negativeButton: 221 | positiveButton: joystick button 2 222 | altNegativeButton: 223 | altPositiveButton: 224 | gravity: 1000 225 | dead: 0.001 226 | sensitivity: 1000 227 | snap: 0 228 | invert: 0 229 | type: 0 230 | axis: 0 231 | joyNum: 0 232 | - serializedVersion: 3 233 | m_Name: Jump 234 | descriptiveName: 235 | descriptiveNegativeName: 236 | negativeButton: 237 | positiveButton: joystick button 3 238 | altNegativeButton: 239 | altPositiveButton: 240 | gravity: 1000 241 | dead: 0.001 242 | sensitivity: 1000 243 | snap: 0 244 | invert: 0 245 | type: 0 246 | axis: 0 247 | joyNum: 0 248 | - serializedVersion: 3 249 | m_Name: Submit 250 | descriptiveName: 251 | descriptiveNegativeName: 252 | negativeButton: 253 | positiveButton: return 254 | altNegativeButton: 255 | altPositiveButton: joystick button 0 256 | gravity: 1000 257 | dead: 0.001 258 | sensitivity: 1000 259 | snap: 0 260 | invert: 0 261 | type: 0 262 | axis: 0 263 | joyNum: 0 264 | - serializedVersion: 3 265 | m_Name: Submit 266 | descriptiveName: 267 | descriptiveNegativeName: 268 | negativeButton: 269 | positiveButton: enter 270 | altNegativeButton: 271 | altPositiveButton: space 272 | gravity: 1000 273 | dead: 0.001 274 | sensitivity: 1000 275 | snap: 0 276 | invert: 0 277 | type: 0 278 | axis: 0 279 | joyNum: 0 280 | - serializedVersion: 3 281 | m_Name: Cancel 282 | descriptiveName: 283 | descriptiveNegativeName: 284 | negativeButton: 285 | positiveButton: escape 286 | altNegativeButton: 287 | altPositiveButton: joystick button 1 288 | gravity: 1000 289 | dead: 0.001 290 | sensitivity: 1000 291 | snap: 0 292 | invert: 0 293 | type: 0 294 | axis: 0 295 | joyNum: 0 296 | -------------------------------------------------------------------------------- /ProjectSettings/NavMeshAreas.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!126 &1 4 | NavMeshProjectSettings: 5 | m_ObjectHideFlags: 0 6 | serializedVersion: 2 7 | areas: 8 | - name: Walkable 9 | cost: 1 10 | - name: Not Walkable 11 | cost: 1 12 | - name: Jump 13 | cost: 2 14 | - name: 15 | cost: 1 16 | - name: 17 | cost: 1 18 | - name: 19 | cost: 1 20 | - name: 21 | cost: 1 22 | - name: 23 | cost: 1 24 | - name: 25 | cost: 1 26 | - name: 27 | cost: 1 28 | - name: 29 | cost: 1 30 | - name: 31 | cost: 1 32 | - name: 33 | cost: 1 34 | - name: 35 | cost: 1 36 | - name: 37 | cost: 1 38 | - name: 39 | cost: 1 40 | - name: 41 | cost: 1 42 | - name: 43 | cost: 1 44 | - name: 45 | cost: 1 46 | - name: 47 | cost: 1 48 | - name: 49 | cost: 1 50 | - name: 51 | cost: 1 52 | - name: 53 | cost: 1 54 | - name: 55 | cost: 1 56 | - name: 57 | cost: 1 58 | - name: 59 | cost: 1 60 | - name: 61 | cost: 1 62 | - name: 63 | cost: 1 64 | - name: 65 | cost: 1 66 | - name: 67 | cost: 1 68 | - name: 69 | cost: 1 70 | - name: 71 | cost: 1 72 | m_LastAgentTypeID: -887442657 73 | m_Settings: 74 | - serializedVersion: 2 75 | agentTypeID: 0 76 | agentRadius: 0.5 77 | agentHeight: 2 78 | agentSlope: 45 79 | agentClimb: 0.75 80 | ledgeDropHeight: 0 81 | maxJumpAcrossDistance: 0 82 | minRegionArea: 2 83 | manualCellSize: 0 84 | cellSize: 0.16666667 85 | manualTileSize: 0 86 | tileSize: 256 87 | accuratePlacement: 0 88 | debug: 89 | m_Flags: 0 90 | m_SettingNames: 91 | - Humanoid 92 | -------------------------------------------------------------------------------- /ProjectSettings/NetworkManager.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!149 &1 4 | NetworkManager: 5 | m_ObjectHideFlags: 0 6 | m_DebugLevel: 0 7 | m_Sendrate: 15 8 | m_AssetToPrefab: {} 9 | -------------------------------------------------------------------------------- /ProjectSettings/Physics2DSettings.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!19 &1 4 | Physics2DSettings: 5 | m_ObjectHideFlags: 0 6 | serializedVersion: 3 7 | m_Gravity: {x: 0, y: -9.81} 8 | m_DefaultMaterial: {fileID: 0} 9 | m_VelocityIterations: 8 10 | m_PositionIterations: 3 11 | m_VelocityThreshold: 1 12 | m_MaxLinearCorrection: 0.2 13 | m_MaxAngularCorrection: 8 14 | m_MaxTranslationSpeed: 100 15 | m_MaxRotationSpeed: 360 16 | m_BaumgarteScale: 0.2 17 | m_BaumgarteTimeOfImpactScale: 0.75 18 | m_TimeToSleep: 0.5 19 | m_LinearSleepTolerance: 0.01 20 | m_AngularSleepTolerance: 2 21 | m_DefaultContactOffset: 0.01 22 | m_AutoSimulation: 1 23 | m_QueriesHitTriggers: 1 24 | m_QueriesStartInColliders: 1 25 | m_ChangeStopsCallbacks: 0 26 | m_CallbacksOnDisable: 1 27 | m_AutoSyncTransforms: 1 28 | m_AlwaysShowColliders: 0 29 | m_ShowColliderSleep: 1 30 | m_ShowColliderContacts: 0 31 | m_ShowColliderAABB: 0 32 | m_ContactArrowScale: 0.2 33 | m_ColliderAwakeColor: {r: 0.5686275, g: 0.95686275, b: 0.54509807, a: 0.7529412} 34 | m_ColliderAsleepColor: {r: 0.5686275, g: 0.95686275, b: 0.54509807, a: 0.36078432} 35 | m_ColliderContactColor: {r: 1, g: 0, b: 1, a: 0.6862745} 36 | m_ColliderAABBColor: {r: 1, g: 1, b: 0, a: 0.2509804} 37 | m_LayerCollisionMatrix: ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 38 | -------------------------------------------------------------------------------- /ProjectSettings/PresetManager.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!1386491679 &1 4 | PresetManager: 5 | m_ObjectHideFlags: 0 6 | m_DefaultList: 7 | - type: 8 | m_NativeTypeID: 108 9 | m_ManagedTypePPtr: {fileID: 0} 10 | m_ManagedTypeFallback: 11 | defaultPresets: 12 | - m_Preset: {fileID: 2655988077585873504, guid: c1cf8506f04ef2c4a88b64b6c4202eea, 13 | type: 2} 14 | - type: 15 | m_NativeTypeID: 1020 16 | m_ManagedTypePPtr: {fileID: 0} 17 | m_ManagedTypeFallback: 18 | defaultPresets: 19 | - m_Preset: {fileID: 2655988077585873504, guid: 0cd792cc87e492d43b4e95b205fc5cc6, 20 | type: 2} 21 | - type: 22 | m_NativeTypeID: 1006 23 | m_ManagedTypePPtr: {fileID: 0} 24 | m_ManagedTypeFallback: 25 | defaultPresets: 26 | - m_Preset: {fileID: 2655988077585873504, guid: 7a99f8aa944efe94cb9bd74562b7d5f9, 27 | type: 2} 28 | -------------------------------------------------------------------------------- /ProjectSettings/ProjectSettings.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!129 &1 4 | PlayerSettings: 5 | m_ObjectHideFlags: 0 6 | serializedVersion: 15 7 | productGUID: 84f1c1a3224ffbb45a516c23182add5c 8 | AndroidProfiler: 0 9 | AndroidFilterTouchesWhenObscured: 0 10 | AndroidEnableSustainedPerformanceMode: 0 11 | defaultScreenOrientation: 4 12 | targetDevice: 2 13 | useOnDemandResources: 0 14 | accelerometerFrequency: 60 15 | companyName: DefaultCompany 16 | productName: SimplePhysicsDemo 17 | defaultCursor: {fileID: 0} 18 | cursorHotspot: {x: 0, y: 0} 19 | m_SplashScreenBackgroundColor: {r: 0.13725491, g: 0.12156863, b: 0.1254902, a: 1} 20 | m_ShowUnitySplashScreen: 1 21 | m_ShowUnitySplashLogo: 1 22 | m_SplashScreenOverlayOpacity: 1 23 | m_SplashScreenAnimation: 1 24 | m_SplashScreenLogoStyle: 1 25 | m_SplashScreenDrawMode: 0 26 | m_SplashScreenBackgroundAnimationZoom: 1 27 | m_SplashScreenLogoAnimationZoom: 1 28 | m_SplashScreenBackgroundLandscapeAspect: 1 29 | m_SplashScreenBackgroundPortraitAspect: 1 30 | m_SplashScreenBackgroundLandscapeUvs: 31 | serializedVersion: 2 32 | x: 0 33 | y: 0 34 | width: 1 35 | height: 1 36 | m_SplashScreenBackgroundPortraitUvs: 37 | serializedVersion: 2 38 | x: 0 39 | y: 0 40 | width: 1 41 | height: 1 42 | m_SplashScreenLogos: [] 43 | m_VirtualRealitySplashScreen: {fileID: 0} 44 | m_HolographicTrackingLossScreen: {fileID: 0} 45 | defaultScreenWidth: 1024 46 | defaultScreenHeight: 768 47 | defaultScreenWidthWeb: 960 48 | defaultScreenHeightWeb: 600 49 | m_StereoRenderingPath: 0 50 | m_ActiveColorSpace: 0 51 | m_MTRendering: 1 52 | m_StackTraceTypes: 010000000100000001000000010000000100000001000000 53 | iosShowActivityIndicatorOnLoading: -1 54 | androidShowActivityIndicatorOnLoading: -1 55 | tizenShowActivityIndicatorOnLoading: -1 56 | iosAppInBackgroundBehavior: 0 57 | displayResolutionDialog: 1 58 | iosAllowHTTPDownload: 1 59 | allowedAutorotateToPortrait: 1 60 | allowedAutorotateToPortraitUpsideDown: 1 61 | allowedAutorotateToLandscapeRight: 1 62 | allowedAutorotateToLandscapeLeft: 1 63 | useOSAutorotation: 1 64 | use32BitDisplayBuffer: 1 65 | preserveFramebufferAlpha: 0 66 | disableDepthAndStencilBuffers: 0 67 | androidBlitType: 0 68 | defaultIsNativeResolution: 1 69 | macRetinaSupport: 1 70 | runInBackground: 1 71 | captureSingleScreen: 0 72 | muteOtherAudioSources: 0 73 | Prepare IOS For Recording: 0 74 | Force IOS Speakers When Recording: 0 75 | deferSystemGesturesMode: 0 76 | hideHomeButton: 0 77 | submitAnalytics: 1 78 | usePlayerLog: 1 79 | bakeCollisionMeshes: 0 80 | forceSingleInstance: 0 81 | resizableWindow: 0 82 | useMacAppStoreValidation: 0 83 | macAppStoreCategory: public.app-category.games 84 | gpuSkinning: 1 85 | graphicsJobs: 1 86 | xboxPIXTextureCapture: 0 87 | xboxEnableAvatar: 0 88 | xboxEnableKinect: 0 89 | xboxEnableKinectAutoTracking: 0 90 | xboxEnableFitness: 0 91 | visibleInBackground: 1 92 | allowFullscreenSwitch: 1 93 | graphicsJobMode: 0 94 | fullscreenMode: 1 95 | xboxSpeechDB: 0 96 | xboxEnableHeadOrientation: 0 97 | xboxEnableGuest: 0 98 | xboxEnablePIXSampling: 0 99 | metalFramebufferOnly: 0 100 | n3dsDisableStereoscopicView: 0 101 | n3dsEnableSharedListOpt: 1 102 | n3dsEnableVSync: 0 103 | xboxOneResolution: 0 104 | xboxOneSResolution: 0 105 | xboxOneXResolution: 3 106 | xboxOneMonoLoggingLevel: 0 107 | xboxOneLoggingLevel: 1 108 | xboxOneDisableEsram: 0 109 | xboxOnePresentImmediateThreshold: 0 110 | switchQueueCommandMemory: 0 111 | videoMemoryForVertexBuffers: 0 112 | psp2PowerMode: 0 113 | psp2AcquireBGM: 1 114 | m_SupportedAspectRatios: 115 | 4:3: 1 116 | 5:4: 1 117 | 16:10: 1 118 | 16:9: 1 119 | Others: 1 120 | bundleVersion: 0.1 121 | preloadedAssets: [] 122 | metroInputSource: 0 123 | wsaTransparentSwapchain: 0 124 | m_HolographicPauseOnTrackingLoss: 1 125 | xboxOneDisableKinectGpuReservation: 0 126 | xboxOneEnable7thCore: 0 127 | vrSettings: 128 | cardboard: 129 | depthFormat: 0 130 | enableTransitionView: 0 131 | daydream: 132 | depthFormat: 0 133 | useSustainedPerformanceMode: 0 134 | enableVideoLayer: 0 135 | useProtectedVideoMemory: 0 136 | minimumSupportedHeadTracking: 0 137 | maximumSupportedHeadTracking: 1 138 | hololens: 139 | depthFormat: 1 140 | depthBufferSharingEnabled: 0 141 | enable360StereoCapture: 0 142 | oculus: 143 | sharedDepthBuffer: 0 144 | dashSupport: 0 145 | protectGraphicsMemory: 0 146 | useHDRDisplay: 0 147 | m_ColorGamuts: 00000000 148 | targetPixelDensity: 30 149 | resolutionScalingMode: 0 150 | androidSupportedAspectRatio: 1 151 | androidMaxAspectRatio: 2.1 152 | applicationIdentifier: {} 153 | buildNumber: {} 154 | AndroidBundleVersionCode: 1 155 | AndroidMinSdkVersion: 16 156 | AndroidTargetSdkVersion: 0 157 | AndroidPreferredInstallLocation: 1 158 | aotOptions: 159 | stripEngineCode: 1 160 | iPhoneStrippingLevel: 0 161 | iPhoneScriptCallOptimization: 0 162 | ForceInternetPermission: 0 163 | ForceSDCardPermission: 0 164 | CreateWallpaper: 0 165 | APKExpansionFiles: 0 166 | keepLoadedShadersAlive: 0 167 | StripUnusedMeshComponents: 1 168 | VertexChannelCompressionMask: 4054 169 | iPhoneSdkVersion: 988 170 | iOSTargetOSVersionString: 8.0 171 | tvOSSdkVersion: 0 172 | tvOSRequireExtendedGameController: 0 173 | tvOSTargetOSVersionString: 9.0 174 | uIPrerenderedIcon: 0 175 | uIRequiresPersistentWiFi: 0 176 | uIRequiresFullScreen: 1 177 | uIStatusBarHidden: 1 178 | uIExitOnSuspend: 0 179 | uIStatusBarStyle: 0 180 | iPhoneSplashScreen: {fileID: 0} 181 | iPhoneHighResSplashScreen: {fileID: 0} 182 | iPhoneTallHighResSplashScreen: {fileID: 0} 183 | iPhone47inSplashScreen: {fileID: 0} 184 | iPhone55inPortraitSplashScreen: {fileID: 0} 185 | iPhone55inLandscapeSplashScreen: {fileID: 0} 186 | iPhone58inPortraitSplashScreen: {fileID: 0} 187 | iPhone58inLandscapeSplashScreen: {fileID: 0} 188 | iPadPortraitSplashScreen: {fileID: 0} 189 | iPadHighResPortraitSplashScreen: {fileID: 0} 190 | iPadLandscapeSplashScreen: {fileID: 0} 191 | iPadHighResLandscapeSplashScreen: {fileID: 0} 192 | appleTVSplashScreen: {fileID: 0} 193 | appleTVSplashScreen2x: {fileID: 0} 194 | tvOSSmallIconLayers: [] 195 | tvOSSmallIconLayers2x: [] 196 | tvOSLargeIconLayers: [] 197 | tvOSLargeIconLayers2x: [] 198 | tvOSTopShelfImageLayers: [] 199 | tvOSTopShelfImageLayers2x: [] 200 | tvOSTopShelfImageWideLayers: [] 201 | tvOSTopShelfImageWideLayers2x: [] 202 | iOSLaunchScreenType: 0 203 | iOSLaunchScreenPortrait: {fileID: 0} 204 | iOSLaunchScreenLandscape: {fileID: 0} 205 | iOSLaunchScreenBackgroundColor: 206 | serializedVersion: 2 207 | rgba: 0 208 | iOSLaunchScreenFillPct: 100 209 | iOSLaunchScreenSize: 100 210 | iOSLaunchScreenCustomXibPath: 211 | iOSLaunchScreeniPadType: 0 212 | iOSLaunchScreeniPadImage: {fileID: 0} 213 | iOSLaunchScreeniPadBackgroundColor: 214 | serializedVersion: 2 215 | rgba: 0 216 | iOSLaunchScreeniPadFillPct: 100 217 | iOSLaunchScreeniPadSize: 100 218 | iOSLaunchScreeniPadCustomXibPath: 219 | iOSUseLaunchScreenStoryboard: 0 220 | iOSLaunchScreenCustomStoryboardPath: 221 | iOSDeviceRequirements: [] 222 | iOSURLSchemes: [] 223 | iOSBackgroundModes: 0 224 | iOSMetalForceHardShadows: 0 225 | metalEditorSupport: 1 226 | metalAPIValidation: 1 227 | iOSRenderExtraFrameOnPause: 0 228 | appleDeveloperTeamID: 229 | iOSManualSigningProvisioningProfileID: 230 | tvOSManualSigningProvisioningProfileID: 231 | appleEnableAutomaticSigning: 0 232 | iOSRequireARKit: 0 233 | appleEnableProMotion: 0 234 | clonedFromGUID: 56e7a2d3a00f33d44bdd161b773c35b5 235 | templatePackageId: com.unity.3dempty@0.0.1 236 | templateDefaultScene: Assets/Scenes/SampleScene.unity 237 | AndroidTargetArchitectures: 5 238 | AndroidSplashScreenScale: 0 239 | androidSplashScreen: {fileID: 0} 240 | AndroidKeystoreName: 241 | AndroidKeyaliasName: 242 | AndroidTVCompatibility: 1 243 | AndroidIsGame: 1 244 | AndroidEnableTango: 0 245 | androidEnableBanner: 1 246 | androidUseLowAccuracyLocation: 0 247 | m_AndroidBanners: 248 | - width: 320 249 | height: 180 250 | banner: {fileID: 0} 251 | androidGamepadSupportLevel: 0 252 | resolutionDialogBanner: {fileID: 0} 253 | m_BuildTargetIcons: [] 254 | m_BuildTargetPlatformIcons: [] 255 | m_BuildTargetBatching: [] 256 | m_BuildTargetGraphicsAPIs: 257 | - m_BuildTarget: WebGLSupport 258 | m_APIs: 0b000000 259 | m_Automatic: 1 260 | m_BuildTargetVRSettings: 261 | - m_BuildTarget: Standalone 262 | m_Enabled: 0 263 | m_Devices: 264 | - Oculus 265 | - OpenVR 266 | m_BuildTargetEnableVuforiaSettings: [] 267 | openGLRequireES31: 0 268 | openGLRequireES31AEP: 0 269 | m_TemplateCustomTags: {} 270 | mobileMTRendering: 271 | Android: 1 272 | iPhone: 1 273 | tvOS: 1 274 | m_BuildTargetGroupLightmapEncodingQuality: [] 275 | playModeTestRunnerEnabled: 0 276 | runPlayModeTestAsEditModeTest: 0 277 | actionOnDotNetUnhandledException: 1 278 | enableInternalProfiler: 0 279 | logObjCUncaughtExceptions: 1 280 | enableCrashReportAPI: 0 281 | cameraUsageDescription: 282 | locationUsageDescription: 283 | microphoneUsageDescription: 284 | switchNetLibKey: 285 | switchSocketMemoryPoolSize: 6144 286 | switchSocketAllocatorPoolSize: 128 287 | switchSocketConcurrencyLimit: 14 288 | switchScreenResolutionBehavior: 2 289 | switchUseCPUProfiler: 0 290 | switchApplicationID: 0x01004b9000490000 291 | switchNSODependencies: 292 | switchTitleNames_0: 293 | switchTitleNames_1: 294 | switchTitleNames_2: 295 | switchTitleNames_3: 296 | switchTitleNames_4: 297 | switchTitleNames_5: 298 | switchTitleNames_6: 299 | switchTitleNames_7: 300 | switchTitleNames_8: 301 | switchTitleNames_9: 302 | switchTitleNames_10: 303 | switchTitleNames_11: 304 | switchTitleNames_12: 305 | switchTitleNames_13: 306 | switchTitleNames_14: 307 | switchPublisherNames_0: 308 | switchPublisherNames_1: 309 | switchPublisherNames_2: 310 | switchPublisherNames_3: 311 | switchPublisherNames_4: 312 | switchPublisherNames_5: 313 | switchPublisherNames_6: 314 | switchPublisherNames_7: 315 | switchPublisherNames_8: 316 | switchPublisherNames_9: 317 | switchPublisherNames_10: 318 | switchPublisherNames_11: 319 | switchPublisherNames_12: 320 | switchPublisherNames_13: 321 | switchPublisherNames_14: 322 | switchIcons_0: {fileID: 0} 323 | switchIcons_1: {fileID: 0} 324 | switchIcons_2: {fileID: 0} 325 | switchIcons_3: {fileID: 0} 326 | switchIcons_4: {fileID: 0} 327 | switchIcons_5: {fileID: 0} 328 | switchIcons_6: {fileID: 0} 329 | switchIcons_7: {fileID: 0} 330 | switchIcons_8: {fileID: 0} 331 | switchIcons_9: {fileID: 0} 332 | switchIcons_10: {fileID: 0} 333 | switchIcons_11: {fileID: 0} 334 | switchIcons_12: {fileID: 0} 335 | switchIcons_13: {fileID: 0} 336 | switchIcons_14: {fileID: 0} 337 | switchSmallIcons_0: {fileID: 0} 338 | switchSmallIcons_1: {fileID: 0} 339 | switchSmallIcons_2: {fileID: 0} 340 | switchSmallIcons_3: {fileID: 0} 341 | switchSmallIcons_4: {fileID: 0} 342 | switchSmallIcons_5: {fileID: 0} 343 | switchSmallIcons_6: {fileID: 0} 344 | switchSmallIcons_7: {fileID: 0} 345 | switchSmallIcons_8: {fileID: 0} 346 | switchSmallIcons_9: {fileID: 0} 347 | switchSmallIcons_10: {fileID: 0} 348 | switchSmallIcons_11: {fileID: 0} 349 | switchSmallIcons_12: {fileID: 0} 350 | switchSmallIcons_13: {fileID: 0} 351 | switchSmallIcons_14: {fileID: 0} 352 | switchManualHTML: 353 | switchAccessibleURLs: 354 | switchLegalInformation: 355 | switchMainThreadStackSize: 1048576 356 | switchPresenceGroupId: 357 | switchLogoHandling: 0 358 | switchReleaseVersion: 0 359 | switchDisplayVersion: 1.0.0 360 | switchStartupUserAccount: 0 361 | switchTouchScreenUsage: 0 362 | switchSupportedLanguagesMask: 0 363 | switchLogoType: 0 364 | switchApplicationErrorCodeCategory: 365 | switchUserAccountSaveDataSize: 0 366 | switchUserAccountSaveDataJournalSize: 0 367 | switchApplicationAttribute: 0 368 | switchCardSpecSize: -1 369 | switchCardSpecClock: -1 370 | switchRatingsMask: 0 371 | switchRatingsInt_0: 0 372 | switchRatingsInt_1: 0 373 | switchRatingsInt_2: 0 374 | switchRatingsInt_3: 0 375 | switchRatingsInt_4: 0 376 | switchRatingsInt_5: 0 377 | switchRatingsInt_6: 0 378 | switchRatingsInt_7: 0 379 | switchRatingsInt_8: 0 380 | switchRatingsInt_9: 0 381 | switchRatingsInt_10: 0 382 | switchRatingsInt_11: 0 383 | switchLocalCommunicationIds_0: 384 | switchLocalCommunicationIds_1: 385 | switchLocalCommunicationIds_2: 386 | switchLocalCommunicationIds_3: 387 | switchLocalCommunicationIds_4: 388 | switchLocalCommunicationIds_5: 389 | switchLocalCommunicationIds_6: 390 | switchLocalCommunicationIds_7: 391 | switchParentalControl: 0 392 | switchAllowsScreenshot: 1 393 | switchAllowsVideoCapturing: 1 394 | switchAllowsRuntimeAddOnContentInstall: 0 395 | switchDataLossConfirmation: 0 396 | switchSupportedNpadStyles: 3 397 | switchSocketConfigEnabled: 0 398 | switchTcpInitialSendBufferSize: 32 399 | switchTcpInitialReceiveBufferSize: 64 400 | switchTcpAutoSendBufferSizeMax: 256 401 | switchTcpAutoReceiveBufferSizeMax: 256 402 | switchUdpSendBufferSize: 9 403 | switchUdpReceiveBufferSize: 42 404 | switchSocketBufferEfficiency: 4 405 | switchSocketInitializeEnabled: 1 406 | switchNetworkInterfaceManagerInitializeEnabled: 1 407 | switchPlayerConnectionEnabled: 1 408 | ps4NPAgeRating: 12 409 | ps4NPTitleSecret: 410 | ps4NPTrophyPackPath: 411 | ps4ParentalLevel: 11 412 | ps4ContentID: ED1633-NPXX51362_00-0000000000000000 413 | ps4Category: 0 414 | ps4MasterVersion: 01.00 415 | ps4AppVersion: 01.00 416 | ps4AppType: 0 417 | ps4ParamSfxPath: 418 | ps4VideoOutPixelFormat: 0 419 | ps4VideoOutInitialWidth: 1920 420 | ps4VideoOutBaseModeInitialWidth: 1920 421 | ps4VideoOutReprojectionRate: 60 422 | ps4PronunciationXMLPath: 423 | ps4PronunciationSIGPath: 424 | ps4BackgroundImagePath: 425 | ps4StartupImagePath: 426 | ps4StartupImagesFolder: 427 | ps4IconImagesFolder: 428 | ps4SaveDataImagePath: 429 | ps4SdkOverride: 430 | ps4BGMPath: 431 | ps4ShareFilePath: 432 | ps4ShareOverlayImagePath: 433 | ps4PrivacyGuardImagePath: 434 | ps4NPtitleDatPath: 435 | ps4RemotePlayKeyAssignment: -1 436 | ps4RemotePlayKeyMappingDir: 437 | ps4PlayTogetherPlayerCount: 0 438 | ps4EnterButtonAssignment: 1 439 | ps4ApplicationParam1: 0 440 | ps4ApplicationParam2: 0 441 | ps4ApplicationParam3: 0 442 | ps4ApplicationParam4: 0 443 | ps4DownloadDataSize: 0 444 | ps4GarlicHeapSize: 2048 445 | ps4ProGarlicHeapSize: 2560 446 | ps4Passcode: frAQBc8Wsa1xVPfvJcrgRYwTiizs2trQ 447 | ps4pnSessions: 1 448 | ps4pnPresence: 1 449 | ps4pnFriends: 1 450 | ps4pnGameCustomData: 1 451 | playerPrefsSupport: 0 452 | enableApplicationExit: 0 453 | restrictedAudioUsageRights: 0 454 | ps4UseResolutionFallback: 0 455 | ps4ReprojectionSupport: 0 456 | ps4UseAudio3dBackend: 0 457 | ps4SocialScreenEnabled: 0 458 | ps4ScriptOptimizationLevel: 0 459 | ps4Audio3dVirtualSpeakerCount: 14 460 | ps4attribCpuUsage: 0 461 | ps4PatchPkgPath: 462 | ps4PatchLatestPkgPath: 463 | ps4PatchChangeinfoPath: 464 | ps4PatchDayOne: 0 465 | ps4attribUserManagement: 0 466 | ps4attribMoveSupport: 0 467 | ps4attrib3DSupport: 0 468 | ps4attribShareSupport: 0 469 | ps4attribExclusiveVR: 0 470 | ps4disableAutoHideSplash: 0 471 | ps4videoRecordingFeaturesUsed: 0 472 | ps4contentSearchFeaturesUsed: 0 473 | ps4attribEyeToEyeDistanceSettingVR: 0 474 | ps4IncludedModules: [] 475 | monoEnv: 476 | psp2Splashimage: {fileID: 0} 477 | psp2NPTrophyPackPath: 478 | psp2NPSupportGBMorGJP: 0 479 | psp2NPAgeRating: 12 480 | psp2NPTitleDatPath: 481 | psp2NPCommsID: 482 | psp2NPCommunicationsID: 483 | psp2NPCommsPassphrase: 484 | psp2NPCommsSig: 485 | psp2ParamSfxPath: 486 | psp2ManualPath: 487 | psp2LiveAreaGatePath: 488 | psp2LiveAreaBackroundPath: 489 | psp2LiveAreaPath: 490 | psp2LiveAreaTrialPath: 491 | psp2PatchChangeInfoPath: 492 | psp2PatchOriginalPackage: 493 | psp2PackagePassword: F69AzBlax3CF3EDNhm3soLBPh71Yexui 494 | psp2KeystoneFile: 495 | psp2MemoryExpansionMode: 0 496 | psp2DRMType: 0 497 | psp2StorageType: 0 498 | psp2MediaCapacity: 0 499 | psp2DLCConfigPath: 500 | psp2ThumbnailPath: 501 | psp2BackgroundPath: 502 | psp2SoundPath: 503 | psp2TrophyCommId: 504 | psp2TrophyPackagePath: 505 | psp2PackagedResourcesPath: 506 | psp2SaveDataQuota: 10240 507 | psp2ParentalLevel: 1 508 | psp2ShortTitle: Not Set 509 | psp2ContentID: IV0000-ABCD12345_00-0123456789ABCDEF 510 | psp2Category: 0 511 | psp2MasterVersion: 01.00 512 | psp2AppVersion: 01.00 513 | psp2TVBootMode: 0 514 | psp2EnterButtonAssignment: 2 515 | psp2TVDisableEmu: 0 516 | psp2AllowTwitterDialog: 1 517 | psp2Upgradable: 0 518 | psp2HealthWarning: 0 519 | psp2UseLibLocation: 0 520 | psp2InfoBarOnStartup: 0 521 | psp2InfoBarColor: 0 522 | psp2ScriptOptimizationLevel: 0 523 | splashScreenBackgroundSourceLandscape: {fileID: 0} 524 | splashScreenBackgroundSourcePortrait: {fileID: 0} 525 | spritePackerPolicy: 526 | webGLMemorySize: 256 527 | webGLExceptionSupport: 1 528 | webGLNameFilesAsHashes: 0 529 | webGLDataCaching: 0 530 | webGLDebugSymbols: 0 531 | webGLEmscriptenArgs: 532 | webGLModulesDirectory: 533 | webGLTemplate: APPLICATION:Default 534 | webGLAnalyzeBuildSize: 0 535 | webGLUseEmbeddedResources: 0 536 | webGLCompressionFormat: 1 537 | webGLLinkerTarget: 0 538 | scriptingDefineSymbols: 539 | 1: UNITY_POST_PROCESSING_STACK_V2 540 | 4: UNITY_POST_PROCESSING_STACK_V2 541 | 7: UNITY_POST_PROCESSING_STACK_V2 542 | 13: UNITY_POST_PROCESSING_STACK_V2 543 | 17: UNITY_POST_PROCESSING_STACK_V2 544 | 18: UNITY_POST_PROCESSING_STACK_V2 545 | 19: UNITY_POST_PROCESSING_STACK_V2 546 | 21: UNITY_POST_PROCESSING_STACK_V2 547 | 23: UNITY_POST_PROCESSING_STACK_V2 548 | 24: UNITY_POST_PROCESSING_STACK_V2 549 | 25: UNITY_POST_PROCESSING_STACK_V2 550 | 26: UNITY_POST_PROCESSING_STACK_V2 551 | 27: UNITY_POST_PROCESSING_STACK_V2 552 | platformArchitecture: {} 553 | scriptingBackend: {} 554 | il2cppCompilerConfiguration: {} 555 | incrementalIl2cppBuild: {} 556 | allowUnsafeCode: 0 557 | additionalIl2CppArgs: 558 | scriptingRuntimeVersion: 1 559 | apiCompatibilityLevelPerPlatform: {} 560 | m_RenderingPath: 1 561 | m_MobileRenderingPath: 1 562 | metroPackageName: Template_3D 563 | metroPackageVersion: 564 | metroCertificatePath: 565 | metroCertificatePassword: 566 | metroCertificateSubject: 567 | metroCertificateIssuer: 568 | metroCertificateNotAfter: 0000000000000000 569 | metroApplicationDescription: Template_3D 570 | wsaImages: {} 571 | metroTileShortName: 572 | metroCommandLineArgsFile: 573 | metroTileShowName: 0 574 | metroMediumTileShowName: 0 575 | metroLargeTileShowName: 0 576 | metroWideTileShowName: 0 577 | metroDefaultTileSize: 1 578 | metroTileForegroundText: 2 579 | metroTileBackgroundColor: {r: 0.13333334, g: 0.17254902, b: 0.21568628, a: 0} 580 | metroSplashScreenBackgroundColor: {r: 0.12941177, g: 0.17254902, b: 0.21568628, 581 | a: 1} 582 | metroSplashScreenUseBackgroundColor: 0 583 | platformCapabilities: {} 584 | metroFTAName: 585 | metroFTAFileTypes: [] 586 | metroProtocolName: 587 | metroCompilationOverrides: 1 588 | tizenProductDescription: 589 | tizenProductURL: 590 | tizenSigningProfileName: 591 | tizenGPSPermissions: 0 592 | tizenMicrophonePermissions: 0 593 | tizenDeploymentTarget: 594 | tizenDeploymentTargetType: -1 595 | tizenMinOSVersion: 1 596 | n3dsUseExtSaveData: 0 597 | n3dsCompressStaticMem: 1 598 | n3dsExtSaveDataNumber: 0x12345 599 | n3dsStackSize: 131072 600 | n3dsTargetPlatform: 2 601 | n3dsRegion: 7 602 | n3dsMediaSize: 0 603 | n3dsLogoStyle: 3 604 | n3dsTitle: GameName 605 | n3dsProductCode: 606 | n3dsApplicationId: 0xFF3FF 607 | XboxOneProductId: 608 | XboxOneUpdateKey: 609 | XboxOneSandboxId: 610 | XboxOneContentId: 611 | XboxOneTitleId: 612 | XboxOneSCId: 613 | XboxOneGameOsOverridePath: 614 | XboxOnePackagingOverridePath: 615 | XboxOneAppManifestOverridePath: 616 | XboxOnePackageEncryption: 0 617 | XboxOnePackageUpdateGranularity: 2 618 | XboxOneDescription: 619 | XboxOneLanguage: 620 | - enus 621 | XboxOneCapability: [] 622 | XboxOneGameRating: {} 623 | XboxOneIsContentPackage: 0 624 | XboxOneEnableGPUVariability: 0 625 | XboxOneSockets: {} 626 | XboxOneSplashScreen: {fileID: 0} 627 | XboxOneAllowedProductIds: [] 628 | XboxOnePersistentLocalStorageSize: 0 629 | XboxOneXTitleMemory: 8 630 | xboxOneScriptCompiler: 0 631 | vrEditorSettings: 632 | daydream: 633 | daydreamIconForeground: {fileID: 0} 634 | daydreamIconBackground: {fileID: 0} 635 | cloudServicesEnabled: 636 | UNet: 1 637 | facebookSdkVersion: 7.9.4 638 | apiCompatibilityLevel: 2 639 | cloudProjectId: 640 | projectName: Template_3D 641 | organizationId: 642 | cloudEnabled: 0 643 | enableNativePlatformBackendsForNewInputSystem: 0 644 | disableOldInputManagerSupport: 0 645 | -------------------------------------------------------------------------------- /ProjectSettings/ProjectVersion.txt: -------------------------------------------------------------------------------- 1 | m_EditorVersion: 2018.1.0b12 2 | -------------------------------------------------------------------------------- /ProjectSettings/QualitySettings.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!47 &1 4 | QualitySettings: 5 | m_ObjectHideFlags: 0 6 | serializedVersion: 5 7 | m_CurrentQuality: 0 8 | m_QualitySettings: 9 | - serializedVersion: 2 10 | name: High 11 | pixelLightCount: 2 12 | shadows: 2 13 | shadowResolution: 1 14 | shadowProjection: 1 15 | shadowCascades: 2 16 | shadowDistance: 60 17 | shadowNearPlaneOffset: 3 18 | shadowCascade2Split: 0.33333334 19 | shadowCascade4Split: {x: 0.06666667, y: 0.2, z: 0.46666667} 20 | shadowmaskMode: 1 21 | blendWeights: 2 22 | textureQuality: 0 23 | anisotropicTextures: 1 24 | antiAliasing: 2 25 | softParticles: 0 26 | softVegetation: 1 27 | realtimeReflectionProbes: 1 28 | billboardsFaceCameraPosition: 1 29 | vSyncCount: 1 30 | lodBias: 1 31 | maximumLODLevel: 0 32 | particleRaycastBudget: 256 33 | asyncUploadTimeSlice: 2 34 | asyncUploadBufferSize: 4 35 | resolutionScalingFixedDPIFactor: 1 36 | excludedTargetPlatforms: [] 37 | m_PerPlatformDefaultQuality: 38 | Android: 0 39 | Nintendo 3DS: 0 40 | Nintendo Switch: 0 41 | PS4: 0 42 | PSP2: 0 43 | Standalone: 0 44 | Tizen: 0 45 | WebGL: 0 46 | WiiU: 0 47 | Windows Store Apps: 0 48 | XboxOne: 0 49 | iPhone: 0 50 | tvOS: 0 51 | -------------------------------------------------------------------------------- /ProjectSettings/TagManager.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!78 &1 4 | TagManager: 5 | serializedVersion: 2 6 | tags: [] 7 | layers: 8 | - Default 9 | - TransparentFX 10 | - Ignore Raycast 11 | - 12 | - Water 13 | - UI 14 | - 15 | - 16 | - PostProcessing 17 | - 18 | - 19 | - 20 | - 21 | - 22 | - 23 | - 24 | - 25 | - 26 | - 27 | - 28 | - 29 | - 30 | - 31 | - 32 | - 33 | - 34 | - 35 | - 36 | - 37 | - 38 | - 39 | - 40 | m_SortingLayers: 41 | - name: Default 42 | uniqueID: 0 43 | locked: 0 44 | -------------------------------------------------------------------------------- /ProjectSettings/TimeManager.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!5 &1 4 | TimeManager: 5 | m_ObjectHideFlags: 0 6 | Fixed Timestep: 0.0167 7 | Maximum Allowed Timestep: 0.1 8 | m_TimeScale: 1 9 | Maximum Particle Timestep: 0.03 10 | -------------------------------------------------------------------------------- /ProjectSettings/UnityConnectSettings.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!310 &1 4 | UnityConnectSettings: 5 | m_ObjectHideFlags: 0 6 | m_Enabled: 0 7 | m_TestMode: 0 8 | m_TestEventUrl: 9 | m_TestConfigUrl: 10 | m_TestInitMode: 0 11 | CrashReportingSettings: 12 | m_EventUrl: https://perf-events.cloud.unity3d.com/api/events/crashes 13 | m_NativeEventUrl: https://perf-events.cloud.unity3d.com/symbolicate 14 | m_Enabled: 0 15 | m_CaptureEditorExceptions: 1 16 | UnityPurchasingSettings: 17 | m_Enabled: 0 18 | m_TestMode: 0 19 | UnityAnalyticsSettings: 20 | m_Enabled: 1 21 | m_InitializeOnStartup: 1 22 | m_TestMode: 0 23 | m_TestEventUrl: 24 | m_TestConfigUrl: 25 | UnityAdsSettings: 26 | m_Enabled: 0 27 | m_InitializeOnStartup: 1 28 | m_TestMode: 0 29 | m_IosGameId: 30 | m_AndroidGameId: 31 | m_GameIds: {} 32 | m_GameId: 33 | PerformanceReportingSettings: 34 | m_Enabled: 0 35 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # SimplePhysics Demo Buy Me a Coffee at ko-fi.com Become a Patron! 2 | ![Maintenance](https://img.shields.io/maintenance/no/2018) [![GitHub license](https://img.shields.io/github/license/LotteMakesStuff/SimplePhysicsDemo)](https://github.com/LotteMakesStuff/SimplePhysicsDemo/blob/master/LICENSE) 3 | [![Twitter Follow](https://img.shields.io/twitter/follow/LotteMakesStuff?label=follow&style=social)](https://twitter.com/LotteMakesStuff) ![UnityVersion](https://img.shields.io/badge/made%20with%20unity-2018.1-orange?logo=unity) 4 | 5 | 6 | 7 | SimplePhysics is a Unity 2018.1 demo showcasing a custom physics system which has all of its processing via the new Unity Jobs system. 8 | ![demo gif - boxes flying everywhere!](/Docs/phys.gif) 9 | * Its a simplified, bare-bones version of the same concepts behind [LotteMakesStuff's HyperPhysics engine](https://twitter.com/LotteMakesStuff/status/964612077708070912). 10 | * It uses the new Unity 2018.1 Job system to run the physics simulation across all your CPUs cores at once. 11 | * Its a good nontrivial example of how to chain job dependencies together and how to use NativeArrays 12 | * It demos Unity's RaycastCommand - a new way of sending batches of raycasts to be processed in jobs 13 | * It's tiny!! (less than 300 lines!) 14 | * It's open source- do what you want with it MIT licensed 15 | 16 | ## How do I run it? 17 | This demo showcases new feature added in Unity 2018.1, and has been tested with 2018.1b6. [Any release after that should be fine](https://unity3d.com/unity/beta-download). Once you have cloned the repository, simply open `Scenes/SampleScene.unity`. There's a fairly basic little set up here, a floor, one wall to bounce off and of course, our physics system (its attached to the Physics Spawner game object). The floor and wall just has regular Unity colliders attached, nothing special there. The spawner only has 3 public properties, Mesh, Material and Spawn direction. 18 | * Mesh and Material set the assets you want to render the physics objects with. Defaults to a pinkish cube. 19 | * Spawn Direction defaults to the walls transform. The initial velocity for physics object will be angled towards this transform, spraying out in a satisfying arch. 20 | 21 | ## Wheres the code? 22 | Its all contained in [`SimpleJobifiedPhysics.cs`](/Assets/SimpleJobifiedPhysics.cs). 23 | 24 | ## How does it work? 25 | Unlike unity game objects and rigidbodies, our physics objects aren't represented by concrete objects in this engine, but by a "structure of arrays'. At the top of SimpleJobifiedPhysics we define a whole bunch of NativeArrays that hold all the various properties that make up a physics object. If you imagine these laid out in a table or excel sheet, each row across all the arrays is an individual object. 26 | 27 | Position | Velocity | Sleeping | RenderingMatrix 28 | ------------ | -------------|------------ | ------------- 29 | Vector3 | Vector3 | int | Matrix4x4 30 | The position of the obect after the previous update | The direction and speed the object is moving in |
  • Sleeping == 0, the object is moving.
  • Sleeping >= 0, the objet is stable. Counter gets incremented every frame the object sleeps for.
| We need this to draw the object with Graphics.DrawMeshInstanced(...) 31 | 32 | Okay, there are 5 steps in running this physics engine! All of these steps are implemented as an [`IJobParallelFor`](https://docs.unity3d.com/2018.1/Documentation/ScriptReference/Unity.Jobs.IJobParallelFor.html) job. These jobs split the work up into batches and run it on all free CPU cores in the system - allowing us to process a lot of stuff very fast. 33 | 34 | 1. Force Accumulation - Forces are things that affect the Velocity of our physics objects. Our first task is to calculate all these forces and merge them into Velocity. This demo only ships with one force generator - `GravityJob`. As long as an object isn't sleeping, we apply gravity to it. Once we have done this we will know how are we want to move 35 | 1. Collision Detection - Now we know how much Velocity is acting on our object, we can use a raycast to see if it would hit anything if it moved the maximum amount it was allowed to move this frame (`float distance = (Velocities[i] * DeltaTime).magnitude;`). We use Unity's new batch raycasting system, [`RaycastCommand`](https://docs.unity3d.com/2018.1/Documentation/ScriptReference/RaycastCommand.html). Its built on the Job system and runs our casts over all the available CPU cores, just like the rest of our physics engine! Once we have done this we will know how far its safe to move. 36 | 1. Velocity Integration - Now we know how far we can move, we have to integrate it onto our position. We do this in the most simple way possible, adding the velocity scaled by delta time to the position (Euler Integration). 37 | 1. Collision Response - Here we can respond if an object actually hits a collider in the world. In this demo, we reflect the velocity so the colliding object bounces. We also dampen the objects velocity to simulate friction. This damping effect is what ultimately brings an object to a stop. When we detect an object has next to no velocity acting on it we mark it as sleeping -so no forces affect it at all and its position is totally stable. Once an object has been stable for 15 updates, we respawn it to keep the simulation going! 38 | 1. Rendering - Finally, we calculate a matrix we can send to Unity's renderer to correctly position the physics object on the screen. We use `Graphics.DrawMeshInstanced(...)` to draw all the physics objects because gosh its fast! 39 | 40 | All of these steps are implemented as one (or more!) unity jobs and each job in the chain depends on the one that came before it, that's why were passing the [`JobHandle`](https://docs.unity3d.com/2018.1/Documentation/ScriptReference/Unity.Jobs.JobHandle.html) from each job into the next one we schedule. This tells unity about that dependency, and it won't schedule a job higher up in the chain until the previous job has been totally completed 41 | 42 | ### What next? 43 | Well, that's kinda all there is to it in this demo - there is a lot of room for improvement though if you want to use this as a foundation to build your own physics system! Some of these ideas I have already implemented in HyperPhysics and might write about in the future - others are just cool things to experiment with 44 | 45 | * Currently there is only one force generator, gravity. Try implementing Springs (google for Hooke's Law!), or bouncy, or maybe even joints and constraints! 46 | * Currently all objects experience the same gravity in the same direction - why not try adding more interesting gravity implementations like gravity attractors, gravity that makes you fall towards the closest tiny planet (like Mario galaxy!). you could even experiment with trigger volumes that slow down all objects that enter them! 47 | * The simulation size is currently limited to 1023 objects - this is because that is the most `Graphics.DrawMeshInstanced(...)` can draw in a single call. Try drawing in batches so you can break this limit and 48 | * The part of this system that scales the worst is our dependancy of Unity's `RaycastCommand`. Try to write your own raycast system (the custom raycaster in HyperPhysics is the main reason its so fast and can handle so many objects). 49 | * We are currently treating our Physics Objects as zero mass particles... they cant even rotate! try adding mass and rotations to the system. 50 | 51 | Have fun! 52 | love, 53 | [@LotteMakesStuff ![twitter icon](http://i.imgur.com/wWzX9uB.png)](http://www.twitter.com/LotteMakesStuff) 54 | 55 | --------------------------------------------------------------------------------