mirror of
https://gitee.com/jisol/jisol-game/
synced 2025-06-26 03:14:47 +00:00
提交
This commit is contained in:
parent
aa4d6c3ce2
commit
877dca3b43
762
JNFrame/App.csproj
Normal file
762
JNFrame/App.csproj
Normal file
@ -0,0 +1,762 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<LangVersion>9.0</LangVersion>
|
||||
<_TargetFrameworkDirectories>non_empty_path_generated_by_unity.rider.package</_TargetFrameworkDirectories>
|
||||
<_FullFrameworkReferenceAssemblyPaths>non_empty_path_generated_by_unity.rider.package</_FullFrameworkReferenceAssemblyPaths>
|
||||
<DisableHandlePackageFileConflicts>true</DisableHandlePackageFileConflicts>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProductVersion>10.0.20506</ProductVersion>
|
||||
<SchemaVersion>2.0</SchemaVersion>
|
||||
<RootNamespace></RootNamespace>
|
||||
<ProjectGuid>{86f5a836-c92e-bcf7-bc96-4683fb573cb1}</ProjectGuid>
|
||||
<ProjectTypeGuids>{E097FAD1-6243-4DAD-9C02-E9B9EFC3FFC1};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
|
||||
<OutputType>Library</OutputType>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<AssemblyName>App</AssemblyName>
|
||||
<TargetFrameworkVersion>v4.7.1</TargetFrameworkVersion>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<BaseDirectory>.</BaseDirectory>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>Temp\Bin\Debug\App\</OutputPath>
|
||||
<DefineConstants>UNITY_2022_3_16;UNITY_2022_3;UNITY_2022;UNITY_5_3_OR_NEWER;UNITY_5_4_OR_NEWER;UNITY_5_5_OR_NEWER;UNITY_5_6_OR_NEWER;UNITY_2017_1_OR_NEWER;UNITY_2017_2_OR_NEWER;UNITY_2017_3_OR_NEWER;UNITY_2017_4_OR_NEWER;UNITY_2018_1_OR_NEWER;UNITY_2018_2_OR_NEWER;UNITY_2018_3_OR_NEWER;UNITY_2018_4_OR_NEWER;UNITY_2019_1_OR_NEWER;UNITY_2019_2_OR_NEWER;UNITY_2019_3_OR_NEWER;UNITY_2019_4_OR_NEWER;UNITY_2020_1_OR_NEWER;UNITY_2020_2_OR_NEWER;UNITY_2020_3_OR_NEWER;UNITY_2021_1_OR_NEWER;UNITY_2021_2_OR_NEWER;UNITY_2021_3_OR_NEWER;UNITY_2022_1_OR_NEWER;UNITY_2022_2_OR_NEWER;UNITY_2022_3_OR_NEWER;UNITY_INCLUDE_TESTS;ENABLE_AR;ENABLE_AUDIO;ENABLE_CACHING;ENABLE_CLOTH;ENABLE_EVENT_QUEUE;ENABLE_MICROPHONE;ENABLE_MULTIPLE_DISPLAYS;ENABLE_PHYSICS;ENABLE_TEXTURE_STREAMING;ENABLE_LZMA;ENABLE_UNITYEVENTS;ENABLE_VR;ENABLE_WEBCAM;ENABLE_UNITYWEBREQUEST;ENABLE_WWW;ENABLE_CLOUD_SERVICES;ENABLE_CLOUD_SERVICES_ADS;ENABLE_CLOUD_SERVICES_USE_WEBREQUEST;ENABLE_CLOUD_SERVICES_CRASH_REPORTING;ENABLE_CLOUD_SERVICES_NATIVE_CRASH_REPORTING;ENABLE_CLOUD_SERVICES_PURCHASING;ENABLE_CLOUD_SERVICES_ANALYTICS;ENABLE_CLOUD_SERVICES_BUILD;ENABLE_EDITOR_GAME_SERVICES;ENABLE_UNITY_GAME_SERVICES_ANALYTICS_SUPPORT;ENABLE_CLOUD_LICENSE;ENABLE_EDITOR_HUB_LICENSE;ENABLE_WEBSOCKET_CLIENT;ENABLE_GENERATE_NATIVE_PLUGINS_FOR_ASSEMBLIES_API;ENABLE_DIRECTOR_AUDIO;ENABLE_DIRECTOR_TEXTURE;ENABLE_MANAGED_JOBS;ENABLE_MANAGED_TRANSFORM_JOBS;ENABLE_MANAGED_ANIMATION_JOBS;ENABLE_MANAGED_AUDIO_JOBS;ENABLE_RUNTIME_PERMISSIONS;ENABLE_ENGINE_CODE_STRIPPING;ENABLE_ONSCREEN_KEYBOARD;ENABLE_MANAGED_UNITYTLS;INCLUDE_DYNAMIC_GI;ENABLE_SCRIPTING_GC_WBARRIERS;PLATFORM_SUPPORTS_MONO;ENABLE_VIDEO;ENABLE_ACCELERATOR_CLIENT_DEBUGGING;ENABLE_NAVIGATION_PACKAGE_DEBUG_VISUALIZATION;ENABLE_NAVIGATION_HEIGHTMESH_RUNTIME_SUPPORT;ENABLE_NAVIGATION_UI_REQUIRES_PACKAGE;PLATFORM_ANDROID;TEXTCORE_1_0_OR_NEWER;UNITY_ANDROID;UNITY_ANDROID_API;ENABLE_EGL;ENABLE_NETWORK;ENABLE_RUNTIME_GI;ENABLE_CRUNCH_TEXTURE_COMPRESSION;UNITY_CAN_SHOW_SPLASH_SCREEN;UNITY_HAS_GOOGLEVR;UNITY_HAS_TANGO;ENABLE_SPATIALTRACKING;ENABLE_ETC_COMPRESSION;PLATFORM_EXTENDS_VULKAN_DEVICE;PLATFORM_HAS_MULTIPLE_SWAPCHAINS;UNITY_ANDROID_SUPPORTS_SHADOWFILES;PLATFORM_UPDATES_TIME_OUTSIDE_OF_PLAYER_LOOP;ENABLE_UNITYADS_RUNTIME;UNITY_UNITYADS_API;ENABLE_MONO;NET_STANDARD_2_0;NET_STANDARD;NET_STANDARD_2_1;NETSTANDARD;NETSTANDARD2_1;ENABLE_PROFILER;DEBUG;TRACE;UNITY_ASSERTIONS;UNITY_EDITOR;UNITY_EDITOR_64;UNITY_EDITOR_WIN;ENABLE_UNITY_COLLECTIONS_CHECKS;ENABLE_BURST_AOT;UNITY_TEAM_LICENSE;ENABLE_CUSTOM_RENDER_TEXTURE;ENABLE_DIRECTOR;ENABLE_LOCALIZATION;ENABLE_SPRITES;ENABLE_TERRAIN;ENABLE_TILEMAP;ENABLE_TIMELINE;ENABLE_LEGACY_INPUT_MANAGER;TEXTCORE_FONT_ENGINE_1_5_OR_NEWER;UNITY_PHYSICS_CUSTOM;CSHARP_7_OR_LATER;CSHARP_7_3_OR_NEWER</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<NoWarn>0169,0649</NoWarn>
|
||||
<AllowUnsafeBlocks>False</AllowUnsafeBlocks>
|
||||
<TreatWarningsAsErrors>False</TreatWarningsAsErrors>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<NoConfig>true</NoConfig>
|
||||
<NoStdLib>true</NoStdLib>
|
||||
<AddAdditionalExplicitAssemblyReferences>false</AddAdditionalExplicitAssemblyReferences>
|
||||
<ImplicitlyExpandNETStandardFacades>false</ImplicitlyExpandNETStandardFacades>
|
||||
<ImplicitlyExpandDesignTimeFacades>false</ImplicitlyExpandDesignTimeFacades>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Analyzer Include="D:\Unity\2022.3.16f1c1\Editor\Data\Tools\Unity.SourceGenerators\Unity.SourceGenerators.dll" />
|
||||
<Analyzer Include="D:\Unity\2022.3.16f1c1\Editor\Data\Tools\Unity.SourceGenerators\Unity.Properties.SourceGenerator.dll" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="Assets\Game\Plugins\App\App.cs" />
|
||||
<Compile Include="Assets\Game\Plugins\App\Sync\JNGSyncFrame.cs" />
|
||||
<Compile Include="Assets\Game\Plugins\App\JNGSyncFrame.cs" />
|
||||
<Compile Include="Assets\Game\Plugins\App\JNGSocket.cs" />
|
||||
<Compile Include="Assets\Game\Plugins\App\Sync\JNGSyncFrameDefault.cs" />
|
||||
<Compile Include="Assets\Game\Plugins\App\Sync\JNGSyncFrameEntrust.cs" />
|
||||
<None Include="Assets\Game\Plugins\App\App.asmdef" />
|
||||
<Reference Include="UnityEngine">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.AIModule">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.AIModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.ARModule">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.ARModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.AccessibilityModule">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.AccessibilityModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.AndroidJNIModule">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.AndroidJNIModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.AnimationModule">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.AnimationModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.AssetBundleModule">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.AssetBundleModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.AudioModule">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.AudioModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.ClothModule">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.ClothModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.ContentLoadModule">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.ContentLoadModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.CoreModule">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.CoreModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.CrashReportingModule">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.CrashReportingModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.DSPGraphModule">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.DSPGraphModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.DirectorModule">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.DirectorModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.GIModule">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.GIModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.GameCenterModule">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.GameCenterModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.GridModule">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.GridModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.HotReloadModule">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.HotReloadModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.IMGUIModule">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.IMGUIModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.ImageConversionModule">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.ImageConversionModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.InputModule">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.InputModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.InputLegacyModule">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.InputLegacyModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.JSONSerializeModule">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.JSONSerializeModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.LocalizationModule">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.LocalizationModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.ParticleSystemModule">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.ParticleSystemModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.PerformanceReportingModule">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.PerformanceReportingModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.PhysicsModule">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.PhysicsModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.Physics2DModule">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.Physics2DModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.ProfilerModule">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.ProfilerModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.PropertiesModule">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.PropertiesModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.RuntimeInitializeOnLoadManagerInitializerModule">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.RuntimeInitializeOnLoadManagerInitializerModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.ScreenCaptureModule">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.ScreenCaptureModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.SharedInternalsModule">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.SharedInternalsModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.SpriteMaskModule">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.SpriteMaskModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.SpriteShapeModule">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.SpriteShapeModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.StreamingModule">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.StreamingModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.SubstanceModule">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.SubstanceModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.SubsystemsModule">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.SubsystemsModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.TLSModule">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.TLSModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.TerrainModule">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.TerrainModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.TerrainPhysicsModule">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.TerrainPhysicsModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.TextCoreFontEngineModule">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.TextCoreFontEngineModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.TextCoreTextEngineModule">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.TextCoreTextEngineModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.TextRenderingModule">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.TextRenderingModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.TilemapModule">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.TilemapModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.UIModule">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.UIModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.UIElementsModule">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.UIElementsModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.UmbraModule">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.UmbraModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.UnityAnalyticsModule">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.UnityAnalyticsModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.UnityAnalyticsCommonModule">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.UnityAnalyticsCommonModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.UnityConnectModule">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.UnityConnectModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.UnityCurlModule">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.UnityCurlModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.UnityTestProtocolModule">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.UnityTestProtocolModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.UnityWebRequestModule">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.UnityWebRequestModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.UnityWebRequestAssetBundleModule">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.UnityWebRequestAssetBundleModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.UnityWebRequestAudioModule">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.UnityWebRequestAudioModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.UnityWebRequestTextureModule">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.UnityWebRequestTextureModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.UnityWebRequestWWWModule">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.UnityWebRequestWWWModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.VFXModule">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.VFXModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.VRModule">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.VRModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.VehiclesModule">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.VehiclesModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.VideoModule">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.VideoModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.WindModule">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.WindModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.XRModule">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.XRModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEditor">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEditor.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEditor.CoreModule">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEditor.CoreModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEditor.DeviceSimulatorModule">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEditor.DeviceSimulatorModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEditor.DiagnosticsModule">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEditor.DiagnosticsModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEditor.EditorToolbarModule">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEditor.EditorToolbarModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEditor.GraphViewModule">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEditor.GraphViewModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEditor.PresetsUIModule">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEditor.PresetsUIModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEditor.QuickSearchModule">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEditor.QuickSearchModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEditor.SceneTemplateModule">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEditor.SceneTemplateModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEditor.SceneViewModule">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEditor.SceneViewModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEditor.TextCoreFontEngineModule">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEditor.TextCoreFontEngineModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEditor.TextCoreTextEngineModule">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEditor.TextCoreTextEngineModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEditor.UIBuilderModule">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEditor.UIBuilderModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEditor.UIElementsModule">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEditor.UIElementsModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEditor.UIElementsSamplesModule">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEditor.UIElementsSamplesModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEditor.UnityConnectModule">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEditor.UnityConnectModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEditor.Graphs">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEditor.Graphs.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEditor.Android.Extensions">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\PlaybackEngines\AndroidPlayer\UnityEditor.Android.Extensions.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEditor.WindowsStandalone.Extensions">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\PlaybackEngines\WindowsStandaloneSupport\UnityEditor.WindowsStandalone.Extensions.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Pathfinding.Poly2Tri">
|
||||
<HintPath>D:\myproject\JisolGame\JNFrame\Assets\Game\Plugins\AstarPathfindingProject\Plugins\Poly2Tri\Pathfinding.Poly2Tri.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Unity.VisualScripting.YamlDotNet">
|
||||
<HintPath>D:\myproject\JisolGame\JNFrame\Library\PackageCache\com.unity.visualscripting@1.9.1\Editor\VisualScripting.Core\Dependencies\YamlDotNet\Unity.VisualScripting.YamlDotNet.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="BepuUtilities">
|
||||
<HintPath>D:\myproject\JisolGame\JNFrame\Assets\Game\Plugins\JNGame\BepuPhysics\Core\BepuPhysics2\BepuUtilities.2.3.4\lib\netstandard2.0\BepuUtilities.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Newtonsoft.Json">
|
||||
<HintPath>D:\myproject\JisolGame\JNFrame\Assets\Packages\Newtonsoft.Json.13.0.3\lib\netstandard2.0\Newtonsoft.Json.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Google.Protobuf">
|
||||
<HintPath>D:\myproject\JisolGame\JNFrame\Assets\Packages\Google.Protobuf.3.19.6\lib\netstandard2.0\Google.Protobuf.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="ReportGeneratorMerged">
|
||||
<HintPath>D:\myproject\JisolGame\JNFrame\Library\PackageCache\com.unity.testtools.codecoverage@1.2.4\lib\ReportGenerator\ReportGeneratorMerged.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Runtime.CompilerServices.Unsafe">
|
||||
<HintPath>D:\myproject\JisolGame\JNFrame\Assets\Packages\System.Runtime.CompilerServices.Unsafe.6.0.0\lib\netstandard2.0\System.Runtime.CompilerServices.Unsafe.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Unity.Plastic.Antlr3.Runtime">
|
||||
<HintPath>D:\myproject\JisolGame\JNFrame\Library\PackageCache\com.unity.collab-proxy@2.2.0\Lib\Editor\PlasticSCM\Unity.Plastic.Antlr3.Runtime.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="unityplastic">
|
||||
<HintPath>D:\myproject\JisolGame\JNFrame\Library\PackageCache\com.unity.collab-proxy@2.2.0\Lib\Editor\PlasticSCM\unityplastic.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="BepuPhysics">
|
||||
<HintPath>D:\myproject\JisolGame\JNFrame\Assets\Game\Plugins\JNGame\BepuPhysics\Core\BepuPhysics2\BepuPhysics.2.3.4\lib\netstandard2.0\BepuPhysics.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Unity.Plastic.Newtonsoft.Json">
|
||||
<HintPath>D:\myproject\JisolGame\JNFrame\Library\PackageCache\com.unity.collab-proxy@2.2.0\Lib\Editor\PlasticSCM\Unity.Plastic.Newtonsoft.Json.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="log4netPlastic">
|
||||
<HintPath>D:\myproject\JisolGame\JNFrame\Library\PackageCache\com.unity.collab-proxy@2.2.0\Lib\Editor\PlasticSCM\log4netPlastic.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Unity.VisualScripting.IonicZip">
|
||||
<HintPath>D:\myproject\JisolGame\JNFrame\Library\PackageCache\com.unity.visualscripting@1.9.1\Editor\VisualScripting.Core\Dependencies\DotNetZip\Unity.VisualScripting.IonicZip.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Pathfinding.ClipperLib">
|
||||
<HintPath>D:\myproject\JisolGame\JNFrame\Assets\Game\Plugins\AstarPathfindingProject\Plugins\Clipper\Pathfinding.ClipperLib.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Unity.VisualScripting.Antlr3.Runtime">
|
||||
<HintPath>D:\myproject\JisolGame\JNFrame\Library\PackageCache\com.unity.visualscripting@1.9.1\Runtime\VisualScripting.Flow\Dependencies\NCalc\Unity.VisualScripting.Antlr3.Runtime.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Unity.VisualScripting.TextureAssets">
|
||||
<HintPath>D:\myproject\JisolGame\JNFrame\Library\PackageCache\com.unity.visualscripting@1.9.1\Editor\VisualScripting.Core\EditorAssetResources\Unity.VisualScripting.TextureAssets.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="NugetForUnity">
|
||||
<HintPath>D:\myproject\JisolGame\JNFrame\Assets\NuGet\Editor\NugetForUnity.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Pathfinding.Ionic.Zip.Reduced">
|
||||
<HintPath>D:\myproject\JisolGame\JNFrame\Assets\Game\Plugins\AstarPathfindingProject\Plugins\DotNetZip\Pathfinding.Ionic.Zip.Reduced.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Unity.Android.Types">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\PlaybackEngines\AndroidPlayer\Unity.Android.Types.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Unity.Android.Gradle">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\PlaybackEngines\AndroidPlayer\Unity.Android.Gradle.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Unity.Android.GradleProject">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\PlaybackEngines\AndroidPlayer\Unity.Android.GradleProject.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="netstandard">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\ref\2.1.0\netstandard.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Microsoft.Win32.Primitives">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\Microsoft.Win32.Primitives.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.AppContext">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.AppContext.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Buffers">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Buffers.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Collections.Concurrent">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Collections.Concurrent.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Collections">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Collections.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Collections.NonGeneric">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Collections.NonGeneric.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Collections.Specialized">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Collections.Specialized.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.ComponentModel">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.ComponentModel.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.ComponentModel.EventBasedAsync">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.ComponentModel.EventBasedAsync.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.ComponentModel.Primitives">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.ComponentModel.Primitives.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.ComponentModel.TypeConverter">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.ComponentModel.TypeConverter.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Console">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Console.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Data.Common">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Data.Common.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Diagnostics.Contracts">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Diagnostics.Contracts.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Diagnostics.Debug">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Diagnostics.Debug.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Diagnostics.FileVersionInfo">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Diagnostics.FileVersionInfo.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Diagnostics.Process">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Diagnostics.Process.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Diagnostics.StackTrace">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Diagnostics.StackTrace.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Diagnostics.TextWriterTraceListener">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Diagnostics.TextWriterTraceListener.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Diagnostics.Tools">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Diagnostics.Tools.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Diagnostics.TraceSource">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Diagnostics.TraceSource.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Diagnostics.Tracing">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Diagnostics.Tracing.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Drawing.Primitives">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Drawing.Primitives.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Dynamic.Runtime">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Dynamic.Runtime.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Globalization.Calendars">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Globalization.Calendars.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Globalization">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Globalization.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Globalization.Extensions">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Globalization.Extensions.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.IO.Compression">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.IO.Compression.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.IO.Compression.ZipFile">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.IO.Compression.ZipFile.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.IO">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.IO.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.IO.FileSystem">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.IO.FileSystem.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.IO.FileSystem.DriveInfo">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.IO.FileSystem.DriveInfo.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.IO.FileSystem.Primitives">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.IO.FileSystem.Primitives.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.IO.FileSystem.Watcher">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.IO.FileSystem.Watcher.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.IO.IsolatedStorage">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.IO.IsolatedStorage.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.IO.MemoryMappedFiles">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.IO.MemoryMappedFiles.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.IO.Pipes">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.IO.Pipes.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.IO.UnmanagedMemoryStream">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.IO.UnmanagedMemoryStream.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Linq">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Linq.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Linq.Expressions">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Linq.Expressions.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Linq.Parallel">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Linq.Parallel.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Linq.Queryable">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Linq.Queryable.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Memory">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Memory.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Net.Http">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Net.Http.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Net.NameResolution">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Net.NameResolution.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Net.NetworkInformation">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Net.NetworkInformation.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Net.Ping">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Net.Ping.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Net.Primitives">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Net.Primitives.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Net.Requests">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Net.Requests.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Net.Security">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Net.Security.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Net.Sockets">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Net.Sockets.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Net.WebHeaderCollection">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Net.WebHeaderCollection.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Net.WebSockets.Client">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Net.WebSockets.Client.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Net.WebSockets">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Net.WebSockets.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Numerics.Vectors">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Numerics.Vectors.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.ObjectModel">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.ObjectModel.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Reflection.DispatchProxy">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Reflection.DispatchProxy.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Reflection">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Reflection.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Reflection.Emit">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Reflection.Emit.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Reflection.Emit.ILGeneration">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Reflection.Emit.ILGeneration.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Reflection.Emit.Lightweight">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Reflection.Emit.Lightweight.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Reflection.Extensions">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Reflection.Extensions.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Reflection.Primitives">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Reflection.Primitives.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Resources.Reader">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Resources.Reader.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Resources.ResourceManager">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Resources.ResourceManager.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Resources.Writer">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Resources.Writer.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Runtime.CompilerServices.VisualC">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Runtime.CompilerServices.VisualC.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Runtime">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Runtime.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Runtime.Extensions">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Runtime.Extensions.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Runtime.Handles">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Runtime.Handles.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Runtime.InteropServices">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Runtime.InteropServices.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Runtime.InteropServices.RuntimeInformation">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Runtime.InteropServices.RuntimeInformation.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Runtime.Numerics">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Runtime.Numerics.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Runtime.Serialization.Formatters">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Runtime.Serialization.Formatters.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Runtime.Serialization.Json">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Runtime.Serialization.Json.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Runtime.Serialization.Primitives">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Runtime.Serialization.Primitives.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Runtime.Serialization.Xml">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Runtime.Serialization.Xml.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Security.Claims">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Security.Claims.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Security.Cryptography.Algorithms">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Security.Cryptography.Algorithms.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Security.Cryptography.Csp">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Security.Cryptography.Csp.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Security.Cryptography.Encoding">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Security.Cryptography.Encoding.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Security.Cryptography.Primitives">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Security.Cryptography.Primitives.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Security.Cryptography.X509Certificates">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Security.Cryptography.X509Certificates.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Security.Principal">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Security.Principal.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Security.SecureString">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Security.SecureString.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Text.Encoding">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Text.Encoding.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Text.Encoding.Extensions">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Text.Encoding.Extensions.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Text.RegularExpressions">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Text.RegularExpressions.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Threading">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Threading.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Threading.Overlapped">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Threading.Overlapped.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Threading.Tasks">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Threading.Tasks.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Threading.Tasks.Extensions">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Threading.Tasks.Extensions.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Threading.Tasks.Parallel">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Threading.Tasks.Parallel.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Threading.Thread">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Threading.Thread.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Threading.ThreadPool">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Threading.ThreadPool.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Threading.Timer">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Threading.Timer.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.ValueTuple">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.ValueTuple.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Xml.ReaderWriter">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Xml.ReaderWriter.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Xml.XDocument">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Xml.XDocument.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Xml.XmlDocument">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Xml.XmlDocument.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Xml.XmlSerializer">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Xml.XmlSerializer.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Xml.XPath">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Xml.XPath.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Xml.XPath.XDocument">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Xml.XPath.XDocument.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Runtime.InteropServices.WindowsRuntime">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\Extensions\2.0.0\System.Runtime.InteropServices.WindowsRuntime.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="mscorlib">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netfx\mscorlib.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.ComponentModel.Composition">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netfx\System.ComponentModel.Composition.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Core">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netfx\System.Core.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Data">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netfx\System.Data.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netfx\System.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Drawing">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netfx\System.Drawing.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.IO.Compression.FileSystem">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netfx\System.IO.Compression.FileSystem.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Net">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netfx\System.Net.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Numerics">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netfx\System.Numerics.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Runtime.Serialization">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netfx\System.Runtime.Serialization.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.ServiceModel.Web">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netfx\System.ServiceModel.Web.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Transactions">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netfx\System.Transactions.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Web">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netfx\System.Web.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Windows">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netfx\System.Windows.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Xml">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netfx\System.Xml.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Xml.Linq">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netfx\System.Xml.Linq.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Xml.Serialization">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netfx\System.Xml.Serialization.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEditor.UI">
|
||||
<HintPath>D:\myproject\JisolGame\JNFrame\Library\ScriptAssemblies\UnityEditor.UI.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.UI">
|
||||
<HintPath>D:\myproject\JisolGame\JNFrame\Library\ScriptAssemblies\UnityEngine.UI.dll</HintPath>
|
||||
</Reference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="JNGame.csproj">
|
||||
<Project>{6daf7f60-fa83-da88-56be-04871b5df574}</Project>
|
||||
<Name>JNGame</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="UniTask.csproj">
|
||||
<Project>{39f5acb9-cdbb-9f48-497c-14159a0afd38}</Project>
|
||||
<Name>UniTask</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="BestHTTP.csproj">
|
||||
<Project>{49f1e414-166b-61b7-ba11-ad89c8d920ee}</Project>
|
||||
<Name>BestHTTP</Name>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||
Other similar extension points exist, see Microsoft.Common.targets.
|
||||
<Target Name="BeforeBuild">
|
||||
</Target>
|
||||
<Target Name="AfterBuild">
|
||||
</Target>
|
||||
-->
|
||||
</Project>
|
750
JNFrame/AppImpl.csproj
Normal file
750
JNFrame/AppImpl.csproj
Normal file
@ -0,0 +1,750 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<LangVersion>9.0</LangVersion>
|
||||
<_TargetFrameworkDirectories>non_empty_path_generated_by_unity.rider.package</_TargetFrameworkDirectories>
|
||||
<_FullFrameworkReferenceAssemblyPaths>non_empty_path_generated_by_unity.rider.package</_FullFrameworkReferenceAssemblyPaths>
|
||||
<DisableHandlePackageFileConflicts>true</DisableHandlePackageFileConflicts>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProductVersion>10.0.20506</ProductVersion>
|
||||
<SchemaVersion>2.0</SchemaVersion>
|
||||
<RootNamespace></RootNamespace>
|
||||
<ProjectGuid>{147feb2d-a20c-54d8-e097-7e523b3c69f1}</ProjectGuid>
|
||||
<ProjectTypeGuids>{E097FAD1-6243-4DAD-9C02-E9B9EFC3FFC1};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
|
||||
<OutputType>Library</OutputType>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<AssemblyName>AppImpl</AssemblyName>
|
||||
<TargetFrameworkVersion>v4.7.1</TargetFrameworkVersion>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<BaseDirectory>.</BaseDirectory>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>Temp\Bin\Debug\AppImpl\</OutputPath>
|
||||
<DefineConstants>UNITY_2022_3_16;UNITY_2022_3;UNITY_2022;UNITY_5_3_OR_NEWER;UNITY_5_4_OR_NEWER;UNITY_5_5_OR_NEWER;UNITY_5_6_OR_NEWER;UNITY_2017_1_OR_NEWER;UNITY_2017_2_OR_NEWER;UNITY_2017_3_OR_NEWER;UNITY_2017_4_OR_NEWER;UNITY_2018_1_OR_NEWER;UNITY_2018_2_OR_NEWER;UNITY_2018_3_OR_NEWER;UNITY_2018_4_OR_NEWER;UNITY_2019_1_OR_NEWER;UNITY_2019_2_OR_NEWER;UNITY_2019_3_OR_NEWER;UNITY_2019_4_OR_NEWER;UNITY_2020_1_OR_NEWER;UNITY_2020_2_OR_NEWER;UNITY_2020_3_OR_NEWER;UNITY_2021_1_OR_NEWER;UNITY_2021_2_OR_NEWER;UNITY_2021_3_OR_NEWER;UNITY_2022_1_OR_NEWER;UNITY_2022_2_OR_NEWER;UNITY_2022_3_OR_NEWER;UNITY_INCLUDE_TESTS;ENABLE_AR;ENABLE_AUDIO;ENABLE_CACHING;ENABLE_CLOTH;ENABLE_EVENT_QUEUE;ENABLE_MICROPHONE;ENABLE_MULTIPLE_DISPLAYS;ENABLE_PHYSICS;ENABLE_TEXTURE_STREAMING;ENABLE_LZMA;ENABLE_UNITYEVENTS;ENABLE_VR;ENABLE_WEBCAM;ENABLE_UNITYWEBREQUEST;ENABLE_WWW;ENABLE_CLOUD_SERVICES;ENABLE_CLOUD_SERVICES_ADS;ENABLE_CLOUD_SERVICES_USE_WEBREQUEST;ENABLE_CLOUD_SERVICES_CRASH_REPORTING;ENABLE_CLOUD_SERVICES_NATIVE_CRASH_REPORTING;ENABLE_CLOUD_SERVICES_PURCHASING;ENABLE_CLOUD_SERVICES_ANALYTICS;ENABLE_CLOUD_SERVICES_BUILD;ENABLE_EDITOR_GAME_SERVICES;ENABLE_UNITY_GAME_SERVICES_ANALYTICS_SUPPORT;ENABLE_CLOUD_LICENSE;ENABLE_EDITOR_HUB_LICENSE;ENABLE_WEBSOCKET_CLIENT;ENABLE_GENERATE_NATIVE_PLUGINS_FOR_ASSEMBLIES_API;ENABLE_DIRECTOR_AUDIO;ENABLE_DIRECTOR_TEXTURE;ENABLE_MANAGED_JOBS;ENABLE_MANAGED_TRANSFORM_JOBS;ENABLE_MANAGED_ANIMATION_JOBS;ENABLE_MANAGED_AUDIO_JOBS;ENABLE_RUNTIME_PERMISSIONS;ENABLE_ENGINE_CODE_STRIPPING;ENABLE_ONSCREEN_KEYBOARD;ENABLE_MANAGED_UNITYTLS;INCLUDE_DYNAMIC_GI;ENABLE_SCRIPTING_GC_WBARRIERS;PLATFORM_SUPPORTS_MONO;ENABLE_VIDEO;ENABLE_ACCELERATOR_CLIENT_DEBUGGING;ENABLE_NAVIGATION_PACKAGE_DEBUG_VISUALIZATION;ENABLE_NAVIGATION_HEIGHTMESH_RUNTIME_SUPPORT;ENABLE_NAVIGATION_UI_REQUIRES_PACKAGE;PLATFORM_ANDROID;TEXTCORE_1_0_OR_NEWER;UNITY_ANDROID;UNITY_ANDROID_API;ENABLE_EGL;ENABLE_NETWORK;ENABLE_RUNTIME_GI;ENABLE_CRUNCH_TEXTURE_COMPRESSION;UNITY_CAN_SHOW_SPLASH_SCREEN;UNITY_HAS_GOOGLEVR;UNITY_HAS_TANGO;ENABLE_SPATIALTRACKING;ENABLE_ETC_COMPRESSION;PLATFORM_EXTENDS_VULKAN_DEVICE;PLATFORM_HAS_MULTIPLE_SWAPCHAINS;UNITY_ANDROID_SUPPORTS_SHADOWFILES;PLATFORM_UPDATES_TIME_OUTSIDE_OF_PLAYER_LOOP;ENABLE_UNITYADS_RUNTIME;UNITY_UNITYADS_API;ENABLE_MONO;NET_STANDARD_2_0;NET_STANDARD;NET_STANDARD_2_1;NETSTANDARD;NETSTANDARD2_1;ENABLE_PROFILER;DEBUG;TRACE;UNITY_ASSERTIONS;UNITY_EDITOR;UNITY_EDITOR_64;UNITY_EDITOR_WIN;ENABLE_UNITY_COLLECTIONS_CHECKS;ENABLE_BURST_AOT;UNITY_TEAM_LICENSE;ENABLE_CUSTOM_RENDER_TEXTURE;ENABLE_DIRECTOR;ENABLE_LOCALIZATION;ENABLE_SPRITES;ENABLE_TERRAIN;ENABLE_TILEMAP;ENABLE_TIMELINE;ENABLE_LEGACY_INPUT_MANAGER;TEXTCORE_FONT_ENGINE_1_5_OR_NEWER;UNITY_PHYSICS_CUSTOM;CSHARP_7_OR_LATER;CSHARP_7_3_OR_NEWER</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<NoWarn>0169,0649</NoWarn>
|
||||
<AllowUnsafeBlocks>False</AllowUnsafeBlocks>
|
||||
<TreatWarningsAsErrors>False</TreatWarningsAsErrors>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<NoConfig>true</NoConfig>
|
||||
<NoStdLib>true</NoStdLib>
|
||||
<AddAdditionalExplicitAssemblyReferences>false</AddAdditionalExplicitAssemblyReferences>
|
||||
<ImplicitlyExpandNETStandardFacades>false</ImplicitlyExpandNETStandardFacades>
|
||||
<ImplicitlyExpandDesignTimeFacades>false</ImplicitlyExpandDesignTimeFacades>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Analyzer Include="D:\myproject\JisolGame\JNFrame\Assets\AstarPathfindingProject\Plugins\DotNetZip\Pathfinding.Ionic.Zip.Reduced.dll" />
|
||||
<Analyzer Include="D:\myproject\JisolGame\JNFrame\Assets\AstarPathfindingProject\Plugins\Poly2Tri\Pathfinding.Poly2Tri.dll" />
|
||||
<Analyzer Include="D:\myproject\JisolGame\JNFrame\Assets\AstarPathfindingProject\Plugins\Clipper\Pathfinding.ClipperLib.dll" />
|
||||
<Analyzer Include="D:\Unity\2022.3.16f1c1\Editor\Data\Tools\Unity.SourceGenerators\Unity.SourceGenerators.dll" />
|
||||
<Analyzer Include="D:\Unity\2022.3.16f1c1\Editor\Data\Tools\Unity.SourceGenerators\Unity.Properties.SourceGenerator.dll" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="Assets\Game\Script\AppImpl\JNGSyncFrame.cs" />
|
||||
<Compile Include="Assets\Game\Script\AppImpl\JNGSocket.cs" />
|
||||
<Compile Include="Assets\Game\Script\AppImpl\Sync\JNGSyncFrame.cs" />
|
||||
<None Include="Assets\Game\Script\AppImpl\AppImpl.asmdef" />
|
||||
<Reference Include="UnityEngine">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.AIModule">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.AIModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.ARModule">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.ARModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.AccessibilityModule">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.AccessibilityModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.AndroidJNIModule">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.AndroidJNIModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.AnimationModule">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.AnimationModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.AssetBundleModule">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.AssetBundleModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.AudioModule">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.AudioModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.ClothModule">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.ClothModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.ContentLoadModule">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.ContentLoadModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.CoreModule">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.CoreModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.CrashReportingModule">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.CrashReportingModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.DSPGraphModule">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.DSPGraphModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.DirectorModule">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.DirectorModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.GIModule">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.GIModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.GameCenterModule">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.GameCenterModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.GridModule">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.GridModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.HotReloadModule">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.HotReloadModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.IMGUIModule">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.IMGUIModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.ImageConversionModule">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.ImageConversionModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.InputModule">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.InputModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.InputLegacyModule">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.InputLegacyModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.JSONSerializeModule">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.JSONSerializeModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.LocalizationModule">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.LocalizationModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.ParticleSystemModule">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.ParticleSystemModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.PerformanceReportingModule">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.PerformanceReportingModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.PhysicsModule">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.PhysicsModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.Physics2DModule">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.Physics2DModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.ProfilerModule">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.ProfilerModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.PropertiesModule">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.PropertiesModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.RuntimeInitializeOnLoadManagerInitializerModule">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.RuntimeInitializeOnLoadManagerInitializerModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.ScreenCaptureModule">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.ScreenCaptureModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.SharedInternalsModule">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.SharedInternalsModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.SpriteMaskModule">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.SpriteMaskModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.SpriteShapeModule">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.SpriteShapeModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.StreamingModule">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.StreamingModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.SubstanceModule">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.SubstanceModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.SubsystemsModule">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.SubsystemsModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.TLSModule">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.TLSModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.TerrainModule">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.TerrainModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.TerrainPhysicsModule">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.TerrainPhysicsModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.TextCoreFontEngineModule">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.TextCoreFontEngineModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.TextCoreTextEngineModule">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.TextCoreTextEngineModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.TextRenderingModule">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.TextRenderingModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.TilemapModule">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.TilemapModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.UIModule">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.UIModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.UIElementsModule">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.UIElementsModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.UmbraModule">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.UmbraModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.UnityAnalyticsModule">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.UnityAnalyticsModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.UnityAnalyticsCommonModule">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.UnityAnalyticsCommonModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.UnityConnectModule">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.UnityConnectModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.UnityCurlModule">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.UnityCurlModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.UnityTestProtocolModule">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.UnityTestProtocolModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.UnityWebRequestModule">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.UnityWebRequestModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.UnityWebRequestAssetBundleModule">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.UnityWebRequestAssetBundleModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.UnityWebRequestAudioModule">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.UnityWebRequestAudioModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.UnityWebRequestTextureModule">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.UnityWebRequestTextureModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.UnityWebRequestWWWModule">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.UnityWebRequestWWWModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.VFXModule">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.VFXModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.VRModule">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.VRModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.VehiclesModule">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.VehiclesModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.VideoModule">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.VideoModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.WindModule">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.WindModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.XRModule">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.XRModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEditor">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEditor.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEditor.CoreModule">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEditor.CoreModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEditor.DeviceSimulatorModule">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEditor.DeviceSimulatorModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEditor.DiagnosticsModule">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEditor.DiagnosticsModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEditor.EditorToolbarModule">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEditor.EditorToolbarModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEditor.GraphViewModule">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEditor.GraphViewModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEditor.PresetsUIModule">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEditor.PresetsUIModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEditor.QuickSearchModule">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEditor.QuickSearchModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEditor.SceneTemplateModule">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEditor.SceneTemplateModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEditor.SceneViewModule">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEditor.SceneViewModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEditor.TextCoreFontEngineModule">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEditor.TextCoreFontEngineModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEditor.TextCoreTextEngineModule">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEditor.TextCoreTextEngineModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEditor.UIBuilderModule">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEditor.UIBuilderModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEditor.UIElementsModule">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEditor.UIElementsModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEditor.UIElementsSamplesModule">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEditor.UIElementsSamplesModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEditor.UnityConnectModule">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEditor.UnityConnectModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEditor.Graphs">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEditor.Graphs.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEditor.Android.Extensions">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\PlaybackEngines\AndroidPlayer\UnityEditor.Android.Extensions.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEditor.WindowsStandalone.Extensions">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\PlaybackEngines\WindowsStandaloneSupport\UnityEditor.WindowsStandalone.Extensions.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Unity.VisualScripting.YamlDotNet">
|
||||
<HintPath>D:\myproject\JisolGame\JNFrame\Library\PackageCache\com.unity.visualscripting@1.9.1\Editor\VisualScripting.Core\Dependencies\YamlDotNet\Unity.VisualScripting.YamlDotNet.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="BepuUtilities">
|
||||
<HintPath>D:\myproject\JisolGame\JNFrame\Assets\Game\Plugins\JNGame\BepuPhysics\Core\BepuPhysics2\BepuUtilities.2.3.4\lib\netstandard2.0\BepuUtilities.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Newtonsoft.Json">
|
||||
<HintPath>D:\myproject\JisolGame\JNFrame\Assets\Packages\Newtonsoft.Json.13.0.3\lib\netstandard2.0\Newtonsoft.Json.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Google.Protobuf">
|
||||
<HintPath>D:\myproject\JisolGame\JNFrame\Assets\Packages\Google.Protobuf.3.19.6\lib\netstandard2.0\Google.Protobuf.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="ReportGeneratorMerged">
|
||||
<HintPath>D:\myproject\JisolGame\JNFrame\Library\PackageCache\com.unity.testtools.codecoverage@1.2.4\lib\ReportGenerator\ReportGeneratorMerged.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Runtime.CompilerServices.Unsafe">
|
||||
<HintPath>D:\myproject\JisolGame\JNFrame\Assets\Packages\System.Runtime.CompilerServices.Unsafe.6.0.0\lib\netstandard2.0\System.Runtime.CompilerServices.Unsafe.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Unity.Plastic.Antlr3.Runtime">
|
||||
<HintPath>D:\myproject\JisolGame\JNFrame\Library\PackageCache\com.unity.collab-proxy@2.2.0\Lib\Editor\PlasticSCM\Unity.Plastic.Antlr3.Runtime.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="unityplastic">
|
||||
<HintPath>D:\myproject\JisolGame\JNFrame\Library\PackageCache\com.unity.collab-proxy@2.2.0\Lib\Editor\PlasticSCM\unityplastic.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="BepuPhysics">
|
||||
<HintPath>D:\myproject\JisolGame\JNFrame\Assets\Game\Plugins\JNGame\BepuPhysics\Core\BepuPhysics2\BepuPhysics.2.3.4\lib\netstandard2.0\BepuPhysics.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Unity.Plastic.Newtonsoft.Json">
|
||||
<HintPath>D:\myproject\JisolGame\JNFrame\Library\PackageCache\com.unity.collab-proxy@2.2.0\Lib\Editor\PlasticSCM\Unity.Plastic.Newtonsoft.Json.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="log4netPlastic">
|
||||
<HintPath>D:\myproject\JisolGame\JNFrame\Library\PackageCache\com.unity.collab-proxy@2.2.0\Lib\Editor\PlasticSCM\log4netPlastic.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Unity.VisualScripting.IonicZip">
|
||||
<HintPath>D:\myproject\JisolGame\JNFrame\Library\PackageCache\com.unity.visualscripting@1.9.1\Editor\VisualScripting.Core\Dependencies\DotNetZip\Unity.VisualScripting.IonicZip.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Unity.VisualScripting.Antlr3.Runtime">
|
||||
<HintPath>D:\myproject\JisolGame\JNFrame\Library\PackageCache\com.unity.visualscripting@1.9.1\Runtime\VisualScripting.Flow\Dependencies\NCalc\Unity.VisualScripting.Antlr3.Runtime.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Unity.VisualScripting.TextureAssets">
|
||||
<HintPath>D:\myproject\JisolGame\JNFrame\Library\PackageCache\com.unity.visualscripting@1.9.1\Editor\VisualScripting.Core\EditorAssetResources\Unity.VisualScripting.TextureAssets.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="NugetForUnity">
|
||||
<HintPath>D:\myproject\JisolGame\JNFrame\Assets\NuGet\Editor\NugetForUnity.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Pathfinding.Ionic.Zip.Reduced">
|
||||
<HintPath>D:\myproject\JisolGame\JNFrame\Assets\Game\Plugins\AstarPathfindingProject\Plugins\DotNetZip\Pathfinding.Ionic.Zip.Reduced.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Pathfinding.ClipperLib">
|
||||
<HintPath>D:\myproject\JisolGame\JNFrame\Assets\Game\Plugins\AstarPathfindingProject\Plugins\Clipper\Pathfinding.ClipperLib.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Pathfinding.Poly2Tri">
|
||||
<HintPath>D:\myproject\JisolGame\JNFrame\Assets\Game\Plugins\AstarPathfindingProject\Plugins\Poly2Tri\Pathfinding.Poly2Tri.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Unity.Android.Types">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\PlaybackEngines\AndroidPlayer\Unity.Android.Types.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Unity.Android.Gradle">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\PlaybackEngines\AndroidPlayer\Unity.Android.Gradle.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Unity.Android.GradleProject">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\PlaybackEngines\AndroidPlayer\Unity.Android.GradleProject.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="netstandard">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\ref\2.1.0\netstandard.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Microsoft.Win32.Primitives">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\Microsoft.Win32.Primitives.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.AppContext">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.AppContext.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Buffers">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Buffers.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Collections.Concurrent">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Collections.Concurrent.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Collections">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Collections.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Collections.NonGeneric">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Collections.NonGeneric.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Collections.Specialized">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Collections.Specialized.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.ComponentModel">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.ComponentModel.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.ComponentModel.EventBasedAsync">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.ComponentModel.EventBasedAsync.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.ComponentModel.Primitives">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.ComponentModel.Primitives.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.ComponentModel.TypeConverter">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.ComponentModel.TypeConverter.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Console">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Console.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Data.Common">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Data.Common.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Diagnostics.Contracts">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Diagnostics.Contracts.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Diagnostics.Debug">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Diagnostics.Debug.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Diagnostics.FileVersionInfo">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Diagnostics.FileVersionInfo.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Diagnostics.Process">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Diagnostics.Process.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Diagnostics.StackTrace">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Diagnostics.StackTrace.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Diagnostics.TextWriterTraceListener">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Diagnostics.TextWriterTraceListener.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Diagnostics.Tools">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Diagnostics.Tools.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Diagnostics.TraceSource">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Diagnostics.TraceSource.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Diagnostics.Tracing">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Diagnostics.Tracing.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Drawing.Primitives">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Drawing.Primitives.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Dynamic.Runtime">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Dynamic.Runtime.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Globalization.Calendars">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Globalization.Calendars.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Globalization">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Globalization.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Globalization.Extensions">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Globalization.Extensions.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.IO.Compression">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.IO.Compression.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.IO.Compression.ZipFile">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.IO.Compression.ZipFile.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.IO">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.IO.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.IO.FileSystem">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.IO.FileSystem.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.IO.FileSystem.DriveInfo">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.IO.FileSystem.DriveInfo.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.IO.FileSystem.Primitives">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.IO.FileSystem.Primitives.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.IO.FileSystem.Watcher">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.IO.FileSystem.Watcher.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.IO.IsolatedStorage">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.IO.IsolatedStorage.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.IO.MemoryMappedFiles">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.IO.MemoryMappedFiles.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.IO.Pipes">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.IO.Pipes.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.IO.UnmanagedMemoryStream">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.IO.UnmanagedMemoryStream.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Linq">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Linq.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Linq.Expressions">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Linq.Expressions.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Linq.Parallel">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Linq.Parallel.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Linq.Queryable">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Linq.Queryable.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Memory">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Memory.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Net.Http">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Net.Http.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Net.NameResolution">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Net.NameResolution.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Net.NetworkInformation">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Net.NetworkInformation.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Net.Ping">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Net.Ping.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Net.Primitives">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Net.Primitives.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Net.Requests">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Net.Requests.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Net.Security">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Net.Security.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Net.Sockets">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Net.Sockets.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Net.WebHeaderCollection">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Net.WebHeaderCollection.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Net.WebSockets.Client">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Net.WebSockets.Client.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Net.WebSockets">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Net.WebSockets.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Numerics.Vectors">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Numerics.Vectors.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.ObjectModel">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.ObjectModel.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Reflection.DispatchProxy">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Reflection.DispatchProxy.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Reflection">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Reflection.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Reflection.Emit">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Reflection.Emit.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Reflection.Emit.ILGeneration">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Reflection.Emit.ILGeneration.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Reflection.Emit.Lightweight">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Reflection.Emit.Lightweight.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Reflection.Extensions">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Reflection.Extensions.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Reflection.Primitives">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Reflection.Primitives.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Resources.Reader">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Resources.Reader.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Resources.ResourceManager">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Resources.ResourceManager.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Resources.Writer">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Resources.Writer.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Runtime.CompilerServices.VisualC">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Runtime.CompilerServices.VisualC.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Runtime">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Runtime.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Runtime.Extensions">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Runtime.Extensions.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Runtime.Handles">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Runtime.Handles.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Runtime.InteropServices">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Runtime.InteropServices.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Runtime.InteropServices.RuntimeInformation">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Runtime.InteropServices.RuntimeInformation.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Runtime.Numerics">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Runtime.Numerics.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Runtime.Serialization.Formatters">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Runtime.Serialization.Formatters.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Runtime.Serialization.Json">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Runtime.Serialization.Json.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Runtime.Serialization.Primitives">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Runtime.Serialization.Primitives.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Runtime.Serialization.Xml">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Runtime.Serialization.Xml.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Security.Claims">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Security.Claims.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Security.Cryptography.Algorithms">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Security.Cryptography.Algorithms.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Security.Cryptography.Csp">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Security.Cryptography.Csp.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Security.Cryptography.Encoding">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Security.Cryptography.Encoding.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Security.Cryptography.Primitives">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Security.Cryptography.Primitives.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Security.Cryptography.X509Certificates">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Security.Cryptography.X509Certificates.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Security.Principal">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Security.Principal.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Security.SecureString">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Security.SecureString.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Text.Encoding">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Text.Encoding.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Text.Encoding.Extensions">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Text.Encoding.Extensions.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Text.RegularExpressions">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Text.RegularExpressions.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Threading">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Threading.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Threading.Overlapped">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Threading.Overlapped.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Threading.Tasks">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Threading.Tasks.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Threading.Tasks.Extensions">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Threading.Tasks.Extensions.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Threading.Tasks.Parallel">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Threading.Tasks.Parallel.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Threading.Thread">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Threading.Thread.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Threading.ThreadPool">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Threading.ThreadPool.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Threading.Timer">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Threading.Timer.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.ValueTuple">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.ValueTuple.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Xml.ReaderWriter">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Xml.ReaderWriter.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Xml.XDocument">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Xml.XDocument.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Xml.XmlDocument">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Xml.XmlDocument.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Xml.XmlSerializer">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Xml.XmlSerializer.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Xml.XPath">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Xml.XPath.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Xml.XPath.XDocument">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Xml.XPath.XDocument.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Runtime.InteropServices.WindowsRuntime">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\Extensions\2.0.0\System.Runtime.InteropServices.WindowsRuntime.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="mscorlib">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netfx\mscorlib.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.ComponentModel.Composition">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netfx\System.ComponentModel.Composition.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Core">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netfx\System.Core.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Data">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netfx\System.Data.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netfx\System.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Drawing">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netfx\System.Drawing.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.IO.Compression.FileSystem">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netfx\System.IO.Compression.FileSystem.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Net">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netfx\System.Net.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Numerics">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netfx\System.Numerics.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Runtime.Serialization">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netfx\System.Runtime.Serialization.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.ServiceModel.Web">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netfx\System.ServiceModel.Web.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Transactions">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netfx\System.Transactions.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Web">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netfx\System.Web.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Windows">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netfx\System.Windows.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Xml">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netfx\System.Xml.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Xml.Linq">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netfx\System.Xml.Linq.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Xml.Serialization">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netfx\System.Xml.Serialization.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEditor.UI">
|
||||
<HintPath>D:\myproject\JisolGame\JNFrame\Library\ScriptAssemblies\UnityEditor.UI.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.UI">
|
||||
<HintPath>D:\myproject\JisolGame\JNFrame\Library\ScriptAssemblies\UnityEngine.UI.dll</HintPath>
|
||||
</Reference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||
Other similar extension points exist, see Microsoft.Common.targets.
|
||||
<Target Name="BeforeBuild">
|
||||
</Target>
|
||||
<Target Name="AfterBuild">
|
||||
</Target>
|
||||
-->
|
||||
</Project>
|
@ -25,12 +25,12 @@
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>Temp\Bin\Debug\Unity.Rider.Editor\</OutputPath>
|
||||
<DefineConstants>UNITY_EDITOR</DefineConstants>
|
||||
<OutputPath>Temp\Bin\Debug\Assembly-CSharp-Editor\</OutputPath>
|
||||
<DefineConstants>UNITY_2022_3_16;UNITY_2022_3;UNITY_2022;UNITY_5_3_OR_NEWER;UNITY_5_4_OR_NEWER;UNITY_5_5_OR_NEWER;UNITY_5_6_OR_NEWER;UNITY_2017_1_OR_NEWER;UNITY_2017_2_OR_NEWER;UNITY_2017_3_OR_NEWER;UNITY_2017_4_OR_NEWER;UNITY_2018_1_OR_NEWER;UNITY_2018_2_OR_NEWER;UNITY_2018_3_OR_NEWER;UNITY_2018_4_OR_NEWER;UNITY_2019_1_OR_NEWER;UNITY_2019_2_OR_NEWER;UNITY_2019_3_OR_NEWER;UNITY_2019_4_OR_NEWER;UNITY_2020_1_OR_NEWER;UNITY_2020_2_OR_NEWER;UNITY_2020_3_OR_NEWER;UNITY_2021_1_OR_NEWER;UNITY_2021_2_OR_NEWER;UNITY_2021_3_OR_NEWER;UNITY_2022_1_OR_NEWER;UNITY_2022_2_OR_NEWER;UNITY_2022_3_OR_NEWER;UNITY_INCLUDE_TESTS;ENABLE_AR;ENABLE_AUDIO;ENABLE_CACHING;ENABLE_CLOTH;ENABLE_EVENT_QUEUE;ENABLE_MICROPHONE;ENABLE_MULTIPLE_DISPLAYS;ENABLE_PHYSICS;ENABLE_TEXTURE_STREAMING;ENABLE_LZMA;ENABLE_UNITYEVENTS;ENABLE_VR;ENABLE_WEBCAM;ENABLE_UNITYWEBREQUEST;ENABLE_WWW;ENABLE_CLOUD_SERVICES;ENABLE_CLOUD_SERVICES_ADS;ENABLE_CLOUD_SERVICES_USE_WEBREQUEST;ENABLE_CLOUD_SERVICES_CRASH_REPORTING;ENABLE_CLOUD_SERVICES_NATIVE_CRASH_REPORTING;ENABLE_CLOUD_SERVICES_PURCHASING;ENABLE_CLOUD_SERVICES_ANALYTICS;ENABLE_CLOUD_SERVICES_BUILD;ENABLE_EDITOR_GAME_SERVICES;ENABLE_UNITY_GAME_SERVICES_ANALYTICS_SUPPORT;ENABLE_CLOUD_LICENSE;ENABLE_EDITOR_HUB_LICENSE;ENABLE_WEBSOCKET_CLIENT;ENABLE_GENERATE_NATIVE_PLUGINS_FOR_ASSEMBLIES_API;ENABLE_DIRECTOR_AUDIO;ENABLE_DIRECTOR_TEXTURE;ENABLE_MANAGED_JOBS;ENABLE_MANAGED_TRANSFORM_JOBS;ENABLE_MANAGED_ANIMATION_JOBS;ENABLE_MANAGED_AUDIO_JOBS;ENABLE_RUNTIME_PERMISSIONS;ENABLE_ENGINE_CODE_STRIPPING;ENABLE_ONSCREEN_KEYBOARD;ENABLE_MANAGED_UNITYTLS;INCLUDE_DYNAMIC_GI;ENABLE_SCRIPTING_GC_WBARRIERS;PLATFORM_SUPPORTS_MONO;ENABLE_VIDEO;ENABLE_ACCELERATOR_CLIENT_DEBUGGING;ENABLE_NAVIGATION_PACKAGE_DEBUG_VISUALIZATION;ENABLE_NAVIGATION_HEIGHTMESH_RUNTIME_SUPPORT;ENABLE_NAVIGATION_UI_REQUIRES_PACKAGE;PLATFORM_ANDROID;TEXTCORE_1_0_OR_NEWER;UNITY_ANDROID;UNITY_ANDROID_API;ENABLE_EGL;ENABLE_NETWORK;ENABLE_RUNTIME_GI;ENABLE_CRUNCH_TEXTURE_COMPRESSION;UNITY_CAN_SHOW_SPLASH_SCREEN;UNITY_HAS_GOOGLEVR;UNITY_HAS_TANGO;ENABLE_SPATIALTRACKING;ENABLE_ETC_COMPRESSION;PLATFORM_EXTENDS_VULKAN_DEVICE;PLATFORM_HAS_MULTIPLE_SWAPCHAINS;UNITY_ANDROID_SUPPORTS_SHADOWFILES;PLATFORM_UPDATES_TIME_OUTSIDE_OF_PLAYER_LOOP;ENABLE_UNITYADS_RUNTIME;UNITY_UNITYADS_API;ENABLE_MONO;NET_4_6;NET_UNITY_4_8;ENABLE_PROFILER;DEBUG;TRACE;UNITY_ASSERTIONS;UNITY_EDITOR;UNITY_EDITOR_64;UNITY_EDITOR_WIN;ENABLE_UNITY_COLLECTIONS_CHECKS;ENABLE_BURST_AOT;UNITY_TEAM_LICENSE;ENABLE_CUSTOM_RENDER_TEXTURE;ENABLE_DIRECTOR;ENABLE_LOCALIZATION;ENABLE_SPRITES;ENABLE_TERRAIN;ENABLE_TILEMAP;ENABLE_TIMELINE;ENABLE_LEGACY_INPUT_MANAGER;TEXTCORE_FONT_ENGINE_1_5_OR_NEWER;UNITY_PHYSICS_CUSTOM;CSHARP_7_OR_LATER;CSHARP_7_3_OR_NEWER;UNITY_EDITOR_ONLY_COMPILATION</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<NoWarn>0169,0649</NoWarn>
|
||||
<AllowUnsafeBlocks>False</AllowUnsafeBlocks>
|
||||
<AllowUnsafeBlocks>True</AllowUnsafeBlocks>
|
||||
<TreatWarningsAsErrors>False</TreatWarningsAsErrors>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
@ -41,16 +41,849 @@
|
||||
<ImplicitlyExpandDesignTimeFacades>false</ImplicitlyExpandDesignTimeFacades>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Folder Include="Assets\NuGet\Editor" />
|
||||
<Reference Include="UnityEngine">
|
||||
<HintPath>C:\APP\UnityEdit\2021.3.33f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.CoreModule">
|
||||
<HintPath>C:\APP\UnityEdit\2021.3.33f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.CoreModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEditor">
|
||||
<HintPath>C:\APP\UnityEdit\2021.3.33f1c1\Editor\Data\Managed\UnityEngine\UnityEditor.dll</HintPath>
|
||||
</Reference>
|
||||
<Analyzer Include="D:\Unity\2022.3.16f1c1\Editor\Data\Tools\Unity.SourceGenerators\Unity.SourceGenerators.dll" />
|
||||
<Analyzer Include="D:\Unity\2022.3.16f1c1\Editor\Data\Tools\Unity.SourceGenerators\Unity.Properties.SourceGenerator.dll" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="Assets\Game\Plugins\AstarPathfindingProject\Legacy\Editor\LegacyAIPathEditor.cs" />
|
||||
<Compile Include="Assets\Game\Plugins\AstarPathfindingProject\Legacy\Editor\LegacyEditorHelper.cs" />
|
||||
<Compile Include="Assets\Game\Plugins\AstarPathfindingProject\Legacy\Editor\LegacyRVOControllerEditor.cs" />
|
||||
<Compile Include="Assets\Game\Plugins\AstarPathfindingProject\Legacy\Editor\LegacyRichAIEditor.cs" />
|
||||
<Reference Include="UnityEngine">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.AIModule">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.AIModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.ARModule">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.ARModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.AccessibilityModule">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.AccessibilityModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.AndroidJNIModule">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.AndroidJNIModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.AnimationModule">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.AnimationModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.AssetBundleModule">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.AssetBundleModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.AudioModule">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.AudioModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.ClothModule">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.ClothModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.ClusterInputModule">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.ClusterInputModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.ClusterRendererModule">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.ClusterRendererModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.ContentLoadModule">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.ContentLoadModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.CoreModule">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.CoreModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.CrashReportingModule">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.CrashReportingModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.DSPGraphModule">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.DSPGraphModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.DirectorModule">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.DirectorModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.GIModule">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.GIModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.GameCenterModule">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.GameCenterModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.GridModule">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.GridModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.HotReloadModule">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.HotReloadModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.IMGUIModule">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.IMGUIModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.ImageConversionModule">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.ImageConversionModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.InputModule">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.InputModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.InputLegacyModule">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.InputLegacyModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.JSONSerializeModule">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.JSONSerializeModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.LocalizationModule">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.LocalizationModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.NVIDIAModule">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.NVIDIAModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.ParticleSystemModule">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.ParticleSystemModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.PerformanceReportingModule">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.PerformanceReportingModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.PhysicsModule">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.PhysicsModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.Physics2DModule">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.Physics2DModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.ProfilerModule">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.ProfilerModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.PropertiesModule">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.PropertiesModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.RuntimeInitializeOnLoadManagerInitializerModule">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.RuntimeInitializeOnLoadManagerInitializerModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.ScreenCaptureModule">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.ScreenCaptureModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.SharedInternalsModule">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.SharedInternalsModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.SpriteMaskModule">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.SpriteMaskModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.SpriteShapeModule">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.SpriteShapeModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.StreamingModule">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.StreamingModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.SubstanceModule">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.SubstanceModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.SubsystemsModule">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.SubsystemsModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.TLSModule">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.TLSModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.TerrainModule">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.TerrainModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.TerrainPhysicsModule">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.TerrainPhysicsModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.TextCoreFontEngineModule">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.TextCoreFontEngineModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.TextCoreTextEngineModule">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.TextCoreTextEngineModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.TextRenderingModule">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.TextRenderingModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.TilemapModule">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.TilemapModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.UIModule">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.UIModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.UIElementsModule">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.UIElementsModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.UmbraModule">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.UmbraModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.UnityAnalyticsModule">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.UnityAnalyticsModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.UnityAnalyticsCommonModule">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.UnityAnalyticsCommonModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.UnityConnectModule">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.UnityConnectModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.UnityCurlModule">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.UnityCurlModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.UnityTestProtocolModule">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.UnityTestProtocolModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.UnityWebRequestModule">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.UnityWebRequestModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.UnityWebRequestAssetBundleModule">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.UnityWebRequestAssetBundleModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.UnityWebRequestAudioModule">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.UnityWebRequestAudioModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.UnityWebRequestTextureModule">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.UnityWebRequestTextureModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.UnityWebRequestWWWModule">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.UnityWebRequestWWWModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.VFXModule">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.VFXModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.VRModule">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.VRModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.VehiclesModule">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.VehiclesModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.VideoModule">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.VideoModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.VirtualTexturingModule">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.VirtualTexturingModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.WindModule">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.WindModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.XRModule">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.XRModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEditor">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEditor.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEditor.CoreModule">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEditor.CoreModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEditor.DeviceSimulatorModule">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEditor.DeviceSimulatorModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEditor.DiagnosticsModule">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEditor.DiagnosticsModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEditor.EditorToolbarModule">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEditor.EditorToolbarModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEditor.GraphViewModule">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEditor.GraphViewModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEditor.PresetsUIModule">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEditor.PresetsUIModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEditor.QuickSearchModule">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEditor.QuickSearchModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEditor.SceneTemplateModule">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEditor.SceneTemplateModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEditor.SceneViewModule">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEditor.SceneViewModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEditor.TextCoreFontEngineModule">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEditor.TextCoreFontEngineModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEditor.TextCoreTextEngineModule">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEditor.TextCoreTextEngineModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEditor.UIBuilderModule">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEditor.UIBuilderModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEditor.UIElementsModule">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEditor.UIElementsModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEditor.UIElementsSamplesModule">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEditor.UIElementsSamplesModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEditor.UnityConnectModule">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEditor.UnityConnectModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEditor.Graphs">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEditor.Graphs.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEditor.Android.Extensions">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\PlaybackEngines\AndroidPlayer\UnityEditor.Android.Extensions.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEditor.WindowsStandalone.Extensions">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\PlaybackEngines\WindowsStandaloneSupport\UnityEditor.WindowsStandalone.Extensions.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Pathfinding.Poly2Tri">
|
||||
<HintPath>D:\myproject\JisolGame\JNFrame\Assets\Game\Plugins\AstarPathfindingProject\Plugins\Poly2Tri\Pathfinding.Poly2Tri.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Unity.VisualScripting.YamlDotNet">
|
||||
<HintPath>D:\myproject\JisolGame\JNFrame\Library\PackageCache\com.unity.visualscripting@1.9.1\Editor\VisualScripting.Core\Dependencies\YamlDotNet\Unity.VisualScripting.YamlDotNet.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="BepuUtilities">
|
||||
<HintPath>D:\myproject\JisolGame\JNFrame\Assets\Game\Plugins\JNGame\BepuPhysics\Core\BepuPhysics2\BepuUtilities.2.3.4\lib\netstandard2.0\BepuUtilities.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Newtonsoft.Json">
|
||||
<HintPath>D:\myproject\JisolGame\JNFrame\Assets\Packages\Newtonsoft.Json.13.0.3\lib\netstandard2.0\Newtonsoft.Json.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Google.Protobuf">
|
||||
<HintPath>D:\myproject\JisolGame\JNFrame\Assets\Packages\Google.Protobuf.3.19.6\lib\netstandard2.0\Google.Protobuf.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="ReportGeneratorMerged">
|
||||
<HintPath>D:\myproject\JisolGame\JNFrame\Library\PackageCache\com.unity.testtools.codecoverage@1.2.4\lib\ReportGenerator\ReportGeneratorMerged.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Runtime.CompilerServices.Unsafe">
|
||||
<HintPath>D:\myproject\JisolGame\JNFrame\Assets\Packages\System.Runtime.CompilerServices.Unsafe.6.0.0\lib\netstandard2.0\System.Runtime.CompilerServices.Unsafe.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Unity.Plastic.Antlr3.Runtime">
|
||||
<HintPath>D:\myproject\JisolGame\JNFrame\Library\PackageCache\com.unity.collab-proxy@2.2.0\Lib\Editor\PlasticSCM\Unity.Plastic.Antlr3.Runtime.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="unityplastic">
|
||||
<HintPath>D:\myproject\JisolGame\JNFrame\Library\PackageCache\com.unity.collab-proxy@2.2.0\Lib\Editor\PlasticSCM\unityplastic.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="BepuPhysics">
|
||||
<HintPath>D:\myproject\JisolGame\JNFrame\Assets\Game\Plugins\JNGame\BepuPhysics\Core\BepuPhysics2\BepuPhysics.2.3.4\lib\netstandard2.0\BepuPhysics.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Unity.Plastic.Newtonsoft.Json">
|
||||
<HintPath>D:\myproject\JisolGame\JNFrame\Library\PackageCache\com.unity.collab-proxy@2.2.0\Lib\Editor\PlasticSCM\Unity.Plastic.Newtonsoft.Json.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="log4netPlastic">
|
||||
<HintPath>D:\myproject\JisolGame\JNFrame\Library\PackageCache\com.unity.collab-proxy@2.2.0\Lib\Editor\PlasticSCM\log4netPlastic.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Unity.VisualScripting.IonicZip">
|
||||
<HintPath>D:\myproject\JisolGame\JNFrame\Library\PackageCache\com.unity.visualscripting@1.9.1\Editor\VisualScripting.Core\Dependencies\DotNetZip\Unity.VisualScripting.IonicZip.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Pathfinding.ClipperLib">
|
||||
<HintPath>D:\myproject\JisolGame\JNFrame\Assets\Game\Plugins\AstarPathfindingProject\Plugins\Clipper\Pathfinding.ClipperLib.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Unity.VisualScripting.Antlr3.Runtime">
|
||||
<HintPath>D:\myproject\JisolGame\JNFrame\Library\PackageCache\com.unity.visualscripting@1.9.1\Runtime\VisualScripting.Flow\Dependencies\NCalc\Unity.VisualScripting.Antlr3.Runtime.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Unity.VisualScripting.TextureAssets">
|
||||
<HintPath>D:\myproject\JisolGame\JNFrame\Library\PackageCache\com.unity.visualscripting@1.9.1\Editor\VisualScripting.Core\EditorAssetResources\Unity.VisualScripting.TextureAssets.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="NugetForUnity">
|
||||
<HintPath>D:\myproject\JisolGame\JNFrame\Assets\NuGet\Editor\NugetForUnity.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Pathfinding.Ionic.Zip.Reduced">
|
||||
<HintPath>D:\myproject\JisolGame\JNFrame\Assets\Game\Plugins\AstarPathfindingProject\Plugins\DotNetZip\Pathfinding.Ionic.Zip.Reduced.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="nunit.framework">
|
||||
<HintPath>D:\myproject\JisolGame\JNFrame\Library\PackageCache\com.unity.ext.nunit@1.0.6\net35\unity-custom\nunit.framework.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Unity.Android.Types">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\PlaybackEngines\AndroidPlayer\Unity.Android.Types.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Unity.Android.Gradle">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\PlaybackEngines\AndroidPlayer\Unity.Android.Gradle.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Unity.Android.GradleProject">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\PlaybackEngines\AndroidPlayer\Unity.Android.GradleProject.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="mscorlib">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\UnityReferenceAssemblies\unity-4.8-api\mscorlib.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\UnityReferenceAssemblies\unity-4.8-api\System.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Core">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\UnityReferenceAssemblies\unity-4.8-api\System.Core.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Runtime.Serialization">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\UnityReferenceAssemblies\unity-4.8-api\System.Runtime.Serialization.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Xml">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\UnityReferenceAssemblies\unity-4.8-api\System.Xml.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Xml.Linq">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\UnityReferenceAssemblies\unity-4.8-api\System.Xml.Linq.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Numerics">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\UnityReferenceAssemblies\unity-4.8-api\System.Numerics.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Numerics.Vectors">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\UnityReferenceAssemblies\unity-4.8-api\System.Numerics.Vectors.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Net.Http">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\UnityReferenceAssemblies\unity-4.8-api\System.Net.Http.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.IO.Compression">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\UnityReferenceAssemblies\unity-4.8-api\System.IO.Compression.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Microsoft.CSharp">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\UnityReferenceAssemblies\unity-4.8-api\Microsoft.CSharp.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Data">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\UnityReferenceAssemblies\unity-4.8-api\System.Data.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Data.DataSetExtensions">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\UnityReferenceAssemblies\unity-4.8-api\System.Data.DataSetExtensions.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Drawing">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\UnityReferenceAssemblies\unity-4.8-api\System.Drawing.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.IO.Compression.FileSystem">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\UnityReferenceAssemblies\unity-4.8-api\System.IO.Compression.FileSystem.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.ComponentModel.Composition">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\UnityReferenceAssemblies\unity-4.8-api\System.ComponentModel.Composition.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Transactions">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\UnityReferenceAssemblies\unity-4.8-api\System.Transactions.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Microsoft.Win32.Primitives">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\UnityReferenceAssemblies\unity-4.8-api\Facades\Microsoft.Win32.Primitives.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="netstandard">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\UnityReferenceAssemblies\unity-4.8-api\Facades\netstandard.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.AppContext">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\UnityReferenceAssemblies\unity-4.8-api\Facades\System.AppContext.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Buffers">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\UnityReferenceAssemblies\unity-4.8-api\Facades\System.Buffers.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Collections.Concurrent">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\UnityReferenceAssemblies\unity-4.8-api\Facades\System.Collections.Concurrent.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Collections">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\UnityReferenceAssemblies\unity-4.8-api\Facades\System.Collections.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Collections.NonGeneric">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\UnityReferenceAssemblies\unity-4.8-api\Facades\System.Collections.NonGeneric.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Collections.Specialized">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\UnityReferenceAssemblies\unity-4.8-api\Facades\System.Collections.Specialized.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.ComponentModel.Annotations">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\UnityReferenceAssemblies\unity-4.8-api\Facades\System.ComponentModel.Annotations.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.ComponentModel">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\UnityReferenceAssemblies\unity-4.8-api\Facades\System.ComponentModel.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.ComponentModel.EventBasedAsync">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\UnityReferenceAssemblies\unity-4.8-api\Facades\System.ComponentModel.EventBasedAsync.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.ComponentModel.Primitives">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\UnityReferenceAssemblies\unity-4.8-api\Facades\System.ComponentModel.Primitives.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.ComponentModel.TypeConverter">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\UnityReferenceAssemblies\unity-4.8-api\Facades\System.ComponentModel.TypeConverter.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Console">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\UnityReferenceAssemblies\unity-4.8-api\Facades\System.Console.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Data.Common">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\UnityReferenceAssemblies\unity-4.8-api\Facades\System.Data.Common.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Diagnostics.Contracts">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\UnityReferenceAssemblies\unity-4.8-api\Facades\System.Diagnostics.Contracts.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Diagnostics.Debug">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\UnityReferenceAssemblies\unity-4.8-api\Facades\System.Diagnostics.Debug.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Diagnostics.FileVersionInfo">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\UnityReferenceAssemblies\unity-4.8-api\Facades\System.Diagnostics.FileVersionInfo.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Diagnostics.Process">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\UnityReferenceAssemblies\unity-4.8-api\Facades\System.Diagnostics.Process.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Diagnostics.StackTrace">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\UnityReferenceAssemblies\unity-4.8-api\Facades\System.Diagnostics.StackTrace.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Diagnostics.TextWriterTraceListener">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\UnityReferenceAssemblies\unity-4.8-api\Facades\System.Diagnostics.TextWriterTraceListener.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Diagnostics.Tools">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\UnityReferenceAssemblies\unity-4.8-api\Facades\System.Diagnostics.Tools.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Diagnostics.TraceSource">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\UnityReferenceAssemblies\unity-4.8-api\Facades\System.Diagnostics.TraceSource.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Drawing.Primitives">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\UnityReferenceAssemblies\unity-4.8-api\Facades\System.Drawing.Primitives.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Dynamic.Runtime">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\UnityReferenceAssemblies\unity-4.8-api\Facades\System.Dynamic.Runtime.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Globalization.Calendars">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\UnityReferenceAssemblies\unity-4.8-api\Facades\System.Globalization.Calendars.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Globalization">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\UnityReferenceAssemblies\unity-4.8-api\Facades\System.Globalization.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Globalization.Extensions">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\UnityReferenceAssemblies\unity-4.8-api\Facades\System.Globalization.Extensions.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.IO.Compression.ZipFile">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\UnityReferenceAssemblies\unity-4.8-api\Facades\System.IO.Compression.ZipFile.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.IO">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\UnityReferenceAssemblies\unity-4.8-api\Facades\System.IO.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.IO.FileSystem">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\UnityReferenceAssemblies\unity-4.8-api\Facades\System.IO.FileSystem.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.IO.FileSystem.DriveInfo">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\UnityReferenceAssemblies\unity-4.8-api\Facades\System.IO.FileSystem.DriveInfo.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.IO.FileSystem.Primitives">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\UnityReferenceAssemblies\unity-4.8-api\Facades\System.IO.FileSystem.Primitives.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.IO.FileSystem.Watcher">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\UnityReferenceAssemblies\unity-4.8-api\Facades\System.IO.FileSystem.Watcher.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.IO.IsolatedStorage">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\UnityReferenceAssemblies\unity-4.8-api\Facades\System.IO.IsolatedStorage.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.IO.MemoryMappedFiles">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\UnityReferenceAssemblies\unity-4.8-api\Facades\System.IO.MemoryMappedFiles.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.IO.Pipes">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\UnityReferenceAssemblies\unity-4.8-api\Facades\System.IO.Pipes.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.IO.UnmanagedMemoryStream">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\UnityReferenceAssemblies\unity-4.8-api\Facades\System.IO.UnmanagedMemoryStream.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Linq">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\UnityReferenceAssemblies\unity-4.8-api\Facades\System.Linq.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Linq.Expressions">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\UnityReferenceAssemblies\unity-4.8-api\Facades\System.Linq.Expressions.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Linq.Parallel">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\UnityReferenceAssemblies\unity-4.8-api\Facades\System.Linq.Parallel.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Linq.Queryable">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\UnityReferenceAssemblies\unity-4.8-api\Facades\System.Linq.Queryable.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Memory">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\UnityReferenceAssemblies\unity-4.8-api\Facades\System.Memory.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Net.Http.Rtc">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\UnityReferenceAssemblies\unity-4.8-api\Facades\System.Net.Http.Rtc.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Net.NameResolution">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\UnityReferenceAssemblies\unity-4.8-api\Facades\System.Net.NameResolution.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Net.NetworkInformation">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\UnityReferenceAssemblies\unity-4.8-api\Facades\System.Net.NetworkInformation.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Net.Ping">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\UnityReferenceAssemblies\unity-4.8-api\Facades\System.Net.Ping.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Net.Primitives">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\UnityReferenceAssemblies\unity-4.8-api\Facades\System.Net.Primitives.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Net.Requests">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\UnityReferenceAssemblies\unity-4.8-api\Facades\System.Net.Requests.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Net.Security">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\UnityReferenceAssemblies\unity-4.8-api\Facades\System.Net.Security.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Net.Sockets">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\UnityReferenceAssemblies\unity-4.8-api\Facades\System.Net.Sockets.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Net.WebHeaderCollection">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\UnityReferenceAssemblies\unity-4.8-api\Facades\System.Net.WebHeaderCollection.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Net.WebSockets.Client">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\UnityReferenceAssemblies\unity-4.8-api\Facades\System.Net.WebSockets.Client.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Net.WebSockets">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\UnityReferenceAssemblies\unity-4.8-api\Facades\System.Net.WebSockets.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.ObjectModel">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\UnityReferenceAssemblies\unity-4.8-api\Facades\System.ObjectModel.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Reflection.DispatchProxy">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\UnityReferenceAssemblies\unity-4.8-api\Facades\System.Reflection.DispatchProxy.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Reflection">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\UnityReferenceAssemblies\unity-4.8-api\Facades\System.Reflection.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Reflection.Emit">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\UnityReferenceAssemblies\unity-4.8-api\Facades\System.Reflection.Emit.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Reflection.Emit.ILGeneration">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\UnityReferenceAssemblies\unity-4.8-api\Facades\System.Reflection.Emit.ILGeneration.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Reflection.Emit.Lightweight">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\UnityReferenceAssemblies\unity-4.8-api\Facades\System.Reflection.Emit.Lightweight.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Reflection.Extensions">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\UnityReferenceAssemblies\unity-4.8-api\Facades\System.Reflection.Extensions.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Reflection.Primitives">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\UnityReferenceAssemblies\unity-4.8-api\Facades\System.Reflection.Primitives.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Resources.Reader">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\UnityReferenceAssemblies\unity-4.8-api\Facades\System.Resources.Reader.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Resources.ResourceManager">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\UnityReferenceAssemblies\unity-4.8-api\Facades\System.Resources.ResourceManager.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Resources.Writer">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\UnityReferenceAssemblies\unity-4.8-api\Facades\System.Resources.Writer.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Runtime.CompilerServices.VisualC">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\UnityReferenceAssemblies\unity-4.8-api\Facades\System.Runtime.CompilerServices.VisualC.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Runtime">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\UnityReferenceAssemblies\unity-4.8-api\Facades\System.Runtime.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Runtime.Extensions">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\UnityReferenceAssemblies\unity-4.8-api\Facades\System.Runtime.Extensions.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Runtime.Handles">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\UnityReferenceAssemblies\unity-4.8-api\Facades\System.Runtime.Handles.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Runtime.InteropServices">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\UnityReferenceAssemblies\unity-4.8-api\Facades\System.Runtime.InteropServices.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Runtime.InteropServices.RuntimeInformation">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\UnityReferenceAssemblies\unity-4.8-api\Facades\System.Runtime.InteropServices.RuntimeInformation.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Runtime.InteropServices.WindowsRuntime">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\UnityReferenceAssemblies\unity-4.8-api\Facades\System.Runtime.InteropServices.WindowsRuntime.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Runtime.Numerics">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\UnityReferenceAssemblies\unity-4.8-api\Facades\System.Runtime.Numerics.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Runtime.Serialization.Formatters">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\UnityReferenceAssemblies\unity-4.8-api\Facades\System.Runtime.Serialization.Formatters.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Runtime.Serialization.Json">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\UnityReferenceAssemblies\unity-4.8-api\Facades\System.Runtime.Serialization.Json.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Runtime.Serialization.Primitives">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\UnityReferenceAssemblies\unity-4.8-api\Facades\System.Runtime.Serialization.Primitives.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Runtime.Serialization.Xml">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\UnityReferenceAssemblies\unity-4.8-api\Facades\System.Runtime.Serialization.Xml.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Security.Claims">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\UnityReferenceAssemblies\unity-4.8-api\Facades\System.Security.Claims.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Security.Cryptography.Algorithms">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\UnityReferenceAssemblies\unity-4.8-api\Facades\System.Security.Cryptography.Algorithms.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Security.Cryptography.Csp">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\UnityReferenceAssemblies\unity-4.8-api\Facades\System.Security.Cryptography.Csp.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Security.Cryptography.Encoding">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\UnityReferenceAssemblies\unity-4.8-api\Facades\System.Security.Cryptography.Encoding.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Security.Cryptography.Primitives">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\UnityReferenceAssemblies\unity-4.8-api\Facades\System.Security.Cryptography.Primitives.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Security.Cryptography.X509Certificates">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\UnityReferenceAssemblies\unity-4.8-api\Facades\System.Security.Cryptography.X509Certificates.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Security.Principal">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\UnityReferenceAssemblies\unity-4.8-api\Facades\System.Security.Principal.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Security.SecureString">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\UnityReferenceAssemblies\unity-4.8-api\Facades\System.Security.SecureString.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.ServiceModel.Duplex">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\UnityReferenceAssemblies\unity-4.8-api\Facades\System.ServiceModel.Duplex.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.ServiceModel.Http">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\UnityReferenceAssemblies\unity-4.8-api\Facades\System.ServiceModel.Http.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.ServiceModel.NetTcp">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\UnityReferenceAssemblies\unity-4.8-api\Facades\System.ServiceModel.NetTcp.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.ServiceModel.Primitives">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\UnityReferenceAssemblies\unity-4.8-api\Facades\System.ServiceModel.Primitives.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.ServiceModel.Security">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\UnityReferenceAssemblies\unity-4.8-api\Facades\System.ServiceModel.Security.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Text.Encoding">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\UnityReferenceAssemblies\unity-4.8-api\Facades\System.Text.Encoding.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Text.Encoding.Extensions">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\UnityReferenceAssemblies\unity-4.8-api\Facades\System.Text.Encoding.Extensions.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Text.RegularExpressions">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\UnityReferenceAssemblies\unity-4.8-api\Facades\System.Text.RegularExpressions.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Threading">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\UnityReferenceAssemblies\unity-4.8-api\Facades\System.Threading.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Threading.Overlapped">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\UnityReferenceAssemblies\unity-4.8-api\Facades\System.Threading.Overlapped.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Threading.Tasks">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\UnityReferenceAssemblies\unity-4.8-api\Facades\System.Threading.Tasks.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Threading.Tasks.Extensions">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\UnityReferenceAssemblies\unity-4.8-api\Facades\System.Threading.Tasks.Extensions.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Threading.Tasks.Parallel">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\UnityReferenceAssemblies\unity-4.8-api\Facades\System.Threading.Tasks.Parallel.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Threading.Thread">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\UnityReferenceAssemblies\unity-4.8-api\Facades\System.Threading.Thread.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Threading.ThreadPool">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\UnityReferenceAssemblies\unity-4.8-api\Facades\System.Threading.ThreadPool.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Threading.Timer">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\UnityReferenceAssemblies\unity-4.8-api\Facades\System.Threading.Timer.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.ValueTuple">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\UnityReferenceAssemblies\unity-4.8-api\Facades\System.ValueTuple.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Xml.ReaderWriter">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\UnityReferenceAssemblies\unity-4.8-api\Facades\System.Xml.ReaderWriter.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Xml.XDocument">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\UnityReferenceAssemblies\unity-4.8-api\Facades\System.Xml.XDocument.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Xml.XmlDocument">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\UnityReferenceAssemblies\unity-4.8-api\Facades\System.Xml.XmlDocument.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Xml.XmlSerializer">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\UnityReferenceAssemblies\unity-4.8-api\Facades\System.Xml.XmlSerializer.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Xml.XPath">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\UnityReferenceAssemblies\unity-4.8-api\Facades\System.Xml.XPath.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Xml.XPath.XDocument">
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\UnityReferenceAssemblies\unity-4.8-api\Facades\System.Xml.XPath.XDocument.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEditor.TestRunner">
|
||||
<HintPath>D:\myproject\JisolGame\JNFrame\Library\ScriptAssemblies\UnityEditor.TestRunner.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.TestRunner">
|
||||
<HintPath>D:\myproject\JisolGame\JNFrame\Library\ScriptAssemblies\UnityEngine.TestRunner.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Unity.EditorCoroutines.Editor">
|
||||
<HintPath>D:\myproject\JisolGame\JNFrame\Library\ScriptAssemblies\Unity.EditorCoroutines.Editor.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Unity.PlasticSCM.Editor">
|
||||
<HintPath>D:\myproject\JisolGame\JNFrame\Library\ScriptAssemblies\Unity.PlasticSCM.Editor.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Unity.AI.Navigation">
|
||||
<HintPath>D:\myproject\JisolGame\JNFrame\Library\ScriptAssemblies\Unity.AI.Navigation.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Unity.Timeline.Editor">
|
||||
<HintPath>D:\myproject\JisolGame\JNFrame\Library\ScriptAssemblies\Unity.Timeline.Editor.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Unity.VisualScripting.Shared.Editor">
|
||||
<HintPath>D:\myproject\JisolGame\JNFrame\Library\ScriptAssemblies\Unity.VisualScripting.Shared.Editor.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Unity.VisualStudio.Editor">
|
||||
<HintPath>D:\myproject\JisolGame\JNFrame\Library\ScriptAssemblies\Unity.VisualStudio.Editor.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEditor.UI">
|
||||
<HintPath>D:\myproject\JisolGame\JNFrame\Library\ScriptAssemblies\UnityEditor.UI.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Unity.VisualScripting.Core">
|
||||
<HintPath>D:\myproject\JisolGame\JNFrame\Library\ScriptAssemblies\Unity.VisualScripting.Core.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Unity.VisualScripting.Core.Editor">
|
||||
<HintPath>D:\myproject\JisolGame\JNFrame\Library\ScriptAssemblies\Unity.VisualScripting.Core.Editor.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Unity.Rider.Editor">
|
||||
<HintPath>D:\myproject\JisolGame\JNFrame\Library\ScriptAssemblies\Unity.Rider.Editor.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.UI">
|
||||
<HintPath>D:\myproject\JisolGame\JNFrame\Library\ScriptAssemblies\UnityEngine.UI.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Unity.VisualScripting.Flow">
|
||||
<HintPath>D:\myproject\JisolGame\JNFrame\Library\ScriptAssemblies\Unity.VisualScripting.Flow.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Unity.VisualScripting.Flow.Editor">
|
||||
<HintPath>D:\myproject\JisolGame\JNFrame\Library\ScriptAssemblies\Unity.VisualScripting.Flow.Editor.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Unity.Timeline">
|
||||
<HintPath>D:\myproject\JisolGame\JNFrame\Library\ScriptAssemblies\Unity.Timeline.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Unity.TestTools.CodeCoverage.Editor.OpenCover.Mono.Reflection">
|
||||
<HintPath>D:\myproject\JisolGame\JNFrame\Library\ScriptAssemblies\Unity.TestTools.CodeCoverage.Editor.OpenCover.Mono.Reflection.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Unity.VisualScripting.SettingsProvider.Editor">
|
||||
<HintPath>D:\myproject\JisolGame\JNFrame\Library\ScriptAssemblies\Unity.VisualScripting.SettingsProvider.Editor.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Unity.Performance.Profile-Analyzer.Editor">
|
||||
<HintPath>D:\myproject\JisolGame\JNFrame\Library\ScriptAssemblies\Unity.Performance.Profile-Analyzer.Editor.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Unity.TestTools.CodeCoverage.Editor">
|
||||
<HintPath>D:\myproject\JisolGame\JNFrame\Library\ScriptAssemblies\Unity.TestTools.CodeCoverage.Editor.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Unity.AI.Navigation.Updater">
|
||||
<HintPath>D:\myproject\JisolGame\JNFrame\Library\ScriptAssemblies\Unity.AI.Navigation.Updater.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Unity.TestTools.CodeCoverage.Editor.OpenCover.Model">
|
||||
<HintPath>D:\myproject\JisolGame\JNFrame\Library\ScriptAssemblies\Unity.TestTools.CodeCoverage.Editor.OpenCover.Model.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Unity.VisualScripting.State.Editor">
|
||||
<HintPath>D:\myproject\JisolGame\JNFrame\Library\ScriptAssemblies\Unity.VisualScripting.State.Editor.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Unity.TextMeshPro">
|
||||
<HintPath>D:\myproject\JisolGame\JNFrame\Library\ScriptAssemblies\Unity.TextMeshPro.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Unity.TextMeshPro.Editor">
|
||||
<HintPath>D:\myproject\JisolGame\JNFrame\Library\ScriptAssemblies\Unity.TextMeshPro.Editor.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Unity.AI.Navigation.Editor">
|
||||
<HintPath>D:\myproject\JisolGame\JNFrame\Library\ScriptAssemblies\Unity.AI.Navigation.Editor.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Unity.VisualScripting.State">
|
||||
<HintPath>D:\myproject\JisolGame\JNFrame\Library\ScriptAssemblies\Unity.VisualScripting.State.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Unity.AI.Navigation.Editor.ConversionSystem">
|
||||
<HintPath>D:\myproject\JisolGame\JNFrame\Library\ScriptAssemblies\Unity.AI.Navigation.Editor.ConversionSystem.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Unity.VSCode.Editor">
|
||||
<HintPath>D:\myproject\JisolGame\JNFrame\Library\ScriptAssemblies\Unity.VSCode.Editor.dll</HintPath>
|
||||
</Reference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="Assembly-CSharp.csproj">
|
||||
<Project>{3ca4410c-c33b-25ce-55bc-3a432b9830ed}</Project>
|
||||
<Name>Assembly-CSharp</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="AstarPathfindingProjectEditor.csproj">
|
||||
<Project>{c006c4ab-5a1d-a86c-7397-6d5ecfbfd468}</Project>
|
||||
<Name>AstarPathfindingProjectEditor</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="UniTask.csproj">
|
||||
<Project>{39f5acb9-cdbb-9f48-497c-14159a0afd38}</Project>
|
||||
<Name>UniTask</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="UniTask.TextMeshPro.csproj">
|
||||
<Project>{4b964c85-7c9d-2d07-a2e0-8595262e4e96}</Project>
|
||||
<Name>UniTask.TextMeshPro</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="JNGame.csproj">
|
||||
<Project>{6daf7f60-fa83-da88-56be-04871b5df574}</Project>
|
||||
<Name>JNGame</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="BestHTTP.csproj">
|
||||
<Project>{49f1e414-166b-61b7-ba11-ad89c8d920ee}</Project>
|
||||
<Name>BestHTTP</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="PackageToolsEditor.csproj">
|
||||
<Project>{d850d0b5-3d03-e2f4-ebd4-5c75d2c94d81}</Project>
|
||||
<Name>PackageToolsEditor</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="UniTask.Addressables.csproj">
|
||||
<Project>{6d8bd378-3e5b-6997-5e5e-288243f0f72b}</Project>
|
||||
<Name>UniTask.Addressables</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="NewAssembly.csproj">
|
||||
<Project>{99ac6bed-aaad-5209-33d3-6f459696a074}</Project>
|
||||
<Name>NewAssembly</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="UniTask.DOTween.csproj">
|
||||
<Project>{99c4c7d2-ca96-1038-95e0-77e225df2b06}</Project>
|
||||
<Name>UniTask.DOTween</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="UniTask.Linq.csproj">
|
||||
<Project>{7f60f694-1f75-f2f0-5fde-36ccb7fd82d1}</Project>
|
||||
<Name>UniTask.Linq</Name>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||
|
@ -26,7 +26,7 @@
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>Temp\Bin\Debug\Assembly-CSharp-firstpass\</OutputPath>
|
||||
<DefineConstants>UNITY_2022_3_16;UNITY_2022_3;UNITY_2022;UNITY_5_3_OR_NEWER;UNITY_5_4_OR_NEWER;UNITY_5_5_OR_NEWER;UNITY_5_6_OR_NEWER;UNITY_2017_1_OR_NEWER;UNITY_2017_2_OR_NEWER;UNITY_2017_3_OR_NEWER;UNITY_2017_4_OR_NEWER;UNITY_2018_1_OR_NEWER;UNITY_2018_2_OR_NEWER;UNITY_2018_3_OR_NEWER;UNITY_2018_4_OR_NEWER;UNITY_2019_1_OR_NEWER;UNITY_2019_2_OR_NEWER;UNITY_2019_3_OR_NEWER;UNITY_2019_4_OR_NEWER;UNITY_2020_1_OR_NEWER;UNITY_2020_2_OR_NEWER;UNITY_2020_3_OR_NEWER;UNITY_2021_1_OR_NEWER;UNITY_2021_2_OR_NEWER;UNITY_2021_3_OR_NEWER;UNITY_2022_1_OR_NEWER;UNITY_2022_2_OR_NEWER;UNITY_2022_3_OR_NEWER;PLATFORM_ARCH_64;UNITY_64;UNITY_INCLUDE_TESTS;ENABLE_AR;ENABLE_AUDIO;ENABLE_CACHING;ENABLE_CLOTH;ENABLE_EVENT_QUEUE;ENABLE_MICROPHONE;ENABLE_MULTIPLE_DISPLAYS;ENABLE_PHYSICS;ENABLE_TEXTURE_STREAMING;ENABLE_VIRTUALTEXTURING;ENABLE_LZMA;ENABLE_UNITYEVENTS;ENABLE_VR;ENABLE_WEBCAM;ENABLE_UNITYWEBREQUEST;ENABLE_WWW;ENABLE_CLOUD_SERVICES;ENABLE_CLOUD_SERVICES_ADS;ENABLE_CLOUD_SERVICES_USE_WEBREQUEST;ENABLE_CLOUD_SERVICES_CRASH_REPORTING;ENABLE_CLOUD_SERVICES_PURCHASING;ENABLE_CLOUD_SERVICES_ANALYTICS;ENABLE_CLOUD_SERVICES_BUILD;ENABLE_EDITOR_GAME_SERVICES;ENABLE_UNITY_GAME_SERVICES_ANALYTICS_SUPPORT;ENABLE_CLOUD_LICENSE;ENABLE_EDITOR_HUB_LICENSE;ENABLE_WEBSOCKET_CLIENT;ENABLE_GENERATE_NATIVE_PLUGINS_FOR_ASSEMBLIES_API;ENABLE_DIRECTOR_AUDIO;ENABLE_DIRECTOR_TEXTURE;ENABLE_MANAGED_JOBS;ENABLE_MANAGED_TRANSFORM_JOBS;ENABLE_MANAGED_ANIMATION_JOBS;ENABLE_MANAGED_AUDIO_JOBS;ENABLE_MANAGED_UNITYTLS;INCLUDE_DYNAMIC_GI;ENABLE_SCRIPTING_GC_WBARRIERS;PLATFORM_SUPPORTS_MONO;RENDER_SOFTWARE_CURSOR;ENABLE_VIDEO;ENABLE_ACCELERATOR_CLIENT_DEBUGGING;ENABLE_NAVIGATION_PACKAGE_DEBUG_VISUALIZATION;ENABLE_NAVIGATION_HEIGHTMESH_RUNTIME_SUPPORT;ENABLE_NAVIGATION_UI_REQUIRES_PACKAGE;PLATFORM_STANDALONE;TEXTCORE_1_0_OR_NEWER;PLATFORM_STANDALONE_WIN;UNITY_STANDALONE_WIN;UNITY_STANDALONE;UNITY_UGP_API;ENABLE_RUNTIME_GI;ENABLE_MOVIES;ENABLE_NETWORK;ENABLE_NVIDIA;ENABLE_CRUNCH_TEXTURE_COMPRESSION;ENABLE_OUT_OF_PROCESS_CRASH_HANDLER;ENABLE_CLUSTER_SYNC;ENABLE_CLUSTERINPUT;PLATFORM_UPDATES_TIME_OUTSIDE_OF_PLAYER_LOOP;GFXDEVICE_WAITFOREVENT_MESSAGEPUMP;PLATFORM_INITIALIZES_MEMORY_MANAGER_EXPLICITLY;ENABLE_MONO;NET_STANDARD_2_0;NET_STANDARD;NET_STANDARD_2_1;NETSTANDARD;NETSTANDARD2_1;ENABLE_PROFILER;DEBUG;TRACE;UNITY_ASSERTIONS;UNITY_EDITOR;UNITY_EDITOR_64;UNITY_EDITOR_WIN;ENABLE_UNITY_COLLECTIONS_CHECKS;ENABLE_BURST_AOT;UNITY_TEAM_LICENSE;ENABLE_CUSTOM_RENDER_TEXTURE;ENABLE_DIRECTOR;ENABLE_LOCALIZATION;ENABLE_SPRITES;ENABLE_TERRAIN;ENABLE_TILEMAP;ENABLE_TIMELINE;ENABLE_LEGACY_INPUT_MANAGER;TEXTCORE_FONT_ENGINE_1_5_OR_NEWER;UNITY_PHYSICS_CUSTOM;CSHARP_7_OR_LATER;CSHARP_7_3_OR_NEWER</DefineConstants>
|
||||
<DefineConstants>UNITY_2022_3_16;UNITY_2022_3;UNITY_2022;UNITY_5_3_OR_NEWER;UNITY_5_4_OR_NEWER;UNITY_5_5_OR_NEWER;UNITY_5_6_OR_NEWER;UNITY_2017_1_OR_NEWER;UNITY_2017_2_OR_NEWER;UNITY_2017_3_OR_NEWER;UNITY_2017_4_OR_NEWER;UNITY_2018_1_OR_NEWER;UNITY_2018_2_OR_NEWER;UNITY_2018_3_OR_NEWER;UNITY_2018_4_OR_NEWER;UNITY_2019_1_OR_NEWER;UNITY_2019_2_OR_NEWER;UNITY_2019_3_OR_NEWER;UNITY_2019_4_OR_NEWER;UNITY_2020_1_OR_NEWER;UNITY_2020_2_OR_NEWER;UNITY_2020_3_OR_NEWER;UNITY_2021_1_OR_NEWER;UNITY_2021_2_OR_NEWER;UNITY_2021_3_OR_NEWER;UNITY_2022_1_OR_NEWER;UNITY_2022_2_OR_NEWER;UNITY_2022_3_OR_NEWER;UNITY_INCLUDE_TESTS;ENABLE_AR;ENABLE_AUDIO;ENABLE_CACHING;ENABLE_CLOTH;ENABLE_EVENT_QUEUE;ENABLE_MICROPHONE;ENABLE_MULTIPLE_DISPLAYS;ENABLE_PHYSICS;ENABLE_TEXTURE_STREAMING;ENABLE_LZMA;ENABLE_UNITYEVENTS;ENABLE_VR;ENABLE_WEBCAM;ENABLE_UNITYWEBREQUEST;ENABLE_WWW;ENABLE_CLOUD_SERVICES;ENABLE_CLOUD_SERVICES_ADS;ENABLE_CLOUD_SERVICES_USE_WEBREQUEST;ENABLE_CLOUD_SERVICES_CRASH_REPORTING;ENABLE_CLOUD_SERVICES_NATIVE_CRASH_REPORTING;ENABLE_CLOUD_SERVICES_PURCHASING;ENABLE_CLOUD_SERVICES_ANALYTICS;ENABLE_CLOUD_SERVICES_BUILD;ENABLE_EDITOR_GAME_SERVICES;ENABLE_UNITY_GAME_SERVICES_ANALYTICS_SUPPORT;ENABLE_CLOUD_LICENSE;ENABLE_EDITOR_HUB_LICENSE;ENABLE_WEBSOCKET_CLIENT;ENABLE_GENERATE_NATIVE_PLUGINS_FOR_ASSEMBLIES_API;ENABLE_DIRECTOR_AUDIO;ENABLE_DIRECTOR_TEXTURE;ENABLE_MANAGED_JOBS;ENABLE_MANAGED_TRANSFORM_JOBS;ENABLE_MANAGED_ANIMATION_JOBS;ENABLE_MANAGED_AUDIO_JOBS;ENABLE_RUNTIME_PERMISSIONS;ENABLE_ENGINE_CODE_STRIPPING;ENABLE_ONSCREEN_KEYBOARD;ENABLE_MANAGED_UNITYTLS;INCLUDE_DYNAMIC_GI;ENABLE_SCRIPTING_GC_WBARRIERS;PLATFORM_SUPPORTS_MONO;ENABLE_VIDEO;ENABLE_ACCELERATOR_CLIENT_DEBUGGING;ENABLE_NAVIGATION_PACKAGE_DEBUG_VISUALIZATION;ENABLE_NAVIGATION_HEIGHTMESH_RUNTIME_SUPPORT;ENABLE_NAVIGATION_UI_REQUIRES_PACKAGE;PLATFORM_ANDROID;TEXTCORE_1_0_OR_NEWER;UNITY_ANDROID;UNITY_ANDROID_API;ENABLE_EGL;ENABLE_NETWORK;ENABLE_RUNTIME_GI;ENABLE_CRUNCH_TEXTURE_COMPRESSION;UNITY_CAN_SHOW_SPLASH_SCREEN;UNITY_HAS_GOOGLEVR;UNITY_HAS_TANGO;ENABLE_SPATIALTRACKING;ENABLE_ETC_COMPRESSION;PLATFORM_EXTENDS_VULKAN_DEVICE;PLATFORM_HAS_MULTIPLE_SWAPCHAINS;UNITY_ANDROID_SUPPORTS_SHADOWFILES;PLATFORM_UPDATES_TIME_OUTSIDE_OF_PLAYER_LOOP;ENABLE_UNITYADS_RUNTIME;UNITY_UNITYADS_API;ENABLE_MONO;NET_STANDARD_2_0;NET_STANDARD;NET_STANDARD_2_1;NETSTANDARD;NETSTANDARD2_1;ENABLE_PROFILER;DEBUG;TRACE;UNITY_ASSERTIONS;UNITY_EDITOR;UNITY_EDITOR_64;UNITY_EDITOR_WIN;ENABLE_UNITY_COLLECTIONS_CHECKS;ENABLE_BURST_AOT;UNITY_TEAM_LICENSE;ENABLE_CUSTOM_RENDER_TEXTURE;ENABLE_DIRECTOR;ENABLE_LOCALIZATION;ENABLE_SPRITES;ENABLE_TERRAIN;ENABLE_TILEMAP;ENABLE_TIMELINE;ENABLE_LEGACY_INPUT_MANAGER;TEXTCORE_FONT_ENGINE_1_5_OR_NEWER;UNITY_PHYSICS_CUSTOM;CSHARP_7_OR_LATER;CSHARP_7_3_OR_NEWER</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<NoWarn>0169,0649</NoWarn>
|
||||
@ -41,8 +41,8 @@
|
||||
<ImplicitlyExpandDesignTimeFacades>false</ImplicitlyExpandDesignTimeFacades>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Analyzer Include="C:\APP\UnityEdit\2022.3.16f1c1\Editor\Data\Tools\Unity.SourceGenerators\Unity.SourceGenerators.dll" />
|
||||
<Analyzer Include="C:\APP\UnityEdit\2022.3.16f1c1\Editor\Data\Tools\Unity.SourceGenerators\Unity.Properties.SourceGenerator.dll" />
|
||||
<Analyzer Include="D:\Unity\2022.3.16f1c1\Editor\Data\Tools\Unity.SourceGenerators\Unity.SourceGenerators.dll" />
|
||||
<Analyzer Include="D:\Unity\2022.3.16f1c1\Editor\Data\Tools\Unity.SourceGenerators\Unity.Properties.SourceGenerator.dll" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="Assets\Plugins\BestHTTP\BestHTTP\SecureProtocol\asn1\bc\BCObjectIdentifiers.cs" />
|
||||
@ -2049,730 +2049,721 @@
|
||||
<None Include="Assets\Plugins\BestHTTP\link.xml" />
|
||||
<None Include="Assets\Plugins\BestHTTP\ReleaseNotes.txt" />
|
||||
<Reference Include="UnityEngine">
|
||||
<HintPath>C:\APP\UnityEdit\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.dll</HintPath>
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.AIModule">
|
||||
<HintPath>C:\APP\UnityEdit\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.AIModule.dll</HintPath>
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.AIModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.ARModule">
|
||||
<HintPath>C:\APP\UnityEdit\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.ARModule.dll</HintPath>
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.ARModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.AccessibilityModule">
|
||||
<HintPath>C:\APP\UnityEdit\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.AccessibilityModule.dll</HintPath>
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.AccessibilityModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.AndroidJNIModule">
|
||||
<HintPath>C:\APP\UnityEdit\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.AndroidJNIModule.dll</HintPath>
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.AndroidJNIModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.AnimationModule">
|
||||
<HintPath>C:\APP\UnityEdit\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.AnimationModule.dll</HintPath>
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.AnimationModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.AssetBundleModule">
|
||||
<HintPath>C:\APP\UnityEdit\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.AssetBundleModule.dll</HintPath>
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.AssetBundleModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.AudioModule">
|
||||
<HintPath>C:\APP\UnityEdit\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.AudioModule.dll</HintPath>
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.AudioModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.ClothModule">
|
||||
<HintPath>C:\APP\UnityEdit\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.ClothModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.ClusterInputModule">
|
||||
<HintPath>C:\APP\UnityEdit\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.ClusterInputModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.ClusterRendererModule">
|
||||
<HintPath>C:\APP\UnityEdit\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.ClusterRendererModule.dll</HintPath>
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.ClothModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.ContentLoadModule">
|
||||
<HintPath>C:\APP\UnityEdit\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.ContentLoadModule.dll</HintPath>
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.ContentLoadModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.CoreModule">
|
||||
<HintPath>C:\APP\UnityEdit\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.CoreModule.dll</HintPath>
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.CoreModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.CrashReportingModule">
|
||||
<HintPath>C:\APP\UnityEdit\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.CrashReportingModule.dll</HintPath>
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.CrashReportingModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.DSPGraphModule">
|
||||
<HintPath>C:\APP\UnityEdit\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.DSPGraphModule.dll</HintPath>
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.DSPGraphModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.DirectorModule">
|
||||
<HintPath>C:\APP\UnityEdit\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.DirectorModule.dll</HintPath>
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.DirectorModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.GIModule">
|
||||
<HintPath>C:\APP\UnityEdit\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.GIModule.dll</HintPath>
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.GIModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.GameCenterModule">
|
||||
<HintPath>C:\APP\UnityEdit\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.GameCenterModule.dll</HintPath>
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.GameCenterModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.GridModule">
|
||||
<HintPath>C:\APP\UnityEdit\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.GridModule.dll</HintPath>
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.GridModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.HotReloadModule">
|
||||
<HintPath>C:\APP\UnityEdit\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.HotReloadModule.dll</HintPath>
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.HotReloadModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.IMGUIModule">
|
||||
<HintPath>C:\APP\UnityEdit\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.IMGUIModule.dll</HintPath>
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.IMGUIModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.ImageConversionModule">
|
||||
<HintPath>C:\APP\UnityEdit\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.ImageConversionModule.dll</HintPath>
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.ImageConversionModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.InputModule">
|
||||
<HintPath>C:\APP\UnityEdit\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.InputModule.dll</HintPath>
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.InputModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.InputLegacyModule">
|
||||
<HintPath>C:\APP\UnityEdit\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.InputLegacyModule.dll</HintPath>
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.InputLegacyModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.JSONSerializeModule">
|
||||
<HintPath>C:\APP\UnityEdit\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.JSONSerializeModule.dll</HintPath>
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.JSONSerializeModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.LocalizationModule">
|
||||
<HintPath>C:\APP\UnityEdit\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.LocalizationModule.dll</HintPath>
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.LocalizationModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.ParticleSystemModule">
|
||||
<HintPath>C:\APP\UnityEdit\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.ParticleSystemModule.dll</HintPath>
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.ParticleSystemModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.PerformanceReportingModule">
|
||||
<HintPath>C:\APP\UnityEdit\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.PerformanceReportingModule.dll</HintPath>
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.PerformanceReportingModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.PhysicsModule">
|
||||
<HintPath>C:\APP\UnityEdit\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.PhysicsModule.dll</HintPath>
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.PhysicsModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.Physics2DModule">
|
||||
<HintPath>C:\APP\UnityEdit\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.Physics2DModule.dll</HintPath>
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.Physics2DModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.ProfilerModule">
|
||||
<HintPath>C:\APP\UnityEdit\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.ProfilerModule.dll</HintPath>
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.ProfilerModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.PropertiesModule">
|
||||
<HintPath>C:\APP\UnityEdit\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.PropertiesModule.dll</HintPath>
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.PropertiesModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.RuntimeInitializeOnLoadManagerInitializerModule">
|
||||
<HintPath>C:\APP\UnityEdit\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.RuntimeInitializeOnLoadManagerInitializerModule.dll</HintPath>
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.RuntimeInitializeOnLoadManagerInitializerModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.ScreenCaptureModule">
|
||||
<HintPath>C:\APP\UnityEdit\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.ScreenCaptureModule.dll</HintPath>
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.ScreenCaptureModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.SharedInternalsModule">
|
||||
<HintPath>C:\APP\UnityEdit\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.SharedInternalsModule.dll</HintPath>
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.SharedInternalsModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.SpriteMaskModule">
|
||||
<HintPath>C:\APP\UnityEdit\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.SpriteMaskModule.dll</HintPath>
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.SpriteMaskModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.SpriteShapeModule">
|
||||
<HintPath>C:\APP\UnityEdit\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.SpriteShapeModule.dll</HintPath>
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.SpriteShapeModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.StreamingModule">
|
||||
<HintPath>C:\APP\UnityEdit\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.StreamingModule.dll</HintPath>
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.StreamingModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.SubstanceModule">
|
||||
<HintPath>C:\APP\UnityEdit\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.SubstanceModule.dll</HintPath>
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.SubstanceModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.SubsystemsModule">
|
||||
<HintPath>C:\APP\UnityEdit\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.SubsystemsModule.dll</HintPath>
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.SubsystemsModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.TLSModule">
|
||||
<HintPath>C:\APP\UnityEdit\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.TLSModule.dll</HintPath>
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.TLSModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.TerrainModule">
|
||||
<HintPath>C:\APP\UnityEdit\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.TerrainModule.dll</HintPath>
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.TerrainModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.TerrainPhysicsModule">
|
||||
<HintPath>C:\APP\UnityEdit\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.TerrainPhysicsModule.dll</HintPath>
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.TerrainPhysicsModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.TextCoreFontEngineModule">
|
||||
<HintPath>C:\APP\UnityEdit\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.TextCoreFontEngineModule.dll</HintPath>
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.TextCoreFontEngineModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.TextCoreTextEngineModule">
|
||||
<HintPath>C:\APP\UnityEdit\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.TextCoreTextEngineModule.dll</HintPath>
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.TextCoreTextEngineModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.TextRenderingModule">
|
||||
<HintPath>C:\APP\UnityEdit\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.TextRenderingModule.dll</HintPath>
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.TextRenderingModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.TilemapModule">
|
||||
<HintPath>C:\APP\UnityEdit\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.TilemapModule.dll</HintPath>
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.TilemapModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.UIModule">
|
||||
<HintPath>C:\APP\UnityEdit\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.UIModule.dll</HintPath>
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.UIModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.UIElementsModule">
|
||||
<HintPath>C:\APP\UnityEdit\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.UIElementsModule.dll</HintPath>
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.UIElementsModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.UmbraModule">
|
||||
<HintPath>C:\APP\UnityEdit\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.UmbraModule.dll</HintPath>
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.UmbraModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.UnityAnalyticsModule">
|
||||
<HintPath>C:\APP\UnityEdit\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.UnityAnalyticsModule.dll</HintPath>
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.UnityAnalyticsModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.UnityAnalyticsCommonModule">
|
||||
<HintPath>C:\APP\UnityEdit\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.UnityAnalyticsCommonModule.dll</HintPath>
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.UnityAnalyticsCommonModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.UnityConnectModule">
|
||||
<HintPath>C:\APP\UnityEdit\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.UnityConnectModule.dll</HintPath>
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.UnityConnectModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.UnityCurlModule">
|
||||
<HintPath>C:\APP\UnityEdit\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.UnityCurlModule.dll</HintPath>
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.UnityCurlModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.UnityTestProtocolModule">
|
||||
<HintPath>C:\APP\UnityEdit\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.UnityTestProtocolModule.dll</HintPath>
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.UnityTestProtocolModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.UnityWebRequestModule">
|
||||
<HintPath>C:\APP\UnityEdit\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.UnityWebRequestModule.dll</HintPath>
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.UnityWebRequestModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.UnityWebRequestAssetBundleModule">
|
||||
<HintPath>C:\APP\UnityEdit\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.UnityWebRequestAssetBundleModule.dll</HintPath>
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.UnityWebRequestAssetBundleModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.UnityWebRequestAudioModule">
|
||||
<HintPath>C:\APP\UnityEdit\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.UnityWebRequestAudioModule.dll</HintPath>
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.UnityWebRequestAudioModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.UnityWebRequestTextureModule">
|
||||
<HintPath>C:\APP\UnityEdit\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.UnityWebRequestTextureModule.dll</HintPath>
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.UnityWebRequestTextureModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.UnityWebRequestWWWModule">
|
||||
<HintPath>C:\APP\UnityEdit\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.UnityWebRequestWWWModule.dll</HintPath>
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.UnityWebRequestWWWModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.VFXModule">
|
||||
<HintPath>C:\APP\UnityEdit\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.VFXModule.dll</HintPath>
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.VFXModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.VRModule">
|
||||
<HintPath>C:\APP\UnityEdit\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.VRModule.dll</HintPath>
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.VRModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.VehiclesModule">
|
||||
<HintPath>C:\APP\UnityEdit\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.VehiclesModule.dll</HintPath>
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.VehiclesModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.VideoModule">
|
||||
<HintPath>C:\APP\UnityEdit\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.VideoModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.VirtualTexturingModule">
|
||||
<HintPath>C:\APP\UnityEdit\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.VirtualTexturingModule.dll</HintPath>
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.VideoModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.WindModule">
|
||||
<HintPath>C:\APP\UnityEdit\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.WindModule.dll</HintPath>
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.WindModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.XRModule">
|
||||
<HintPath>C:\APP\UnityEdit\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.XRModule.dll</HintPath>
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.XRModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEditor">
|
||||
<HintPath>C:\APP\UnityEdit\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEditor.dll</HintPath>
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEditor.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEditor.CoreModule">
|
||||
<HintPath>C:\APP\UnityEdit\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEditor.CoreModule.dll</HintPath>
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEditor.CoreModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEditor.DeviceSimulatorModule">
|
||||
<HintPath>C:\APP\UnityEdit\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEditor.DeviceSimulatorModule.dll</HintPath>
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEditor.DeviceSimulatorModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEditor.DiagnosticsModule">
|
||||
<HintPath>C:\APP\UnityEdit\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEditor.DiagnosticsModule.dll</HintPath>
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEditor.DiagnosticsModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEditor.EditorToolbarModule">
|
||||
<HintPath>C:\APP\UnityEdit\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEditor.EditorToolbarModule.dll</HintPath>
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEditor.EditorToolbarModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEditor.GraphViewModule">
|
||||
<HintPath>C:\APP\UnityEdit\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEditor.GraphViewModule.dll</HintPath>
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEditor.GraphViewModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEditor.PresetsUIModule">
|
||||
<HintPath>C:\APP\UnityEdit\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEditor.PresetsUIModule.dll</HintPath>
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEditor.PresetsUIModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEditor.QuickSearchModule">
|
||||
<HintPath>C:\APP\UnityEdit\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEditor.QuickSearchModule.dll</HintPath>
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEditor.QuickSearchModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEditor.SceneTemplateModule">
|
||||
<HintPath>C:\APP\UnityEdit\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEditor.SceneTemplateModule.dll</HintPath>
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEditor.SceneTemplateModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEditor.SceneViewModule">
|
||||
<HintPath>C:\APP\UnityEdit\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEditor.SceneViewModule.dll</HintPath>
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEditor.SceneViewModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEditor.TextCoreFontEngineModule">
|
||||
<HintPath>C:\APP\UnityEdit\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEditor.TextCoreFontEngineModule.dll</HintPath>
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEditor.TextCoreFontEngineModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEditor.TextCoreTextEngineModule">
|
||||
<HintPath>C:\APP\UnityEdit\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEditor.TextCoreTextEngineModule.dll</HintPath>
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEditor.TextCoreTextEngineModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEditor.UIBuilderModule">
|
||||
<HintPath>C:\APP\UnityEdit\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEditor.UIBuilderModule.dll</HintPath>
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEditor.UIBuilderModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEditor.UIElementsModule">
|
||||
<HintPath>C:\APP\UnityEdit\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEditor.UIElementsModule.dll</HintPath>
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEditor.UIElementsModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEditor.UIElementsSamplesModule">
|
||||
<HintPath>C:\APP\UnityEdit\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEditor.UIElementsSamplesModule.dll</HintPath>
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEditor.UIElementsSamplesModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEditor.UnityConnectModule">
|
||||
<HintPath>C:\APP\UnityEdit\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEditor.UnityConnectModule.dll</HintPath>
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\Managed\UnityEngine\UnityEditor.UnityConnectModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="BepuUtilities">
|
||||
<HintPath>D:\Jisol\JisolGame\JNFrame\Assets\Plugins\JNGame\BepuPhysics\Core\BepuPhysics2\BepuUtilities.2.3.4\lib\netstandard2.0\BepuUtilities.dll</HintPath>
|
||||
<HintPath>D:\myproject\JisolGame\JNFrame\Assets\Plugins\JNGame\BepuPhysics\Core\BepuPhysics2\BepuUtilities.2.3.4\lib\netstandard2.0\BepuUtilities.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Newtonsoft.Json">
|
||||
<HintPath>D:\Jisol\JisolGame\JNFrame\Assets\Packages\Newtonsoft.Json.13.0.3\lib\netstandard2.0\Newtonsoft.Json.dll</HintPath>
|
||||
<HintPath>D:\myproject\JisolGame\JNFrame\Assets\Packages\Newtonsoft.Json.13.0.3\lib\netstandard2.0\Newtonsoft.Json.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Google.Protobuf">
|
||||
<HintPath>D:\Jisol\JisolGame\JNFrame\Assets\Packages\Google.Protobuf.3.19.6\lib\netstandard2.0\Google.Protobuf.dll</HintPath>
|
||||
<HintPath>D:\myproject\JisolGame\JNFrame\Assets\Packages\Google.Protobuf.3.19.6\lib\netstandard2.0\Google.Protobuf.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="ReportGeneratorMerged">
|
||||
<HintPath>D:\Jisol\JisolGame\JNFrame\Library\PackageCache\com.unity.testtools.codecoverage@1.2.4\lib\ReportGenerator\ReportGeneratorMerged.dll</HintPath>
|
||||
<HintPath>D:\myproject\JisolGame\JNFrame\Library\PackageCache\com.unity.testtools.codecoverage@1.2.4\lib\ReportGenerator\ReportGeneratorMerged.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Runtime.CompilerServices.Unsafe">
|
||||
<HintPath>D:\Jisol\JisolGame\JNFrame\Assets\Packages\System.Runtime.CompilerServices.Unsafe.6.0.0\lib\netstandard2.0\System.Runtime.CompilerServices.Unsafe.dll</HintPath>
|
||||
<HintPath>D:\myproject\JisolGame\JNFrame\Assets\Packages\System.Runtime.CompilerServices.Unsafe.6.0.0\lib\netstandard2.0\System.Runtime.CompilerServices.Unsafe.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="BepuPhysics">
|
||||
<HintPath>D:\Jisol\JisolGame\JNFrame\Assets\Plugins\JNGame\BepuPhysics\Core\BepuPhysics2\BepuPhysics.2.3.4\lib\netstandard2.0\BepuPhysics.dll</HintPath>
|
||||
<HintPath>D:\myproject\JisolGame\JNFrame\Assets\Plugins\JNGame\BepuPhysics\Core\BepuPhysics2\BepuPhysics.2.3.4\lib\netstandard2.0\BepuPhysics.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Unity.VisualScripting.Antlr3.Runtime">
|
||||
<HintPath>D:\Jisol\JisolGame\JNFrame\Library\PackageCache\com.unity.visualscripting@1.9.1\Runtime\VisualScripting.Flow\Dependencies\NCalc\Unity.VisualScripting.Antlr3.Runtime.dll</HintPath>
|
||||
<HintPath>D:\myproject\JisolGame\JNFrame\Library\PackageCache\com.unity.visualscripting@1.9.1\Runtime\VisualScripting.Flow\Dependencies\NCalc\Unity.VisualScripting.Antlr3.Runtime.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Unity.Android.Types">
|
||||
<HintPath>C:\APP\UnityEdit\2022.3.16f1c1\Editor\Data\PlaybackEngines\AndroidPlayer\Unity.Android.Types.dll</HintPath>
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\PlaybackEngines\AndroidPlayer\Unity.Android.Types.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Unity.Android.Gradle">
|
||||
<HintPath>C:\APP\UnityEdit\2022.3.16f1c1\Editor\Data\PlaybackEngines\AndroidPlayer\Unity.Android.Gradle.dll</HintPath>
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\PlaybackEngines\AndroidPlayer\Unity.Android.Gradle.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Unity.Android.GradleProject">
|
||||
<HintPath>C:\APP\UnityEdit\2022.3.16f1c1\Editor\Data\PlaybackEngines\AndroidPlayer\Unity.Android.GradleProject.dll</HintPath>
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\PlaybackEngines\AndroidPlayer\Unity.Android.GradleProject.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="netstandard">
|
||||
<HintPath>C:\APP\UnityEdit\2022.3.16f1c1\Editor\Data\NetStandard\ref\2.1.0\netstandard.dll</HintPath>
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\ref\2.1.0\netstandard.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Microsoft.Win32.Primitives">
|
||||
<HintPath>C:\APP\UnityEdit\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\Microsoft.Win32.Primitives.dll</HintPath>
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\Microsoft.Win32.Primitives.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.AppContext">
|
||||
<HintPath>C:\APP\UnityEdit\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.AppContext.dll</HintPath>
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.AppContext.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Buffers">
|
||||
<HintPath>C:\APP\UnityEdit\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Buffers.dll</HintPath>
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Buffers.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Collections.Concurrent">
|
||||
<HintPath>C:\APP\UnityEdit\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Collections.Concurrent.dll</HintPath>
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Collections.Concurrent.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Collections">
|
||||
<HintPath>C:\APP\UnityEdit\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Collections.dll</HintPath>
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Collections.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Collections.NonGeneric">
|
||||
<HintPath>C:\APP\UnityEdit\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Collections.NonGeneric.dll</HintPath>
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Collections.NonGeneric.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Collections.Specialized">
|
||||
<HintPath>C:\APP\UnityEdit\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Collections.Specialized.dll</HintPath>
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Collections.Specialized.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.ComponentModel">
|
||||
<HintPath>C:\APP\UnityEdit\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.ComponentModel.dll</HintPath>
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.ComponentModel.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.ComponentModel.EventBasedAsync">
|
||||
<HintPath>C:\APP\UnityEdit\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.ComponentModel.EventBasedAsync.dll</HintPath>
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.ComponentModel.EventBasedAsync.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.ComponentModel.Primitives">
|
||||
<HintPath>C:\APP\UnityEdit\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.ComponentModel.Primitives.dll</HintPath>
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.ComponentModel.Primitives.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.ComponentModel.TypeConverter">
|
||||
<HintPath>C:\APP\UnityEdit\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.ComponentModel.TypeConverter.dll</HintPath>
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.ComponentModel.TypeConverter.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Console">
|
||||
<HintPath>C:\APP\UnityEdit\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Console.dll</HintPath>
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Console.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Data.Common">
|
||||
<HintPath>C:\APP\UnityEdit\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Data.Common.dll</HintPath>
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Data.Common.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Diagnostics.Contracts">
|
||||
<HintPath>C:\APP\UnityEdit\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Diagnostics.Contracts.dll</HintPath>
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Diagnostics.Contracts.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Diagnostics.Debug">
|
||||
<HintPath>C:\APP\UnityEdit\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Diagnostics.Debug.dll</HintPath>
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Diagnostics.Debug.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Diagnostics.FileVersionInfo">
|
||||
<HintPath>C:\APP\UnityEdit\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Diagnostics.FileVersionInfo.dll</HintPath>
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Diagnostics.FileVersionInfo.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Diagnostics.Process">
|
||||
<HintPath>C:\APP\UnityEdit\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Diagnostics.Process.dll</HintPath>
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Diagnostics.Process.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Diagnostics.StackTrace">
|
||||
<HintPath>C:\APP\UnityEdit\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Diagnostics.StackTrace.dll</HintPath>
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Diagnostics.StackTrace.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Diagnostics.TextWriterTraceListener">
|
||||
<HintPath>C:\APP\UnityEdit\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Diagnostics.TextWriterTraceListener.dll</HintPath>
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Diagnostics.TextWriterTraceListener.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Diagnostics.Tools">
|
||||
<HintPath>C:\APP\UnityEdit\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Diagnostics.Tools.dll</HintPath>
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Diagnostics.Tools.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Diagnostics.TraceSource">
|
||||
<HintPath>C:\APP\UnityEdit\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Diagnostics.TraceSource.dll</HintPath>
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Diagnostics.TraceSource.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Diagnostics.Tracing">
|
||||
<HintPath>C:\APP\UnityEdit\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Diagnostics.Tracing.dll</HintPath>
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Diagnostics.Tracing.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Drawing.Primitives">
|
||||
<HintPath>C:\APP\UnityEdit\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Drawing.Primitives.dll</HintPath>
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Drawing.Primitives.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Dynamic.Runtime">
|
||||
<HintPath>C:\APP\UnityEdit\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Dynamic.Runtime.dll</HintPath>
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Dynamic.Runtime.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Globalization.Calendars">
|
||||
<HintPath>C:\APP\UnityEdit\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Globalization.Calendars.dll</HintPath>
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Globalization.Calendars.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Globalization">
|
||||
<HintPath>C:\APP\UnityEdit\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Globalization.dll</HintPath>
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Globalization.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Globalization.Extensions">
|
||||
<HintPath>C:\APP\UnityEdit\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Globalization.Extensions.dll</HintPath>
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Globalization.Extensions.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.IO.Compression">
|
||||
<HintPath>C:\APP\UnityEdit\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.IO.Compression.dll</HintPath>
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.IO.Compression.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.IO.Compression.ZipFile">
|
||||
<HintPath>C:\APP\UnityEdit\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.IO.Compression.ZipFile.dll</HintPath>
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.IO.Compression.ZipFile.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.IO">
|
||||
<HintPath>C:\APP\UnityEdit\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.IO.dll</HintPath>
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.IO.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.IO.FileSystem">
|
||||
<HintPath>C:\APP\UnityEdit\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.IO.FileSystem.dll</HintPath>
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.IO.FileSystem.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.IO.FileSystem.DriveInfo">
|
||||
<HintPath>C:\APP\UnityEdit\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.IO.FileSystem.DriveInfo.dll</HintPath>
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.IO.FileSystem.DriveInfo.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.IO.FileSystem.Primitives">
|
||||
<HintPath>C:\APP\UnityEdit\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.IO.FileSystem.Primitives.dll</HintPath>
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.IO.FileSystem.Primitives.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.IO.FileSystem.Watcher">
|
||||
<HintPath>C:\APP\UnityEdit\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.IO.FileSystem.Watcher.dll</HintPath>
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.IO.FileSystem.Watcher.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.IO.IsolatedStorage">
|
||||
<HintPath>C:\APP\UnityEdit\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.IO.IsolatedStorage.dll</HintPath>
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.IO.IsolatedStorage.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.IO.MemoryMappedFiles">
|
||||
<HintPath>C:\APP\UnityEdit\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.IO.MemoryMappedFiles.dll</HintPath>
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.IO.MemoryMappedFiles.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.IO.Pipes">
|
||||
<HintPath>C:\APP\UnityEdit\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.IO.Pipes.dll</HintPath>
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.IO.Pipes.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.IO.UnmanagedMemoryStream">
|
||||
<HintPath>C:\APP\UnityEdit\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.IO.UnmanagedMemoryStream.dll</HintPath>
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.IO.UnmanagedMemoryStream.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Linq">
|
||||
<HintPath>C:\APP\UnityEdit\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Linq.dll</HintPath>
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Linq.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Linq.Expressions">
|
||||
<HintPath>C:\APP\UnityEdit\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Linq.Expressions.dll</HintPath>
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Linq.Expressions.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Linq.Parallel">
|
||||
<HintPath>C:\APP\UnityEdit\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Linq.Parallel.dll</HintPath>
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Linq.Parallel.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Linq.Queryable">
|
||||
<HintPath>C:\APP\UnityEdit\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Linq.Queryable.dll</HintPath>
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Linq.Queryable.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Memory">
|
||||
<HintPath>C:\APP\UnityEdit\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Memory.dll</HintPath>
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Memory.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Net.Http">
|
||||
<HintPath>C:\APP\UnityEdit\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Net.Http.dll</HintPath>
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Net.Http.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Net.NameResolution">
|
||||
<HintPath>C:\APP\UnityEdit\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Net.NameResolution.dll</HintPath>
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Net.NameResolution.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Net.NetworkInformation">
|
||||
<HintPath>C:\APP\UnityEdit\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Net.NetworkInformation.dll</HintPath>
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Net.NetworkInformation.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Net.Ping">
|
||||
<HintPath>C:\APP\UnityEdit\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Net.Ping.dll</HintPath>
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Net.Ping.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Net.Primitives">
|
||||
<HintPath>C:\APP\UnityEdit\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Net.Primitives.dll</HintPath>
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Net.Primitives.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Net.Requests">
|
||||
<HintPath>C:\APP\UnityEdit\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Net.Requests.dll</HintPath>
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Net.Requests.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Net.Security">
|
||||
<HintPath>C:\APP\UnityEdit\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Net.Security.dll</HintPath>
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Net.Security.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Net.Sockets">
|
||||
<HintPath>C:\APP\UnityEdit\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Net.Sockets.dll</HintPath>
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Net.Sockets.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Net.WebHeaderCollection">
|
||||
<HintPath>C:\APP\UnityEdit\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Net.WebHeaderCollection.dll</HintPath>
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Net.WebHeaderCollection.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Net.WebSockets.Client">
|
||||
<HintPath>C:\APP\UnityEdit\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Net.WebSockets.Client.dll</HintPath>
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Net.WebSockets.Client.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Net.WebSockets">
|
||||
<HintPath>C:\APP\UnityEdit\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Net.WebSockets.dll</HintPath>
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Net.WebSockets.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Numerics.Vectors">
|
||||
<HintPath>C:\APP\UnityEdit\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Numerics.Vectors.dll</HintPath>
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Numerics.Vectors.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.ObjectModel">
|
||||
<HintPath>C:\APP\UnityEdit\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.ObjectModel.dll</HintPath>
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.ObjectModel.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Reflection.DispatchProxy">
|
||||
<HintPath>C:\APP\UnityEdit\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Reflection.DispatchProxy.dll</HintPath>
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Reflection.DispatchProxy.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Reflection">
|
||||
<HintPath>C:\APP\UnityEdit\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Reflection.dll</HintPath>
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Reflection.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Reflection.Emit">
|
||||
<HintPath>C:\APP\UnityEdit\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Reflection.Emit.dll</HintPath>
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Reflection.Emit.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Reflection.Emit.ILGeneration">
|
||||
<HintPath>C:\APP\UnityEdit\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Reflection.Emit.ILGeneration.dll</HintPath>
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Reflection.Emit.ILGeneration.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Reflection.Emit.Lightweight">
|
||||
<HintPath>C:\APP\UnityEdit\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Reflection.Emit.Lightweight.dll</HintPath>
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Reflection.Emit.Lightweight.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Reflection.Extensions">
|
||||
<HintPath>C:\APP\UnityEdit\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Reflection.Extensions.dll</HintPath>
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Reflection.Extensions.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Reflection.Primitives">
|
||||
<HintPath>C:\APP\UnityEdit\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Reflection.Primitives.dll</HintPath>
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Reflection.Primitives.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Resources.Reader">
|
||||
<HintPath>C:\APP\UnityEdit\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Resources.Reader.dll</HintPath>
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Resources.Reader.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Resources.ResourceManager">
|
||||
<HintPath>C:\APP\UnityEdit\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Resources.ResourceManager.dll</HintPath>
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Resources.ResourceManager.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Resources.Writer">
|
||||
<HintPath>C:\APP\UnityEdit\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Resources.Writer.dll</HintPath>
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Resources.Writer.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Runtime.CompilerServices.VisualC">
|
||||
<HintPath>C:\APP\UnityEdit\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Runtime.CompilerServices.VisualC.dll</HintPath>
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Runtime.CompilerServices.VisualC.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Runtime">
|
||||
<HintPath>C:\APP\UnityEdit\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Runtime.dll</HintPath>
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Runtime.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Runtime.Extensions">
|
||||
<HintPath>C:\APP\UnityEdit\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Runtime.Extensions.dll</HintPath>
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Runtime.Extensions.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Runtime.Handles">
|
||||
<HintPath>C:\APP\UnityEdit\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Runtime.Handles.dll</HintPath>
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Runtime.Handles.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Runtime.InteropServices">
|
||||
<HintPath>C:\APP\UnityEdit\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Runtime.InteropServices.dll</HintPath>
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Runtime.InteropServices.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Runtime.InteropServices.RuntimeInformation">
|
||||
<HintPath>C:\APP\UnityEdit\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Runtime.InteropServices.RuntimeInformation.dll</HintPath>
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Runtime.InteropServices.RuntimeInformation.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Runtime.Numerics">
|
||||
<HintPath>C:\APP\UnityEdit\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Runtime.Numerics.dll</HintPath>
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Runtime.Numerics.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Runtime.Serialization.Formatters">
|
||||
<HintPath>C:\APP\UnityEdit\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Runtime.Serialization.Formatters.dll</HintPath>
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Runtime.Serialization.Formatters.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Runtime.Serialization.Json">
|
||||
<HintPath>C:\APP\UnityEdit\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Runtime.Serialization.Json.dll</HintPath>
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Runtime.Serialization.Json.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Runtime.Serialization.Primitives">
|
||||
<HintPath>C:\APP\UnityEdit\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Runtime.Serialization.Primitives.dll</HintPath>
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Runtime.Serialization.Primitives.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Runtime.Serialization.Xml">
|
||||
<HintPath>C:\APP\UnityEdit\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Runtime.Serialization.Xml.dll</HintPath>
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Runtime.Serialization.Xml.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Security.Claims">
|
||||
<HintPath>C:\APP\UnityEdit\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Security.Claims.dll</HintPath>
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Security.Claims.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Security.Cryptography.Algorithms">
|
||||
<HintPath>C:\APP\UnityEdit\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Security.Cryptography.Algorithms.dll</HintPath>
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Security.Cryptography.Algorithms.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Security.Cryptography.Csp">
|
||||
<HintPath>C:\APP\UnityEdit\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Security.Cryptography.Csp.dll</HintPath>
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Security.Cryptography.Csp.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Security.Cryptography.Encoding">
|
||||
<HintPath>C:\APP\UnityEdit\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Security.Cryptography.Encoding.dll</HintPath>
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Security.Cryptography.Encoding.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Security.Cryptography.Primitives">
|
||||
<HintPath>C:\APP\UnityEdit\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Security.Cryptography.Primitives.dll</HintPath>
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Security.Cryptography.Primitives.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Security.Cryptography.X509Certificates">
|
||||
<HintPath>C:\APP\UnityEdit\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Security.Cryptography.X509Certificates.dll</HintPath>
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Security.Cryptography.X509Certificates.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Security.Principal">
|
||||
<HintPath>C:\APP\UnityEdit\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Security.Principal.dll</HintPath>
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Security.Principal.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Security.SecureString">
|
||||
<HintPath>C:\APP\UnityEdit\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Security.SecureString.dll</HintPath>
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Security.SecureString.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Text.Encoding">
|
||||
<HintPath>C:\APP\UnityEdit\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Text.Encoding.dll</HintPath>
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Text.Encoding.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Text.Encoding.Extensions">
|
||||
<HintPath>C:\APP\UnityEdit\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Text.Encoding.Extensions.dll</HintPath>
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Text.Encoding.Extensions.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Text.RegularExpressions">
|
||||
<HintPath>C:\APP\UnityEdit\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Text.RegularExpressions.dll</HintPath>
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Text.RegularExpressions.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Threading">
|
||||
<HintPath>C:\APP\UnityEdit\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Threading.dll</HintPath>
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Threading.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Threading.Overlapped">
|
||||
<HintPath>C:\APP\UnityEdit\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Threading.Overlapped.dll</HintPath>
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Threading.Overlapped.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Threading.Tasks">
|
||||
<HintPath>C:\APP\UnityEdit\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Threading.Tasks.dll</HintPath>
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Threading.Tasks.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Threading.Tasks.Extensions">
|
||||
<HintPath>C:\APP\UnityEdit\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Threading.Tasks.Extensions.dll</HintPath>
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Threading.Tasks.Extensions.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Threading.Tasks.Parallel">
|
||||
<HintPath>C:\APP\UnityEdit\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Threading.Tasks.Parallel.dll</HintPath>
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Threading.Tasks.Parallel.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Threading.Thread">
|
||||
<HintPath>C:\APP\UnityEdit\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Threading.Thread.dll</HintPath>
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Threading.Thread.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Threading.ThreadPool">
|
||||
<HintPath>C:\APP\UnityEdit\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Threading.ThreadPool.dll</HintPath>
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Threading.ThreadPool.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Threading.Timer">
|
||||
<HintPath>C:\APP\UnityEdit\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Threading.Timer.dll</HintPath>
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Threading.Timer.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.ValueTuple">
|
||||
<HintPath>C:\APP\UnityEdit\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.ValueTuple.dll</HintPath>
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.ValueTuple.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Xml.ReaderWriter">
|
||||
<HintPath>C:\APP\UnityEdit\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Xml.ReaderWriter.dll</HintPath>
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Xml.ReaderWriter.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Xml.XDocument">
|
||||
<HintPath>C:\APP\UnityEdit\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Xml.XDocument.dll</HintPath>
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Xml.XDocument.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Xml.XmlDocument">
|
||||
<HintPath>C:\APP\UnityEdit\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Xml.XmlDocument.dll</HintPath>
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Xml.XmlDocument.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Xml.XmlSerializer">
|
||||
<HintPath>C:\APP\UnityEdit\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Xml.XmlSerializer.dll</HintPath>
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Xml.XmlSerializer.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Xml.XPath">
|
||||
<HintPath>C:\APP\UnityEdit\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Xml.XPath.dll</HintPath>
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Xml.XPath.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Xml.XPath.XDocument">
|
||||
<HintPath>C:\APP\UnityEdit\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Xml.XPath.XDocument.dll</HintPath>
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Xml.XPath.XDocument.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Runtime.InteropServices.WindowsRuntime">
|
||||
<HintPath>C:\APP\UnityEdit\2022.3.16f1c1\Editor\Data\NetStandard\Extensions\2.0.0\System.Runtime.InteropServices.WindowsRuntime.dll</HintPath>
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\Extensions\2.0.0\System.Runtime.InteropServices.WindowsRuntime.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="mscorlib">
|
||||
<HintPath>C:\APP\UnityEdit\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netfx\mscorlib.dll</HintPath>
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netfx\mscorlib.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.ComponentModel.Composition">
|
||||
<HintPath>C:\APP\UnityEdit\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netfx\System.ComponentModel.Composition.dll</HintPath>
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netfx\System.ComponentModel.Composition.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Core">
|
||||
<HintPath>C:\APP\UnityEdit\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netfx\System.Core.dll</HintPath>
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netfx\System.Core.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Data">
|
||||
<HintPath>C:\APP\UnityEdit\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netfx\System.Data.dll</HintPath>
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netfx\System.Data.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System">
|
||||
<HintPath>C:\APP\UnityEdit\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netfx\System.dll</HintPath>
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netfx\System.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Drawing">
|
||||
<HintPath>C:\APP\UnityEdit\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netfx\System.Drawing.dll</HintPath>
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netfx\System.Drawing.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.IO.Compression.FileSystem">
|
||||
<HintPath>C:\APP\UnityEdit\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netfx\System.IO.Compression.FileSystem.dll</HintPath>
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netfx\System.IO.Compression.FileSystem.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Net">
|
||||
<HintPath>C:\APP\UnityEdit\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netfx\System.Net.dll</HintPath>
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netfx\System.Net.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Numerics">
|
||||
<HintPath>C:\APP\UnityEdit\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netfx\System.Numerics.dll</HintPath>
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netfx\System.Numerics.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Runtime.Serialization">
|
||||
<HintPath>C:\APP\UnityEdit\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netfx\System.Runtime.Serialization.dll</HintPath>
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netfx\System.Runtime.Serialization.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.ServiceModel.Web">
|
||||
<HintPath>C:\APP\UnityEdit\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netfx\System.ServiceModel.Web.dll</HintPath>
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netfx\System.ServiceModel.Web.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Transactions">
|
||||
<HintPath>C:\APP\UnityEdit\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netfx\System.Transactions.dll</HintPath>
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netfx\System.Transactions.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Web">
|
||||
<HintPath>C:\APP\UnityEdit\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netfx\System.Web.dll</HintPath>
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netfx\System.Web.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Windows">
|
||||
<HintPath>C:\APP\UnityEdit\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netfx\System.Windows.dll</HintPath>
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netfx\System.Windows.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Xml">
|
||||
<HintPath>C:\APP\UnityEdit\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netfx\System.Xml.dll</HintPath>
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netfx\System.Xml.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Xml.Linq">
|
||||
<HintPath>C:\APP\UnityEdit\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netfx\System.Xml.Linq.dll</HintPath>
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netfx\System.Xml.Linq.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Xml.Serialization">
|
||||
<HintPath>C:\APP\UnityEdit\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netfx\System.Xml.Serialization.dll</HintPath>
|
||||
<HintPath>D:\Unity\2022.3.16f1c1\Editor\Data\NetStandard\compat\2.1.0\shims\netfx\System.Xml.Serialization.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Unity.EditorCoroutines.Editor">
|
||||
<HintPath>D:\Jisol\JisolGame\JNFrame\Library\ScriptAssemblies\Unity.EditorCoroutines.Editor.dll</HintPath>
|
||||
<HintPath>D:\myproject\JisolGame\JNFrame\Library\ScriptAssemblies\Unity.EditorCoroutines.Editor.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Unity.AI.Navigation">
|
||||
<HintPath>D:\Jisol\JisolGame\JNFrame\Library\ScriptAssemblies\Unity.AI.Navigation.dll</HintPath>
|
||||
<HintPath>D:\myproject\JisolGame\JNFrame\Library\ScriptAssemblies\Unity.AI.Navigation.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Unity.PlasticSCM.Editor">
|
||||
<HintPath>D:\Jisol\JisolGame\JNFrame\Library\ScriptAssemblies\Unity.PlasticSCM.Editor.dll</HintPath>
|
||||
<HintPath>D:\myproject\JisolGame\JNFrame\Library\ScriptAssemblies\Unity.PlasticSCM.Editor.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Unity.Timeline.Editor">
|
||||
<HintPath>D:\Jisol\JisolGame\JNFrame\Library\ScriptAssemblies\Unity.Timeline.Editor.dll</HintPath>
|
||||
<HintPath>D:\myproject\JisolGame\JNFrame\Library\ScriptAssemblies\Unity.Timeline.Editor.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Unity.VisualScripting.Shared.Editor">
|
||||
<HintPath>D:\Jisol\JisolGame\JNFrame\Library\ScriptAssemblies\Unity.VisualScripting.Shared.Editor.dll</HintPath>
|
||||
<HintPath>D:\myproject\JisolGame\JNFrame\Library\ScriptAssemblies\Unity.VisualScripting.Shared.Editor.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Unity.VisualStudio.Editor">
|
||||
<HintPath>D:\Jisol\JisolGame\JNFrame\Library\ScriptAssemblies\Unity.VisualStudio.Editor.dll</HintPath>
|
||||
<HintPath>D:\myproject\JisolGame\JNFrame\Library\ScriptAssemblies\Unity.VisualStudio.Editor.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEditor.UI">
|
||||
<HintPath>D:\Jisol\JisolGame\JNFrame\Library\ScriptAssemblies\UnityEditor.UI.dll</HintPath>
|
||||
<HintPath>D:\myproject\JisolGame\JNFrame\Library\ScriptAssemblies\UnityEditor.UI.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Unity.VisualScripting.Core">
|
||||
<HintPath>D:\Jisol\JisolGame\JNFrame\Library\ScriptAssemblies\Unity.VisualScripting.Core.dll</HintPath>
|
||||
<HintPath>D:\myproject\JisolGame\JNFrame\Library\ScriptAssemblies\Unity.VisualScripting.Core.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.UI">
|
||||
<HintPath>D:\Jisol\JisolGame\JNFrame\Library\ScriptAssemblies\UnityEngine.UI.dll</HintPath>
|
||||
<HintPath>D:\myproject\JisolGame\JNFrame\Library\ScriptAssemblies\UnityEngine.UI.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Unity.VisualScripting.Core.Editor">
|
||||
<HintPath>D:\Jisol\JisolGame\JNFrame\Library\ScriptAssemblies\Unity.VisualScripting.Core.Editor.dll</HintPath>
|
||||
<HintPath>D:\myproject\JisolGame\JNFrame\Library\ScriptAssemblies\Unity.VisualScripting.Core.Editor.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Unity.Rider.Editor">
|
||||
<HintPath>D:\Jisol\JisolGame\JNFrame\Library\ScriptAssemblies\Unity.Rider.Editor.dll</HintPath>
|
||||
<HintPath>D:\myproject\JisolGame\JNFrame\Library\ScriptAssemblies\Unity.Rider.Editor.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Unity.VisualScripting.Flow">
|
||||
<HintPath>D:\Jisol\JisolGame\JNFrame\Library\ScriptAssemblies\Unity.VisualScripting.Flow.dll</HintPath>
|
||||
<HintPath>D:\myproject\JisolGame\JNFrame\Library\ScriptAssemblies\Unity.VisualScripting.Flow.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Unity.VisualScripting.Flow.Editor">
|
||||
<HintPath>D:\Jisol\JisolGame\JNFrame\Library\ScriptAssemblies\Unity.VisualScripting.Flow.Editor.dll</HintPath>
|
||||
<HintPath>D:\myproject\JisolGame\JNFrame\Library\ScriptAssemblies\Unity.VisualScripting.Flow.Editor.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Unity.Timeline">
|
||||
<HintPath>D:\Jisol\JisolGame\JNFrame\Library\ScriptAssemblies\Unity.Timeline.dll</HintPath>
|
||||
<HintPath>D:\myproject\JisolGame\JNFrame\Library\ScriptAssemblies\Unity.Timeline.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Unity.TestTools.CodeCoverage.Editor.OpenCover.Mono.Reflection">
|
||||
<HintPath>D:\Jisol\JisolGame\JNFrame\Library\ScriptAssemblies\Unity.TestTools.CodeCoverage.Editor.OpenCover.Mono.Reflection.dll</HintPath>
|
||||
<HintPath>D:\myproject\JisolGame\JNFrame\Library\ScriptAssemblies\Unity.TestTools.CodeCoverage.Editor.OpenCover.Mono.Reflection.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Unity.VisualScripting.SettingsProvider.Editor">
|
||||
<HintPath>D:\Jisol\JisolGame\JNFrame\Library\ScriptAssemblies\Unity.VisualScripting.SettingsProvider.Editor.dll</HintPath>
|
||||
<HintPath>D:\myproject\JisolGame\JNFrame\Library\ScriptAssemblies\Unity.VisualScripting.SettingsProvider.Editor.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Unity.Performance.Profile-Analyzer.Editor">
|
||||
<HintPath>D:\Jisol\JisolGame\JNFrame\Library\ScriptAssemblies\Unity.Performance.Profile-Analyzer.Editor.dll</HintPath>
|
||||
<HintPath>D:\myproject\JisolGame\JNFrame\Library\ScriptAssemblies\Unity.Performance.Profile-Analyzer.Editor.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Unity.TestTools.CodeCoverage.Editor">
|
||||
<HintPath>D:\Jisol\JisolGame\JNFrame\Library\ScriptAssemblies\Unity.TestTools.CodeCoverage.Editor.dll</HintPath>
|
||||
<HintPath>D:\myproject\JisolGame\JNFrame\Library\ScriptAssemblies\Unity.TestTools.CodeCoverage.Editor.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Unity.TestTools.CodeCoverage.Editor.OpenCover.Model">
|
||||
<HintPath>D:\Jisol\JisolGame\JNFrame\Library\ScriptAssemblies\Unity.TestTools.CodeCoverage.Editor.OpenCover.Model.dll</HintPath>
|
||||
<HintPath>D:\myproject\JisolGame\JNFrame\Library\ScriptAssemblies\Unity.TestTools.CodeCoverage.Editor.OpenCover.Model.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Unity.AI.Navigation.Updater">
|
||||
<HintPath>D:\Jisol\JisolGame\JNFrame\Library\ScriptAssemblies\Unity.AI.Navigation.Updater.dll</HintPath>
|
||||
<HintPath>D:\myproject\JisolGame\JNFrame\Library\ScriptAssemblies\Unity.AI.Navigation.Updater.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Unity.VisualScripting.State.Editor">
|
||||
<HintPath>D:\Jisol\JisolGame\JNFrame\Library\ScriptAssemblies\Unity.VisualScripting.State.Editor.dll</HintPath>
|
||||
<HintPath>D:\myproject\JisolGame\JNFrame\Library\ScriptAssemblies\Unity.VisualScripting.State.Editor.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Unity.TextMeshPro">
|
||||
<HintPath>D:\Jisol\JisolGame\JNFrame\Library\ScriptAssemblies\Unity.TextMeshPro.dll</HintPath>
|
||||
<HintPath>D:\myproject\JisolGame\JNFrame\Library\ScriptAssemblies\Unity.TextMeshPro.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Unity.TextMeshPro.Editor">
|
||||
<HintPath>D:\Jisol\JisolGame\JNFrame\Library\ScriptAssemblies\Unity.TextMeshPro.Editor.dll</HintPath>
|
||||
<HintPath>D:\myproject\JisolGame\JNFrame\Library\ScriptAssemblies\Unity.TextMeshPro.Editor.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Unity.AI.Navigation.Editor">
|
||||
<HintPath>D:\Jisol\JisolGame\JNFrame\Library\ScriptAssemblies\Unity.AI.Navigation.Editor.dll</HintPath>
|
||||
<HintPath>D:\myproject\JisolGame\JNFrame\Library\ScriptAssemblies\Unity.AI.Navigation.Editor.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Unity.VisualScripting.State">
|
||||
<HintPath>D:\Jisol\JisolGame\JNFrame\Library\ScriptAssemblies\Unity.VisualScripting.State.dll</HintPath>
|
||||
<HintPath>D:\myproject\JisolGame\JNFrame\Library\ScriptAssemblies\Unity.VisualScripting.State.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Unity.AI.Navigation.Editor.ConversionSystem">
|
||||
<HintPath>D:\Jisol\JisolGame\JNFrame\Library\ScriptAssemblies\Unity.AI.Navigation.Editor.ConversionSystem.dll</HintPath>
|
||||
<HintPath>D:\myproject\JisolGame\JNFrame\Library\ScriptAssemblies\Unity.AI.Navigation.Editor.ConversionSystem.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Unity.VSCode.Editor">
|
||||
<HintPath>D:\Jisol\JisolGame\JNFrame\Library\ScriptAssemblies\Unity.VSCode.Editor.dll</HintPath>
|
||||
<HintPath>D:\myproject\JisolGame\JNFrame\Library\ScriptAssemblies\Unity.VSCode.Editor.dll</HintPath>
|
||||
</Reference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
|
File diff suppressed because it is too large
Load Diff
8
JNFrame/Assets/Game.meta
Normal file
8
JNFrame/Assets/Game.meta
Normal file
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: cf65a94ea616d32448e8c4f37bb609ef
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
18
JNFrame/Assets/Game/Plugins/App/App.asmdef
Normal file
18
JNFrame/Assets/Game/Plugins/App/App.asmdef
Normal file
@ -0,0 +1,18 @@
|
||||
{
|
||||
"name": "App",
|
||||
"rootNamespace": "",
|
||||
"references": [
|
||||
"GUID:7a47da2842efe384ba63b83f4b1471db",
|
||||
"GUID:f51ebe6a0ceec4240a699833d6309b23",
|
||||
"GUID:9069ac25d95ca17448a247f3bb1c769f"
|
||||
],
|
||||
"includePlatforms": [],
|
||||
"excludePlatforms": [],
|
||||
"allowUnsafeCode": false,
|
||||
"overrideReferences": false,
|
||||
"precompiledReferences": [],
|
||||
"autoReferenced": true,
|
||||
"defineConstraints": [],
|
||||
"versionDefines": [],
|
||||
"noEngineReferences": false
|
||||
}
|
7
JNFrame/Assets/Game/Plugins/App/App.asmdef.meta
Normal file
7
JNFrame/Assets/Game/Plugins/App/App.asmdef.meta
Normal file
@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: cfa590ecbcd6ced438358a8dea07179c
|
||||
AssemblyDefinitionImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -1,15 +1,14 @@
|
||||
using Plugins.JNGame.System;
|
||||
using Plugins.JNGame.Util;
|
||||
using Script.AppImpl;
|
||||
|
||||
namespace Script
|
||||
namespace Game.Plugins.App
|
||||
{
|
||||
public static class App
|
||||
{
|
||||
|
||||
public static readonly JNGSocket Socket = new JNGSocket();
|
||||
public static readonly JNGSyncFrame Sync = new JNGSyncFrame();
|
||||
public static readonly JAPI Api = new(new JAPIConfig(){BaseURL = "http://192.168.1.23:8080"});
|
||||
public static readonly JAPI Api = new(new JAPIConfig(){BaseURL = "http://192.168.0.118:8080"});
|
||||
public static readonly EventDispatcher Event = EventDispatcher.Event;
|
||||
|
||||
public static SystemBase[] System()
|
8
JNFrame/Assets/Game/Plugins/App/Game.meta
Normal file
8
JNFrame/Assets/Game/Plugins/App/Game.meta
Normal file
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7c7041250350ad645a506ee45d362da3
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
14
JNFrame/Assets/Game/Plugins/App/JNGSocket.cs
Normal file
14
JNFrame/Assets/Game/Plugins/App/JNGSocket.cs
Normal file
@ -0,0 +1,14 @@
|
||||
using Cysharp.Threading.Tasks;
|
||||
using Plugins.JNGame.Network;
|
||||
|
||||
namespace Game.Plugins.App
|
||||
{
|
||||
public class JNGSocket : JNSocket
|
||||
{
|
||||
protected override async UniTask<string> GetUrl()
|
||||
{
|
||||
await UniTask.NextFrame();
|
||||
return "ws://192.168.0.118:8080/websocket";
|
||||
}
|
||||
}
|
||||
}
|
30
JNFrame/Assets/Game/Plugins/App/JNGSyncFrame.cs
Normal file
30
JNFrame/Assets/Game/Plugins/App/JNGSyncFrame.cs
Normal file
@ -0,0 +1,30 @@
|
||||
using Cysharp.Threading.Tasks;
|
||||
using Plugins.JNGame.Sync.Frame;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Game.Plugins.App
|
||||
{
|
||||
public class JNGSyncFrame : JNSyncFrame
|
||||
{
|
||||
protected override void OnSendInput(JNFrameInputs inputs)
|
||||
{
|
||||
throw new System.NotImplementedException();
|
||||
}
|
||||
|
||||
protected override async UniTask<JNFrameInfos> OnServerData(int start, int end)
|
||||
{
|
||||
Debug.Log($"OnServerData - {start}");
|
||||
var data = (await App.Api.GetByte($"/sync/frame?start={start}"));
|
||||
if (data is { Length: > 0 })
|
||||
{
|
||||
JNFrameInfos info = JNFrameInfos.Parser.ParseFrom(data);
|
||||
Debug.Log($"OnServerData - {start} 结束");
|
||||
return info;
|
||||
}
|
||||
else
|
||||
{
|
||||
return new JNFrameInfos();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
16
JNFrame/Assets/Game/Plugins/App/Sync/JNGSyncFrame.cs
Normal file
16
JNFrame/Assets/Game/Plugins/App/Sync/JNGSyncFrame.cs
Normal file
@ -0,0 +1,16 @@
|
||||
using Plugins.JNGame.Sync.Frame;
|
||||
using Plugins.JNGame.Sync.Frame.game;
|
||||
|
||||
namespace Game.Plugins.App.Sync
|
||||
{
|
||||
public abstract class JNGSyncFrame<T> : JNSyncFrameComponent<T>
|
||||
{
|
||||
protected override JNSyncFrame GetSync()
|
||||
{
|
||||
return App.Sync;
|
||||
}
|
||||
|
||||
public override void OnSyncLoad(){}
|
||||
|
||||
}
|
||||
}
|
11
JNFrame/Assets/Game/Plugins/App/Sync/JNGSyncFrameDefault.cs
Normal file
11
JNFrame/Assets/Game/Plugins/App/Sync/JNGSyncFrameDefault.cs
Normal file
@ -0,0 +1,11 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace Game.Plugins.App.Sync
|
||||
{
|
||||
public class JNGSyncFrameDefault : JNGSyncFrame<Object>
|
||||
{
|
||||
public override void OnSyncUpdate(int dt, JNFrameInfo frame, Object input)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 67efd019640f42afb3840659516d244a
|
||||
timeCreated: 1706773209
|
52
JNFrame/Assets/Game/Plugins/App/Sync/JNGSyncFrameEntrust.cs
Normal file
52
JNFrame/Assets/Game/Plugins/App/Sync/JNGSyncFrameEntrust.cs
Normal file
@ -0,0 +1,52 @@
|
||||
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Plugins.JNGame.Sync.Frame.game;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Game.Plugins.App.Sync
|
||||
{
|
||||
public class JNGSyncFrameEntrust : JNGSyncFrameDefault
|
||||
{
|
||||
|
||||
private IEnumerable<Component> _components;
|
||||
public IEnumerable<Component> Components => _components;
|
||||
|
||||
public Component[] allow;
|
||||
|
||||
public override void OnSyncLoad()
|
||||
{
|
||||
|
||||
//获取非同步的组件
|
||||
_components = this.GetComponents<Component>()
|
||||
.Where(item => !(item is IJNSyncFrameComponent))
|
||||
.Where(item => !(item is Transform))
|
||||
.Where(item => !(allow.Contains(item)));
|
||||
|
||||
Debug.Log($"{this.NID} 有{Components.Count()}组件不是同步组件 尝试接管同步 请保证被接管的组件有enabled 同时被接管的组件 enabled 禁止修改");
|
||||
|
||||
foreach (var component in Components)
|
||||
{
|
||||
var property = component.GetType().GetProperty("enabled");
|
||||
if (property == null)
|
||||
{
|
||||
Debug.Log($"{this.NID} 有组件不是同步组件 并且没有 enabled 为了防止不同步 直接删除!");
|
||||
Destroy(component);
|
||||
continue;
|
||||
}
|
||||
property.SetValue(component,false);
|
||||
}
|
||||
|
||||
_components = this.GetComponents<Component>()
|
||||
.Where(item => !(item.GetType().IsAssignableFrom(typeof(IJNSyncFrameComponent))));
|
||||
|
||||
}
|
||||
|
||||
public override void OnSyncUpdate(int dt, JNFrameInfo frame, Object input)
|
||||
{
|
||||
base.OnSyncUpdate(dt, frame, input);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 32f8b8b7207b1a24ea68368f6a1a91b9
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
2
JNFrame/Assets/Game/Plugins/AstarPathfindingProject.meta
Normal file
2
JNFrame/Assets/Game/Plugins/AstarPathfindingProject.meta
Normal file
@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6942e1e80e8b54fde9147e843f1bec4f
|
@ -0,0 +1,18 @@
|
||||
{
|
||||
"name": "AstarPathfindingProject",
|
||||
"rootNamespace": "",
|
||||
"references": [
|
||||
"GUID:cfa590ecbcd6ced438358a8dea07179c",
|
||||
"GUID:7a47da2842efe384ba63b83f4b1471db",
|
||||
"GUID:f51ebe6a0ceec4240a699833d6309b23"
|
||||
],
|
||||
"includePlatforms": [],
|
||||
"excludePlatforms": [],
|
||||
"allowUnsafeCode": false,
|
||||
"overrideReferences": false,
|
||||
"precompiledReferences": [],
|
||||
"autoReferenced": true,
|
||||
"defineConstraints": [],
|
||||
"versionDefines": [],
|
||||
"noEngineReferences": false
|
||||
}
|
@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: efa45043feb7e4147a305b73b5cea642
|
||||
AssemblyDefinitionImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,9 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5eeb3c5df5ca840d3ae6b93e6b207d74
|
||||
folderAsset: yes
|
||||
timeCreated: 1497206641
|
||||
licenseType: Store
|
||||
DefaultImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,39 @@
|
||||
using UnityEngine;
|
||||
using System.Collections;
|
||||
|
||||
namespace Pathfinding {
|
||||
/// <summary>
|
||||
/// Sets the destination of an AI to the position of a specified object.
|
||||
/// This component should be attached to a GameObject together with a movement script such as AIPath, RichAI or AILerp.
|
||||
/// This component will then make the AI move towards the <see cref="target"/> set on this component.
|
||||
///
|
||||
/// See: <see cref="Pathfinding.IAstarAI.destination"/>
|
||||
///
|
||||
/// [Open online documentation to see images]
|
||||
/// </summary>
|
||||
[UniqueComponent(tag = "ai.destination")]
|
||||
[HelpURL("https://arongranberg.com/astar/documentation/stable/class_pathfinding_1_1_a_i_destination_setter.php")]
|
||||
public class AIDestinationSetter : VersionedMonoBehaviour {
|
||||
/// <summary>The object that the AI should move to</summary>
|
||||
public Transform target;
|
||||
IAstarAI ai;
|
||||
|
||||
void OnEnable () {
|
||||
ai = GetComponent<IAstarAI>();
|
||||
// Update the destination right before searching for a path as well.
|
||||
// This is enough in theory, but this script will also update the destination every
|
||||
// frame as the destination is used for debugging and may be used for other things by other
|
||||
// scripts as well. So it makes sense that it is up to date every frame.
|
||||
if (ai != null) ai.onSearchPath += Update;
|
||||
}
|
||||
|
||||
void OnDisable () {
|
||||
if (ai != null) ai.onSearchPath -= Update;
|
||||
}
|
||||
|
||||
/// <summary>Updates the AI's destination every frame</summary>
|
||||
void Update () {
|
||||
if (target != null && ai != null) ai.destination = target.position;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c9679e68a0f1144e79c664d9a11ca121
|
||||
timeCreated: 1495015523
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,66 @@
|
||||
using UnityEngine;
|
||||
using System.Collections;
|
||||
|
||||
namespace Pathfinding {
|
||||
/// <summary>
|
||||
/// Simple patrol behavior.
|
||||
/// This will set the destination on the agent so that it moves through the sequence of objects in the <see cref="targets"/> array.
|
||||
/// Upon reaching a target it will wait for <see cref="delay"/> seconds.
|
||||
///
|
||||
/// See: <see cref="Pathfinding.AIDestinationSetter"/>
|
||||
/// See: <see cref="Pathfinding.AIPath"/>
|
||||
/// See: <see cref="Pathfinding.RichAI"/>
|
||||
/// See: <see cref="Pathfinding.AILerp"/>
|
||||
/// </summary>
|
||||
[UniqueComponent(tag = "ai.destination")]
|
||||
[HelpURL("https://arongranberg.com/astar/documentation/stable/class_pathfinding_1_1_patrol.php")]
|
||||
public class Patrol : VersionedMonoBehaviour {
|
||||
/// <summary>Target points to move to in order</summary>
|
||||
public Transform[] targets;
|
||||
|
||||
/// <summary>Time in seconds to wait at each target</summary>
|
||||
public float delay = 0;
|
||||
|
||||
/// <summary>
|
||||
/// If true, the agent's destination will be updated every frame instead of only when switching targets.
|
||||
///
|
||||
/// This is good if you have moving targets, but is otherwise unnecessary and slightly slower.
|
||||
/// </summary>
|
||||
public bool updateDestinationEveryFrame = false;
|
||||
|
||||
/// <summary>Current target index</summary>
|
||||
int index = -1;
|
||||
|
||||
IAstarAI agent;
|
||||
float switchTime = float.NegativeInfinity;
|
||||
|
||||
public override void OnSyncLoad()
|
||||
{
|
||||
base.OnSyncLoad();
|
||||
agent = GetComponent<IAstarAI>();
|
||||
}
|
||||
|
||||
/// <summary>Update is called once per frame</summary>
|
||||
void Update () {
|
||||
if (targets.Length == 0) return;
|
||||
|
||||
// Note: using reachedEndOfPath and pathPending instead of reachedDestination here because
|
||||
// if the destination cannot be reached by the agent, we don't want it to get stuck, we just want it to get as close as possible and then move on.
|
||||
if (agent.reachedEndOfPath && !agent.pathPending && float.IsPositiveInfinity(switchTime)) {
|
||||
switchTime = GetSync().Time.time + delay;
|
||||
}
|
||||
|
||||
if (GetSync().Time.time >= switchTime) {
|
||||
index++;
|
||||
switchTime = float.PositiveInfinity;
|
||||
|
||||
index = index % targets.Length;
|
||||
agent.destination = targets[index].position;
|
||||
agent.SearchPath();
|
||||
} else if (updateDestinationEveryFrame) {
|
||||
index = index % targets.Length;
|
||||
agent.destination = targets[index].position;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 22e6c29e32504465faa943c537d8029b
|
||||
timeCreated: 1495286303
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
2092
JNFrame/Assets/Game/Plugins/AstarPathfindingProject/CHANGELOG.md
Normal file
2092
JNFrame/Assets/Game/Plugins/AstarPathfindingProject/CHANGELOG.md
Normal file
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e271255bdfe8941f9ab0acccbb14dd82
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b6b8abb917bca4ce0ad1b26452b3c58d
|
@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5ab9be352d07b44e68ad7c1a03eef3a5
|
@ -0,0 +1,789 @@
|
||||
using UnityEngine;
|
||||
using System.Collections;
|
||||
using UnityEngine.Serialization;
|
||||
|
||||
namespace Pathfinding {
|
||||
using Pathfinding.RVO;
|
||||
using Pathfinding.Util;
|
||||
|
||||
/// <summary>
|
||||
/// Base class for AIPath and RichAI.
|
||||
/// This class holds various methods and fields that are common to both AIPath and RichAI.
|
||||
///
|
||||
/// See: <see cref="Pathfinding.AIPath"/>
|
||||
/// See: <see cref="Pathfinding.RichAI"/>
|
||||
/// See: <see cref="Pathfinding.IAstarAI"/> (all movement scripts implement this interface)
|
||||
/// </summary>
|
||||
[RequireComponent(typeof(Seeker))]
|
||||
public abstract class AIBase : VersionedMonoBehaviour {
|
||||
/// <summary>\copydoc Pathfinding::IAstarAI::radius</summary>
|
||||
public float radius = 0.5f;
|
||||
|
||||
/// <summary>\copydoc Pathfinding::IAstarAI::height</summary>
|
||||
public float height = 2;
|
||||
|
||||
/// <summary>
|
||||
/// Determines how often the agent will search for new paths (in seconds).
|
||||
/// The agent will plan a new path to the target every N seconds.
|
||||
///
|
||||
/// If you have fast moving targets or AIs, you might want to set it to a lower value.
|
||||
///
|
||||
/// See: <see cref="shouldRecalculatePath"/>
|
||||
/// See: <see cref="SearchPath"/>
|
||||
///
|
||||
/// Deprecated: This has been renamed to <see cref="autoRepath.period"/>.
|
||||
/// See: <see cref="AutoRepathPolicy"/>
|
||||
/// </summary>
|
||||
public float repathRate {
|
||||
get {
|
||||
return this.autoRepath.period;
|
||||
}
|
||||
set {
|
||||
this.autoRepath.period = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// \copydoc Pathfinding::IAstarAI::canSearch
|
||||
/// Deprecated: This has been superseded by <see cref="autoRepath.mode"/>.
|
||||
/// </summary>
|
||||
public bool canSearch {
|
||||
get {
|
||||
return this.autoRepath.mode != AutoRepathPolicy.Mode.Never;
|
||||
}
|
||||
set {
|
||||
if (value) {
|
||||
if (this.autoRepath.mode == AutoRepathPolicy.Mode.Never) {
|
||||
this.autoRepath.mode = AutoRepathPolicy.Mode.EveryNSeconds;
|
||||
}
|
||||
} else {
|
||||
this.autoRepath.mode = AutoRepathPolicy.Mode.Never;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>\copydoc Pathfinding::IAstarAI::canMove</summary>
|
||||
public bool canMove = true;
|
||||
|
||||
/// <summary>Max speed in world units per second</summary>
|
||||
[UnityEngine.Serialization.FormerlySerializedAs("speed")]
|
||||
public float maxSpeed = 1;
|
||||
|
||||
/// <summary>
|
||||
/// Gravity to use.
|
||||
/// If set to (NaN,NaN,NaN) then Physics.Gravity (configured in the Unity project settings) will be used.
|
||||
/// If set to (0,0,0) then no gravity will be used and no raycast to check for ground penetration will be performed.
|
||||
/// </summary>
|
||||
public Vector3 gravity = new Vector3(float.NaN, float.NaN, float.NaN);
|
||||
|
||||
/// <summary>
|
||||
/// Layer mask to use for ground placement.
|
||||
/// Make sure this does not include the layer of any colliders attached to this gameobject.
|
||||
///
|
||||
/// See: <see cref="gravity"/>
|
||||
/// See: https://docs.unity3d.com/Manual/Layers.html
|
||||
/// </summary>
|
||||
public LayerMask groundMask = -1;
|
||||
|
||||
/// <summary>
|
||||
/// Offset along the Y coordinate for the ground raycast start position.
|
||||
/// Normally the pivot of the character is at the character's feet, but you usually want to fire the raycast
|
||||
/// from the character's center, so this value should be half of the character's height.
|
||||
///
|
||||
/// A green gizmo line will be drawn upwards from the pivot point of the character to indicate where the raycast will start.
|
||||
///
|
||||
/// See: <see cref="gravity"/>
|
||||
/// Deprecated: Use the <see cref="height"/> property instead (2x this value)
|
||||
/// </summary>
|
||||
[System.Obsolete("Use the height property instead (2x this value)")]
|
||||
public float centerOffset {
|
||||
get { return height * 0.5f; } set { height = value * 2; }
|
||||
}
|
||||
|
||||
[SerializeField]
|
||||
[HideInInspector]
|
||||
[FormerlySerializedAs("centerOffset")]
|
||||
float centerOffsetCompatibility = float.NaN;
|
||||
|
||||
[SerializeField]
|
||||
[HideInInspector]
|
||||
[UnityEngine.Serialization.FormerlySerializedAs("repathRate")]
|
||||
float repathRateCompatibility = float.NaN;
|
||||
|
||||
[SerializeField]
|
||||
[HideInInspector]
|
||||
[UnityEngine.Serialization.FormerlySerializedAs("canSearch")]
|
||||
[UnityEngine.Serialization.FormerlySerializedAs("repeatedlySearchPaths")]
|
||||
bool canSearchCompability = false;
|
||||
|
||||
/// <summary>
|
||||
/// Determines which direction the agent moves in.
|
||||
/// For 3D games you most likely want the ZAxisIsForward option as that is the convention for 3D games.
|
||||
/// For 2D games you most likely want the YAxisIsForward option as that is the convention for 2D games.
|
||||
///
|
||||
/// Using the YAxisForward option will also allow the agent to assume that the movement will happen in the 2D (XY) plane instead of the XZ plane
|
||||
/// if it does not know. This is important only for the point graph which does not have a well defined up direction. The other built-in graphs (e.g the grid graph)
|
||||
/// will all tell the agent which movement plane it is supposed to use.
|
||||
///
|
||||
/// [Open online documentation to see images]
|
||||
/// </summary>
|
||||
[UnityEngine.Serialization.FormerlySerializedAs("rotationIn2D")]
|
||||
public OrientationMode orientation = OrientationMode.ZAxisForward;
|
||||
|
||||
/// <summary>
|
||||
/// If true, the forward axis of the character will be along the Y axis instead of the Z axis.
|
||||
///
|
||||
/// Deprecated: Use <see cref="orientation"/> instead
|
||||
/// </summary>
|
||||
[System.Obsolete("Use orientation instead")]
|
||||
public bool rotationIn2D {
|
||||
get { return orientation == OrientationMode.YAxisForward; }
|
||||
set { orientation = value ? OrientationMode.YAxisForward : OrientationMode.ZAxisForward; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// If true, the AI will rotate to face the movement direction.
|
||||
/// See: <see cref="orientation"/>
|
||||
/// </summary>
|
||||
public bool enableRotation = true;
|
||||
|
||||
/// <summary>
|
||||
/// Position of the agent.
|
||||
/// If <see cref="updatePosition"/> is true then this value will be synchronized every frame with Transform.position.
|
||||
/// </summary>
|
||||
protected Vector3 simulatedPosition;
|
||||
|
||||
/// <summary>
|
||||
/// Rotation of the agent.
|
||||
/// If <see cref="updateRotation"/> is true then this value will be synchronized every frame with Transform.rotation.
|
||||
/// </summary>
|
||||
protected Quaternion simulatedRotation;
|
||||
|
||||
/// <summary>
|
||||
/// Position of the agent.
|
||||
/// In world space.
|
||||
/// If <see cref="updatePosition"/> is true then this value is idential to transform.position.
|
||||
/// See: <see cref="Teleport"/>
|
||||
/// See: <see cref="Move"/>
|
||||
/// </summary>
|
||||
public Vector3 position { get { return updatePosition ? tr.position : simulatedPosition; } }
|
||||
|
||||
/// <summary>
|
||||
/// Rotation of the agent.
|
||||
/// If <see cref="updateRotation"/> is true then this value is identical to transform.rotation.
|
||||
/// </summary>
|
||||
public Quaternion rotation {
|
||||
get { return updateRotation ? tr.rotation : simulatedRotation; }
|
||||
set {
|
||||
if (updateRotation) {
|
||||
tr.rotation = value;
|
||||
} else {
|
||||
simulatedRotation = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Accumulated movement deltas from the <see cref="Move"/> method</summary>
|
||||
Vector3 accumulatedMovementDelta = Vector3.zero;
|
||||
|
||||
/// <summary>
|
||||
/// Current desired velocity of the agent (does not include local avoidance and physics).
|
||||
/// Lies in the movement plane.
|
||||
/// </summary>
|
||||
protected Vector2 velocity2D;
|
||||
|
||||
/// <summary>
|
||||
/// Velocity due to gravity.
|
||||
/// Perpendicular to the movement plane.
|
||||
///
|
||||
/// When the agent is grounded this may not accurately reflect the velocity of the agent.
|
||||
/// It may be non-zero even though the agent is not moving.
|
||||
/// </summary>
|
||||
protected float verticalVelocity;
|
||||
|
||||
/// <summary>Cached Seeker component</summary>
|
||||
protected Seeker seeker;
|
||||
|
||||
/// <summary>Cached Transform component</summary>
|
||||
protected Transform tr;
|
||||
|
||||
/// <summary>Cached Rigidbody component</summary>
|
||||
protected Rigidbody rigid;
|
||||
|
||||
/// <summary>Cached Rigidbody component</summary>
|
||||
protected Rigidbody2D rigid2D;
|
||||
|
||||
/// <summary>Cached CharacterController component</summary>
|
||||
protected CharacterController controller;
|
||||
|
||||
/// <summary>Cached RVOController component</summary>
|
||||
protected RVOController rvoController;
|
||||
|
||||
/// <summary>
|
||||
/// Plane which this agent is moving in.
|
||||
/// This is used to convert between world space and a movement plane to make it possible to use this script in
|
||||
/// both 2D games and 3D games.
|
||||
/// </summary>
|
||||
public IMovementPlane movementPlane = GraphTransform.identityTransform;
|
||||
|
||||
/// <summary>
|
||||
/// Determines if the character's position should be coupled to the Transform's position.
|
||||
/// If false then all movement calculations will happen as usual, but the object that this component is attached to will not move
|
||||
/// instead only the <see cref="position"/> property will change.
|
||||
///
|
||||
/// This is useful if you want to control the movement of the character using some other means such
|
||||
/// as for example root motion but still want the AI to move freely.
|
||||
/// See: Combined with calling <see cref="MovementUpdate"/> from a separate script instead of it being called automatically one can take a similar approach to what is documented here: https://docs.unity3d.com/Manual/nav-CouplingAnimationAndNavigation.html
|
||||
///
|
||||
/// See: <see cref="canMove"/> which in contrast to this field will disable all movement calculations.
|
||||
/// See: <see cref="updateRotation"/>
|
||||
/// </summary>
|
||||
[System.NonSerialized]
|
||||
public bool updatePosition = true;
|
||||
|
||||
/// <summary>
|
||||
/// Determines if the character's rotation should be coupled to the Transform's rotation.
|
||||
/// If false then all movement calculations will happen as usual, but the object that this component is attached to will not rotate
|
||||
/// instead only the <see cref="rotation"/> property will change.
|
||||
///
|
||||
/// See: <see cref="updatePosition"/>
|
||||
/// </summary>
|
||||
[System.NonSerialized]
|
||||
public bool updateRotation = true;
|
||||
|
||||
/// <summary>
|
||||
/// Determines how the agent recalculates its path automatically.
|
||||
/// This corresponds to the settings under the "Recalculate Paths Automatically" field in the inspector.
|
||||
/// </summary>
|
||||
public AutoRepathPolicy autoRepath = new AutoRepathPolicy();
|
||||
|
||||
/// <summary>Indicates if gravity is used during this frame</summary>
|
||||
protected bool usingGravity { get; set; }
|
||||
|
||||
/// <summary>Delta time used for movement during the last frame</summary>
|
||||
protected float lastDeltaTime;
|
||||
|
||||
/// <summary>Last frame index when <see cref="prevPosition1"/> was updated</summary>
|
||||
protected int prevFrame;
|
||||
|
||||
/// <summary>Position of the character at the end of the last frame</summary>
|
||||
protected Vector3 prevPosition1;
|
||||
|
||||
/// <summary>Position of the character at the end of the frame before the last frame</summary>
|
||||
protected Vector3 prevPosition2;
|
||||
|
||||
/// <summary>Amount which the character wants or tried to move with during the last frame</summary>
|
||||
protected Vector2 lastDeltaPosition;
|
||||
|
||||
/// <summary>Only when the previous path has been calculated should the script consider searching for a new path</summary>
|
||||
protected bool waitingForPathCalculation = false;
|
||||
|
||||
[UnityEngine.Serialization.FormerlySerializedAs("target")][SerializeField][HideInInspector]
|
||||
Transform targetCompatibility;
|
||||
|
||||
/// <summary>
|
||||
/// True if the Start method has been executed.
|
||||
/// Used to test if coroutines should be started in OnEnable to prevent calculating paths
|
||||
/// in the awake stage (or rather before start on frame 0).
|
||||
/// </summary>
|
||||
bool startHasRun = false;
|
||||
|
||||
/// <summary>
|
||||
/// Target to move towards.
|
||||
/// The AI will try to follow/move towards this target.
|
||||
/// It can be a point on the ground where the player has clicked in an RTS for example, or it can be the player object in a zombie game.
|
||||
///
|
||||
/// Deprecated: In 4.1 this will automatically add a <see cref="Pathfinding.AIDestinationSetter"/> component and set the target on that component.
|
||||
/// Try instead to use the <see cref="destination"/> property which does not require a transform to be created as the target or use
|
||||
/// the AIDestinationSetter component directly.
|
||||
/// </summary>
|
||||
[System.Obsolete("Use the destination property or the AIDestinationSetter component instead")]
|
||||
public Transform target {
|
||||
get {
|
||||
var setter = GetComponent<AIDestinationSetter>();
|
||||
return setter != null ? setter.target : null;
|
||||
}
|
||||
set {
|
||||
targetCompatibility = null;
|
||||
var setter = GetComponent<AIDestinationSetter>();
|
||||
if (setter == null) setter = gameObject.AddComponent<AIDestinationSetter>();
|
||||
setter.target = value;
|
||||
destination = value != null ? value.position : new Vector3(float.PositiveInfinity, float.PositiveInfinity, float.PositiveInfinity);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>\copydoc Pathfinding::IAstarAI::destination</summary>
|
||||
public Vector3 destination { get; set; }
|
||||
|
||||
/// <summary>\copydoc Pathfinding::IAstarAI::velocity</summary>
|
||||
public Vector3 velocity {
|
||||
get {
|
||||
return lastDeltaTime > 0.000001f ? (prevPosition1 - prevPosition2) / lastDeltaTime : Vector3.zero;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>\copydoc Pathfinding::IAstarAI::desiredVelocity</summary>
|
||||
public Vector3 desiredVelocity {
|
||||
get { return lastDeltaTime > 0.00001f ? movementPlane.ToWorld(lastDeltaPosition / lastDeltaTime, verticalVelocity) : Vector3.zero; }
|
||||
}
|
||||
|
||||
/// <summary>\copydoc Pathfinding::IAstarAI::endOfPath</summary>
|
||||
public abstract Vector3 endOfPath { get; }
|
||||
|
||||
/// <summary>\copydoc Pathfinding::IAstarAI::isStopped</summary>
|
||||
public bool isStopped { get; set; }
|
||||
|
||||
/// <summary>\copydoc Pathfinding::IAstarAI::onSearchPath</summary>
|
||||
public System.Action onSearchPath { get; set; }
|
||||
|
||||
/// <summary>True if the path should be automatically recalculated as soon as possible</summary>
|
||||
protected virtual bool shouldRecalculatePath {
|
||||
get {
|
||||
return !waitingForPathCalculation && autoRepath.ShouldRecalculatePath(position, radius, destination);
|
||||
}
|
||||
}
|
||||
|
||||
protected AIBase () {
|
||||
// Note that this needs to be set here in the constructor and not in e.g Awake
|
||||
// because it is possible that other code runs and sets the destination property
|
||||
// before the Awake method on this script runs.
|
||||
destination = new Vector3(float.PositiveInfinity, float.PositiveInfinity, float.PositiveInfinity);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks for any attached components like RVOController and CharacterController etc.
|
||||
///
|
||||
/// This is done during <see cref="OnEnable"/>. If you are adding/removing components during runtime you may want to call this function
|
||||
/// to make sure that this script finds them. It is unfortunately prohibitive from a performance standpoint to look for components every frame.
|
||||
/// </summary>
|
||||
public virtual void FindComponents () {
|
||||
tr = transform;
|
||||
seeker = GetComponent<Seeker>();
|
||||
rvoController = GetComponent<RVOController>();
|
||||
// Find attached movement components
|
||||
controller = GetComponent<CharacterController>();
|
||||
rigid = GetComponent<Rigidbody>();
|
||||
rigid2D = GetComponent<Rigidbody2D>();
|
||||
}
|
||||
|
||||
/// <summary>Called when the component is enabled</summary>
|
||||
protected virtual void OnEnable () {
|
||||
FindComponents();
|
||||
// Make sure we receive callbacks when paths are calculated
|
||||
seeker.pathCallback += OnPathComplete;
|
||||
Init();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Starts searching for paths.
|
||||
/// If you override this method you should in most cases call base.Start () at the start of it.
|
||||
/// See: <see cref="Init"/>
|
||||
/// </summary>
|
||||
protected virtual void Start () {
|
||||
startHasRun = true;
|
||||
Init();
|
||||
}
|
||||
|
||||
void Init () {
|
||||
if (startHasRun) {
|
||||
// Clamp the agent to the navmesh (which is what the Teleport call will do essentially. Though only some movement scripts require this, like RichAI).
|
||||
// The Teleport call will also make sure some variables are properly initialized (like #prevPosition1 and #prevPosition2)
|
||||
if (canMove) Teleport(position, false);
|
||||
autoRepath.Reset();
|
||||
if (shouldRecalculatePath) SearchPath();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>\copydoc Pathfinding::IAstarAI::Teleport</summary>
|
||||
public virtual void Teleport (Vector3 newPosition, bool clearPath = true) {
|
||||
if (clearPath) ClearPath();
|
||||
prevPosition1 = prevPosition2 = simulatedPosition = newPosition;
|
||||
if (updatePosition) tr.position = newPosition;
|
||||
if (rvoController != null) rvoController.Move(Vector3.zero);
|
||||
if (clearPath) SearchPath();
|
||||
}
|
||||
|
||||
protected void CancelCurrentPathRequest () {
|
||||
waitingForPathCalculation = false;
|
||||
// Abort calculation of the current path
|
||||
if (seeker != null) seeker.CancelCurrentPathRequest();
|
||||
}
|
||||
|
||||
protected virtual void OnDisable () {
|
||||
ClearPath();
|
||||
|
||||
// Make sure we no longer receive callbacks when paths complete
|
||||
seeker.pathCallback -= OnPathComplete;
|
||||
|
||||
velocity2D = Vector3.zero;
|
||||
accumulatedMovementDelta = Vector3.zero;
|
||||
verticalVelocity = 0f;
|
||||
lastDeltaTime = 0;
|
||||
}
|
||||
|
||||
public override void OnSyncUpdate(int dt, JNFrameInfo frame, Object input)
|
||||
{
|
||||
if (shouldRecalculatePath) SearchPath();
|
||||
|
||||
// If gravity is used depends on a lot of things.
|
||||
// For example when a non-kinematic rigidbody is used then the rigidbody will apply the gravity itself
|
||||
// Note that the gravity can contain NaN's, which is why the comparison uses !(a==b) instead of just a!=b.
|
||||
usingGravity = !(gravity == Vector3.zero) && (!updatePosition || ((rigid == null || rigid.isKinematic) && (rigid2D == null || rigid2D.isKinematic)));
|
||||
if (rigid == null && rigid2D == null && canMove) {
|
||||
Vector3 nextPosition;
|
||||
Quaternion nextRotation;
|
||||
MovementUpdate(GetSync().Time.deltaTime, out nextPosition, out nextRotation);
|
||||
FinalizeMovement(nextPosition, nextRotation);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Called every physics update.
|
||||
/// If rigidbodies are used then all movement happens here.
|
||||
/// </summary>
|
||||
protected virtual void FixedUpdate () {
|
||||
if (!(rigid == null && rigid2D == null) && canMove) {
|
||||
Vector3 nextPosition;
|
||||
Quaternion nextRotation;
|
||||
MovementUpdate(GetSync().Time.fixedDeltaTime, out nextPosition, out nextRotation);
|
||||
FinalizeMovement(nextPosition, nextRotation);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>\copydoc Pathfinding::IAstarAI::MovementUpdate</summary>
|
||||
public void MovementUpdate (float deltaTime, out Vector3 nextPosition, out Quaternion nextRotation) {
|
||||
lastDeltaTime = deltaTime;
|
||||
MovementUpdateInternal(deltaTime, out nextPosition, out nextRotation);
|
||||
}
|
||||
|
||||
/// <summary>Called during either Update or FixedUpdate depending on if rigidbodies are used for movement or not</summary>
|
||||
protected abstract void MovementUpdateInternal(float deltaTime, out Vector3 nextPosition, out Quaternion nextRotation);
|
||||
|
||||
/// <summary>
|
||||
/// Outputs the start point and end point of the next automatic path request.
|
||||
/// This is a separate method to make it easy for subclasses to swap out the endpoints
|
||||
/// of path requests. For example the <see cref="LocalSpaceRichAI"/> script which requires the endpoints
|
||||
/// to be transformed to graph space first.
|
||||
/// </summary>
|
||||
protected virtual void CalculatePathRequestEndpoints (out Vector3 start, out Vector3 end) {
|
||||
start = GetFeetPosition();
|
||||
end = destination;
|
||||
}
|
||||
|
||||
/// <summary>\copydoc Pathfinding::IAstarAI::SearchPath</summary>
|
||||
public virtual void SearchPath () {
|
||||
if (float.IsPositiveInfinity(destination.x)) return;
|
||||
if (onSearchPath != null) onSearchPath();
|
||||
|
||||
Vector3 start, end;
|
||||
CalculatePathRequestEndpoints(out start, out end);
|
||||
|
||||
// Request a path to be calculated from our current position to the destination
|
||||
ABPath p = ABPath.Construct(start, end, null);
|
||||
SetPath(p, false);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Position of the base of the character.
|
||||
/// This is used for pathfinding as the character's pivot point is sometimes placed
|
||||
/// at the center of the character instead of near the feet. In a building with multiple floors
|
||||
/// the center of a character may in some scenarios be closer to the navmesh on the floor above
|
||||
/// than to the floor below which could cause an incorrect path to be calculated.
|
||||
/// To solve this the start point of the requested paths is always at the base of the character.
|
||||
/// </summary>
|
||||
public virtual Vector3 GetFeetPosition () {
|
||||
return position;
|
||||
}
|
||||
|
||||
/// <summary>Called when a requested path has been calculated</summary>
|
||||
protected abstract void OnPathComplete(Path newPath);
|
||||
|
||||
/// <summary>
|
||||
/// Clears the current path of the agent.
|
||||
///
|
||||
/// Usually invoked using <see cref="SetPath(null)"/>
|
||||
///
|
||||
/// See: <see cref="SetPath"/>
|
||||
/// See: <see cref="isStopped"/>
|
||||
/// </summary>
|
||||
protected abstract void ClearPath();
|
||||
|
||||
/// <summary>\copydoc Pathfinding::IAstarAI::SetPath</summary>
|
||||
public void SetPath (Path path, bool updateDestinationFromPath = true) {
|
||||
if (updateDestinationFromPath && path is ABPath abPath && !(path is RandomPath)) {
|
||||
this.destination = abPath.originalEndPoint;
|
||||
}
|
||||
|
||||
if (path == null) {
|
||||
CancelCurrentPathRequest();
|
||||
ClearPath();
|
||||
} else if (path.PipelineState == PathState.Created) {
|
||||
// Path has not started calculation yet
|
||||
waitingForPathCalculation = true;
|
||||
seeker.CancelCurrentPathRequest();
|
||||
seeker.StartPath(path);
|
||||
autoRepath.DidRecalculatePath(destination);
|
||||
} else if (path.PipelineState >= PathState.Returning) {
|
||||
// Path has already been calculated
|
||||
|
||||
// We might be calculating another path at the same time, and we don't want that path to override this one. So cancel it.
|
||||
if (seeker.GetCurrentPath() != path) seeker.CancelCurrentPathRequest();
|
||||
else throw new System.ArgumentException("If you calculate the path using seeker.StartPath then this script will pick up the calculated path anyway as it listens for all paths the Seeker finishes calculating. You should not call SetPath in that case.");
|
||||
|
||||
OnPathComplete(path);
|
||||
} else {
|
||||
// Path calculation has been started, but it is not yet complete. Cannot really handle this.
|
||||
throw new System.ArgumentException("You must call the SetPath method with a path that either has been completely calculated or one whose path calculation has not been started at all. It looks like the path calculation for the path you tried to use has been started, but is not yet finished.");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Accelerates the agent downwards.
|
||||
/// See: <see cref="verticalVelocity"/>
|
||||
/// See: <see cref="gravity"/>
|
||||
/// </summary>
|
||||
protected void ApplyGravity (float deltaTime) {
|
||||
// Apply gravity
|
||||
if (usingGravity) {
|
||||
float verticalGravity;
|
||||
velocity2D += movementPlane.ToPlane(deltaTime * (float.IsNaN(gravity.x) ? Physics.gravity : gravity), out verticalGravity);
|
||||
verticalVelocity += verticalGravity;
|
||||
} else {
|
||||
verticalVelocity = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Calculates how far to move during a single frame</summary>
|
||||
protected Vector2 CalculateDeltaToMoveThisFrame (Vector2 position, float distanceToEndOfPath, float deltaTime) {
|
||||
if (rvoController != null && rvoController.enabled) {
|
||||
// Use RVOController to get a processed delta position
|
||||
// such that collisions will be avoided if possible
|
||||
return movementPlane.ToPlane(rvoController.CalculateMovementDelta(movementPlane.ToWorld(position, 0), deltaTime));
|
||||
}
|
||||
// Direction and distance to move during this frame
|
||||
return Vector2.ClampMagnitude(velocity2D * deltaTime, distanceToEndOfPath);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Simulates rotating the agent towards the specified direction and returns the new rotation.
|
||||
///
|
||||
/// Note that this only calculates a new rotation, it does not change the actual rotation of the agent.
|
||||
/// Useful when you are handling movement externally using <see cref="FinalizeMovement"/> but you want to use the built-in rotation code.
|
||||
///
|
||||
/// See: <see cref="orientation"/>
|
||||
/// </summary>
|
||||
/// <param name="direction">Direction in world space to rotate towards.</param>
|
||||
/// <param name="maxDegrees">Maximum number of degrees to rotate this frame.</param>
|
||||
public Quaternion SimulateRotationTowards (Vector3 direction, float maxDegrees) {
|
||||
return SimulateRotationTowards(movementPlane.ToPlane(direction), maxDegrees);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Simulates rotating the agent towards the specified direction and returns the new rotation.
|
||||
///
|
||||
/// Note that this only calculates a new rotation, it does not change the actual rotation of the agent.
|
||||
///
|
||||
/// See: <see cref="orientation"/>
|
||||
/// See: <see cref="movementPlane"/>
|
||||
/// </summary>
|
||||
/// <param name="direction">Direction in the movement plane to rotate towards.</param>
|
||||
/// <param name="maxDegrees">Maximum number of degrees to rotate this frame.</param>
|
||||
protected Quaternion SimulateRotationTowards (Vector2 direction, float maxDegrees) {
|
||||
if (direction != Vector2.zero) {
|
||||
Quaternion targetRotation = Quaternion.LookRotation(movementPlane.ToWorld(direction, 0), movementPlane.ToWorld(Vector2.zero, 1));
|
||||
// This causes the character to only rotate around the Z axis
|
||||
if (orientation == OrientationMode.YAxisForward) targetRotation *= Quaternion.Euler(90, 0, 0);
|
||||
return Quaternion.RotateTowards(simulatedRotation, targetRotation, maxDegrees);
|
||||
}
|
||||
return simulatedRotation;
|
||||
}
|
||||
|
||||
/// <summary>\copydoc Pathfinding::IAstarAI::Move</summary>
|
||||
public virtual void Move (Vector3 deltaPosition) {
|
||||
accumulatedMovementDelta += deltaPosition;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Moves the agent to a position.
|
||||
///
|
||||
/// This is used if you want to override how the agent moves. For example if you are using
|
||||
/// root motion with Mecanim.
|
||||
///
|
||||
/// This will use a CharacterController, Rigidbody, Rigidbody2D or the Transform component depending on what options
|
||||
/// are available.
|
||||
///
|
||||
/// The agent will be clamped to the navmesh after the movement (if such information is available, generally this is only done by the RichAI component).
|
||||
///
|
||||
/// See: <see cref="MovementUpdate"/> for some example code.
|
||||
/// See: <see cref="controller"/>, <see cref="rigid"/>, <see cref="rigid2D"/>
|
||||
/// </summary>
|
||||
/// <param name="nextPosition">New position of the agent.</param>
|
||||
/// <param name="nextRotation">New rotation of the agent. If #enableRotation is false then this parameter will be ignored.</param>
|
||||
public virtual void FinalizeMovement (Vector3 nextPosition, Quaternion nextRotation) {
|
||||
if (enableRotation) FinalizeRotation(nextRotation);
|
||||
FinalizePosition(nextPosition);
|
||||
}
|
||||
|
||||
void FinalizeRotation (Quaternion nextRotation) {
|
||||
simulatedRotation = nextRotation;
|
||||
if (updateRotation) {
|
||||
if (rigid != null) rigid.MoveRotation(nextRotation);
|
||||
else if (rigid2D != null) rigid2D.MoveRotation(nextRotation.eulerAngles.z);
|
||||
else tr.rotation = nextRotation;
|
||||
}
|
||||
}
|
||||
|
||||
void FinalizePosition (Vector3 nextPosition) {
|
||||
// Use a local variable, it is significantly faster
|
||||
Vector3 currentPosition = simulatedPosition;
|
||||
bool positionDirty1 = false;
|
||||
|
||||
if (controller != null && controller.enabled && updatePosition) {
|
||||
// Use CharacterController
|
||||
// The Transform may not be at #position if it was outside the navmesh and had to be moved to the closest valid position
|
||||
tr.position = currentPosition;
|
||||
controller.Move((nextPosition - currentPosition) + accumulatedMovementDelta);
|
||||
// Grab the position after the movement to be able to take physics into account
|
||||
// TODO: Add this into the clampedPosition calculation below to make RVO better respond to physics
|
||||
currentPosition = tr.position;
|
||||
if (controller.isGrounded) verticalVelocity = 0;
|
||||
} else {
|
||||
// Use Transform, Rigidbody, Rigidbody2D or nothing at all (if updatePosition = false)
|
||||
float lastElevation;
|
||||
movementPlane.ToPlane(currentPosition, out lastElevation);
|
||||
currentPosition = nextPosition + accumulatedMovementDelta;
|
||||
|
||||
// Position the character on the ground
|
||||
if (usingGravity) currentPosition = RaycastPosition(currentPosition, lastElevation);
|
||||
positionDirty1 = true;
|
||||
}
|
||||
|
||||
// Clamp the position to the navmesh after movement is done
|
||||
bool positionDirty2 = false;
|
||||
currentPosition = ClampToNavmesh(currentPosition, out positionDirty2);
|
||||
|
||||
// Assign the final position to the character if we haven't already set it (mostly for performance, setting the position can be slow)
|
||||
if ((positionDirty1 || positionDirty2) && updatePosition) {
|
||||
// Note that rigid.MovePosition may or may not move the character immediately.
|
||||
// Check the Unity documentation for the special cases.
|
||||
if (rigid != null) rigid.MovePosition(currentPosition);
|
||||
else if (rigid2D != null) rigid2D.MovePosition(currentPosition);
|
||||
else tr.position = currentPosition;
|
||||
}
|
||||
|
||||
accumulatedMovementDelta = Vector3.zero;
|
||||
simulatedPosition = currentPosition;
|
||||
UpdateVelocity();
|
||||
}
|
||||
|
||||
protected void UpdateVelocity () {
|
||||
var currentFrame = GetSync().Time.frameCount;
|
||||
|
||||
if (currentFrame != prevFrame) prevPosition2 = prevPosition1;
|
||||
prevPosition1 = position;
|
||||
prevFrame = currentFrame;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Constrains the character's position to lie on the navmesh.
|
||||
/// Not all movement scripts have support for this.
|
||||
///
|
||||
/// Returns: New position of the character that has been clamped to the navmesh.
|
||||
/// </summary>
|
||||
/// <param name="position">Current position of the character.</param>
|
||||
/// <param name="positionChanged">True if the character's position was modified by this method.</param>
|
||||
protected virtual Vector3 ClampToNavmesh (Vector3 position, out bool positionChanged) {
|
||||
positionChanged = false;
|
||||
return position;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks if the character is grounded and prevents ground penetration.
|
||||
///
|
||||
/// Sets <see cref="verticalVelocity"/> to zero if the character is grounded.
|
||||
///
|
||||
/// Returns: The new position of the character.
|
||||
/// </summary>
|
||||
/// <param name="position">Position of the character in the world.</param>
|
||||
/// <param name="lastElevation">Elevation coordinate before the agent was moved. This is along the 'up' axis of the #movementPlane.</param>
|
||||
protected Vector3 RaycastPosition (Vector3 position, float lastElevation) {
|
||||
RaycastHit hit;
|
||||
float elevation;
|
||||
|
||||
movementPlane.ToPlane(position, out elevation);
|
||||
float rayLength = tr.localScale.y * height * 0.5f + Mathf.Max(0, lastElevation-elevation);
|
||||
Vector3 rayOffset = movementPlane.ToWorld(Vector2.zero, rayLength);
|
||||
|
||||
if (Physics.Raycast(position + rayOffset, -rayOffset, out hit, rayLength, groundMask, QueryTriggerInteraction.Ignore)) {
|
||||
// Grounded
|
||||
// Make the vertical velocity fall off exponentially. This is reasonable from a physical standpoint as characters
|
||||
// are not completely stiff and touching the ground will not immediately negate all velocity downwards. The AI will
|
||||
// stop moving completely due to the raycast penetration test but it will still *try* to move downwards. This helps
|
||||
// significantly when moving down along slopes as if the vertical velocity would be set to zero when the character
|
||||
// was grounded it would lead to a kind of 'bouncing' behavior (try it, it's hard to explain). Ideally this should
|
||||
// use a more physically correct formula but this is a good approximation and is much more performant. The constant
|
||||
// '5' in the expression below determines how quickly it converges but high values can lead to too much noise.
|
||||
verticalVelocity *= System.Math.Max(0, 1 - 5 * lastDeltaTime);
|
||||
return hit.point;
|
||||
}
|
||||
return position;
|
||||
}
|
||||
|
||||
protected virtual void OnDrawGizmosSelected () {
|
||||
// When selected in the Unity inspector it's nice to make the component react instantly if
|
||||
// any other components are attached/detached or enabled/disabled.
|
||||
// We don't want to do this normally every frame because that would be expensive.
|
||||
if (Application.isPlaying) FindComponents();
|
||||
}
|
||||
|
||||
public static readonly Color ShapeGizmoColor = new Color(240/255f, 213/255f, 30/255f);
|
||||
|
||||
protected virtual void OnDrawGizmos () {
|
||||
if (!Application.isPlaying || !enabled) FindComponents();
|
||||
|
||||
var color = ShapeGizmoColor;
|
||||
if (rvoController != null && rvoController.locked) color *= 0.5f;
|
||||
if (orientation == OrientationMode.YAxisForward) {
|
||||
Draw.Gizmos.Cylinder(position, Vector3.forward, 0, radius * tr.localScale.x, color);
|
||||
} else {
|
||||
Draw.Gizmos.Cylinder(position, rotation * Vector3.up, tr.localScale.y * height, radius * tr.localScale.x, color);
|
||||
}
|
||||
|
||||
if (!float.IsPositiveInfinity(destination.x) && Application.isPlaying) Draw.Gizmos.CircleXZ(destination, 0.2f, Color.blue);
|
||||
|
||||
autoRepath.DrawGizmos(position, radius);
|
||||
}
|
||||
|
||||
protected override void Reset () {
|
||||
ResetShape();
|
||||
base.Reset();
|
||||
}
|
||||
|
||||
void ResetShape () {
|
||||
var cc = GetComponent<CharacterController>();
|
||||
|
||||
if (cc != null) {
|
||||
radius = cc.radius;
|
||||
height = Mathf.Max(radius*2, cc.height);
|
||||
}
|
||||
}
|
||||
|
||||
protected override int OnUpgradeSerializedData (int version, bool unityThread) {
|
||||
if (unityThread && !float.IsNaN(centerOffsetCompatibility)) {
|
||||
height = centerOffsetCompatibility*2;
|
||||
ResetShape();
|
||||
var rvo = GetComponent<RVOController>();
|
||||
if (rvo != null) radius = rvo.radiusBackingField;
|
||||
centerOffsetCompatibility = float.NaN;
|
||||
}
|
||||
#pragma warning disable 618
|
||||
if (unityThread && targetCompatibility != null) target = targetCompatibility;
|
||||
#pragma warning restore 618
|
||||
if (version <= 3) {
|
||||
repathRate = repathRateCompatibility;
|
||||
canSearch = canSearchCompability;
|
||||
}
|
||||
return 5;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a08f67bbe580e4ddfaebd06363c9cc97
|
||||
timeCreated: 1496932372
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 100
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,727 @@
|
||||
using UnityEngine;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Pathfinding {
|
||||
using Pathfinding.Util;
|
||||
|
||||
/// <summary>
|
||||
/// Linearly interpolating movement script.
|
||||
///
|
||||
/// [Open online documentation to see images]
|
||||
///
|
||||
/// This movement script will follow the path exactly, it uses linear interpolation to move between the waypoints in the path.
|
||||
/// This is desirable for some types of games.
|
||||
/// It also works in 2D.
|
||||
///
|
||||
/// See: You can see an example of this script in action in the example scene called Example15_2D.
|
||||
///
|
||||
/// \section rec Configuration
|
||||
/// \subsection rec-snapped Recommended setup for movement along connections
|
||||
///
|
||||
/// This depends on what type of movement you are aiming for.
|
||||
/// If you are aiming for movement where the unit follows the path exactly and move only along the graph connections on a grid/point graph.
|
||||
/// I recommend that you adjust the StartEndModifier on the Seeker component: set the 'Start Point Snapping' field to 'NodeConnection' and the 'End Point Snapping' field to 'SnapToNode'.
|
||||
/// [Open online documentation to see images]
|
||||
/// [Open online documentation to see images]
|
||||
///
|
||||
/// \subsection rec-smooth Recommended setup for smooth movement
|
||||
/// If you on the other hand want smoother movement I recommend setting 'Start Point Snapping' and 'End Point Snapping' to 'ClosestOnNode' and to add the Simple Smooth Modifier to the GameObject as well.
|
||||
/// Alternatively you can use the <see cref="Pathfinding.FunnelModifier Funnel"/> which works better on navmesh/recast graphs or the <see cref="Pathfinding.RaycastModifier"/>.
|
||||
///
|
||||
/// You should not combine the Simple Smooth Modifier or the Funnel Modifier with the NodeConnection snapping mode. This may lead to very odd behavior.
|
||||
///
|
||||
/// [Open online documentation to see images]
|
||||
/// [Open online documentation to see images]
|
||||
/// You may also want to tweak the <see cref="rotationSpeed"/>.
|
||||
/// </summary>
|
||||
[RequireComponent(typeof(Seeker))]
|
||||
[AddComponentMenu("Pathfinding/AI/AILerp (2D,3D)")]
|
||||
[UniqueComponent(tag = "ai")]
|
||||
[HelpURL("https://arongranberg.com/astar/documentation/stable/class_pathfinding_1_1_a_i_lerp.php")]
|
||||
public class AILerp : VersionedMonoBehaviour, IAstarAI {
|
||||
/// <summary>
|
||||
/// Determines how often it will search for new paths.
|
||||
/// If you have fast moving targets or AIs, you might want to set it to a lower value.
|
||||
/// The value is in seconds between path requests.
|
||||
///
|
||||
/// Deprecated: This has been renamed to <see cref="autoRepath.period"/>.
|
||||
/// See: <see cref="AutoRepathPolicy"/>
|
||||
/// </summary>
|
||||
public float repathRate {
|
||||
get {
|
||||
return this.autoRepath.period;
|
||||
}
|
||||
set {
|
||||
this.autoRepath.period = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// \copydoc Pathfinding::IAstarAI::canSearch
|
||||
/// Deprecated: This has been superseded by <see cref="autoRepath.mode"/>.
|
||||
/// </summary>
|
||||
public bool canSearch {
|
||||
get {
|
||||
return this.autoRepath.mode != AutoRepathPolicy.Mode.Never;
|
||||
}
|
||||
set {
|
||||
this.autoRepath.mode = value ? AutoRepathPolicy.Mode.EveryNSeconds : AutoRepathPolicy.Mode.Never;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines how the agent recalculates its path automatically.
|
||||
/// This corresponds to the settings under the "Recalculate Paths Automatically" field in the inspector.
|
||||
/// </summary>
|
||||
public AutoRepathPolicy autoRepath = new AutoRepathPolicy();
|
||||
|
||||
/// <summary>\copydoc Pathfinding::IAstarAI::canMove</summary>
|
||||
public bool canMove = true;
|
||||
|
||||
/// <summary>Speed in world units</summary>
|
||||
public float speed = 3;
|
||||
|
||||
/// <summary>
|
||||
/// Determines which direction the agent moves in.
|
||||
/// For 3D games you most likely want the ZAxisIsForward option as that is the convention for 3D games.
|
||||
/// For 2D games you most likely want the YAxisIsForward option as that is the convention for 2D games.
|
||||
///
|
||||
/// Using the YAxisForward option will also allow the agent to assume that the movement will happen in the 2D (XY) plane instead of the XZ plane
|
||||
/// if it does not know. This is important only for the point graph which does not have a well defined up direction. The other built-in graphs (e.g the grid graph)
|
||||
/// will all tell the agent which movement plane it is supposed to use.
|
||||
///
|
||||
/// [Open online documentation to see images]
|
||||
/// </summary>
|
||||
[UnityEngine.Serialization.FormerlySerializedAs("rotationIn2D")]
|
||||
public OrientationMode orientation = OrientationMode.ZAxisForward;
|
||||
|
||||
/// <summary>
|
||||
/// If true, the forward axis of the character will be along the Y axis instead of the Z axis.
|
||||
///
|
||||
/// Deprecated: Use <see cref="orientation"/> instead
|
||||
/// </summary>
|
||||
[System.Obsolete("Use orientation instead")]
|
||||
public bool rotationIn2D {
|
||||
get { return orientation == OrientationMode.YAxisForward; }
|
||||
set { orientation = value ? OrientationMode.YAxisForward : OrientationMode.ZAxisForward; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// If true, the AI will rotate to face the movement direction.
|
||||
/// See: <see cref="orientation"/>
|
||||
/// </summary>
|
||||
public bool enableRotation = true;
|
||||
|
||||
/// <summary>How quickly to rotate</summary>
|
||||
public float rotationSpeed = 10;
|
||||
|
||||
/// <summary>
|
||||
/// If true, some interpolation will be done when a new path has been calculated.
|
||||
/// This is used to avoid short distance teleportation.
|
||||
/// See: <see cref="switchPathInterpolationSpeed"/>
|
||||
/// </summary>
|
||||
public bool interpolatePathSwitches = true;
|
||||
|
||||
/// <summary>
|
||||
/// How quickly to interpolate to the new path.
|
||||
/// See: <see cref="interpolatePathSwitches"/>
|
||||
/// </summary>
|
||||
public float switchPathInterpolationSpeed = 5;
|
||||
|
||||
/// <summary>True if the end of the current path has been reached</summary>
|
||||
public bool reachedEndOfPath { get; private set; }
|
||||
|
||||
/// <summary>\copydoc Pathfinding::IAstarAI::reachedDestination</summary>
|
||||
public bool reachedDestination {
|
||||
get {
|
||||
if (!reachedEndOfPath || !interpolator.valid) return false;
|
||||
// Note: distanceToSteeringTarget is the distance to the end of the path when approachingPathEndpoint is true
|
||||
var dir = destination - interpolator.endPoint;
|
||||
// Ignore either the y or z coordinate depending on if we are using 2D mode or not
|
||||
if (orientation == OrientationMode.YAxisForward) dir.z = 0;
|
||||
else dir.y = 0;
|
||||
|
||||
// Check against using a very small margin
|
||||
// In theory a check against 0 should be done, but this will be a bit more resilient against targets that move slowly or maybe jitter around due to floating point errors.
|
||||
if (remainingDistance + dir.magnitude >= 0.05f) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
public Vector3 destination { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Determines if the character's position should be coupled to the Transform's position.
|
||||
/// If false then all movement calculations will happen as usual, but the object that this component is attached to will not move
|
||||
/// instead only the <see cref="position"/> property will change.
|
||||
///
|
||||
/// See: <see cref="canMove"/> which in contrast to this field will disable all movement calculations.
|
||||
/// See: <see cref="updateRotation"/>
|
||||
/// </summary>
|
||||
[System.NonSerialized]
|
||||
public bool updatePosition = true;
|
||||
|
||||
/// <summary>
|
||||
/// Determines if the character's rotation should be coupled to the Transform's rotation.
|
||||
/// If false then all movement calculations will happen as usual, but the object that this component is attached to will not rotate
|
||||
/// instead only the <see cref="rotation"/> property will change.
|
||||
///
|
||||
/// See: <see cref="updatePosition"/>
|
||||
/// </summary>
|
||||
[System.NonSerialized]
|
||||
public bool updateRotation = true;
|
||||
|
||||
/// <summary>
|
||||
/// Target to move towards.
|
||||
/// The AI will try to follow/move towards this target.
|
||||
/// It can be a point on the ground where the player has clicked in an RTS for example, or it can be the player object in a zombie game.
|
||||
///
|
||||
/// Deprecated: In 4.0 this will automatically add a <see cref="Pathfinding.AIDestinationSetter"/> component and set the target on that component.
|
||||
/// Try instead to use the <see cref="destination"/> property which does not require a transform to be created as the target or use
|
||||
/// the AIDestinationSetter component directly.
|
||||
/// </summary>
|
||||
[System.Obsolete("Use the destination property or the AIDestinationSetter component instead")]
|
||||
public Transform target {
|
||||
get {
|
||||
var setter = GetComponent<AIDestinationSetter>();
|
||||
return setter != null ? setter.target : null;
|
||||
}
|
||||
set {
|
||||
targetCompatibility = null;
|
||||
var setter = GetComponent<AIDestinationSetter>();
|
||||
if (setter == null) setter = gameObject.AddComponent<AIDestinationSetter>();
|
||||
setter.target = value;
|
||||
destination = value != null ? value.position : new Vector3(float.PositiveInfinity, float.PositiveInfinity, float.PositiveInfinity);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>\copydoc Pathfinding::IAstarAI::position</summary>
|
||||
public Vector3 position { get { return updatePosition ? tr.position : simulatedPosition; } }
|
||||
|
||||
/// <summary>\copydoc Pathfinding::IAstarAI::rotation</summary>
|
||||
public Quaternion rotation {
|
||||
get { return updateRotation ? tr.rotation : simulatedRotation; }
|
||||
set {
|
||||
if (updateRotation) {
|
||||
tr.rotation = value;
|
||||
} else {
|
||||
simulatedRotation = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>\copydoc Pathfinding::IAstarAI::endOfPath</summary>
|
||||
public Vector3 endOfPath {
|
||||
get {
|
||||
return interpolator.valid ? interpolator.endPoint : destination;
|
||||
}
|
||||
}
|
||||
|
||||
#region IAstarAI implementation
|
||||
|
||||
/// <summary>\copydoc Pathfinding::IAstarAI::Move</summary>
|
||||
void IAstarAI.Move (Vector3 deltaPosition) {
|
||||
// This script does not know the concept of being away from the path that it is following
|
||||
// so this call will be ignored (as is also mentioned in the documentation).
|
||||
}
|
||||
|
||||
/// <summary>\copydoc Pathfinding::IAstarAI::radius</summary>
|
||||
float IAstarAI.radius { get { return 0; } set {} }
|
||||
|
||||
/// <summary>\copydoc Pathfinding::IAstarAI::height</summary>
|
||||
float IAstarAI.height { get { return 0; } set {} }
|
||||
|
||||
/// <summary>\copydoc Pathfinding::IAstarAI::maxSpeed</summary>
|
||||
float IAstarAI.maxSpeed { get { return speed; } set { speed = value; } }
|
||||
|
||||
/// <summary>\copydoc Pathfinding::IAstarAI::canSearch</summary>
|
||||
bool IAstarAI.canSearch { get { return canSearch; } set { canSearch = value; } }
|
||||
|
||||
/// <summary>\copydoc Pathfinding::IAstarAI::canMove</summary>
|
||||
bool IAstarAI.canMove { get { return canMove; } set { canMove = value; } }
|
||||
|
||||
/// <summary>\copydoc Pathfinding::IAstarAI::velocity</summary>
|
||||
public Vector3 velocity {
|
||||
get {
|
||||
return GetSync().Time.deltaTime > 0.00001f ? (previousPosition1 - previousPosition2) / GetSync().Time.deltaTime : Vector3.zero;
|
||||
}
|
||||
}
|
||||
|
||||
Vector3 IAstarAI.desiredVelocity {
|
||||
get {
|
||||
// The AILerp script sets the position every frame. It does not take into account physics
|
||||
// or other things. So the velocity should always be the same as the desired velocity.
|
||||
return (this as IAstarAI).velocity;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>\copydoc Pathfinding::IAstarAI::steeringTarget</summary>
|
||||
Vector3 IAstarAI.steeringTarget {
|
||||
get {
|
||||
// AILerp doesn't use steering at all, so we will just return a point ahead of the agent in the direction it is moving.
|
||||
return interpolator.valid ? interpolator.position + interpolator.tangent : simulatedPosition;
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
/// <summary>\copydoc Pathfinding::IAstarAI::remainingDistance</summary>
|
||||
public float remainingDistance {
|
||||
get {
|
||||
return Mathf.Max(interpolator.remainingDistance, 0);
|
||||
}
|
||||
set {
|
||||
interpolator.remainingDistance = Mathf.Max(value, 0);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>\copydoc Pathfinding::IAstarAI::hasPath</summary>
|
||||
public bool hasPath {
|
||||
get {
|
||||
return interpolator.valid;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>\copydoc Pathfinding::IAstarAI::pathPending</summary>
|
||||
public bool pathPending {
|
||||
get {
|
||||
return !canSearchAgain;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>\copydoc Pathfinding::IAstarAI::isStopped</summary>
|
||||
public bool isStopped { get; set; }
|
||||
|
||||
/// <summary>\copydoc Pathfinding::IAstarAI::onSearchPath</summary>
|
||||
public System.Action onSearchPath { get; set; }
|
||||
|
||||
/// <summary>Cached Seeker component</summary>
|
||||
protected Seeker seeker;
|
||||
|
||||
/// <summary>Cached Transform component</summary>
|
||||
protected Transform tr;
|
||||
|
||||
/// <summary>Current path which is followed</summary>
|
||||
protected ABPath path;
|
||||
|
||||
/// <summary>Only when the previous path has been returned should a search for a new path be done</summary>
|
||||
protected bool canSearchAgain = true;
|
||||
|
||||
/// <summary>
|
||||
/// When a new path was returned, the AI was moving along this ray.
|
||||
/// Used to smoothly interpolate between the previous movement and the movement along the new path.
|
||||
/// The speed is equal to movement direction.
|
||||
/// </summary>
|
||||
protected Vector3 previousMovementOrigin;
|
||||
protected Vector3 previousMovementDirection;
|
||||
|
||||
/// <summary>
|
||||
/// Time since the path was replaced by a new path.
|
||||
/// See: <see cref="interpolatePathSwitches"/>
|
||||
/// </summary>
|
||||
protected float pathSwitchInterpolationTime = 0;
|
||||
|
||||
protected PathInterpolator interpolator = new PathInterpolator();
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Holds if the Start function has been run.
|
||||
/// Used to test if coroutines should be started in OnEnable to prevent calculating paths
|
||||
/// in the awake stage (or rather before start on frame 0).
|
||||
/// </summary>
|
||||
bool startHasRun = false;
|
||||
|
||||
Vector3 previousPosition1, previousPosition2, simulatedPosition;
|
||||
Quaternion simulatedRotation;
|
||||
|
||||
/// <summary>Required for serialization backward compatibility</summary>
|
||||
[UnityEngine.Serialization.FormerlySerializedAs("target")][SerializeField][HideInInspector]
|
||||
Transform targetCompatibility;
|
||||
|
||||
[SerializeField]
|
||||
[HideInInspector]
|
||||
[UnityEngine.Serialization.FormerlySerializedAs("repathRate")]
|
||||
float repathRateCompatibility = float.NaN;
|
||||
|
||||
[SerializeField]
|
||||
[HideInInspector]
|
||||
[UnityEngine.Serialization.FormerlySerializedAs("canSearch")]
|
||||
bool canSearchCompability = false;
|
||||
|
||||
protected AILerp () {
|
||||
// Note that this needs to be set here in the constructor and not in e.g Awake
|
||||
// because it is possible that other code runs and sets the destination property
|
||||
// before the Awake method on this script runs.
|
||||
destination = new Vector3(float.PositiveInfinity, float.PositiveInfinity, float.PositiveInfinity);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Initializes reference variables.
|
||||
/// If you override this function you should in most cases call base.Awake () at the start of it.
|
||||
/// </summary>
|
||||
public override void OnSyncLoad()
|
||||
{
|
||||
base.OnSyncLoad();
|
||||
//This is a simple optimization, cache the transform component lookup
|
||||
tr = transform;
|
||||
|
||||
seeker = GetComponent<Seeker>();
|
||||
|
||||
// Tell the StartEndModifier to ask for our exact position when post processing the path This
|
||||
// is important if we are using prediction and requesting a path from some point slightly ahead
|
||||
// of us since then the start point in the path request may be far from our position when the
|
||||
// path has been calculated. This is also good because if a long path is requested, it may take
|
||||
// a few frames for it to be calculated so we could have moved some distance during that time
|
||||
seeker.startEndModifier.adjustStartPoint = () => simulatedPosition;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Starts searching for paths.
|
||||
/// If you override this function you should in most cases call base.Start () at the start of it.
|
||||
/// See: <see cref="Init"/>
|
||||
/// See: <see cref="RepeatTrySearchPath"/>
|
||||
/// </summary>
|
||||
protected virtual void Start () {
|
||||
startHasRun = true;
|
||||
Init();
|
||||
}
|
||||
|
||||
/// <summary>Called when the component is enabled</summary>
|
||||
protected virtual void OnEnable () {
|
||||
// Make sure we receive callbacks when paths complete
|
||||
seeker.pathCallback += OnPathComplete;
|
||||
Init();
|
||||
}
|
||||
|
||||
void Init () {
|
||||
if (startHasRun) {
|
||||
// The Teleport call will make sure some variables are properly initialized (like #prevPosition1 and #prevPosition2)
|
||||
Teleport(position, false);
|
||||
autoRepath.Reset();
|
||||
if (shouldRecalculatePath) SearchPath();
|
||||
}
|
||||
}
|
||||
|
||||
public void OnDisable () {
|
||||
ClearPath();
|
||||
// Make sure we no longer receive callbacks when paths complete
|
||||
seeker.pathCallback -= OnPathComplete;
|
||||
}
|
||||
|
||||
/// <summary>\copydoc Pathfinding::IAstarAI::GetRemainingPath</summary>
|
||||
public void GetRemainingPath (List<Vector3> buffer, out bool stale) {
|
||||
buffer.Clear();
|
||||
if (!interpolator.valid) {
|
||||
buffer.Add(position);
|
||||
stale = true;
|
||||
return;
|
||||
}
|
||||
|
||||
stale = false;
|
||||
interpolator.GetRemainingPath(buffer);
|
||||
// The agent is almost always at interpolation.position (which is buffer[0])
|
||||
// but sometimes - in particular when interpolating between two paths - the agent might at a slightly different position.
|
||||
// So we replace the first point with the actual position of the agent.
|
||||
buffer[0] = position;
|
||||
}
|
||||
|
||||
public void Teleport (Vector3 position, bool clearPath = true) {
|
||||
if (clearPath) ClearPath();
|
||||
simulatedPosition = previousPosition1 = previousPosition2 = position;
|
||||
if (updatePosition) tr.position = position;
|
||||
reachedEndOfPath = false;
|
||||
if (clearPath) SearchPath();
|
||||
}
|
||||
|
||||
/// <summary>True if the path should be automatically recalculated as soon as possible</summary>
|
||||
protected virtual bool shouldRecalculatePath {
|
||||
get {
|
||||
return canSearchAgain && autoRepath.ShouldRecalculatePath(position, 0.0f, destination);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Requests a path to the target.
|
||||
/// Deprecated: Use <see cref="SearchPath"/> instead.
|
||||
/// </summary>
|
||||
[System.Obsolete("Use SearchPath instead")]
|
||||
public virtual void ForceSearchPath () {
|
||||
SearchPath();
|
||||
}
|
||||
|
||||
/// <summary>Requests a path to the target.</summary>
|
||||
public virtual void SearchPath () {
|
||||
if (float.IsPositiveInfinity(destination.x)) return;
|
||||
if (onSearchPath != null) onSearchPath();
|
||||
|
||||
// This is where the path should start to search from
|
||||
var currentPosition = GetFeetPosition();
|
||||
|
||||
// If we are following a path, start searching from the node we will
|
||||
// reach next this can prevent odd turns right at the start of the path
|
||||
/*if (interpolator.valid) {
|
||||
var prevDist = interpolator.distance;
|
||||
// Move to the end of the current segment
|
||||
interpolator.MoveToSegment(interpolator.segmentIndex, 1);
|
||||
currentPosition = interpolator.position;
|
||||
// Move back to the original position
|
||||
interpolator.distance = prevDist;
|
||||
}*/
|
||||
|
||||
canSearchAgain = false;
|
||||
|
||||
// Create a new path request
|
||||
// The OnPathComplete method will later be called with the result
|
||||
SetPath(ABPath.Construct(currentPosition, destination, null), false);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The end of the path has been reached.
|
||||
/// If you want custom logic for when the AI has reached it's destination
|
||||
/// add it here.
|
||||
/// You can also create a new script which inherits from this one
|
||||
/// and override the function in that script.
|
||||
///
|
||||
/// Deprecated: Avoid overriding this method. Instead poll the <see cref="reachedDestination"/> or <see cref="reachedEndOfPath"/> properties.
|
||||
/// </summary>
|
||||
public virtual void OnTargetReached () {
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Called when a requested path has finished calculation.
|
||||
/// A path is first requested by <see cref="SearchPath"/>, it is then calculated, probably in the same or the next frame.
|
||||
/// Finally it is returned to the seeker which forwards it to this function.
|
||||
/// </summary>
|
||||
protected virtual void OnPathComplete (Path _p) {
|
||||
ABPath p = _p as ABPath;
|
||||
|
||||
if (p == null) throw new System.Exception("This function only handles ABPaths, do not use special path types");
|
||||
|
||||
canSearchAgain = true;
|
||||
|
||||
// Increase the reference count on the path.
|
||||
// This is used for path pooling
|
||||
p.Claim(this);
|
||||
|
||||
// Path couldn't be calculated of some reason.
|
||||
// More info in p.errorLog (debug string)
|
||||
if (p.error) {
|
||||
p.Release(this);
|
||||
return;
|
||||
}
|
||||
|
||||
if (interpolatePathSwitches) {
|
||||
ConfigurePathSwitchInterpolation();
|
||||
}
|
||||
|
||||
|
||||
// Replace the old path
|
||||
var oldPath = path;
|
||||
path = p;
|
||||
reachedEndOfPath = false;
|
||||
|
||||
// The RandomPath and MultiTargetPath do not have a well defined destination that could have been
|
||||
// set before the paths were calculated. So we instead set the destination here so that some properties
|
||||
// like #reachedDestination and #remainingDistance work correctly.
|
||||
if (path is RandomPath rpath) {
|
||||
destination = rpath.originalEndPoint;
|
||||
} else if (path is MultiTargetPath mpath) {
|
||||
destination = mpath.originalEndPoint;
|
||||
}
|
||||
|
||||
// Just for the rest of the code to work, if there
|
||||
// is only one waypoint in the path add another one
|
||||
if (path.vectorPath != null && path.vectorPath.Count == 1) {
|
||||
path.vectorPath.Insert(0, GetFeetPosition());
|
||||
}
|
||||
|
||||
// Reset some variables
|
||||
ConfigureNewPath();
|
||||
|
||||
// Release the previous path
|
||||
// This is used for path pooling.
|
||||
// This is done after the interpolator has been configured in the ConfigureNewPath method
|
||||
// as this method would otherwise invalidate the interpolator
|
||||
// since the vectorPath list (which the interpolator uses) will be pooled.
|
||||
if (oldPath != null) oldPath.Release(this);
|
||||
|
||||
if (interpolator.remainingDistance < 0.0001f && !reachedEndOfPath) {
|
||||
reachedEndOfPath = true;
|
||||
OnTargetReached();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Clears the current path of the agent.
|
||||
///
|
||||
/// Usually invoked using <see cref="SetPath(null)"/>
|
||||
///
|
||||
/// See: <see cref="SetPath"/>
|
||||
/// See: <see cref="isStopped"/>
|
||||
/// </summary>
|
||||
protected virtual void ClearPath () {
|
||||
// Abort any calculations in progress
|
||||
if (seeker != null) seeker.CancelCurrentPathRequest();
|
||||
canSearchAgain = true;
|
||||
reachedEndOfPath = false;
|
||||
|
||||
// Release current path so that it can be pooled
|
||||
if (path != null) path.Release(this);
|
||||
path = null;
|
||||
interpolator.SetPath(null);
|
||||
}
|
||||
|
||||
/// <summary>\copydoc Pathfinding::IAstarAI::SetPath</summary>
|
||||
public void SetPath (Path path, bool updateDestinationFromPath = true) {
|
||||
if (updateDestinationFromPath && path is ABPath abPath && !(path is RandomPath)) {
|
||||
this.destination = abPath.originalEndPoint;
|
||||
}
|
||||
|
||||
if (path == null) {
|
||||
ClearPath();
|
||||
} else if (path.PipelineState == PathState.Created) {
|
||||
// Path has not started calculation yet
|
||||
canSearchAgain = false;
|
||||
seeker.CancelCurrentPathRequest();
|
||||
seeker.StartPath(path);
|
||||
autoRepath.DidRecalculatePath(destination);
|
||||
} else if (path.PipelineState >= PathState.Returning) {
|
||||
// Path has already been calculated
|
||||
|
||||
// We might be calculating another path at the same time, and we don't want that path to override this one. So cancel it.
|
||||
if (seeker.GetCurrentPath() != path) seeker.CancelCurrentPathRequest();
|
||||
else throw new System.ArgumentException("If you calculate the path using seeker.StartPath then this script will pick up the calculated path anyway as it listens for all paths the Seeker finishes calculating. You should not call SetPath in that case.");
|
||||
|
||||
OnPathComplete(path);
|
||||
} else {
|
||||
// Path calculation has been started, but it is not yet complete. Cannot really handle this.
|
||||
throw new System.ArgumentException("You must call the SetPath method with a path that either has been completely calculated or one whose path calculation has not been started at all. It looks like the path calculation for the path you tried to use has been started, but is not yet finished.");
|
||||
}
|
||||
}
|
||||
|
||||
protected virtual void ConfigurePathSwitchInterpolation () {
|
||||
bool reachedEndOfPreviousPath = interpolator.valid && interpolator.remainingDistance < 0.0001f;
|
||||
|
||||
if (interpolator.valid && !reachedEndOfPreviousPath) {
|
||||
previousMovementOrigin = interpolator.position;
|
||||
previousMovementDirection = interpolator.tangent.normalized * interpolator.remainingDistance;
|
||||
pathSwitchInterpolationTime = 0;
|
||||
} else {
|
||||
previousMovementOrigin = Vector3.zero;
|
||||
previousMovementDirection = Vector3.zero;
|
||||
pathSwitchInterpolationTime = float.PositiveInfinity;
|
||||
}
|
||||
}
|
||||
|
||||
public virtual Vector3 GetFeetPosition () {
|
||||
return position;
|
||||
}
|
||||
|
||||
/// <summary>Finds the closest point on the current path and configures the <see cref="interpolator"/></summary>
|
||||
protected virtual void ConfigureNewPath () {
|
||||
var hadValidPath = interpolator.valid;
|
||||
var prevTangent = hadValidPath ? interpolator.tangent : Vector3.zero;
|
||||
|
||||
interpolator.SetPath(path.vectorPath);
|
||||
interpolator.MoveToClosestPoint(GetFeetPosition());
|
||||
|
||||
if (interpolatePathSwitches && switchPathInterpolationSpeed > 0.01f && hadValidPath) {
|
||||
var correctionFactor = Mathf.Max(-Vector3.Dot(prevTangent.normalized, interpolator.tangent.normalized), 0);
|
||||
interpolator.distance -= speed*correctionFactor*(1f/switchPathInterpolationSpeed);
|
||||
}
|
||||
}
|
||||
|
||||
protected virtual void Update () {
|
||||
if (shouldRecalculatePath) SearchPath();
|
||||
if (canMove) {
|
||||
Vector3 nextPosition;
|
||||
Quaternion nextRotation;
|
||||
MovementUpdate(GetSync().Time.deltaTime, out nextPosition, out nextRotation);
|
||||
FinalizeMovement(nextPosition, nextRotation);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>\copydoc Pathfinding::IAstarAI::MovementUpdate</summary>
|
||||
public void MovementUpdate (float deltaTime, out Vector3 nextPosition, out Quaternion nextRotation) {
|
||||
if (updatePosition) simulatedPosition = tr.position;
|
||||
if (updateRotation) simulatedRotation = tr.rotation;
|
||||
|
||||
Vector3 direction;
|
||||
|
||||
nextPosition = CalculateNextPosition(out direction, isStopped ? 0f : deltaTime);
|
||||
|
||||
if (enableRotation) nextRotation = SimulateRotationTowards(direction, deltaTime);
|
||||
else nextRotation = simulatedRotation;
|
||||
}
|
||||
|
||||
/// <summary>\copydoc Pathfinding::IAstarAI::FinalizeMovement</summary>
|
||||
public void FinalizeMovement (Vector3 nextPosition, Quaternion nextRotation) {
|
||||
previousPosition2 = previousPosition1;
|
||||
previousPosition1 = simulatedPosition = nextPosition;
|
||||
simulatedRotation = nextRotation;
|
||||
if (updatePosition) tr.position = nextPosition;
|
||||
if (updateRotation) tr.rotation = nextRotation;
|
||||
}
|
||||
|
||||
Quaternion SimulateRotationTowards (Vector3 direction, float deltaTime) {
|
||||
// Rotate unless we are really close to the target
|
||||
if (direction != Vector3.zero) {
|
||||
Quaternion targetRotation = Quaternion.LookRotation(direction, orientation == OrientationMode.YAxisForward ? Vector3.back : Vector3.up);
|
||||
// This causes the character to only rotate around the Z axis
|
||||
if (orientation == OrientationMode.YAxisForward) targetRotation *= Quaternion.Euler(90, 0, 0);
|
||||
return Quaternion.Slerp(simulatedRotation, targetRotation, deltaTime * rotationSpeed);
|
||||
}
|
||||
return simulatedRotation;
|
||||
}
|
||||
|
||||
/// <summary>Calculate the AI's next position (one frame in the future).</summary>
|
||||
/// <param name="direction">The tangent of the segment the AI is currently traversing. Not normalized.</param>
|
||||
protected virtual Vector3 CalculateNextPosition (out Vector3 direction, float deltaTime) {
|
||||
if (!interpolator.valid) {
|
||||
direction = Vector3.zero;
|
||||
return simulatedPosition;
|
||||
}
|
||||
|
||||
interpolator.distance += deltaTime * speed;
|
||||
|
||||
if (interpolator.remainingDistance < 0.0001f && !reachedEndOfPath) {
|
||||
reachedEndOfPath = true;
|
||||
OnTargetReached();
|
||||
}
|
||||
|
||||
direction = interpolator.tangent;
|
||||
pathSwitchInterpolationTime += deltaTime;
|
||||
var alpha = switchPathInterpolationSpeed * pathSwitchInterpolationTime;
|
||||
if (interpolatePathSwitches && alpha < 1f) {
|
||||
// Find the approximate position we would be at if we
|
||||
// would have continued to follow the previous path
|
||||
Vector3 positionAlongPreviousPath = previousMovementOrigin + Vector3.ClampMagnitude(previousMovementDirection, speed * pathSwitchInterpolationTime);
|
||||
|
||||
// Interpolate between the position on the current path and the position
|
||||
// we would have had if we would have continued along the previous path.
|
||||
return Vector3.Lerp(positionAlongPreviousPath, interpolator.position, alpha);
|
||||
} else {
|
||||
return interpolator.position;
|
||||
}
|
||||
}
|
||||
|
||||
protected override int OnUpgradeSerializedData (int version, bool unityThread) {
|
||||
#pragma warning disable 618
|
||||
if (unityThread && targetCompatibility != null) target = targetCompatibility;
|
||||
#pragma warning restore 618
|
||||
|
||||
if (version <= 3) {
|
||||
repathRate = repathRateCompatibility;
|
||||
canSearch = canSearchCompability;
|
||||
}
|
||||
return 4;
|
||||
}
|
||||
|
||||
public virtual void OnDrawGizmos () {
|
||||
tr = transform;
|
||||
autoRepath.DrawGizmos(this.position, 0.0f);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 847a14d4dc9cc43679ab34fc78e0182f
|
||||
timeCreated: 1454879612
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,541 @@
|
||||
using UnityEngine;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Pathfinding {
|
||||
using Pathfinding.RVO;
|
||||
using Pathfinding.Util;
|
||||
|
||||
/// <summary>
|
||||
/// AI for following paths.
|
||||
///
|
||||
/// [Open online documentation to see images]
|
||||
///
|
||||
/// This AI is the default movement script which comes with the A* Pathfinding Project.
|
||||
/// It is in no way required by the rest of the system, so feel free to write your own. But I hope this script will make it easier
|
||||
/// to set up movement for the characters in your game.
|
||||
/// This script works well for many types of units, but if you need the highest performance (for example if you are moving hundreds of characters) you
|
||||
/// may want to customize this script or write a custom movement script to be able to optimize it specifically for your game.
|
||||
///
|
||||
/// This script will try to move to a given <see cref="destination"/>. At <see cref="repathRate regular"/>, the path to the destination will be recalculated.
|
||||
/// If you want to make the AI to follow a particular object you can attach the <see cref="Pathfinding.AIDestinationSetter"/> component.
|
||||
/// Take a look at the getstarted (view in online documentation for working links) tutorial for more instructions on how to configure this script.
|
||||
///
|
||||
/// Here is a video of this script being used move an agent around (technically it uses the <see cref="Pathfinding.Examples.MineBotAI"/> script that inherits from this one but adds a bit of animation support for the example scenes):
|
||||
/// [Open online documentation to see videos]
|
||||
///
|
||||
/// \section variables Quick overview of the variables
|
||||
/// In the inspector in Unity, you will see a bunch of variables. You can view detailed information further down, but here's a quick overview.
|
||||
///
|
||||
/// The <see cref="repathRate"/> determines how often it will search for new paths, if you have fast moving targets, you might want to set it to a lower value.
|
||||
/// The <see cref="destination"/> field is where the AI will try to move, it can be a point on the ground where the player has clicked in an RTS for example.
|
||||
/// Or it can be the player object in a zombie game.
|
||||
/// The <see cref="maxSpeed"/> is self-explanatory, as is <see cref="rotationSpeed"/>. however <see cref="slowdownDistance"/> might require some explanation:
|
||||
/// It is the approximate distance from the target where the AI will start to slow down. Setting it to a large value will make the AI slow down very gradually.
|
||||
/// <see cref="pickNextWaypointDist"/> determines the distance to the point the AI will move to (see image below).
|
||||
///
|
||||
/// Below is an image illustrating several variables that are exposed by this class (<see cref="pickNextWaypointDist"/>, <see cref="steeringTarget"/>, <see cref="desiredVelocity)"/>
|
||||
/// [Open online documentation to see images]
|
||||
///
|
||||
/// This script has many movement fallbacks.
|
||||
/// If it finds an RVOController attached to the same GameObject as this component, it will use that. If it finds a character controller it will also use that.
|
||||
/// If it finds a rigidbody it will use that. Lastly it will fall back to simply modifying Transform.position which is guaranteed to always work and is also the most performant option.
|
||||
///
|
||||
/// \section how-aipath-works How it works
|
||||
/// In this section I'm going to go over how this script is structured and how information flows.
|
||||
/// This is useful if you want to make changes to this script or if you just want to understand how it works a bit more deeply.
|
||||
/// However you do not need to read this section if you are just going to use the script as-is.
|
||||
///
|
||||
/// This script inherits from the <see cref="AIBase"/> class. The movement happens either in Unity's standard <see cref="Update"/> or <see cref="FixedUpdate"/> method.
|
||||
/// They are both defined in the AIBase class. Which one is actually used depends on if a rigidbody is used for movement or not.
|
||||
/// Rigidbody movement has to be done inside the FixedUpdate method while otherwise it is better to do it in Update.
|
||||
///
|
||||
/// From there a call is made to the <see cref="MovementUpdate"/> method (which in turn calls <see cref="MovementUpdateInternal)"/>.
|
||||
/// This method contains the main bulk of the code and calculates how the AI *wants* to move. However it doesn't do any movement itself.
|
||||
/// Instead it returns the position and rotation it wants the AI to move to have at the end of the frame.
|
||||
/// The <see cref="Update"/> (or <see cref="FixedUpdate)"/> method then passes these values to the <see cref="FinalizeMovement"/> method which is responsible for actually moving the character.
|
||||
/// That method also handles things like making sure the AI doesn't fall through the ground using raycasting.
|
||||
///
|
||||
/// The AI recalculates its path regularly. This happens in the Update method which checks <see cref="shouldRecalculatePath"/> and if that returns true it will call <see cref="SearchPath"/>.
|
||||
/// The <see cref="SearchPath"/> method will prepare a path request and send it to the <see cref="Pathfinding.Seeker"/> component which should be attached to the same GameObject as this script.
|
||||
/// Since this script will when waking up register to the <see cref="Pathfinding.Seeker.pathCallback"/> delegate this script will be notified every time a new path is calculated by the <see cref="OnPathComplete"/> method being called.
|
||||
/// It may take one or sometimes multiple frames for the path to be calculated, but finally the <see cref="OnPathComplete"/> method will be called and the current path that the AI is following will be replaced.
|
||||
/// </summary>
|
||||
[AddComponentMenu("Pathfinding/AI/AIPath (2D,3D)")]
|
||||
[UniqueComponent(tag = "ai")]
|
||||
public partial class AIPath : AIBase, IAstarAI {
|
||||
/// <summary>
|
||||
/// How quickly the agent accelerates.
|
||||
/// Positive values represent an acceleration in world units per second squared.
|
||||
/// Negative values are interpreted as an inverse time of how long it should take for the agent to reach its max speed.
|
||||
/// For example if it should take roughly 0.4 seconds for the agent to reach its max speed then this field should be set to -1/0.4 = -2.5.
|
||||
/// For a negative value the final acceleration will be: -acceleration*maxSpeed.
|
||||
/// This behaviour exists mostly for compatibility reasons.
|
||||
///
|
||||
/// In the Unity inspector there are two modes: Default and Custom. In the Default mode this field is set to -2.5 which means that it takes about 0.4 seconds for the agent to reach its top speed.
|
||||
/// In the Custom mode you can set the acceleration to any positive value.
|
||||
/// </summary>
|
||||
public float maxAcceleration = -2.5f;
|
||||
|
||||
/// <summary>
|
||||
/// Rotation speed in degrees per second.
|
||||
/// Rotation is calculated using Quaternion.RotateTowards. This variable represents the rotation speed in degrees per second.
|
||||
/// The higher it is, the faster the character will be able to rotate.
|
||||
/// </summary>
|
||||
[UnityEngine.Serialization.FormerlySerializedAs("turningSpeed")]
|
||||
public float rotationSpeed = 360;
|
||||
|
||||
/// <summary>Distance from the end of the path where the AI will start to slow down</summary>
|
||||
public float slowdownDistance = 0.6F;
|
||||
|
||||
/// <summary>
|
||||
/// How far the AI looks ahead along the path to determine the point it moves to.
|
||||
/// In world units.
|
||||
/// If you enable the <see cref="alwaysDrawGizmos"/> toggle this value will be visualized in the scene view as a blue circle around the agent.
|
||||
/// [Open online documentation to see images]
|
||||
///
|
||||
/// Here are a few example videos showing some typical outcomes with good values as well as how it looks when this value is too low and too high.
|
||||
/// <table>
|
||||
/// <tr><td>[Open online documentation to see videos]</td><td>\xmlonly <verbatim><span class="label label-danger">Too low</span><br/></verbatim>\endxmlonly A too low value and a too low acceleration will result in the agent overshooting a lot and not managing to follow the path well.</td></tr>
|
||||
/// <tr><td>[Open online documentation to see videos]</td><td>\xmlonly <verbatim><span class="label label-warning">Ok</span><br/></verbatim>\endxmlonly A low value but a high acceleration works decently to make the AI follow the path more closely. Note that the <see cref="Pathfinding.AILerp"/> component is better suited if you want the agent to follow the path without any deviations.</td></tr>
|
||||
/// <tr><td>[Open online documentation to see videos]</td><td>\xmlonly <verbatim><span class="label label-success">Ok</span><br/></verbatim>\endxmlonly A reasonable value in this example.</td></tr>
|
||||
/// <tr><td>[Open online documentation to see videos]</td><td>\xmlonly <verbatim><span class="label label-success">Ok</span><br/></verbatim>\endxmlonly A reasonable value in this example, but the path is followed slightly more loosely than in the previous video.</td></tr>
|
||||
/// <tr><td>[Open online documentation to see videos]</td><td>\xmlonly <verbatim><span class="label label-danger">Too high</span><br/></verbatim>\endxmlonly A too high value will make the agent follow the path too loosely and may cause it to try to move through obstacles.</td></tr>
|
||||
/// </table>
|
||||
/// </summary>
|
||||
public float pickNextWaypointDist = 2;
|
||||
|
||||
/// <summary>
|
||||
/// Distance to the end point to consider the end of path to be reached.
|
||||
/// When the end is within this distance then <see cref="OnTargetReached"/> will be called and <see cref="reachedEndOfPath"/> will return true.
|
||||
/// </summary>
|
||||
public float endReachedDistance = 0.2F;
|
||||
|
||||
/// <summary>Draws detailed gizmos constantly in the scene view instead of only when the agent is selected and settings are being modified</summary>
|
||||
public bool alwaysDrawGizmos;
|
||||
|
||||
/// <summary>
|
||||
/// Slow down when not facing the target direction.
|
||||
/// Incurs at a small performance overhead.
|
||||
/// </summary>
|
||||
public bool slowWhenNotFacingTarget = true;
|
||||
|
||||
/// <summary>
|
||||
/// What to do when within <see cref="endReachedDistance"/> units from the destination.
|
||||
/// The character can either stop immediately when it comes within that distance, which is useful for e.g archers
|
||||
/// or other ranged units that want to fire on a target. Or the character can continue to try to reach the exact
|
||||
/// destination point and come to a full stop there. This is useful if you want the character to reach the exact
|
||||
/// point that you specified.
|
||||
///
|
||||
/// Note: <see cref="reachedEndOfPath"/> will become true when the character is within <see cref="endReachedDistance"/> units from the destination
|
||||
/// regardless of what this field is set to.
|
||||
/// </summary>
|
||||
public CloseToDestinationMode whenCloseToDestination = CloseToDestinationMode.Stop;
|
||||
|
||||
/// <summary>
|
||||
/// Ensure that the character is always on the traversable surface of the navmesh.
|
||||
/// When this option is enabled a <see cref="AstarPath.GetNearest"/> query will be done every frame to find the closest node that the agent can walk on
|
||||
/// and if the agent is not inside that node, then the agent will be moved to it.
|
||||
///
|
||||
/// This is especially useful together with local avoidance in order to avoid agents pushing each other into walls.
|
||||
/// See: local-avoidance (view in online documentation for working links) for more info about this.
|
||||
///
|
||||
/// This option also integrates with local avoidance so that if the agent is say forced into a wall by other agents the local avoidance
|
||||
/// system will be informed about that wall and can take that into account.
|
||||
///
|
||||
/// Enabling this has some performance impact depending on the graph type (pretty fast for grid graphs, slightly slower for navmesh/recast graphs).
|
||||
/// If you are using a navmesh/recast graph you may want to switch to the <see cref="Pathfinding.RichAI"/> movement script which is specifically written for navmesh/recast graphs and
|
||||
/// does this kind of clamping out of the box. In many cases it can also follow the path more smoothly around sharp bends in the path.
|
||||
///
|
||||
/// It is not recommended that you use this option together with the funnel modifier on grid graphs because the funnel modifier will make the path
|
||||
/// go very close to the border of the graph and this script has a tendency to try to cut corners a bit. This may cause it to try to go slightly outside the
|
||||
/// traversable surface near corners and that will look bad if this option is enabled.
|
||||
///
|
||||
/// Warning: This option makes no sense to use on point graphs because point graphs do not have a surface.
|
||||
/// Enabling this option when using a point graph will lead to the agent being snapped to the closest node every frame which is likely not what you want.
|
||||
///
|
||||
/// Below you can see an image where several agents using local avoidance were ordered to go to the same point in a corner.
|
||||
/// When not constraining the agents to the graph they are easily pushed inside obstacles.
|
||||
/// [Open online documentation to see images]
|
||||
/// </summary>
|
||||
public bool constrainInsideGraph = false;
|
||||
|
||||
/// <summary>Current path which is followed</summary>
|
||||
protected Path path;
|
||||
|
||||
/// <summary>Helper which calculates points along the current path</summary>
|
||||
protected PathInterpolator interpolator = new PathInterpolator();
|
||||
|
||||
#region IAstarAI implementation
|
||||
|
||||
/// <summary>\copydoc Pathfinding::IAstarAI::Teleport</summary>
|
||||
public override void Teleport (Vector3 newPosition, bool clearPath = true) {
|
||||
reachedEndOfPath = false;
|
||||
base.Teleport(newPosition, clearPath);
|
||||
}
|
||||
|
||||
/// <summary>\copydoc Pathfinding::IAstarAI::remainingDistance</summary>
|
||||
public float remainingDistance {
|
||||
get {
|
||||
return interpolator.valid ? interpolator.remainingDistance + movementPlane.ToPlane(interpolator.position - position).magnitude : float.PositiveInfinity;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>\copydoc Pathfinding::IAstarAI::reachedDestination</summary>
|
||||
public bool reachedDestination {
|
||||
get {
|
||||
if (!reachedEndOfPath) return false;
|
||||
if (!interpolator.valid || remainingDistance + movementPlane.ToPlane(destination - interpolator.endPoint).magnitude > endReachedDistance) return false;
|
||||
|
||||
// Don't do height checks in 2D mode
|
||||
if (orientation != OrientationMode.YAxisForward) {
|
||||
// Check if the destination is above the head of the character or far below the feet of it
|
||||
float yDifference;
|
||||
movementPlane.ToPlane(destination - position, out yDifference);
|
||||
var h = tr.localScale.y * height;
|
||||
if (yDifference > h || yDifference < -h*0.5) return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>\copydoc Pathfinding::IAstarAI::reachedEndOfPath</summary>
|
||||
public bool reachedEndOfPath { get; protected set; }
|
||||
|
||||
/// <summary>\copydoc Pathfinding::IAstarAI::hasPath</summary>
|
||||
public bool hasPath {
|
||||
get {
|
||||
return interpolator.valid;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>\copydoc Pathfinding::IAstarAI::pathPending</summary>
|
||||
public bool pathPending {
|
||||
get {
|
||||
return waitingForPathCalculation;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>\copydoc Pathfinding::IAstarAI::steeringTarget</summary>
|
||||
public Vector3 steeringTarget {
|
||||
get {
|
||||
return interpolator.valid ? interpolator.position : position;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>\copydoc Pathfinding::IAstarAI::endOfPath</summary>
|
||||
public override Vector3 endOfPath {
|
||||
get {
|
||||
return interpolator.valid ? interpolator.endPoint : destination;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>\copydoc Pathfinding::IAstarAI::radius</summary>
|
||||
float IAstarAI.radius { get { return radius; } set { radius = value; } }
|
||||
|
||||
/// <summary>\copydoc Pathfinding::IAstarAI::height</summary>
|
||||
float IAstarAI.height { get { return height; } set { height = value; } }
|
||||
|
||||
/// <summary>\copydoc Pathfinding::IAstarAI::maxSpeed</summary>
|
||||
float IAstarAI.maxSpeed { get { return maxSpeed; } set { maxSpeed = value; } }
|
||||
|
||||
/// <summary>\copydoc Pathfinding::IAstarAI::canSearch</summary>
|
||||
bool IAstarAI.canSearch { get { return canSearch; } set { canSearch = value; } }
|
||||
|
||||
/// <summary>\copydoc Pathfinding::IAstarAI::canMove</summary>
|
||||
bool IAstarAI.canMove { get { return canMove; } set { canMove = value; } }
|
||||
|
||||
#endregion
|
||||
|
||||
/// <summary>\copydoc Pathfinding::IAstarAI::GetRemainingPath</summary>
|
||||
public void GetRemainingPath (List<Vector3> buffer, out bool stale) {
|
||||
buffer.Clear();
|
||||
buffer.Add(position);
|
||||
if (!interpolator.valid) {
|
||||
stale = true;
|
||||
return;
|
||||
}
|
||||
|
||||
stale = false;
|
||||
interpolator.GetRemainingPath(buffer);
|
||||
}
|
||||
|
||||
protected override void OnDisable () {
|
||||
base.OnDisable();
|
||||
|
||||
// Release current path so that it can be pooled
|
||||
if (path != null) path.Release(this);
|
||||
path = null;
|
||||
interpolator.SetPath(null);
|
||||
reachedEndOfPath = false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The end of the path has been reached.
|
||||
/// If you want custom logic for when the AI has reached it's destination add it here. You can
|
||||
/// also create a new script which inherits from this one and override the function in that script.
|
||||
///
|
||||
/// This method will be called again if a new path is calculated as the destination may have changed.
|
||||
/// So when the agent is close to the destination this method will typically be called every <see cref="repathRate"/> seconds.
|
||||
///
|
||||
/// Deprecated: Avoid overriding this method. Instead poll the <see cref="reachedDestination"/> or <see cref="reachedEndOfPath"/> properties.
|
||||
/// </summary>
|
||||
public virtual void OnTargetReached () {
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Called when a requested path has been calculated.
|
||||
/// A path is first requested by <see cref="UpdatePath"/>, it is then calculated, probably in the same or the next frame.
|
||||
/// Finally it is returned to the seeker which forwards it to this function.
|
||||
/// </summary>
|
||||
protected override void OnPathComplete (Path newPath) {
|
||||
ABPath p = newPath as ABPath;
|
||||
|
||||
if (p == null) throw new System.Exception("This function only handles ABPaths, do not use special path types");
|
||||
|
||||
waitingForPathCalculation = false;
|
||||
|
||||
// Increase the reference count on the new path.
|
||||
// This is used for object pooling to reduce allocations.
|
||||
p.Claim(this);
|
||||
|
||||
// Path couldn't be calculated of some reason.
|
||||
// More info in p.errorLog (debug string)
|
||||
if (p.error) {
|
||||
p.Release(this);
|
||||
SetPath(null);
|
||||
return;
|
||||
}
|
||||
|
||||
// Release the previous path.
|
||||
if (path != null) path.Release(this);
|
||||
|
||||
// Replace the old path
|
||||
path = p;
|
||||
|
||||
// The RandomPath and MultiTargetPath do not have a well defined destination that could have been
|
||||
// set before the paths were calculated. So we instead set the destination here so that some properties
|
||||
// like #reachedDestination and #remainingDistance work correctly.
|
||||
if (path is RandomPath rpath) {
|
||||
destination = rpath.originalEndPoint;
|
||||
} else if (path is MultiTargetPath mpath) {
|
||||
destination = mpath.originalEndPoint;
|
||||
}
|
||||
|
||||
// Make sure the path contains at least 2 points
|
||||
if (path.vectorPath.Count == 1) path.vectorPath.Add(path.vectorPath[0]);
|
||||
interpolator.SetPath(path.vectorPath);
|
||||
|
||||
var graph = path.path.Count > 0 ? AstarData.GetGraph(path.path[0]) as ITransformedGraph : null;
|
||||
movementPlane = graph != null ? graph.transform : (orientation == OrientationMode.YAxisForward ? new GraphTransform(Matrix4x4.TRS(Vector3.zero, Quaternion.Euler(-90, 270, 90), Vector3.one)) : GraphTransform.identityTransform);
|
||||
|
||||
// Reset some variables
|
||||
reachedEndOfPath = false;
|
||||
|
||||
// Simulate movement from the point where the path was requested
|
||||
// to where we are right now. This reduces the risk that the agent
|
||||
// gets confused because the first point in the path is far away
|
||||
// from the current position (possibly behind it which could cause
|
||||
// the agent to turn around, and that looks pretty bad).
|
||||
interpolator.MoveToLocallyClosestPoint((GetFeetPosition() + p.originalStartPoint) * 0.5f);
|
||||
interpolator.MoveToLocallyClosestPoint(GetFeetPosition());
|
||||
|
||||
// Update which point we are moving towards.
|
||||
// Note that we need to do this here because otherwise the remainingDistance field might be incorrect for 1 frame.
|
||||
// (due to interpolator.remainingDistance being incorrect).
|
||||
interpolator.MoveToCircleIntersection2D(position, pickNextWaypointDist, movementPlane);
|
||||
|
||||
var distanceToEnd = remainingDistance;
|
||||
if (distanceToEnd <= endReachedDistance) {
|
||||
reachedEndOfPath = true;
|
||||
OnTargetReached();
|
||||
}
|
||||
}
|
||||
|
||||
protected override void ClearPath () {
|
||||
CancelCurrentPathRequest();
|
||||
if (path != null) path.Release(this);
|
||||
path = null;
|
||||
interpolator.SetPath(null);
|
||||
reachedEndOfPath = false;
|
||||
}
|
||||
|
||||
/// <summary>Called during either Update or FixedUpdate depending on if rigidbodies are used for movement or not</summary>
|
||||
protected override void MovementUpdateInternal (float deltaTime, out Vector3 nextPosition, out Quaternion nextRotation) {
|
||||
float currentAcceleration = maxAcceleration;
|
||||
|
||||
// If negative, calculate the acceleration from the max speed
|
||||
if (currentAcceleration < 0) currentAcceleration *= -maxSpeed;
|
||||
|
||||
if (updatePosition) {
|
||||
// Get our current position. We read from transform.position as few times as possible as it is relatively slow
|
||||
// (at least compared to a local variable)
|
||||
simulatedPosition = tr.position;
|
||||
}
|
||||
if (updateRotation) simulatedRotation = tr.rotation;
|
||||
|
||||
var currentPosition = simulatedPosition;
|
||||
|
||||
// Update which point we are moving towards
|
||||
interpolator.MoveToCircleIntersection2D(currentPosition, pickNextWaypointDist, movementPlane);
|
||||
var dir = movementPlane.ToPlane(steeringTarget - currentPosition);
|
||||
|
||||
// Calculate the distance to the end of the path
|
||||
float distanceToEnd = dir.magnitude + Mathf.Max(0, interpolator.remainingDistance);
|
||||
|
||||
// Check if we have reached the target
|
||||
var prevTargetReached = reachedEndOfPath;
|
||||
reachedEndOfPath = distanceToEnd <= endReachedDistance && interpolator.valid;
|
||||
if (!prevTargetReached && reachedEndOfPath) OnTargetReached();
|
||||
float slowdown;
|
||||
|
||||
// Normalized direction of where the agent is looking
|
||||
var forwards = movementPlane.ToPlane(simulatedRotation * (orientation == OrientationMode.YAxisForward ? Vector3.up : Vector3.forward));
|
||||
|
||||
// Check if we have a valid path to follow and some other script has not stopped the character
|
||||
bool stopped = isStopped || (reachedDestination && whenCloseToDestination == CloseToDestinationMode.Stop);
|
||||
if (interpolator.valid && !stopped) {
|
||||
// How fast to move depending on the distance to the destination.
|
||||
// Move slower as the character gets closer to the destination.
|
||||
// This is always a value between 0 and 1.
|
||||
slowdown = distanceToEnd < slowdownDistance? Mathf.Sqrt(distanceToEnd / slowdownDistance) : 1;
|
||||
|
||||
if (reachedEndOfPath && whenCloseToDestination == CloseToDestinationMode.Stop) {
|
||||
// Slow down as quickly as possible
|
||||
velocity2D -= Vector2.ClampMagnitude(velocity2D, currentAcceleration * deltaTime);
|
||||
} else {
|
||||
velocity2D += MovementUtilities.CalculateAccelerationToReachPoint(dir, dir.normalized*maxSpeed, velocity2D, currentAcceleration, rotationSpeed, maxSpeed, forwards) * deltaTime;
|
||||
}
|
||||
} else {
|
||||
slowdown = 1;
|
||||
// Slow down as quickly as possible
|
||||
velocity2D -= Vector2.ClampMagnitude(velocity2D, currentAcceleration * deltaTime);
|
||||
}
|
||||
|
||||
velocity2D = MovementUtilities.ClampVelocity(velocity2D, maxSpeed, slowdown, slowWhenNotFacingTarget && enableRotation, forwards);
|
||||
|
||||
ApplyGravity(deltaTime);
|
||||
|
||||
if (rvoController != null && rvoController.enabled) {
|
||||
// Send a message to the RVOController that we want to move
|
||||
// with this velocity. In the next simulation step, this
|
||||
// velocity will be processed and it will be fed back to the
|
||||
// rvo controller and finally it will be used by this script
|
||||
// when calling the CalculateMovementDelta method below
|
||||
|
||||
// Make sure that we don't move further than to the end point
|
||||
// of the path. If the RVO simulation FPS is low and we did
|
||||
// not do this, the agent might overshoot the target a lot.
|
||||
var rvoTarget = currentPosition + movementPlane.ToWorld(Vector2.ClampMagnitude(velocity2D, distanceToEnd), 0f);
|
||||
rvoController.SetTarget(rvoTarget, velocity2D.magnitude, maxSpeed);
|
||||
}
|
||||
|
||||
// Set how much the agent wants to move during this frame
|
||||
var delta2D = lastDeltaPosition = CalculateDeltaToMoveThisFrame(movementPlane.ToPlane(currentPosition), distanceToEnd, deltaTime);
|
||||
nextPosition = currentPosition + movementPlane.ToWorld(delta2D, verticalVelocity * lastDeltaTime);
|
||||
CalculateNextRotation(slowdown, out nextRotation);
|
||||
}
|
||||
|
||||
protected virtual void CalculateNextRotation (float slowdown, out Quaternion nextRotation) {
|
||||
if (lastDeltaTime > 0.00001f && enableRotation) {
|
||||
Vector2 desiredRotationDirection;
|
||||
if (rvoController != null && rvoController.enabled) {
|
||||
// When using local avoidance, use the actual velocity we are moving with if that velocity
|
||||
// is high enough, otherwise fall back to the velocity that we want to move with (velocity2D).
|
||||
// The local avoidance velocity can be very jittery when the character is close to standing still
|
||||
// as it constantly makes small corrections. We do not want the rotation of the character to be jittery.
|
||||
var actualVelocity = lastDeltaPosition/lastDeltaTime;
|
||||
desiredRotationDirection = Vector2.Lerp(velocity2D, actualVelocity, 4 * actualVelocity.magnitude / (maxSpeed + 0.0001f));
|
||||
} else {
|
||||
desiredRotationDirection = velocity2D;
|
||||
}
|
||||
|
||||
// Rotate towards the direction we are moving in.
|
||||
// Don't rotate when we are very close to the target.
|
||||
var currentRotationSpeed = rotationSpeed * Mathf.Max(0, (slowdown - 0.3f) / 0.7f);
|
||||
nextRotation = SimulateRotationTowards(desiredRotationDirection, currentRotationSpeed * lastDeltaTime);
|
||||
} else {
|
||||
// TODO: simulatedRotation
|
||||
nextRotation = rotation;
|
||||
}
|
||||
}
|
||||
|
||||
static NNConstraint cachedNNConstraint = NNConstraint.Walkable;
|
||||
protected override Vector3 ClampToNavmesh (Vector3 position, out bool positionChanged) {
|
||||
if (constrainInsideGraph) {
|
||||
cachedNNConstraint.tags = seeker.traversableTags;
|
||||
cachedNNConstraint.graphMask = seeker.graphMask;
|
||||
cachedNNConstraint.distanceXZ = true;
|
||||
var clampedPosition = AstarPath.active.GetNearest(position, cachedNNConstraint).position;
|
||||
|
||||
// We cannot simply check for equality because some precision may be lost
|
||||
// if any coordinate transformations are used.
|
||||
var difference = movementPlane.ToPlane(clampedPosition - position);
|
||||
float sqrDifference = difference.sqrMagnitude;
|
||||
if (sqrDifference > 0.001f*0.001f) {
|
||||
// The agent was outside the navmesh. Remove that component of the velocity
|
||||
// so that the velocity only goes along the direction of the wall, not into it
|
||||
velocity2D -= difference * Vector2.Dot(difference, velocity2D) / sqrDifference;
|
||||
|
||||
// Make sure the RVO system knows that there was a collision here
|
||||
// Otherwise other agents may think this agent continued
|
||||
// to move forwards and avoidance quality may suffer
|
||||
if (rvoController != null && rvoController.enabled) {
|
||||
rvoController.SetCollisionNormal(difference);
|
||||
}
|
||||
positionChanged = true;
|
||||
// Return the new position, but ignore any changes in the y coordinate from the ClampToNavmesh method as the y coordinates in the navmesh are rarely very accurate
|
||||
return position + movementPlane.ToWorld(difference);
|
||||
}
|
||||
}
|
||||
|
||||
positionChanged = false;
|
||||
return position;
|
||||
}
|
||||
|
||||
#if UNITY_EDITOR
|
||||
[System.NonSerialized]
|
||||
int gizmoHash = 0;
|
||||
|
||||
[System.NonSerialized]
|
||||
float lastChangedTime = float.NegativeInfinity;
|
||||
|
||||
protected static readonly Color GizmoColor = new Color(46.0f/255, 104.0f/255, 201.0f/255);
|
||||
|
||||
protected override void OnDrawGizmos () {
|
||||
base.OnDrawGizmos();
|
||||
if (alwaysDrawGizmos) OnDrawGizmosInternal();
|
||||
}
|
||||
|
||||
protected override void OnDrawGizmosSelected () {
|
||||
base.OnDrawGizmosSelected();
|
||||
if (!alwaysDrawGizmos) OnDrawGizmosInternal();
|
||||
}
|
||||
|
||||
void OnDrawGizmosInternal () {
|
||||
var newGizmoHash = pickNextWaypointDist.GetHashCode() ^ slowdownDistance.GetHashCode() ^ endReachedDistance.GetHashCode();
|
||||
|
||||
if (newGizmoHash != gizmoHash && gizmoHash != 0) lastChangedTime = GetSync().Time.realtimeSinceStartup;
|
||||
gizmoHash = newGizmoHash;
|
||||
float alpha = alwaysDrawGizmos ? 1 : Mathf.SmoothStep(1, 0, (GetSync().Time.realtimeSinceStartup - lastChangedTime - 5f)/0.5f) * (UnityEditor.Selection.gameObjects.Length == 1 ? 1 : 0);
|
||||
|
||||
if (alpha > 0) {
|
||||
// Make sure the scene view is repainted while the gizmos are visible
|
||||
if (!alwaysDrawGizmos) UnityEditor.SceneView.RepaintAll();
|
||||
Draw.Gizmos.Line(position, steeringTarget, GizmoColor * new Color(1, 1, 1, alpha));
|
||||
Gizmos.matrix = Matrix4x4.TRS(position, transform.rotation * (orientation == OrientationMode.YAxisForward ? Quaternion.Euler(-90, 0, 0) : Quaternion.identity), Vector3.one);
|
||||
Draw.Gizmos.CircleXZ(Vector3.zero, pickNextWaypointDist, GizmoColor * new Color(1, 1, 1, alpha));
|
||||
Draw.Gizmos.CircleXZ(Vector3.zero, slowdownDistance, Color.Lerp(GizmoColor, Color.red, 0.5f) * new Color(1, 1, 1, alpha));
|
||||
Draw.Gizmos.CircleXZ(Vector3.zero, endReachedDistance, Color.Lerp(GizmoColor, Color.red, 0.8f) * new Color(1, 1, 1, alpha));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
protected override int OnUpgradeSerializedData (int version, bool unityThread) {
|
||||
// Approximately convert from a damping value to a degrees per second value.
|
||||
if (version < 1) rotationSpeed *= 90;
|
||||
return base.OnUpgradeSerializedData(version, unityThread);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f6eb1402c17e84a9282a7f0f62eb584f
|
||||
timeCreated: 1491225739
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,407 @@
|
||||
using UnityEngine;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Pathfinding {
|
||||
/// <summary>
|
||||
/// Common interface for all movement scripts in the A* Pathfinding Project.
|
||||
/// See: <see cref="Pathfinding.AIPath"/>
|
||||
/// See: <see cref="Pathfinding.RichAI"/>
|
||||
/// See: <see cref="Pathfinding.AILerp"/>
|
||||
/// </summary>
|
||||
public interface IAstarAI {
|
||||
/// <summary>
|
||||
/// Radius of the agent in world units.
|
||||
/// This is visualized in the scene view as a yellow cylinder around the character.
|
||||
///
|
||||
/// Note: The <see cref="Pathfinding.AILerp"/> script doesn't really have any use of knowing the radius or the height of the character, so this property will always return 0 in that script.
|
||||
/// </summary>
|
||||
float radius { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Height of the agent in world units.
|
||||
/// This is visualized in the scene view as a yellow cylinder around the character.
|
||||
///
|
||||
/// This value is currently only used if an RVOController is attached to the same GameObject, otherwise it is only used for drawing nice gizmos in the scene view.
|
||||
/// However since the height value is used for some things, the radius field is always visible for consistency and easier visualization of the character.
|
||||
/// That said, it may be used for something in a future release.
|
||||
///
|
||||
/// Note: The <see cref="Pathfinding.AILerp"/> script doesn't really have any use of knowing the radius or the height of the character, so this property will always return 0 in that script.
|
||||
/// </summary>
|
||||
float height { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Position of the agent.
|
||||
/// In world space.
|
||||
/// See: <see cref="rotation"/>
|
||||
///
|
||||
/// If you want to move the agent you may use <see cref="Teleport"/> or <see cref="Move"/>.
|
||||
/// </summary>
|
||||
Vector3 position { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Rotation of the agent.
|
||||
/// In world space.
|
||||
/// See: <see cref="position"/>
|
||||
/// </summary>
|
||||
Quaternion rotation { get; set; }
|
||||
|
||||
/// <summary>Max speed in world units per second</summary>
|
||||
float maxSpeed { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Actual velocity that the agent is moving with.
|
||||
/// In world units per second.
|
||||
///
|
||||
/// See: <see cref="desiredVelocity"/>
|
||||
/// </summary>
|
||||
Vector3 velocity { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Velocity that this agent wants to move with.
|
||||
/// Includes gravity and local avoidance if applicable.
|
||||
/// In world units per second.
|
||||
///
|
||||
/// See: <see cref="velocity"/>
|
||||
/// </summary>
|
||||
Vector3 desiredVelocity { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Approximate remaining distance along the current path to the end of the path.
|
||||
/// The RichAI movement script approximates this distance since it is quite expensive to calculate the real distance.
|
||||
/// However it will be accurate when the agent is within 1 corner of the destination.
|
||||
/// You can use <see cref="GetRemainingPath"/> to calculate the actual remaining path more precisely.
|
||||
///
|
||||
/// The AIPath and AILerp scripts use a more accurate distance calculation at all times.
|
||||
///
|
||||
/// If the agent does not currently have a path, then positive infinity will be returned.
|
||||
///
|
||||
/// Note: This is the distance to the end of the path, which may or may not be at the <see cref="destination"/>. If the character cannot reach the destination it will try to move as close as possible to it.
|
||||
///
|
||||
/// Warning: Since path requests are asynchronous, there is a small delay between a path request being sent and this value being updated with the new calculated path.
|
||||
///
|
||||
/// See: <see cref="reachedDestination"/>
|
||||
/// See: <see cref="reachedEndOfPath"/>
|
||||
/// See: <see cref="pathPending"/>
|
||||
/// </summary>
|
||||
float remainingDistance { get; }
|
||||
|
||||
/// <summary>
|
||||
/// True if the ai has reached the <see cref="destination"/>.
|
||||
/// This is a best effort calculation to see if the <see cref="destination"/> has been reached.
|
||||
/// For the AIPath/RichAI scripts, this is when the character is within <see cref="AIPath.endReachedDistance"/> world units from the <see cref="destination"/>.
|
||||
/// For the AILerp script it is when the character is at the destination (±a very small margin).
|
||||
///
|
||||
/// This value will be updated immediately when the <see cref="destination"/> is changed (in contrast to <see cref="reachedEndOfPath)"/>, however since path requests are asynchronous
|
||||
/// it will use an approximation until it sees the real path result. What this property does is to check the distance to the end of the current path, and add to that the distance
|
||||
/// from the end of the path to the <see cref="destination"/> (i.e. is assumes it is possible to move in a straight line between the end of the current path to the destination) and then checks if that total
|
||||
/// distance is less than <see cref="endReachedDistance"/>. This property is therefore only a best effort, but it will work well for almost all use cases.
|
||||
///
|
||||
/// Furthermore it will not report that the destination is reached if the destination is above the head of the character or more than half the <see cref="height"/> of the character below its feet
|
||||
/// (so if you have a multilevel building, it is important that you configure the <see cref="height"/> of the character correctly).
|
||||
///
|
||||
/// The cases which could be problematic are if an agent is standing next to a very thin wall and the destination suddenly changes to the other side of that thin wall.
|
||||
/// During the time that it takes for the path to be calculated the agent may see itself as alredy having reached the destination because the destination only moved a very small distance (the wall was thin),
|
||||
/// even though it may actually be quite a long way around the wall to the other side.
|
||||
///
|
||||
/// In contrast to <see cref="reachedEndOfPath"/>, this property is immediately updated when the <see cref="destination"/> is changed.
|
||||
///
|
||||
/// <code>
|
||||
/// IEnumerator Start () {
|
||||
/// ai.destination = somePoint;
|
||||
/// // Start to search for a path to the destination immediately
|
||||
/// ai.SearchPath();
|
||||
/// // Wait until the agent has reached the destination
|
||||
/// while (!ai.reachedDestination) {
|
||||
/// yield return null;
|
||||
/// }
|
||||
/// // The agent has reached the destination now
|
||||
/// }
|
||||
/// </code>
|
||||
///
|
||||
/// See: <see cref="AIPath.endReachedDistance"/>
|
||||
/// See: <see cref="remainingDistance"/>
|
||||
/// See: <see cref="reachedEndOfPath"/>
|
||||
/// </summary>
|
||||
bool reachedDestination { get; }
|
||||
|
||||
/// <summary>
|
||||
/// True if the agent has reached the end of the current path.
|
||||
///
|
||||
/// Note that setting the <see cref="destination"/> does not immediately update the path, nor is there any guarantee that the
|
||||
/// AI will actually be able to reach the destination that you set. The AI will try to get as close as possible.
|
||||
/// Often you want to use <see cref="reachedDestination"/> instead which is easier to work with.
|
||||
///
|
||||
/// It is very hard to provide a method for detecting if the AI has reached the <see cref="destination"/> that works across all different games
|
||||
/// because the destination may not even lie on the navmesh and how that is handled differs from game to game (see also the code snippet in the docs for <see cref="destination)"/>.
|
||||
///
|
||||
/// See: <see cref="remainingDistance"/>
|
||||
/// See: <see cref="reachedDestination"/>
|
||||
/// </summary>
|
||||
bool reachedEndOfPath { get; }
|
||||
|
||||
/// <summary>
|
||||
/// End point of path the agent is currently following.
|
||||
/// If the agent has no path (or it might not be calculated yet), this will return the <see cref="destination"/> instead.
|
||||
/// If the agent has no destination it either it will return (+inf,+inf,+inf).
|
||||
///
|
||||
/// The end of the path is usually identical or very close to the <see cref="destination"/>, but it may differ
|
||||
/// if the path for example was blocked by a wall so that the agent couldn't get any closer.
|
||||
///
|
||||
/// This is only updated when the path is recalculated.
|
||||
/// </summary>
|
||||
Vector3 endOfPath { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Position in the world that this agent should move to.
|
||||
///
|
||||
/// If no destination has been set yet, then (+infinity, +infinity, +infinity) will be returned.
|
||||
///
|
||||
/// Note that setting this property does not immediately cause the agent to recalculate its path.
|
||||
/// So it may take some time before the agent starts to move towards this point.
|
||||
/// Most movement scripts have a repathRate field which indicates how often the agent looks
|
||||
/// for a new path. You can also call the <see cref="SearchPath"/> method to immediately
|
||||
/// start to search for a new path. Paths are calculated asynchronously so when an agent starts to
|
||||
/// search for path it may take a few frames (usually 1 or 2) until the result is available.
|
||||
/// During this time the <see cref="pathPending"/> property will return true.
|
||||
///
|
||||
/// If you are setting a destination and then want to know when the agent has reached that destination
|
||||
/// then you could either use <see cref="reachedDestination"/> (recommended) or check both <see cref="pathPending"/> and <see cref="reachedEndOfPath"/>.
|
||||
/// Check the documentation for the respective fields to learn about their differences.
|
||||
///
|
||||
/// <code>
|
||||
/// IEnumerator Start () {
|
||||
/// ai.destination = somePoint;
|
||||
/// // Start to search for a path to the destination immediately
|
||||
/// ai.SearchPath();
|
||||
/// // Wait until the agent has reached the destination
|
||||
/// while (!ai.reachedDestination) {
|
||||
/// yield return null;
|
||||
/// }
|
||||
/// // The agent has reached the destination now
|
||||
/// }
|
||||
/// </code>
|
||||
/// <code>
|
||||
/// IEnumerator Start () {
|
||||
/// ai.destination = somePoint;
|
||||
/// // Start to search for a path to the destination immediately
|
||||
/// // Note that the result may not become available until after a few frames
|
||||
/// // ai.pathPending will be true while the path is being calculated
|
||||
/// ai.SearchPath();
|
||||
/// // Wait until we know for sure that the agent has calculated a path to the destination we set above
|
||||
/// while (ai.pathPending || !ai.reachedEndOfPath) {
|
||||
/// yield return null;
|
||||
/// }
|
||||
/// // The agent has reached the destination now
|
||||
/// }
|
||||
/// </code>
|
||||
/// </summary>
|
||||
Vector3 destination { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Enables or disables recalculating the path at regular intervals.
|
||||
/// Setting this to false does not stop any active path requests from being calculated or stop it from continuing to follow the current path.
|
||||
///
|
||||
/// Note that this only disables automatic path recalculations. If you call the <see cref="SearchPath()"/> method a path will still be calculated.
|
||||
///
|
||||
/// See: <see cref="canMove"/>
|
||||
/// See: <see cref="isStopped"/>
|
||||
/// </summary>
|
||||
bool canSearch { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Enables or disables movement completely.
|
||||
/// If you want the agent to stand still, but still react to local avoidance and use gravity: use <see cref="isStopped"/> instead.
|
||||
///
|
||||
/// This is also useful if you want to have full control over when the movement calculations run.
|
||||
/// Take a look at <see cref="MovementUpdate"/>
|
||||
///
|
||||
/// See: <see cref="canSearch"/>
|
||||
/// See: <see cref="isStopped"/>
|
||||
/// </summary>
|
||||
bool canMove { get; set; }
|
||||
|
||||
/// <summary>True if this agent currently has a path that it follows</summary>
|
||||
bool hasPath { get; }
|
||||
|
||||
/// <summary>True if a path is currently being calculated</summary>
|
||||
bool pathPending { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets if the agent should stop moving.
|
||||
/// If this is set to true the agent will immediately start to slow down as quickly as it can to come to a full stop.
|
||||
/// The agent will still react to local avoidance and gravity (if applicable), but it will not try to move in any particular direction.
|
||||
///
|
||||
/// The current path of the agent will not be cleared, so when this is set
|
||||
/// to false again the agent will continue moving along the previous path.
|
||||
///
|
||||
/// This is a purely user-controlled parameter, so for example it is not set automatically when the agent stops
|
||||
/// moving because it has reached the target. Use <see cref="reachedEndOfPath"/> for that.
|
||||
///
|
||||
/// If this property is set to true while the agent is traversing an off-mesh link (RichAI script only), then the agent will
|
||||
/// continue traversing the link and stop once it has completed it.
|
||||
///
|
||||
/// Note: This is not the same as the <see cref="canMove"/> setting which some movement scripts have. The <see cref="canMove"/> setting
|
||||
/// disables movement calculations completely (which among other things makes it not be affected by local avoidance or gravity).
|
||||
/// For the AILerp movement script which doesn't use gravity or local avoidance anyway changing this property is very similar to
|
||||
/// changing <see cref="canMove"/>.
|
||||
///
|
||||
/// The <see cref="steeringTarget"/> property will continue to indicate the point which the agent would move towards if it would not be stopped.
|
||||
/// </summary>
|
||||
bool isStopped { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Point on the path which the agent is currently moving towards.
|
||||
/// This is usually a point a small distance ahead of the agent
|
||||
/// or the end of the path.
|
||||
///
|
||||
/// If the agent does not have a path at the moment, then the agent's current position will be returned.
|
||||
/// </summary>
|
||||
Vector3 steeringTarget { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Called when the agent recalculates its path.
|
||||
/// This is called both for automatic path recalculations (see <see cref="canSearch)"/> and manual ones (see <see cref="SearchPath)"/>.
|
||||
///
|
||||
/// See: Take a look at the <see cref="Pathfinding.AIDestinationSetter"/> source code for an example of how it can be used.
|
||||
/// </summary>
|
||||
System.Action onSearchPath { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Fills buffer with the remaining path.
|
||||
///
|
||||
/// <code>
|
||||
/// var buffer = new List<Vector3>();
|
||||
///
|
||||
/// ai.GetRemainingPath(buffer, out bool stale);
|
||||
/// for (int i = 0; i < buffer.Count - 1; i++) {
|
||||
/// Debug.DrawLine(buffer[i], buffer[i+1], Color.red);
|
||||
/// }
|
||||
/// </code>
|
||||
/// [Open online documentation to see images]
|
||||
/// </summary>
|
||||
/// <param name="buffer">The buffer will be cleared and replaced with the path. The first point is the current position of the agent.</param>
|
||||
/// <param name="stale">May be true if the path is invalid in some way. For example if the agent has no path or (for the RichAI script only) if the agent has detected that some nodes in the path have been destroyed.</param>
|
||||
void GetRemainingPath(List<Vector3> buffer, out bool stale);
|
||||
|
||||
/// <summary>
|
||||
/// Recalculate the current path.
|
||||
/// You can for example use this if you want very quick reaction times when you have changed the <see cref="destination"/>
|
||||
/// so that the agent does not have to wait until the next automatic path recalculation (see <see cref="canSearch)"/>.
|
||||
///
|
||||
/// If there is an ongoing path calculation, it will be canceled, so make sure you leave time for the paths to get calculated before calling this function again.
|
||||
/// A canceled path will show up in the log with the message "Canceled by script" (see <see cref="Seeker.CancelCurrentPathRequest())"/>.
|
||||
///
|
||||
/// If no <see cref="destination"/> has been set yet then nothing will be done.
|
||||
///
|
||||
/// Note: The path result may not become available until after a few frames.
|
||||
/// During the calculation time the <see cref="pathPending"/> property will return true.
|
||||
///
|
||||
/// See: <see cref="pathPending"/>
|
||||
/// </summary>
|
||||
void SearchPath();
|
||||
|
||||
/// <summary>
|
||||
/// Make the AI follow the specified path.
|
||||
///
|
||||
/// In case the path has not been calculated, the script will call seeker.StartPath to calculate it.
|
||||
/// This means the AI may not actually start to follow the path until in a few frames when the path has been calculated.
|
||||
/// The <see cref="pathPending"/> field will as usual return true while the path is being calculated.
|
||||
///
|
||||
/// In case the path has already been calculated it will immediately replace the current path the AI is following.
|
||||
/// This is useful if you want to replace how the AI calculates its paths.
|
||||
/// Note that if you calculate the path using seeker.StartPath then this script will already pick it up because it is listening for
|
||||
/// all paths that the Seeker finishes calculating. In that case you do not need to call this function.
|
||||
///
|
||||
/// If you pass null as a parameter then the current path will be cleared and the agent will stop moving.
|
||||
/// Note than unless you have also disabled <see cref="canSearch"/> then the agent will soon recalculate its path and start moving again.
|
||||
///
|
||||
/// You can disable the automatic path recalculation by setting the <see cref="canSearch"/> field to false.
|
||||
///
|
||||
/// <code>
|
||||
/// // Disable the automatic path recalculation
|
||||
/// ai.canSearch = false;
|
||||
/// var pointToAvoid = enemy.position;
|
||||
/// // Make the AI flee from the enemy.
|
||||
/// // The path will be about 20 world units long (the default cost of moving 1 world unit is 1000).
|
||||
/// var path = FleePath.Construct(ai.position, pointToAvoid, 1000 * 20);
|
||||
/// ai.SetPath(path);
|
||||
///
|
||||
/// // If you want to make use of properties like ai.reachedDestination or ai.remainingDistance or similar
|
||||
/// // you should also set the destination property to something reasonable.
|
||||
/// // Since the agent's own path recalculation is disabled, setting this will not affect how the paths are calculated.
|
||||
/// // ai.destination = ...
|
||||
/// </code>
|
||||
/// </summary>
|
||||
/// <param name="path">The path to follow.</param>
|
||||
/// <param name="updateDestinationFromPath">If true, the #destination property will be set to the end point of the path. If false, the previous destination value will be kept.</param>
|
||||
void SetPath(Path path, bool updateDestinationFromPath = true);
|
||||
|
||||
/// <summary>
|
||||
/// Instantly move the agent to a new position.
|
||||
/// This will trigger a path recalculation (if clearPath is true, which is the default) so if you want to teleport the agent and change its <see cref="destination"/>
|
||||
/// it is recommended that you set the <see cref="destination"/> before calling this method.
|
||||
///
|
||||
/// The current path will be cleared by default.
|
||||
///
|
||||
/// See: Works similarly to Unity's NavmeshAgent.Warp.
|
||||
/// See: <see cref="SearchPath"/>
|
||||
/// </summary>
|
||||
void Teleport(Vector3 newPosition, bool clearPath = true);
|
||||
|
||||
/// <summary>
|
||||
/// Move the agent.
|
||||
///
|
||||
/// This is intended for external movement forces such as those applied by wind, conveyor belts, knockbacks etc.
|
||||
///
|
||||
/// Some movement scripts may ignore this completely (notably the AILerp script) if it does not have
|
||||
/// any concept of being moved externally.
|
||||
///
|
||||
/// The agent will not be moved immediately when calling this method. Instead this offset will be stored and then
|
||||
/// applied the next time the agent runs its movement calculations (which is usually later this frame or the next frame).
|
||||
/// If you want to move the agent immediately then call:
|
||||
/// <code>
|
||||
/// ai.Move(someVector);
|
||||
/// ai.FinalizeMovement(ai.position, ai.rotation);
|
||||
/// </code>
|
||||
/// </summary>
|
||||
/// <param name="deltaPosition">Direction and distance to move the agent in world space.</param>
|
||||
void Move(Vector3 deltaPosition);
|
||||
|
||||
/// <summary>
|
||||
/// Calculate how the character wants to move during this frame.
|
||||
///
|
||||
/// Note that this does not actually move the character. You need to call <see cref="FinalizeMovement"/> for that.
|
||||
/// This is called automatically unless <see cref="canMove"/> is false.
|
||||
///
|
||||
/// To handle movement yourself you can disable <see cref="canMove"/> and call this method manually.
|
||||
/// This code will replicate the normal behavior of the component:
|
||||
/// <code>
|
||||
/// void Update () {
|
||||
/// // Disable the AIs own movement code
|
||||
/// ai.canMove = false;
|
||||
/// Vector3 nextPosition;
|
||||
/// Quaternion nextRotation;
|
||||
/// // Calculate how the AI wants to move
|
||||
/// ai.MovementUpdate(Time.deltaTime, out nextPosition, out nextRotation);
|
||||
/// // Modify nextPosition and nextRotation in any way you wish
|
||||
/// // Actually move the AI
|
||||
/// ai.FinalizeMovement(nextPosition, nextRotation);
|
||||
/// }
|
||||
/// </code>
|
||||
/// </summary>
|
||||
/// <param name="deltaTime">time to simulate movement for. Usually set to Time.deltaTime.</param>
|
||||
/// <param name="nextPosition">the position that the agent wants to move to during this frame.</param>
|
||||
/// <param name="nextRotation">the rotation that the agent wants to rotate to during this frame.</param>
|
||||
void MovementUpdate(float deltaTime, out Vector3 nextPosition, out Quaternion nextRotation);
|
||||
|
||||
/// <summary>
|
||||
/// Move the agent.
|
||||
/// To be called as the last step when you are handling movement manually.
|
||||
///
|
||||
/// The movement will be clamped to the navmesh if applicable (this is done for the RichAI movement script).
|
||||
///
|
||||
/// See: <see cref="MovementUpdate"/> for a code example.
|
||||
/// </summary>
|
||||
void FinalizeMovement(Vector3 nextPosition, Quaternion nextRotation);
|
||||
}
|
||||
}
|
@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b7438f3f6b9404f05ab7f584f92aa7d5
|
||||
timeCreated: 1495013922
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,4 @@
|
||||
|
||||
// This file has been removed from the project. Since UnityPackages cannot
|
||||
// delete files, only replace them, this message is left here to prevent old
|
||||
// files from causing compiler errors
|
@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 20549335d45df4a329ece093b865221b
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
@ -0,0 +1,603 @@
|
||||
using UnityEngine;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Pathfinding {
|
||||
using Pathfinding.RVO;
|
||||
using Pathfinding.Util;
|
||||
|
||||
[AddComponentMenu("Pathfinding/AI/RichAI (3D, for navmesh)")]
|
||||
[UniqueComponent(tag = "ai")]
|
||||
/// <summary>
|
||||
/// Advanced AI for navmesh based graphs.
|
||||
///
|
||||
/// [Open online documentation to see images]
|
||||
///
|
||||
/// See: movementscripts (view in online documentation for working links)
|
||||
/// </summary>
|
||||
public partial class RichAI : AIBase, IAstarAI {
|
||||
/// <summary>
|
||||
/// Max acceleration of the agent.
|
||||
/// In world units per second per second.
|
||||
/// </summary>
|
||||
public float acceleration = 5;
|
||||
|
||||
/// <summary>
|
||||
/// Max rotation speed of the agent.
|
||||
/// In degrees per second.
|
||||
/// </summary>
|
||||
public float rotationSpeed = 360;
|
||||
|
||||
/// <summary>
|
||||
/// How long before reaching the end of the path to start to slow down.
|
||||
/// A lower value will make the agent stop more abruptly.
|
||||
///
|
||||
/// Note: The agent may require more time to slow down if
|
||||
/// its maximum <see cref="acceleration"/> is not high enough.
|
||||
///
|
||||
/// If set to zero the agent will not even attempt to slow down.
|
||||
/// This can be useful if the target point is not a point you want the agent to stop at
|
||||
/// but it might for example be the player and you want the AI to slam into the player.
|
||||
///
|
||||
/// Note: A value of zero will behave differently from a small but non-zero value (such as 0.0001).
|
||||
/// When it is non-zero the agent will still respect its <see cref="acceleration"/> when determining if it needs
|
||||
/// to slow down, but if it is zero it will disable that check.
|
||||
/// This is useful if the <see cref="destination"/> is not a point where you want the agent to stop.
|
||||
///
|
||||
/// \htmlonly <video class="tinyshadow" controls loop><source src="images/richai_slowdown_time.mp4" type="video/mp4"></video> \endhtmlonly
|
||||
/// </summary>
|
||||
public float slowdownTime = 0.5f;
|
||||
|
||||
/// <summary>
|
||||
/// Max distance to the endpoint to consider it reached.
|
||||
///
|
||||
/// See: <see cref="reachedEndOfPath"/>
|
||||
/// See: <see cref="OnTargetReached"/>
|
||||
/// </summary>
|
||||
public float endReachedDistance = 0.01f;
|
||||
|
||||
/// <summary>
|
||||
/// Force to avoid walls with.
|
||||
/// The agent will try to steer away from walls slightly.
|
||||
///
|
||||
/// See: <see cref="wallDist"/>
|
||||
/// </summary>
|
||||
public float wallForce = 3;
|
||||
|
||||
/// <summary>
|
||||
/// Walls within this range will be used for avoidance.
|
||||
/// Setting this to zero disables wall avoidance and may improve performance slightly
|
||||
///
|
||||
/// See: <see cref="wallForce"/>
|
||||
/// </summary>
|
||||
public float wallDist = 1;
|
||||
|
||||
/// <summary>
|
||||
/// Use funnel simplification.
|
||||
/// On tiled navmesh maps, but sometimes on normal ones as well, it can be good to simplify
|
||||
/// the funnel as a post-processing step to make the paths straighter.
|
||||
///
|
||||
/// This has a moderate performance impact during frames when a path calculation is completed.
|
||||
///
|
||||
/// The RichAI script uses its own internal funnel algorithm, so you never
|
||||
/// need to attach the FunnelModifier component.
|
||||
///
|
||||
/// [Open online documentation to see images]
|
||||
///
|
||||
/// See: <see cref="Pathfinding.FunnelModifier"/>
|
||||
/// </summary>
|
||||
public bool funnelSimplification = false;
|
||||
|
||||
/// <summary>
|
||||
/// Slow down when not facing the target direction.
|
||||
/// Incurs at a small performance overhead.
|
||||
/// </summary>
|
||||
public bool slowWhenNotFacingTarget = true;
|
||||
|
||||
/// <summary>
|
||||
/// Called when the agent starts to traverse an off-mesh link.
|
||||
/// Register to this callback to handle off-mesh links in a custom way.
|
||||
///
|
||||
/// If this event is set to null then the agent will fall back to traversing
|
||||
/// off-mesh links using a very simple linear interpolation.
|
||||
///
|
||||
/// <code>
|
||||
/// void OnEnable () {
|
||||
/// ai = GetComponent<RichAI>();
|
||||
/// if (ai != null) ai.onTraverseOffMeshLink += TraverseOffMeshLink;
|
||||
/// }
|
||||
///
|
||||
/// void OnDisable () {
|
||||
/// if (ai != null) ai.onTraverseOffMeshLink -= TraverseOffMeshLink;
|
||||
/// }
|
||||
///
|
||||
/// IEnumerator TraverseOffMeshLink (RichSpecial link) {
|
||||
/// // Traverse the link over 1 second
|
||||
/// float startTime = Time.time;
|
||||
///
|
||||
/// while (Time.time < startTime + 1) {
|
||||
/// transform.position = Vector3.Lerp(link.first.position, link.second.position, Time.time - startTime);
|
||||
/// yield return null;
|
||||
/// }
|
||||
/// transform.position = link.second.position;
|
||||
/// }
|
||||
/// </code>
|
||||
/// </summary>
|
||||
public System.Func<RichSpecial, IEnumerator> onTraverseOffMeshLink;
|
||||
|
||||
/// <summary>Holds the current path that this agent is following</summary>
|
||||
protected readonly RichPath richPath = new RichPath();
|
||||
|
||||
protected bool delayUpdatePath;
|
||||
protected bool lastCorner;
|
||||
|
||||
/// <summary>Distance to <see cref="steeringTarget"/> in the movement plane</summary>
|
||||
protected float distanceToSteeringTarget = float.PositiveInfinity;
|
||||
|
||||
protected readonly List<Vector3> nextCorners = new List<Vector3>();
|
||||
protected readonly List<Vector3> wallBuffer = new List<Vector3>();
|
||||
|
||||
public bool traversingOffMeshLink { get; protected set; }
|
||||
|
||||
/// <summary>\copydoc Pathfinding::IAstarAI::remainingDistance</summary>
|
||||
public float remainingDistance {
|
||||
get {
|
||||
return distanceToSteeringTarget + Vector3.Distance(steeringTarget, richPath.Endpoint);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>\copydoc Pathfinding::IAstarAI::reachedEndOfPath</summary>
|
||||
public bool reachedEndOfPath { get { return approachingPathEndpoint && distanceToSteeringTarget < endReachedDistance; } }
|
||||
|
||||
/// <summary>\copydoc Pathfinding::IAstarAI::reachedDestination</summary>
|
||||
public bool reachedDestination {
|
||||
get {
|
||||
if (!reachedEndOfPath) return false;
|
||||
// Note: distanceToSteeringTarget is the distance to the end of the path when approachingPathEndpoint is true
|
||||
if (approachingPathEndpoint && distanceToSteeringTarget + movementPlane.ToPlane(destination - richPath.Endpoint).magnitude > endReachedDistance) return false;
|
||||
|
||||
// Don't do height checks in 2D mode
|
||||
if (orientation != OrientationMode.YAxisForward) {
|
||||
// Check if the destination is above the head of the character or far below the feet of it
|
||||
float yDifference;
|
||||
movementPlane.ToPlane(destination - position, out yDifference);
|
||||
var h = tr.localScale.y * height;
|
||||
if (yDifference > h || yDifference < -h*0.5) return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>\copydoc Pathfinding::IAstarAI::hasPath</summary>
|
||||
public bool hasPath { get { return richPath.GetCurrentPart() != null; } }
|
||||
|
||||
/// <summary>\copydoc Pathfinding::IAstarAI::pathPending</summary>
|
||||
public bool pathPending { get { return waitingForPathCalculation || delayUpdatePath; } }
|
||||
|
||||
/// <summary>\copydoc Pathfinding::IAstarAI::steeringTarget</summary>
|
||||
public Vector3 steeringTarget { get; protected set; }
|
||||
|
||||
/// <summary>\copydoc Pathfinding::IAstarAI::radius</summary>
|
||||
float IAstarAI.radius { get { return radius; } set { radius = value; } }
|
||||
|
||||
/// <summary>\copydoc Pathfinding::IAstarAI::height</summary>
|
||||
float IAstarAI.height { get { return height; } set { height = value; } }
|
||||
|
||||
/// <summary>\copydoc Pathfinding::IAstarAI::maxSpeed</summary>
|
||||
float IAstarAI.maxSpeed { get { return maxSpeed; } set { maxSpeed = value; } }
|
||||
|
||||
/// <summary>\copydoc Pathfinding::IAstarAI::canSearch</summary>
|
||||
bool IAstarAI.canSearch { get { return canSearch; } set { canSearch = value; } }
|
||||
|
||||
/// <summary>\copydoc Pathfinding::IAstarAI::canMove</summary>
|
||||
bool IAstarAI.canMove { get { return canMove; } set { canMove = value; } }
|
||||
|
||||
/// <summary>
|
||||
/// True if approaching the last waypoint in the current part of the path.
|
||||
/// Path parts are separated by off-mesh links.
|
||||
///
|
||||
/// See: <see cref="approachingPathEndpoint"/>
|
||||
/// </summary>
|
||||
public bool approachingPartEndpoint {
|
||||
get {
|
||||
return lastCorner && nextCorners.Count == 1;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// True if approaching the last waypoint of all parts in the current path.
|
||||
/// Path parts are separated by off-mesh links.
|
||||
///
|
||||
/// See: <see cref="approachingPartEndpoint"/>
|
||||
/// </summary>
|
||||
public bool approachingPathEndpoint {
|
||||
get {
|
||||
return approachingPartEndpoint && richPath.IsLastPart;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>\copydoc Pathfinding::IAstarAI::endOfPath</summary>
|
||||
public override Vector3 endOfPath {
|
||||
get {
|
||||
return hasPath ? richPath.Endpoint : destination;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// \copydoc Pathfinding::IAstarAI::Teleport
|
||||
///
|
||||
/// When setting transform.position directly the agent
|
||||
/// will be clamped to the part of the navmesh it can
|
||||
/// reach, so it may not end up where you wanted it to.
|
||||
/// This ensures that the agent can move to any part of the navmesh.
|
||||
/// </summary>
|
||||
public override void Teleport (Vector3 newPosition, bool clearPath = true) {
|
||||
// Clamp the new position to the navmesh
|
||||
var nearest = AstarPath.active != null? AstarPath.active.GetNearest(newPosition) : new NNInfo();
|
||||
float elevation;
|
||||
|
||||
movementPlane.ToPlane(newPosition, out elevation);
|
||||
newPosition = movementPlane.ToWorld(movementPlane.ToPlane(nearest.node != null ? nearest.position : newPosition), elevation);
|
||||
base.Teleport(newPosition, clearPath);
|
||||
}
|
||||
|
||||
/// <summary>Called when the component is disabled</summary>
|
||||
protected override void OnDisable () {
|
||||
// Note that the AIBase.OnDisable call will also stop all coroutines
|
||||
base.OnDisable();
|
||||
traversingOffMeshLink = false;
|
||||
// Stop the off mesh link traversal coroutine
|
||||
StopAllCoroutines();
|
||||
}
|
||||
|
||||
protected override bool shouldRecalculatePath {
|
||||
get {
|
||||
// Don't automatically recalculate the path in the middle of an off-mesh link
|
||||
return base.shouldRecalculatePath && !traversingOffMeshLink;
|
||||
}
|
||||
}
|
||||
|
||||
public override void SearchPath () {
|
||||
// Calculate paths after the current off-mesh link has been completed
|
||||
if (traversingOffMeshLink) {
|
||||
delayUpdatePath = true;
|
||||
} else {
|
||||
base.SearchPath();
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnPathComplete (Path p) {
|
||||
waitingForPathCalculation = false;
|
||||
p.Claim(this);
|
||||
|
||||
if (p.error) {
|
||||
p.Release(this);
|
||||
return;
|
||||
}
|
||||
|
||||
if (traversingOffMeshLink) {
|
||||
delayUpdatePath = true;
|
||||
} else {
|
||||
// The RandomPath and MultiTargetPath do not have a well defined destination that could have been
|
||||
// set before the paths were calculated. So we instead set the destination here so that some properties
|
||||
// like #reachedDestination and #remainingDistance work correctly.
|
||||
if (p is RandomPath rpath) {
|
||||
destination = rpath.originalEndPoint;
|
||||
} else if (p is MultiTargetPath mpath) {
|
||||
destination = mpath.originalEndPoint;
|
||||
}
|
||||
|
||||
richPath.Initialize(seeker, p, true, funnelSimplification);
|
||||
|
||||
// Check if we have already reached the end of the path
|
||||
// We need to do this here to make sure that the #reachedEndOfPath
|
||||
// property is up to date.
|
||||
var part = richPath.GetCurrentPart() as RichFunnel;
|
||||
if (part != null) {
|
||||
if (updatePosition) simulatedPosition = tr.position;
|
||||
|
||||
// Note: UpdateTarget has some side effects like setting the nextCorners list and the lastCorner field
|
||||
var localPosition = movementPlane.ToPlane(UpdateTarget(part));
|
||||
|
||||
// Target point
|
||||
steeringTarget = nextCorners[0];
|
||||
Vector2 targetPoint = movementPlane.ToPlane(steeringTarget);
|
||||
distanceToSteeringTarget = (targetPoint - localPosition).magnitude;
|
||||
|
||||
if (lastCorner && nextCorners.Count == 1 && distanceToSteeringTarget <= endReachedDistance) {
|
||||
NextPart();
|
||||
}
|
||||
}
|
||||
}
|
||||
p.Release(this);
|
||||
}
|
||||
|
||||
protected override void ClearPath () {
|
||||
CancelCurrentPathRequest();
|
||||
richPath.Clear();
|
||||
lastCorner = false;
|
||||
delayUpdatePath = false;
|
||||
distanceToSteeringTarget = float.PositiveInfinity;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Declare that the AI has completely traversed the current part.
|
||||
/// This will skip to the next part, or call OnTargetReached if this was the last part
|
||||
/// </summary>
|
||||
protected void NextPart () {
|
||||
if (!richPath.CompletedAllParts) {
|
||||
if (!richPath.IsLastPart) lastCorner = false;
|
||||
richPath.NextPart();
|
||||
if (richPath.CompletedAllParts) {
|
||||
OnTargetReached();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>\copydoc Pathfinding::IAstarAI::GetRemainingPath</summary>
|
||||
public void GetRemainingPath (List<Vector3> buffer, out bool stale) {
|
||||
richPath.GetRemainingPath(buffer, simulatedPosition, out stale);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Called when the end of the path is reached.
|
||||
///
|
||||
/// Deprecated: Avoid overriding this method. Instead poll the <see cref="reachedDestination"/> or <see cref="reachedEndOfPath"/> properties.
|
||||
/// </summary>
|
||||
protected virtual void OnTargetReached () {
|
||||
}
|
||||
|
||||
protected virtual Vector3 UpdateTarget (RichFunnel fn) {
|
||||
nextCorners.Clear();
|
||||
|
||||
// This method assumes simulatedPosition is up to date as our current position.
|
||||
// We read and write to tr.position as few times as possible since doing so
|
||||
// is much slower than to read and write from/to a local/member variable.
|
||||
bool requiresRepath;
|
||||
Vector3 position = fn.Update(simulatedPosition, nextCorners, 2, out lastCorner, out requiresRepath);
|
||||
|
||||
if (requiresRepath && !waitingForPathCalculation && canSearch) {
|
||||
// TODO: What if canSearch is false? How do we notify other scripts that might be handling the path calculation that a new path needs to be calculated?
|
||||
SearchPath();
|
||||
}
|
||||
|
||||
return position;
|
||||
}
|
||||
|
||||
/// <summary>Called during either Update or FixedUpdate depending on if rigidbodies are used for movement or not</summary>
|
||||
protected override void MovementUpdateInternal (float deltaTime, out Vector3 nextPosition, out Quaternion nextRotation) {
|
||||
if (updatePosition) simulatedPosition = tr.position;
|
||||
if (updateRotation) simulatedRotation = tr.rotation;
|
||||
|
||||
RichPathPart currentPart = richPath.GetCurrentPart();
|
||||
|
||||
if (currentPart is RichSpecial) {
|
||||
// Start traversing the off mesh link if we haven't done it yet
|
||||
if (!traversingOffMeshLink && !richPath.CompletedAllParts) {
|
||||
StartCoroutine(TraverseSpecial(currentPart as RichSpecial));
|
||||
}
|
||||
|
||||
nextPosition = steeringTarget = simulatedPosition;
|
||||
nextRotation = rotation;
|
||||
} else {
|
||||
var funnel = currentPart as RichFunnel;
|
||||
|
||||
// Check if we have a valid path to follow and some other script has not stopped the character
|
||||
if (funnel != null && !isStopped) {
|
||||
TraverseFunnel(funnel, deltaTime, out nextPosition, out nextRotation);
|
||||
} else {
|
||||
// Unknown, null path part, or the character is stopped
|
||||
// Slow down as quickly as possible
|
||||
velocity2D -= Vector2.ClampMagnitude(velocity2D, acceleration * deltaTime);
|
||||
FinalMovement(simulatedPosition, deltaTime, float.PositiveInfinity, 1f, out nextPosition, out nextRotation);
|
||||
steeringTarget = simulatedPosition;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TraverseFunnel (RichFunnel fn, float deltaTime, out Vector3 nextPosition, out Quaternion nextRotation) {
|
||||
// Clamp the current position to the navmesh
|
||||
// and update the list of upcoming corners in the path
|
||||
// and store that in the 'nextCorners' field
|
||||
var position3D = UpdateTarget(fn);
|
||||
float elevation;
|
||||
Vector2 position = movementPlane.ToPlane(position3D, out elevation);
|
||||
|
||||
// Only find nearby walls every 5th frame to improve performance
|
||||
if (GetSync().Time.frameCount % 5 == 0 && wallForce > 0 && wallDist > 0) {
|
||||
wallBuffer.Clear();
|
||||
fn.FindWalls(wallBuffer, wallDist);
|
||||
}
|
||||
|
||||
// Target point
|
||||
steeringTarget = nextCorners[0];
|
||||
Vector2 targetPoint = movementPlane.ToPlane(steeringTarget);
|
||||
// Direction to target
|
||||
Vector2 dir = targetPoint - position;
|
||||
|
||||
// Normalized direction to the target
|
||||
Vector2 normdir = VectorMath.Normalize(dir, out distanceToSteeringTarget);
|
||||
// Calculate force from walls
|
||||
Vector2 wallForceVector = CalculateWallForce(position, elevation, normdir);
|
||||
Vector2 targetVelocity;
|
||||
|
||||
if (approachingPartEndpoint) {
|
||||
targetVelocity = slowdownTime > 0 ? Vector2.zero : normdir * maxSpeed;
|
||||
|
||||
// Reduce the wall avoidance force as we get closer to our target
|
||||
wallForceVector *= System.Math.Min(distanceToSteeringTarget/0.5f, 1);
|
||||
|
||||
if (distanceToSteeringTarget <= endReachedDistance) {
|
||||
// Reached the end of the path or an off mesh link
|
||||
NextPart();
|
||||
}
|
||||
} else {
|
||||
var nextNextCorner = nextCorners.Count > 1 ? movementPlane.ToPlane(nextCorners[1]) : position + 2*dir;
|
||||
targetVelocity = (nextNextCorner - targetPoint).normalized * maxSpeed;
|
||||
}
|
||||
|
||||
var forwards = movementPlane.ToPlane(simulatedRotation * (orientation == OrientationMode.YAxisForward ? Vector3.up : Vector3.forward));
|
||||
Vector2 accel = MovementUtilities.CalculateAccelerationToReachPoint(targetPoint - position, targetVelocity, velocity2D, acceleration, rotationSpeed, maxSpeed, forwards);
|
||||
|
||||
// Update the velocity using the acceleration
|
||||
velocity2D += (accel + wallForceVector*wallForce)*deltaTime;
|
||||
|
||||
// Distance to the end of the path (almost as the crow flies)
|
||||
var distanceToEndOfPath = distanceToSteeringTarget + Vector3.Distance(steeringTarget, fn.exactEnd);
|
||||
var slowdownFactor = distanceToEndOfPath < maxSpeed * slowdownTime? Mathf.Sqrt(distanceToEndOfPath / (maxSpeed * slowdownTime)) : 1;
|
||||
FinalMovement(position3D, deltaTime, distanceToEndOfPath, slowdownFactor, out nextPosition, out nextRotation);
|
||||
}
|
||||
|
||||
void FinalMovement (Vector3 position3D, float deltaTime, float distanceToEndOfPath, float slowdownFactor, out Vector3 nextPosition, out Quaternion nextRotation) {
|
||||
var forwards = movementPlane.ToPlane(simulatedRotation * (orientation == OrientationMode.YAxisForward ? Vector3.up : Vector3.forward));
|
||||
|
||||
velocity2D = MovementUtilities.ClampVelocity(velocity2D, maxSpeed, slowdownFactor, slowWhenNotFacingTarget && enableRotation, forwards);
|
||||
|
||||
ApplyGravity(deltaTime);
|
||||
|
||||
if (rvoController != null && rvoController.enabled) {
|
||||
// Send a message to the RVOController that we want to move
|
||||
// with this velocity. In the next simulation step, this
|
||||
// velocity will be processed and it will be fed back to the
|
||||
// rvo controller and finally it will be used by this script
|
||||
// when calling the CalculateMovementDelta method below
|
||||
|
||||
// Make sure that we don't move further than to the end point
|
||||
// of the path. If the RVO simulation FPS is low and we did
|
||||
// not do this, the agent might overshoot the target a lot.
|
||||
var rvoTarget = position3D + movementPlane.ToWorld(Vector2.ClampMagnitude(velocity2D, distanceToEndOfPath));
|
||||
rvoController.SetTarget(rvoTarget, velocity2D.magnitude, maxSpeed);
|
||||
}
|
||||
|
||||
// Direction and distance to move during this frame
|
||||
var deltaPosition = lastDeltaPosition = CalculateDeltaToMoveThisFrame(movementPlane.ToPlane(position3D), distanceToEndOfPath, deltaTime);
|
||||
|
||||
// Rotate towards the direction we are moving in
|
||||
// Slow down the rotation of the character very close to the endpoint of the path to prevent oscillations
|
||||
var rotationSpeedFactor = approachingPartEndpoint ? Mathf.Clamp01(1.1f * slowdownFactor - 0.1f) : 1f;
|
||||
nextRotation = enableRotation ? SimulateRotationTowards(deltaPosition, rotationSpeed * rotationSpeedFactor * deltaTime) : simulatedRotation;
|
||||
|
||||
nextPosition = position3D + movementPlane.ToWorld(deltaPosition, verticalVelocity * deltaTime);
|
||||
}
|
||||
|
||||
protected override Vector3 ClampToNavmesh (Vector3 position, out bool positionChanged) {
|
||||
if (richPath != null) {
|
||||
var funnel = richPath.GetCurrentPart() as RichFunnel;
|
||||
if (funnel != null) {
|
||||
var clampedPosition = funnel.ClampToNavmesh(position);
|
||||
|
||||
// We cannot simply check for equality because some precision may be lost
|
||||
// if any coordinate transformations are used.
|
||||
var difference = movementPlane.ToPlane(clampedPosition - position);
|
||||
float sqrDifference = difference.sqrMagnitude;
|
||||
if (sqrDifference > 0.001f*0.001f) {
|
||||
// The agent was outside the navmesh. Remove that component of the velocity
|
||||
// so that the velocity only goes along the direction of the wall, not into it
|
||||
velocity2D -= difference * Vector2.Dot(difference, velocity2D) / sqrDifference;
|
||||
|
||||
// Make sure the RVO system knows that there was a collision here
|
||||
// Otherwise other agents may think this agent continued
|
||||
// to move forwards and avoidance quality may suffer
|
||||
if (rvoController != null && rvoController.enabled) {
|
||||
rvoController.SetCollisionNormal(difference);
|
||||
}
|
||||
positionChanged = true;
|
||||
// Return the new position, but ignore any changes in the y coordinate from the ClampToNavmesh method as the y coordinates in the navmesh are rarely very accurate
|
||||
return position + movementPlane.ToWorld(difference);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
positionChanged = false;
|
||||
return position;
|
||||
}
|
||||
|
||||
Vector2 CalculateWallForce (Vector2 position, float elevation, Vector2 directionToTarget) {
|
||||
if (wallForce <= 0 || wallDist <= 0) return Vector2.zero;
|
||||
|
||||
float wLeft = 0;
|
||||
float wRight = 0;
|
||||
|
||||
var position3D = movementPlane.ToWorld(position, elevation);
|
||||
for (int i = 0; i < wallBuffer.Count; i += 2) {
|
||||
Vector3 closest = VectorMath.ClosestPointOnSegment(wallBuffer[i], wallBuffer[i+1], position3D);
|
||||
float dist = (closest-position3D).sqrMagnitude;
|
||||
|
||||
if (dist > wallDist*wallDist) continue;
|
||||
|
||||
Vector2 tang = movementPlane.ToPlane(wallBuffer[i+1]-wallBuffer[i]).normalized;
|
||||
|
||||
// Using the fact that all walls are laid out clockwise (looking from inside the obstacle)
|
||||
// Then left and right (ish) can be figured out like this
|
||||
float dot = Vector2.Dot(directionToTarget, tang);
|
||||
float weight = 1 - System.Math.Max(0, (2*(dist / (wallDist*wallDist))-1));
|
||||
if (dot > 0) wRight = System.Math.Max(wRight, dot * weight);
|
||||
else wLeft = System.Math.Max(wLeft, -dot * weight);
|
||||
}
|
||||
|
||||
Vector2 normal = new Vector2(directionToTarget.y, -directionToTarget.x);
|
||||
return normal*(wRight-wLeft);
|
||||
}
|
||||
|
||||
/// <summary>Traverses an off-mesh link</summary>
|
||||
protected virtual IEnumerator TraverseSpecial (RichSpecial link) {
|
||||
traversingOffMeshLink = true;
|
||||
// The current path part is a special part, for example a link
|
||||
// Movement during this part of the path is handled by the TraverseSpecial coroutine
|
||||
velocity2D = Vector3.zero;
|
||||
var offMeshLinkCoroutine = onTraverseOffMeshLink != null? onTraverseOffMeshLink(link) : TraverseOffMeshLinkFallback(link);
|
||||
yield return StartCoroutine(offMeshLinkCoroutine);
|
||||
|
||||
// Off-mesh link traversal completed
|
||||
traversingOffMeshLink = false;
|
||||
NextPart();
|
||||
|
||||
// If a path completed during the time we traversed the special connection, we need to recalculate it
|
||||
if (delayUpdatePath) {
|
||||
delayUpdatePath = false;
|
||||
// TODO: What if canSearch is false? How do we notify other scripts that might be handling the path calculation that a new path needs to be calculated?
|
||||
if (canSearch) SearchPath();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Fallback for traversing off-mesh links in case <see cref="onTraverseOffMeshLink"/> is not set.
|
||||
/// This will do a simple linear interpolation along the link.
|
||||
/// </summary>
|
||||
protected IEnumerator TraverseOffMeshLinkFallback (RichSpecial link) {
|
||||
float duration = maxSpeed > 0 ? Vector3.Distance(link.second.position, link.first.position) / maxSpeed : 1;
|
||||
float startTime = GetSync().Time.time;
|
||||
|
||||
while (true) {
|
||||
var pos = Vector3.Lerp(link.first.position, link.second.position, Mathf.InverseLerp(startTime, startTime + duration, GetSync().Time.time));
|
||||
if (updatePosition) tr.position = pos;
|
||||
else simulatedPosition = pos;
|
||||
|
||||
if (GetSync().Time.time >= startTime + duration) break;
|
||||
yield return null;
|
||||
}
|
||||
}
|
||||
|
||||
protected static readonly Color GizmoColorPath = new Color(8.0f/255, 78.0f/255, 194.0f/255);
|
||||
|
||||
protected override void OnDrawGizmos () {
|
||||
base.OnDrawGizmos();
|
||||
|
||||
if (tr != null) {
|
||||
Gizmos.color = GizmoColorPath;
|
||||
Vector3 lastPosition = position;
|
||||
for (int i = 0; i < nextCorners.Count; lastPosition = nextCorners[i], i++) {
|
||||
Gizmos.DrawLine(lastPosition, nextCorners[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected override int OnUpgradeSerializedData (int version, bool unityThread) {
|
||||
#pragma warning disable 618
|
||||
if (unityThread && animCompatibility != null) anim = animCompatibility;
|
||||
#pragma warning restore 618
|
||||
return base.OnUpgradeSerializedData(version, unityThread);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ce11ea984e202491d9271f53021d8b89
|
||||
timeCreated: 1491225739
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,896 @@
|
||||
using UnityEngine;
|
||||
using System.Collections.Generic;
|
||||
using Pathfinding.Util;
|
||||
|
||||
namespace Pathfinding {
|
||||
public class RichPath {
|
||||
int currentPart;
|
||||
readonly List<RichPathPart> parts = new List<RichPathPart>();
|
||||
|
||||
public Seeker seeker;
|
||||
|
||||
/// <summary>
|
||||
/// Transforms points from path space to world space.
|
||||
/// If null the identity transform will be used.
|
||||
///
|
||||
/// This is used when the world position of the agent does not match the
|
||||
/// corresponding position on the graph. This is the case in the example
|
||||
/// scene called 'Moving'.
|
||||
///
|
||||
/// See: <see cref="Pathfinding.Examples.LocalSpaceRichAI"/>
|
||||
/// </summary>
|
||||
public ITransform transform;
|
||||
|
||||
public RichPath () {
|
||||
Clear();
|
||||
}
|
||||
|
||||
public void Clear () {
|
||||
parts.Clear();
|
||||
currentPart = 0;
|
||||
Endpoint = new Vector3(float.PositiveInfinity, float.PositiveInfinity, float.PositiveInfinity);
|
||||
}
|
||||
|
||||
/// <summary>Use this for initialization.</summary>
|
||||
/// <param name="seeker">Optionally provide in order to take tag penalties into account. May be null if you do not use a Seeker\</param>
|
||||
/// <param name="path">Path to follow</param>
|
||||
/// <param name="mergePartEndpoints">If true, then adjacent parts that the path is split up in will
|
||||
/// try to use the same start/end points. For example when using a link on a navmesh graph
|
||||
/// Instead of first following the path to the center of the node where the link is and then
|
||||
/// follow the link, the path will be adjusted to go to the exact point where the link starts
|
||||
/// which usually makes more sense.</param>
|
||||
/// <param name="simplificationMode">The path can optionally be simplified. This can be a bit expensive for long paths.</param>
|
||||
public void Initialize (Seeker seeker, Path path, bool mergePartEndpoints, bool simplificationMode) {
|
||||
if (path.error) throw new System.ArgumentException("Path has an error");
|
||||
|
||||
List<GraphNode> nodes = path.path;
|
||||
if (nodes.Count == 0) throw new System.ArgumentException("Path traverses no nodes");
|
||||
|
||||
this.seeker = seeker;
|
||||
// Release objects back to object pool
|
||||
// Yeah, I know, it's casting... but this won't be called much
|
||||
for (int i = 0; i < parts.Count; i++) {
|
||||
var funnelPart = parts[i] as RichFunnel;
|
||||
var specialPart = parts[i] as RichSpecial;
|
||||
if (funnelPart != null) ObjectPool<RichFunnel>.Release(ref funnelPart);
|
||||
else if (specialPart != null) ObjectPool<RichSpecial>.Release(ref specialPart);
|
||||
}
|
||||
|
||||
Clear();
|
||||
|
||||
// Initialize new
|
||||
Endpoint = path.vectorPath[path.vectorPath.Count-1];
|
||||
|
||||
//Break path into parts
|
||||
for (int i = 0; i < nodes.Count; i++) {
|
||||
if (nodes[i] is TriangleMeshNode) {
|
||||
var graph = AstarData.GetGraph(nodes[i]) as NavmeshBase;
|
||||
if (graph == null) throw new System.Exception("Found a TriangleMeshNode that was not in a NavmeshBase graph");
|
||||
|
||||
RichFunnel f = ObjectPool<RichFunnel>.Claim().Initialize(this, graph);
|
||||
|
||||
f.funnelSimplification = simplificationMode;
|
||||
|
||||
int sIndex = i;
|
||||
uint currentGraphIndex = nodes[sIndex].GraphIndex;
|
||||
|
||||
|
||||
for (; i < nodes.Count; i++) {
|
||||
if (nodes[i].GraphIndex != currentGraphIndex && !(nodes[i] is NodeLink3Node)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
i--;
|
||||
|
||||
if (sIndex == 0) {
|
||||
f.exactStart = path.vectorPath[0];
|
||||
} else {
|
||||
f.exactStart = (Vector3)nodes[mergePartEndpoints ? sIndex-1 : sIndex].position;
|
||||
}
|
||||
|
||||
if (i == nodes.Count-1) {
|
||||
f.exactEnd = path.vectorPath[path.vectorPath.Count-1];
|
||||
} else {
|
||||
f.exactEnd = (Vector3)nodes[mergePartEndpoints ? i+1 : i].position;
|
||||
}
|
||||
|
||||
f.BuildFunnelCorridor(nodes, sIndex, i);
|
||||
|
||||
parts.Add(f);
|
||||
} else if (NodeLink2.GetNodeLink(nodes[i]) != null) {
|
||||
NodeLink2 nl = NodeLink2.GetNodeLink(nodes[i]);
|
||||
|
||||
int sIndex = i;
|
||||
uint currentGraphIndex = nodes[sIndex].GraphIndex;
|
||||
|
||||
for (i++; i < nodes.Count; i++) {
|
||||
if (nodes[i].GraphIndex != currentGraphIndex) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
i--;
|
||||
|
||||
if (i - sIndex > 1) {
|
||||
throw new System.Exception("NodeLink2 path length greater than two (2) nodes. " + (i - sIndex));
|
||||
} else if (i - sIndex == 0) {
|
||||
//Just continue, it might be the case that a NodeLink was the closest node
|
||||
continue;
|
||||
}
|
||||
|
||||
RichSpecial rps = ObjectPool<RichSpecial>.Claim().Initialize(nl, nodes[sIndex]);
|
||||
parts.Add(rps);
|
||||
} else if (!(nodes[i] is PointNode)) {
|
||||
// Some other graph type which we do not have support for
|
||||
throw new System.InvalidOperationException("The RichAI movment script can only be used on recast/navmesh graphs. A node of type " + nodes[i].GetType().Name + " was in the path.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Vector3 Endpoint { get; private set; }
|
||||
|
||||
/// <summary>True if we have completed (called NextPart for) the last part in the path</summary>
|
||||
public bool CompletedAllParts {
|
||||
get {
|
||||
return currentPart >= parts.Count;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>True if we are traversing the last part of the path</summary>
|
||||
public bool IsLastPart {
|
||||
get {
|
||||
return currentPart >= parts.Count - 1;
|
||||
}
|
||||
}
|
||||
|
||||
public void NextPart () {
|
||||
currentPart = Mathf.Min(currentPart + 1, parts.Count);
|
||||
}
|
||||
|
||||
public RichPathPart GetCurrentPart () {
|
||||
if (parts.Count == 0) return null;
|
||||
return currentPart < parts.Count ? parts[currentPart] : parts[parts.Count - 1];
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Replaces the buffer with the remaining path.
|
||||
/// See: <see cref="Pathfinding.IAstarAI.GetRemainingPath"/>
|
||||
/// </summary>
|
||||
public void GetRemainingPath (List<Vector3> buffer, Vector3 currentPosition, out bool requiresRepath) {
|
||||
buffer.Clear();
|
||||
buffer.Add(currentPosition);
|
||||
requiresRepath = false;
|
||||
for (int i = currentPart; i < parts.Count; i++) {
|
||||
var part = parts[i];
|
||||
if (part is RichFunnel funnel) {
|
||||
bool lastCorner;
|
||||
if (i != 0) buffer.Add(funnel.exactStart);
|
||||
funnel.Update(i == 0 ? currentPosition : funnel.exactStart, buffer, int.MaxValue, out lastCorner, out requiresRepath);
|
||||
if (requiresRepath) {
|
||||
return;
|
||||
}
|
||||
} else if (part is RichSpecial link) {
|
||||
// By adding all points above the link will look like just a stright line, which is reasonable
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public abstract class RichPathPart : Pathfinding.Util.IAstarPooledObject {
|
||||
public abstract void OnEnterPool();
|
||||
}
|
||||
|
||||
public class RichFunnel : RichPathPart {
|
||||
readonly List<Vector3> left;
|
||||
readonly List<Vector3> right;
|
||||
List<TriangleMeshNode> nodes;
|
||||
public Vector3 exactStart;
|
||||
public Vector3 exactEnd;
|
||||
NavmeshBase graph;
|
||||
int currentNode;
|
||||
Vector3 currentPosition;
|
||||
int checkForDestroyedNodesCounter;
|
||||
RichPath path;
|
||||
int[] triBuffer = new int[3];
|
||||
|
||||
/// <summary>Post process the funnel corridor or not</summary>
|
||||
public bool funnelSimplification = true;
|
||||
|
||||
public RichFunnel () {
|
||||
left = Pathfinding.Util.ListPool<Vector3>.Claim();
|
||||
right = Pathfinding.Util.ListPool<Vector3>.Claim();
|
||||
nodes = new List<TriangleMeshNode>();
|
||||
this.graph = null;
|
||||
}
|
||||
|
||||
/// <summary>Works like a constructor, but can be used even for pooled objects. Returns this for easy chaining</summary>
|
||||
public RichFunnel Initialize (RichPath path, NavmeshBase graph) {
|
||||
if (graph == null) throw new System.ArgumentNullException("graph");
|
||||
if (this.graph != null) throw new System.InvalidOperationException("Trying to initialize an already initialized object. " + graph);
|
||||
|
||||
this.graph = graph;
|
||||
this.path = path;
|
||||
return this;
|
||||
}
|
||||
|
||||
public override void OnEnterPool () {
|
||||
left.Clear();
|
||||
right.Clear();
|
||||
nodes.Clear();
|
||||
graph = null;
|
||||
currentNode = 0;
|
||||
checkForDestroyedNodesCounter = 0;
|
||||
}
|
||||
|
||||
public TriangleMeshNode CurrentNode {
|
||||
get {
|
||||
var node = nodes[currentNode];
|
||||
if (!node.Destroyed) {
|
||||
return node;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Build a funnel corridor from a node list slice.
|
||||
/// The nodes are assumed to be of type TriangleMeshNode.
|
||||
/// </summary>
|
||||
/// <param name="nodes">Nodes to build the funnel corridor from</param>
|
||||
/// <param name="start">Start index in the nodes list</param>
|
||||
/// <param name="end">End index in the nodes list, this index is inclusive</param>
|
||||
public void BuildFunnelCorridor (List<GraphNode> nodes, int start, int end) {
|
||||
//Make sure start and end points are on the correct nodes
|
||||
exactStart = (nodes[start] as MeshNode).ClosestPointOnNode(exactStart);
|
||||
exactEnd = (nodes[end] as MeshNode).ClosestPointOnNode(exactEnd);
|
||||
|
||||
left.Clear();
|
||||
right.Clear();
|
||||
left.Add(exactStart);
|
||||
right.Add(exactStart);
|
||||
|
||||
this.nodes.Clear();
|
||||
|
||||
if (funnelSimplification) {
|
||||
List<GraphNode> tmp = Pathfinding.Util.ListPool<GraphNode>.Claim(end-start);
|
||||
|
||||
SimplifyPath(graph, nodes, start, end, tmp, exactStart, exactEnd);
|
||||
|
||||
if (this.nodes.Capacity < tmp.Count) this.nodes.Capacity = tmp.Count;
|
||||
|
||||
for (int i = 0; i < tmp.Count; i++) {
|
||||
//Guaranteed to be TriangleMeshNodes since they are all in the same graph
|
||||
var node = tmp[i] as TriangleMeshNode;
|
||||
if (node != null) this.nodes.Add(node);
|
||||
}
|
||||
|
||||
Pathfinding.Util.ListPool<GraphNode>.Release(ref tmp);
|
||||
} else {
|
||||
if (this.nodes.Capacity < end-start) this.nodes.Capacity = (end-start);
|
||||
for (int i = start; i <= end; i++) {
|
||||
//Guaranteed to be TriangleMeshNodes since they are all in the same graph
|
||||
var node = nodes[i] as TriangleMeshNode;
|
||||
if (node != null) this.nodes.Add(node);
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < this.nodes.Count-1; i++) {
|
||||
/// <summary>TODO: should use return value in future versions</summary>
|
||||
this.nodes[i].GetPortal(this.nodes[i+1], left, right, false);
|
||||
}
|
||||
|
||||
left.Add(exactEnd);
|
||||
right.Add(exactEnd);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Simplifies a funnel path using linecasting.
|
||||
/// Running time is roughly O(n^2 log n) in the worst case (where n = end-start)
|
||||
/// Actually it depends on how the graph looks, so in theory the actual upper limit on the worst case running time is O(n*m log n) (where n = end-start and m = nodes in the graph)
|
||||
/// but O(n^2 log n) is a much more realistic worst case limit.
|
||||
///
|
||||
/// Requires <see cref="graph"/> to implement IRaycastableGraph
|
||||
/// </summary>
|
||||
void SimplifyPath (IRaycastableGraph graph, List<GraphNode> nodes, int start, int end, List<GraphNode> result, Vector3 startPoint, Vector3 endPoint) {
|
||||
if (graph == null) throw new System.ArgumentNullException("graph");
|
||||
|
||||
if (start > end) {
|
||||
throw new System.ArgumentException("start >= end");
|
||||
}
|
||||
|
||||
// Do a straight line of sight check to see if the path can be simplified to a single line
|
||||
{
|
||||
GraphHitInfo hit;
|
||||
if (!graph.Linecast(startPoint, endPoint, out hit) && hit.node == nodes[end]) {
|
||||
graph.Linecast(startPoint, endPoint, out hit, result);
|
||||
|
||||
long penaltySum = 0;
|
||||
long penaltySum2 = 0;
|
||||
for (int i = start; i <= end; i++) {
|
||||
penaltySum += nodes[i].Penalty + (path.seeker != null ? path.seeker.tagPenalties[nodes[i].Tag] : 0);
|
||||
}
|
||||
|
||||
for (int i = 0; i < result.Count; i++) {
|
||||
penaltySum2 += result[i].Penalty + (path.seeker != null ? path.seeker.tagPenalties[result[i].Tag] : 0);
|
||||
}
|
||||
|
||||
// Allow 40% more penalty on average per node
|
||||
if ((penaltySum*1.4*result.Count) < (penaltySum2*(end-start+1))) {
|
||||
// The straight line penalties are much higher than the original path.
|
||||
// Revert the simplification
|
||||
result.Clear();
|
||||
} else {
|
||||
// The straight line simplification looks good.
|
||||
// We are done here.
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int ostart = start;
|
||||
|
||||
int count = 0;
|
||||
while (true) {
|
||||
if (count++ > 1000) {
|
||||
Debug.LogError("Was the path really long or have we got cought in an infinite loop?");
|
||||
break;
|
||||
}
|
||||
|
||||
if (start == end) {
|
||||
result.Add(nodes[end]);
|
||||
return;
|
||||
}
|
||||
|
||||
int resCount = result.Count;
|
||||
|
||||
// Run a binary search to find the furthest node that we have a clear line of sight to
|
||||
int mx = end+1;
|
||||
int mn = start+1;
|
||||
bool anySucceded = false;
|
||||
while (mx > mn+1) {
|
||||
int mid = (mx+mn)/2;
|
||||
|
||||
GraphHitInfo hit;
|
||||
Vector3 sp = start == ostart ? startPoint : (Vector3)nodes[start].position;
|
||||
Vector3 ep = mid == end ? endPoint : (Vector3)nodes[mid].position;
|
||||
|
||||
// Check if there is an obstacle between these points, or if there is no obstacle, but we didn't end up at the right node.
|
||||
// The second case can happen for example in buildings with multiple floors.
|
||||
if (graph.Linecast(sp, ep, out hit) || hit.node != nodes[mid]) {
|
||||
mx = mid;
|
||||
} else {
|
||||
anySucceded = true;
|
||||
mn = mid;
|
||||
}
|
||||
}
|
||||
|
||||
if (!anySucceded) {
|
||||
result.Add(nodes[start]);
|
||||
|
||||
// It is guaranteed that mn = start+1
|
||||
start = mn;
|
||||
} else {
|
||||
// Replace a part of the path with the straight path to the furthest node we had line of sight to.
|
||||
// Need to redo the linecast to get the trace (i.e. list of nodes along the line of sight).
|
||||
GraphHitInfo hit;
|
||||
Vector3 sp = start == ostart ? startPoint : (Vector3)nodes[start].position;
|
||||
Vector3 ep = mn == end ? endPoint : (Vector3)nodes[mn].position;
|
||||
graph.Linecast(sp, ep, out hit, result);
|
||||
|
||||
long penaltySum = 0;
|
||||
long penaltySum2 = 0;
|
||||
for (int i = start; i <= mn; i++) {
|
||||
penaltySum += nodes[i].Penalty + (path.seeker != null ? path.seeker.tagPenalties[nodes[i].Tag] : 0);
|
||||
}
|
||||
|
||||
for (int i = resCount; i < result.Count; i++) {
|
||||
penaltySum2 += result[i].Penalty + (path.seeker != null ? path.seeker.tagPenalties[result[i].Tag] : 0);
|
||||
}
|
||||
|
||||
// Allow 40% more penalty on average per node
|
||||
if ((penaltySum*1.4*(result.Count-resCount)) < (penaltySum2*(mn-start+1)) || result[result.Count-1] != nodes[mn]) {
|
||||
//Debug.DrawLine ((Vector3)nodes[start].Position, (Vector3)nodes[mn].Position, Color.red);
|
||||
// Linecast hit the wrong node
|
||||
result.RemoveRange(resCount, result.Count-resCount);
|
||||
|
||||
result.Add(nodes[start]);
|
||||
//Debug.Break();
|
||||
start = start+1;
|
||||
} else {
|
||||
//Debug.DrawLine ((Vector3)nodes[start].Position, (Vector3)nodes[mn].Position, Color.green);
|
||||
//Remove nodes[end]
|
||||
result.RemoveAt(result.Count-1);
|
||||
start = mn;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Split funnel at node index splitIndex and throw the nodes up to that point away and replace with prefix.
|
||||
/// Used when the AI has happened to get sidetracked and entered a node outside the funnel.
|
||||
/// </summary>
|
||||
void UpdateFunnelCorridor (int splitIndex, List<TriangleMeshNode> prefix) {
|
||||
nodes.RemoveRange(0, splitIndex);
|
||||
nodes.InsertRange(0, prefix);
|
||||
|
||||
left.Clear();
|
||||
right.Clear();
|
||||
left.Add(exactStart);
|
||||
right.Add(exactStart);
|
||||
|
||||
for (int i = 0; i < nodes.Count-1; i++) {
|
||||
//NOTE should use return value in future versions
|
||||
nodes[i].GetPortal(nodes[i+1], left, right, false);
|
||||
}
|
||||
|
||||
left.Add(exactEnd);
|
||||
right.Add(exactEnd);
|
||||
}
|
||||
|
||||
/// <summary>True if any node in the path is destroyed</summary>
|
||||
bool CheckForDestroyedNodes () {
|
||||
// Loop through all nodes and check if they are destroyed
|
||||
// If so, we really need a recalculation of our path quickly
|
||||
// since there might be an obstacle blocking our path after
|
||||
// a graph update or something similar
|
||||
for (int i = 0, t = nodes.Count; i < t; i++) {
|
||||
if (nodes[i].Destroyed) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Approximate distance (as the crow flies) to the endpoint of this path part.
|
||||
/// See: <see cref="exactEnd"/>
|
||||
/// </summary>
|
||||
public float DistanceToEndOfPath {
|
||||
get {
|
||||
var currentNode = CurrentNode;
|
||||
Vector3 closestOnNode = currentNode != null? currentNode.ClosestPointOnNode(currentPosition) : currentPosition;
|
||||
return (exactEnd - closestOnNode).magnitude;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Clamps the position to the navmesh and repairs the path if the agent has moved slightly outside it.
|
||||
/// You should not call this method with anything other than the agent's position.
|
||||
/// </summary>
|
||||
public Vector3 ClampToNavmesh (Vector3 position) {
|
||||
if (path.transform != null) position = path.transform.InverseTransform(position);
|
||||
ClampToNavmeshInternal(ref position);
|
||||
if (path.transform != null) position = path.transform.Transform(position);
|
||||
return position;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Find the next points to move towards and clamp the position to the navmesh.
|
||||
///
|
||||
/// Returns: The position of the agent clamped to make sure it is inside the navmesh.
|
||||
/// </summary>
|
||||
/// <param name="position">The position of the agent.</param>
|
||||
/// <param name="buffer">Will be filled with up to numCorners points which are the next points in the path towards the target.</param>
|
||||
/// <param name="numCorners">See buffer.</param>
|
||||
/// <param name="lastCorner">True if the buffer contains the end point of the path.</param>
|
||||
/// <param name="requiresRepath">True if nodes along the path have been destroyed and a path recalculation is necessary.</param>
|
||||
public Vector3 Update (Vector3 position, List<Vector3> buffer, int numCorners, out bool lastCorner, out bool requiresRepath) {
|
||||
if (path.transform != null) position = path.transform.InverseTransform(position);
|
||||
|
||||
lastCorner = false;
|
||||
requiresRepath = false;
|
||||
|
||||
// Only check for destroyed nodes every 10 frames
|
||||
if (checkForDestroyedNodesCounter >= 10) {
|
||||
checkForDestroyedNodesCounter = 0;
|
||||
requiresRepath |= CheckForDestroyedNodes();
|
||||
} else {
|
||||
checkForDestroyedNodesCounter++;
|
||||
}
|
||||
|
||||
bool nodesDestroyed = ClampToNavmeshInternal(ref position);
|
||||
|
||||
currentPosition = position;
|
||||
|
||||
if (nodesDestroyed) {
|
||||
// Some nodes on the path have been destroyed
|
||||
// we need to recalculate the path immediately
|
||||
requiresRepath = true;
|
||||
lastCorner = false;
|
||||
buffer.Add(position);
|
||||
} else if (!FindNextCorners(position, currentNode, buffer, numCorners, out lastCorner)) {
|
||||
Debug.LogError("Failed to find next corners in the path");
|
||||
buffer.Add(position);
|
||||
}
|
||||
|
||||
if (path.transform != null) {
|
||||
for (int i = 0; i < buffer.Count; i++) {
|
||||
buffer[i] = path.transform.Transform(buffer[i]);
|
||||
}
|
||||
|
||||
position = path.transform.Transform(position);
|
||||
}
|
||||
|
||||
return position;
|
||||
}
|
||||
|
||||
/// <summary>Cached object to avoid unnecessary allocations</summary>
|
||||
static Queue<TriangleMeshNode> navmeshClampQueue = new Queue<TriangleMeshNode>();
|
||||
/// <summary>Cached object to avoid unnecessary allocations</summary>
|
||||
static List<TriangleMeshNode> navmeshClampList = new List<TriangleMeshNode>();
|
||||
/// <summary>Cached object to avoid unnecessary allocations</summary>
|
||||
static Dictionary<TriangleMeshNode, TriangleMeshNode> navmeshClampDict = new Dictionary<TriangleMeshNode, TriangleMeshNode>();
|
||||
|
||||
/// <summary>
|
||||
/// Searches for the node the agent is inside.
|
||||
/// This will also clamp the position to the navmesh
|
||||
/// and repair the funnel cooridor if the agent moves slightly outside it.
|
||||
///
|
||||
/// Returns: True if nodes along the path have been destroyed so that a path recalculation is required
|
||||
/// </summary>
|
||||
bool ClampToNavmeshInternal (ref Vector3 position) {
|
||||
var previousNode = nodes[currentNode];
|
||||
|
||||
if (previousNode.Destroyed) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Check if we are in the same node as we were in during the last frame and otherwise do a more extensive search
|
||||
if (previousNode.ContainsPoint(position)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// This part of the code is relatively seldom called
|
||||
// Most of the time we are still on the same node as during the previous frame
|
||||
|
||||
var que = navmeshClampQueue;
|
||||
var allVisited = navmeshClampList;
|
||||
var parent = navmeshClampDict;
|
||||
previousNode.TemporaryFlag1 = true;
|
||||
parent[previousNode] = null;
|
||||
que.Enqueue(previousNode);
|
||||
allVisited.Add(previousNode);
|
||||
|
||||
float bestDistance = float.PositiveInfinity;
|
||||
Vector3 bestPoint = position;
|
||||
TriangleMeshNode bestNode = null;
|
||||
|
||||
while (que.Count > 0) {
|
||||
var node = que.Dequeue();
|
||||
|
||||
// Snap to the closest point in XZ space (keep the Y coordinate)
|
||||
// If we would have snapped to the closest point in 3D space, the agent
|
||||
// might slow down when traversing slopes
|
||||
var closest = node.ClosestPointOnNodeXZ(position);
|
||||
var dist = VectorMath.MagnitudeXZ(closest - position);
|
||||
|
||||
// Check if this node is any closer than the previous best node.
|
||||
// Allow for a small margin to both avoid floating point errors and to allow
|
||||
// moving past very small local minima.
|
||||
if (dist <= bestDistance * 1.05f + 0.001f) {
|
||||
if (dist < bestDistance) {
|
||||
bestDistance = dist;
|
||||
bestPoint = closest;
|
||||
bestNode = node;
|
||||
}
|
||||
|
||||
for (int i = 0; i < node.connections.Length; i++) {
|
||||
var neighbour = node.connections[i].node as TriangleMeshNode;
|
||||
if (neighbour != null && !neighbour.TemporaryFlag1) {
|
||||
neighbour.TemporaryFlag1 = true;
|
||||
parent[neighbour] = node;
|
||||
que.Enqueue(neighbour);
|
||||
allVisited.Add(neighbour);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < allVisited.Count; i++) allVisited[i].TemporaryFlag1 = false;
|
||||
allVisited.ClearFast();
|
||||
|
||||
var closestNodeInPath = nodes.IndexOf(bestNode);
|
||||
|
||||
// Move the x and z coordinates of the chararacter but not the y coordinate
|
||||
// because the navmesh surface may not line up with the ground
|
||||
position.x = bestPoint.x;
|
||||
position.z = bestPoint.z;
|
||||
|
||||
// Check if the closest node
|
||||
// was on the path already or if we need to adjust it
|
||||
if (closestNodeInPath == -1) {
|
||||
// Reuse this list, because why not.
|
||||
var prefix = navmeshClampList;
|
||||
|
||||
while (closestNodeInPath == -1) {
|
||||
prefix.Add(bestNode);
|
||||
bestNode = parent[bestNode];
|
||||
closestNodeInPath = nodes.IndexOf(bestNode);
|
||||
}
|
||||
|
||||
// We have found a node containing the position, but it is outside the funnel
|
||||
// Recalculate the funnel to include this node
|
||||
exactStart = position;
|
||||
UpdateFunnelCorridor(closestNodeInPath, prefix);
|
||||
|
||||
prefix.ClearFast();
|
||||
|
||||
// Restart from the first node in the updated path
|
||||
currentNode = 0;
|
||||
} else {
|
||||
currentNode = closestNodeInPath;
|
||||
}
|
||||
|
||||
parent.Clear();
|
||||
// Do a quick check to see if the next node in the path has been destroyed
|
||||
// If that is the case then we should plan a new path immediately
|
||||
return currentNode + 1 < nodes.Count && nodes[currentNode+1].Destroyed;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Fill wallBuffer with all navmesh wall segments close to the current position.
|
||||
/// A wall segment is a node edge which is not shared by any other neighbour node, i.e an outer edge on the navmesh.
|
||||
/// </summary>
|
||||
public void FindWalls (List<Vector3> wallBuffer, float range) {
|
||||
FindWalls(currentNode, wallBuffer, currentPosition, range);
|
||||
}
|
||||
|
||||
void FindWalls (int nodeIndex, List<Vector3> wallBuffer, Vector3 position, float range) {
|
||||
if (range <= 0) return;
|
||||
|
||||
bool negAbort = false;
|
||||
bool posAbort = false;
|
||||
|
||||
range *= range;
|
||||
|
||||
position.y = 0;
|
||||
//Looping as 0,-1,1,-2,2,-3,3,-4,4 etc. Avoids code duplication by keeping it to one loop instead of two
|
||||
for (int i = 0; !negAbort || !posAbort; i = i < 0 ? -i : -i-1) {
|
||||
if (i < 0 && negAbort) continue;
|
||||
if (i > 0 && posAbort) continue;
|
||||
|
||||
if (i < 0 && nodeIndex+i < 0) {
|
||||
negAbort = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (i > 0 && nodeIndex+i >= nodes.Count) {
|
||||
posAbort = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
TriangleMeshNode prev = nodeIndex+i-1 < 0 ? null : nodes[nodeIndex+i-1];
|
||||
TriangleMeshNode node = nodes[nodeIndex+i];
|
||||
TriangleMeshNode next = nodeIndex+i+1 >= nodes.Count ? null : nodes[nodeIndex+i+1];
|
||||
|
||||
if (node.Destroyed) {
|
||||
break;
|
||||
}
|
||||
|
||||
if ((node.ClosestPointOnNodeXZ(position)-position).sqrMagnitude > range) {
|
||||
if (i < 0) negAbort = true;
|
||||
else posAbort = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
for (int j = 0; j < 3; j++) triBuffer[j] = 0;
|
||||
|
||||
for (int j = 0; j < node.connections.Length; j++) {
|
||||
var other = node.connections[j].node as TriangleMeshNode;
|
||||
if (other == null) continue;
|
||||
|
||||
int va = -1;
|
||||
for (int a = 0; a < 3; a++) {
|
||||
for (int b = 0; b < 3; b++) {
|
||||
if (node.GetVertex(a) == other.GetVertex((b+1) % 3) && node.GetVertex((a+1) % 3) == other.GetVertex(b)) {
|
||||
va = a;
|
||||
a = 3;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (va == -1) {
|
||||
//No direct connection
|
||||
} else {
|
||||
triBuffer[va] = other == prev || other == next ? 2 : 1;
|
||||
}
|
||||
}
|
||||
|
||||
for (int j = 0; j < 3; j++) {
|
||||
//Tribuffer values
|
||||
// 0 : Navmesh border, outer edge
|
||||
// 1 : Inner edge, to node inside funnel
|
||||
// 2 : Inner edge, to node outside funnel
|
||||
if (triBuffer[j] == 0) {
|
||||
//Add edge to list of walls
|
||||
wallBuffer.Add((Vector3)node.GetVertex(j));
|
||||
wallBuffer.Add((Vector3)node.GetVertex((j+1) % 3));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (path.transform != null) {
|
||||
for (int i = 0; i < wallBuffer.Count; i++) {
|
||||
wallBuffer[i] = path.transform.Transform(wallBuffer[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool FindNextCorners (Vector3 origin, int startIndex, List<Vector3> funnelPath, int numCorners, out bool lastCorner) {
|
||||
lastCorner = false;
|
||||
|
||||
if (left == null) throw new System.Exception("left list is null");
|
||||
if (right == null) throw new System.Exception("right list is null");
|
||||
if (funnelPath == null) throw new System.ArgumentNullException("funnelPath");
|
||||
|
||||
if (left.Count != right.Count) throw new System.ArgumentException("left and right lists must have equal length");
|
||||
|
||||
int diagonalCount = left.Count;
|
||||
|
||||
if (diagonalCount == 0) throw new System.ArgumentException("no diagonals");
|
||||
|
||||
if (diagonalCount-startIndex < 3) {
|
||||
//Direct path
|
||||
funnelPath.Add(left[diagonalCount-1]);
|
||||
lastCorner = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
#if ASTARDEBUG
|
||||
for (int i = startIndex; i < left.Count-1; i++) {
|
||||
Debug.DrawLine(left[i], left[i+1], Color.red);
|
||||
Debug.DrawLine(right[i], right[i+1], Color.magenta);
|
||||
Debug.DrawRay(right[i], Vector3.up, Color.magenta);
|
||||
}
|
||||
for (int i = 0; i < left.Count; i++) {
|
||||
Debug.DrawLine(right[i], left[i], Color.cyan);
|
||||
}
|
||||
#endif
|
||||
|
||||
//Remove identical vertices
|
||||
while (left[startIndex+1] == left[startIndex+2] && right[startIndex+1] == right[startIndex+2]) {
|
||||
//System.Console.WriteLine ("Removing identical left and right");
|
||||
//left.RemoveAt (1);
|
||||
//right.RemoveAt (1);
|
||||
startIndex++;
|
||||
|
||||
if (diagonalCount-startIndex <= 3) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
Vector3 swPoint = left[startIndex+2];
|
||||
if (swPoint == left[startIndex+1]) {
|
||||
swPoint = right[startIndex+2];
|
||||
}
|
||||
|
||||
|
||||
//Test
|
||||
while (VectorMath.IsColinearXZ(origin, left[startIndex+1], right[startIndex+1]) || VectorMath.RightOrColinearXZ(left[startIndex+1], right[startIndex+1], swPoint) == VectorMath.RightOrColinearXZ(left[startIndex+1], right[startIndex+1], origin)) {
|
||||
#if ASTARDEBUG
|
||||
Debug.DrawLine(left[startIndex+1], right[startIndex+1], new Color(0, 0, 0, 0.5F));
|
||||
Debug.DrawLine(origin, swPoint, new Color(0, 0, 0, 0.5F));
|
||||
#endif
|
||||
//left.RemoveAt (1);
|
||||
//right.RemoveAt (1);
|
||||
startIndex++;
|
||||
|
||||
if (diagonalCount-startIndex < 3) {
|
||||
//Debug.Log ("#2 " + left.Count + " - " + startIndex + " = " + (left.Count-startIndex));
|
||||
//Direct path
|
||||
funnelPath.Add(left[diagonalCount-1]);
|
||||
lastCorner = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
swPoint = left[startIndex+2];
|
||||
if (swPoint == left[startIndex+1]) {
|
||||
swPoint = right[startIndex+2];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//funnelPath.Add (origin);
|
||||
|
||||
Vector3 portalApex = origin;
|
||||
Vector3 portalLeft = left[startIndex+1];
|
||||
Vector3 portalRight = right[startIndex+1];
|
||||
|
||||
int apexIndex = startIndex+0;
|
||||
int rightIndex = startIndex+1;
|
||||
int leftIndex = startIndex+1;
|
||||
|
||||
for (int i = startIndex+2; i < diagonalCount; i++) {
|
||||
if (funnelPath.Count >= numCorners) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (funnelPath.Count > 2000) {
|
||||
Debug.LogWarning("Avoiding infinite loop. Remove this check if you have this long paths.");
|
||||
break;
|
||||
}
|
||||
|
||||
Vector3 pLeft = left[i];
|
||||
Vector3 pRight = right[i];
|
||||
|
||||
/*Debug.DrawLine (portalApex,portalLeft,Color.red);
|
||||
* Debug.DrawLine (portalApex,portalRight,Color.yellow);
|
||||
* Debug.DrawLine (portalApex,left,Color.cyan);
|
||||
* Debug.DrawLine (portalApex,right,Color.cyan);*/
|
||||
|
||||
if (VectorMath.SignedTriangleAreaTimes2XZ(portalApex, portalRight, pRight) >= 0) {
|
||||
if (portalApex == portalRight || VectorMath.SignedTriangleAreaTimes2XZ(portalApex, portalLeft, pRight) <= 0) {
|
||||
portalRight = pRight;
|
||||
rightIndex = i;
|
||||
} else {
|
||||
funnelPath.Add(portalLeft);
|
||||
portalApex = portalLeft;
|
||||
apexIndex = leftIndex;
|
||||
|
||||
portalLeft = portalApex;
|
||||
portalRight = portalApex;
|
||||
|
||||
leftIndex = apexIndex;
|
||||
rightIndex = apexIndex;
|
||||
|
||||
i = apexIndex;
|
||||
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (VectorMath.SignedTriangleAreaTimes2XZ(portalApex, portalLeft, pLeft) <= 0) {
|
||||
if (portalApex == portalLeft || VectorMath.SignedTriangleAreaTimes2XZ(portalApex, portalRight, pLeft) >= 0) {
|
||||
portalLeft = pLeft;
|
||||
leftIndex = i;
|
||||
} else {
|
||||
funnelPath.Add(portalRight);
|
||||
portalApex = portalRight;
|
||||
apexIndex = rightIndex;
|
||||
|
||||
portalLeft = portalApex;
|
||||
portalRight = portalApex;
|
||||
|
||||
leftIndex = apexIndex;
|
||||
rightIndex = apexIndex;
|
||||
|
||||
i = apexIndex;
|
||||
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
lastCorner = true;
|
||||
funnelPath.Add(left[diagonalCount-1]);
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
public class RichSpecial : RichPathPart {
|
||||
public NodeLink2 nodeLink;
|
||||
public Transform first;
|
||||
public Transform second;
|
||||
public bool reverse;
|
||||
|
||||
public override void OnEnterPool () {
|
||||
nodeLink = null;
|
||||
}
|
||||
|
||||
/// <summary>Works like a constructor, but can be used even for pooled objects. Returns this for easy chaining</summary>
|
||||
public RichSpecial Initialize (NodeLink2 nodeLink, GraphNode first) {
|
||||
this.nodeLink = nodeLink;
|
||||
if (first == nodeLink.startNode) {
|
||||
this.first = nodeLink.StartTransform;
|
||||
this.second = nodeLink.EndTransform;
|
||||
reverse = false;
|
||||
} else {
|
||||
this.first = nodeLink.EndTransform;
|
||||
this.second = nodeLink.StartTransform;
|
||||
reverse = true;
|
||||
}
|
||||
return this;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6865b0d3859fe4641ad0839b829e00d2
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
@ -0,0 +1,611 @@
|
||||
using UnityEngine;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine.Profiling;
|
||||
|
||||
namespace Pathfinding {
|
||||
/// <summary>
|
||||
/// Handles path calls for a single unit.
|
||||
///
|
||||
/// This is a component which is meant to be attached to a single unit (AI, Robot, Player, whatever) to handle its pathfinding calls.
|
||||
/// It also handles post-processing of paths using modifiers.
|
||||
///
|
||||
/// [Open online documentation to see images]
|
||||
///
|
||||
/// See: calling-pathfinding (view in online documentation for working links)
|
||||
/// See: modifiers (view in online documentation for working links)
|
||||
/// </summary>
|
||||
[AddComponentMenu("Pathfinding/Seeker")]
|
||||
[HelpURL("https://arongranberg.com/astar/documentation/stable/class_pathfinding_1_1_seeker.php")]
|
||||
public class Seeker : VersionedMonoBehaviour {
|
||||
/// <summary>
|
||||
/// Enables drawing of the last calculated path using Gizmos.
|
||||
/// The path will show up in green.
|
||||
///
|
||||
/// See: OnDrawGizmos
|
||||
/// </summary>
|
||||
public bool drawGizmos = true;
|
||||
|
||||
/// <summary>
|
||||
/// Enables drawing of the non-postprocessed path using Gizmos.
|
||||
/// The path will show up in orange.
|
||||
///
|
||||
/// Requires that <see cref="drawGizmos"/> is true.
|
||||
///
|
||||
/// This will show the path before any post processing such as smoothing is applied.
|
||||
///
|
||||
/// See: drawGizmos
|
||||
/// See: OnDrawGizmos
|
||||
/// </summary>
|
||||
public bool detailedGizmos;
|
||||
|
||||
/// <summary>Path modifier which tweaks the start and end points of a path</summary>
|
||||
[HideInInspector]
|
||||
public StartEndModifier startEndModifier = new StartEndModifier();
|
||||
|
||||
/// <summary>
|
||||
/// The tags which the Seeker can traverse.
|
||||
///
|
||||
/// Note: This field is a bitmask.
|
||||
/// See: bitmasks (view in online documentation for working links)
|
||||
/// </summary>
|
||||
[HideInInspector]
|
||||
public int traversableTags = -1;
|
||||
|
||||
/// <summary>
|
||||
/// Penalties for each tag.
|
||||
/// Tag 0 which is the default tag, will have added a penalty of tagPenalties[0].
|
||||
/// These should only be positive values since the A* algorithm cannot handle negative penalties.
|
||||
///
|
||||
/// Note: This array should always have a length of 32 otherwise the system will ignore it.
|
||||
///
|
||||
/// See: Pathfinding.Path.tagPenalties
|
||||
/// </summary>
|
||||
[HideInInspector]
|
||||
public int[] tagPenalties = new int[32];
|
||||
|
||||
/// <summary>
|
||||
/// Graphs that this Seeker can use.
|
||||
/// This field determines which graphs will be considered when searching for the start and end nodes of a path.
|
||||
/// It is useful in numerous situations, for example if you want to make one graph for small units and one graph for large units.
|
||||
///
|
||||
/// This is a bitmask so if you for example want to make the agent only use graph index 3 then you can set this to:
|
||||
/// <code> seeker.graphMask = 1 << 3; </code>
|
||||
///
|
||||
/// See: bitmasks (view in online documentation for working links)
|
||||
///
|
||||
/// Note that this field only stores which graph indices that are allowed. This means that if the graphs change their ordering
|
||||
/// then this mask may no longer be correct.
|
||||
///
|
||||
/// If you know the name of the graph you can use the <see cref="Pathfinding.GraphMask.FromGraphName"/> method:
|
||||
/// <code>
|
||||
/// GraphMask mask1 = GraphMask.FromGraphName("My Grid Graph");
|
||||
/// GraphMask mask2 = GraphMask.FromGraphName("My Other Grid Graph");
|
||||
///
|
||||
/// NNConstraint nn = NNConstraint.Walkable;
|
||||
///
|
||||
/// nn.graphMask = mask1 | mask2;
|
||||
///
|
||||
/// // Find the node closest to somePoint which is either in 'My Grid Graph' OR in 'My Other Grid Graph'
|
||||
/// var info = AstarPath.active.GetNearest(somePoint, nn);
|
||||
/// </code>
|
||||
///
|
||||
/// Some overloads of the <see cref="StartPath"/> methods take a graphMask parameter. If those overloads are used then they
|
||||
/// will override the graph mask for that path request.
|
||||
///
|
||||
/// [Open online documentation to see images]
|
||||
///
|
||||
/// See: multiple-agent-types (view in online documentation for working links)
|
||||
/// </summary>
|
||||
[HideInInspector]
|
||||
public GraphMask graphMask = GraphMask.everything;
|
||||
|
||||
/// <summary>
|
||||
/// Custom traversal provider to calculate which nodes are traversable and their penalties.
|
||||
///
|
||||
/// This can be used to override the built-in pathfinding logic.
|
||||
///
|
||||
/// <code>
|
||||
/// seeker.traversalProvider = new MyCustomTraversalProvider();
|
||||
/// </code>
|
||||
///
|
||||
/// See: traversal_provider (view in online documentation for working links)
|
||||
/// </summary>
|
||||
public ITraversalProvider traversalProvider;
|
||||
|
||||
/// <summary>Used for serialization backwards compatibility</summary>
|
||||
[UnityEngine.Serialization.FormerlySerializedAs("graphMask")]
|
||||
int graphMaskCompatibility = -1;
|
||||
|
||||
/// <summary>
|
||||
/// Callback for when a path is completed.
|
||||
/// Movement scripts should register to this delegate.
|
||||
/// A temporary callback can also be set when calling StartPath, but that delegate will only be called for that path
|
||||
/// </summary>
|
||||
public OnPathDelegate pathCallback;
|
||||
|
||||
/// <summary>Called before pathfinding is started</summary>
|
||||
public OnPathDelegate preProcessPath;
|
||||
|
||||
/// <summary>Called after a path has been calculated, right before modifiers are executed.</summary>
|
||||
public OnPathDelegate postProcessPath;
|
||||
|
||||
#if UNITY_EDITOR
|
||||
/// <summary>Used for drawing gizmos</summary>
|
||||
[System.NonSerialized]
|
||||
List<Vector3> lastCompletedVectorPath;
|
||||
|
||||
/// <summary>Used for drawing gizmos</summary>
|
||||
[System.NonSerialized]
|
||||
List<GraphNode> lastCompletedNodePath;
|
||||
#endif
|
||||
|
||||
/// <summary>The current path</summary>
|
||||
[System.NonSerialized]
|
||||
protected Path path;
|
||||
|
||||
/// <summary>Previous path. Used to draw gizmos</summary>
|
||||
[System.NonSerialized]
|
||||
private Path prevPath;
|
||||
|
||||
/// <summary>Cached delegate to avoid allocating one every time a path is started</summary>
|
||||
private readonly OnPathDelegate onPathDelegate;
|
||||
/// <summary>Cached delegate to avoid allocating one every time a path is started</summary>
|
||||
private readonly OnPathDelegate onPartialPathDelegate;
|
||||
|
||||
/// <summary>Temporary callback only called for the current path. This value is set by the StartPath functions</summary>
|
||||
private OnPathDelegate tmpPathCallback;
|
||||
|
||||
/// <summary>The path ID of the last path queried</summary>
|
||||
protected uint lastPathID;
|
||||
|
||||
/// <summary>Internal list of all modifiers</summary>
|
||||
readonly List<IPathModifier> modifiers = new List<IPathModifier>();
|
||||
|
||||
public enum ModifierPass {
|
||||
PreProcess,
|
||||
// An obsolete item occupied index 1 previously
|
||||
PostProcess = 2,
|
||||
}
|
||||
|
||||
public Seeker () {
|
||||
onPathDelegate = OnPathComplete;
|
||||
onPartialPathDelegate = OnPartialPathComplete;
|
||||
}
|
||||
|
||||
public override void OnSyncLoad()
|
||||
{
|
||||
base.OnSyncLoad();
|
||||
startEndModifier.Awake(this);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Path that is currently being calculated or was last calculated.
|
||||
/// You should rarely have to use this. Instead get the path when the path callback is called.
|
||||
///
|
||||
/// See: <see cref="StartPath"/>
|
||||
/// </summary>
|
||||
public Path GetCurrentPath() => path;
|
||||
|
||||
/// <summary>
|
||||
/// Stop calculating the current path request.
|
||||
/// If this Seeker is currently calculating a path it will be canceled.
|
||||
/// The callback (usually to a method named OnPathComplete) will soon be called
|
||||
/// with a path that has the 'error' field set to true.
|
||||
///
|
||||
/// This does not stop the character from moving, it just aborts
|
||||
/// the path calculation.
|
||||
/// </summary>
|
||||
/// <param name="pool">If true then the path will be pooled when the pathfinding system is done with it.</param>
|
||||
public void CancelCurrentPathRequest (bool pool = true) {
|
||||
if (!IsDone()) {
|
||||
path.FailWithError("Canceled by script (Seeker.CancelCurrentPathRequest)");
|
||||
if (pool) {
|
||||
// Make sure the path has had its reference count incremented and decremented once.
|
||||
// If this is not done the system will think no pooling is used at all and will not pool the path.
|
||||
// The particular object that is used as the parameter (in this case 'path') doesn't matter at all
|
||||
// it just has to be *some* object.
|
||||
path.Claim(path);
|
||||
path.Release(path);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Cleans up some variables.
|
||||
/// Releases any eventually claimed paths.
|
||||
/// Calls OnDestroy on the <see cref="startEndModifier"/>.
|
||||
///
|
||||
/// See: <see cref="ReleaseClaimedPath"/>
|
||||
/// See: <see cref="startEndModifier"/>
|
||||
/// </summary>
|
||||
void OnDestroy () {
|
||||
ReleaseClaimedPath();
|
||||
startEndModifier.OnDestroy(this);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Releases the path used for gizmos (if any).
|
||||
/// The seeker keeps the latest path claimed so it can draw gizmos.
|
||||
/// In some cases this might not be desireable and you want it released.
|
||||
/// In that case, you can call this method to release it (not that path gizmos will then not be drawn).
|
||||
///
|
||||
/// If you didn't understand anything from the description above, you probably don't need to use this method.
|
||||
///
|
||||
/// See: pooling (view in online documentation for working links)
|
||||
/// </summary>
|
||||
void ReleaseClaimedPath () {
|
||||
if (prevPath != null) {
|
||||
prevPath.Release(this, true);
|
||||
prevPath = null;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Called by modifiers to register themselves</summary>
|
||||
public void RegisterModifier (IPathModifier modifier) {
|
||||
modifiers.Add(modifier);
|
||||
|
||||
// Sort the modifiers based on their specified order
|
||||
modifiers.Sort((a, b) => a.Order.CompareTo(b.Order));
|
||||
}
|
||||
|
||||
/// <summary>Called by modifiers when they are disabled or destroyed</summary>
|
||||
public void DeregisterModifier (IPathModifier modifier) {
|
||||
modifiers.Remove(modifier);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Post Processes the path.
|
||||
/// This will run any modifiers attached to this GameObject on the path.
|
||||
/// This is identical to calling RunModifiers(ModifierPass.PostProcess, path)
|
||||
/// See: <see cref="RunModifiers"/>
|
||||
/// </summary>
|
||||
public void PostProcess (Path path) {
|
||||
RunModifiers(ModifierPass.PostProcess, path);
|
||||
}
|
||||
|
||||
/// <summary>Runs modifiers on a path</summary>
|
||||
public void RunModifiers (ModifierPass pass, Path path) {
|
||||
if (pass == ModifierPass.PreProcess) {
|
||||
if (preProcessPath != null) preProcessPath(path);
|
||||
|
||||
for (int i = 0; i < modifiers.Count; i++) modifiers[i].PreProcess(path);
|
||||
} else if (pass == ModifierPass.PostProcess) {
|
||||
Profiler.BeginSample("Running Path Modifiers");
|
||||
// Call delegates if they exist
|
||||
if (postProcessPath != null) postProcessPath(path);
|
||||
|
||||
// Loop through all modifiers and apply post processing
|
||||
for (int i = 0; i < modifiers.Count; i++) modifiers[i].Apply(path);
|
||||
Profiler.EndSample();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Is the current path done calculating.
|
||||
/// Returns true if the current <see cref="path"/> has been returned or if the <see cref="path"/> is null.
|
||||
///
|
||||
/// Note: Do not confuse this with Pathfinding.Path.IsDone. They usually return the same value, but not always.
|
||||
/// The path might be completely calculated, but has not yet been processed by the Seeker.
|
||||
///
|
||||
/// Inside the OnPathComplete callback this method will return true.
|
||||
///
|
||||
/// Version: Before version 4.2.19 this would return false inside the OnPathComplete callback. However this behaviour was unintuitive.
|
||||
/// </summary>
|
||||
public bool IsDone() => path == null || path.PipelineState >= PathState.Returning;
|
||||
|
||||
/// <summary>Called when a path has completed</summary>
|
||||
void OnPathComplete (Path path) {
|
||||
OnPathComplete(path, true, true);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Called when a path has completed.
|
||||
/// Will post process it and return it by calling <see cref="tmpPathCallback"/> and <see cref="pathCallback"/>
|
||||
/// </summary>
|
||||
void OnPathComplete (Path p, bool runModifiers, bool sendCallbacks) {
|
||||
if (p != null && p != path && sendCallbacks) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (this == null || p == null || p != path)
|
||||
return;
|
||||
|
||||
if (!path.error && runModifiers) {
|
||||
// This will send the path for post processing to modifiers attached to this Seeker
|
||||
RunModifiers(ModifierPass.PostProcess, path);
|
||||
}
|
||||
|
||||
if (sendCallbacks) {
|
||||
p.Claim(this);
|
||||
|
||||
#if UNITY_EDITOR
|
||||
lastCompletedNodePath = p.path;
|
||||
lastCompletedVectorPath = p.vectorPath;
|
||||
#endif
|
||||
|
||||
// This will send the path to the callback (if any) specified when calling StartPath
|
||||
if (tmpPathCallback != null) {
|
||||
tmpPathCallback(p);
|
||||
}
|
||||
|
||||
// This will send the path to any script which has registered to the callback
|
||||
if (pathCallback != null) {
|
||||
pathCallback(p);
|
||||
}
|
||||
|
||||
// Note: it is important that #prevPath is kept alive (i.e. not pooled)
|
||||
// if we are drawing gizmos.
|
||||
// It is also important that #path is kept alive since it can be returned
|
||||
// from the GetCurrentPath method.
|
||||
// Since #path will be copied to #prevPath it is sufficient that #prevPath
|
||||
// is kept alive until it is replaced.
|
||||
|
||||
// Recycle the previous path to reduce the load on the GC
|
||||
if (prevPath != null) {
|
||||
prevPath.Release(this, true);
|
||||
}
|
||||
|
||||
prevPath = p;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Called for each path in a MultiTargetPath.
|
||||
/// Only post processes the path, does not return it.
|
||||
/// </summary>
|
||||
void OnPartialPathComplete (Path p) {
|
||||
OnPathComplete(p, true, false);
|
||||
}
|
||||
|
||||
/// <summary>Called once for a MultiTargetPath. Only returns the path, does not post process.</summary>
|
||||
void OnMultiPathComplete (Path p) {
|
||||
OnPathComplete(p, false, true);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a new path instance.
|
||||
/// The path will be taken from the path pool if path recycling is turned on.
|
||||
/// This path can be sent to <see cref="StartPath(Path,OnPathDelegate,int)"/> with no change, but if no change is required <see cref="StartPath(Vector3,Vector3,OnPathDelegate)"/> does just that.
|
||||
/// <code>
|
||||
/// var seeker = GetComponent<Seeker>();
|
||||
/// Path p = seeker.GetNewPath (transform.position, transform.position+transform.forward*100);
|
||||
/// // Disable heuristics on just this path for example
|
||||
/// p.heuristic = Heuristic.None;
|
||||
/// seeker.StartPath (p, OnPathComplete);
|
||||
/// </code>
|
||||
/// Deprecated: Use ABPath.Construct(start, end, null) instead.
|
||||
/// </summary>
|
||||
[System.Obsolete("Use ABPath.Construct(start, end, null) instead")]
|
||||
public ABPath GetNewPath (Vector3 start, Vector3 end) {
|
||||
// Construct a path with start and end points
|
||||
return ABPath.Construct(start, end, null);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Call this function to start calculating a path.
|
||||
/// Since this method does not take a callback parameter, you should set the <see cref="pathCallback"/> field before calling this method.
|
||||
/// </summary>
|
||||
/// <param name="start">The start point of the path</param>
|
||||
/// <param name="end">The end point of the path</param>
|
||||
public Path StartPath (Vector3 start, Vector3 end) {
|
||||
return StartPath(start, end, null);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Call this function to start calculating a path.
|
||||
///
|
||||
/// The callback will be called when the path has been calculated (which may be several frames into the future).
|
||||
/// Callback will not be called if the path is canceled (e.g when a new path is requested before the previous one has completed)
|
||||
/// </summary>
|
||||
/// <param name="start">The start point of the path</param>
|
||||
/// <param name="end">The end point of the path</param>
|
||||
/// <param name="callback">The function to call when the path has been calculated</param>
|
||||
public Path StartPath (Vector3 start, Vector3 end, OnPathDelegate callback) {
|
||||
return StartPath(ABPath.Construct(start, end, null), callback);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Call this function to start calculating a path.
|
||||
///
|
||||
/// The callback will be called when the path has been calculated (which may be several frames into the future).
|
||||
/// Callback will not be called if the path is canceled (e.g when a new path is requested before the previous one has completed)
|
||||
/// </summary>
|
||||
/// <param name="start">The start point of the path</param>
|
||||
/// <param name="end">The end point of the path</param>
|
||||
/// <param name="callback">The function to call when the path has been calculated</param>
|
||||
/// <param name="graphMask">Mask used to specify which graphs should be searched for close nodes. See #Pathfinding.NNConstraint.graphMask. This will override #graphMask for this path request.</param>
|
||||
public Path StartPath (Vector3 start, Vector3 end, OnPathDelegate callback, GraphMask graphMask) {
|
||||
return StartPath(ABPath.Construct(start, end, null), callback, graphMask);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Call this function to start calculating a path.
|
||||
///
|
||||
/// The callback will be called when the path has been calculated (which may be several frames into the future).
|
||||
/// The callback will not be called if a new path request is started before this path request has been calculated.
|
||||
///
|
||||
/// Version: Since 3.8.3 this method works properly if a MultiTargetPath is used.
|
||||
/// It now behaves identically to the StartMultiTargetPath(MultiTargetPath) method.
|
||||
///
|
||||
/// Version: Since 4.1.x this method will no longer overwrite the graphMask on the path unless it is explicitly passed as a parameter (see other overloads of this method).
|
||||
/// </summary>
|
||||
/// <param name="p">The path to start calculating</param>
|
||||
/// <param name="callback">The function to call when the path has been calculated</param>
|
||||
public Path StartPath (Path p, OnPathDelegate callback = null) {
|
||||
// Set the graph mask only if the user has not changed it from the default value.
|
||||
// This is not perfect as the user may have wanted it to be precisely -1
|
||||
// however it is the best detection that I can do.
|
||||
// The non-default check is primarily for compatibility reasons to avoid breaking peoples existing code.
|
||||
// The StartPath overloads with an explicit graphMask field should be used instead to set the graphMask.
|
||||
if (p.nnConstraint.graphMask == -1) p.nnConstraint.graphMask = graphMask;
|
||||
StartPathInternal(p, callback);
|
||||
return p;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Call this function to start calculating a path.
|
||||
///
|
||||
/// The callback will be called when the path has been calculated (which may be several frames into the future).
|
||||
/// The callback will not be called if a new path request is started before this path request has been calculated.
|
||||
///
|
||||
/// Version: Since 3.8.3 this method works properly if a MultiTargetPath is used.
|
||||
/// It now behaves identically to the StartMultiTargetPath(MultiTargetPath) method.
|
||||
/// </summary>
|
||||
/// <param name="p">The path to start calculating</param>
|
||||
/// <param name="callback">The function to call when the path has been calculated</param>
|
||||
/// <param name="graphMask">Mask used to specify which graphs should be searched for close nodes. See #Pathfinding.GraphMask. This will override #graphMask for this path request.</param>
|
||||
public Path StartPath (Path p, OnPathDelegate callback, GraphMask graphMask) {
|
||||
p.nnConstraint.graphMask = graphMask;
|
||||
StartPathInternal(p, callback);
|
||||
return p;
|
||||
}
|
||||
|
||||
/// <summary>Internal method to start a path and mark it as the currently active path</summary>
|
||||
void StartPathInternal (Path p, OnPathDelegate callback) {
|
||||
var mtp = p as MultiTargetPath;
|
||||
if (mtp != null) {
|
||||
// TODO: Allocation, cache
|
||||
var callbacks = new OnPathDelegate[mtp.targetPoints.Length];
|
||||
|
||||
for (int i = 0; i < callbacks.Length; i++) {
|
||||
callbacks[i] = onPartialPathDelegate;
|
||||
}
|
||||
|
||||
mtp.callbacks = callbacks;
|
||||
p.callback += OnMultiPathComplete;
|
||||
} else {
|
||||
p.callback += onPathDelegate;
|
||||
}
|
||||
|
||||
p.enabledTags = traversableTags;
|
||||
p.tagPenalties = tagPenalties;
|
||||
if (traversalProvider != null) p.traversalProvider = traversalProvider;
|
||||
|
||||
// Cancel a previously requested path is it has not been processed yet and also make sure that it has not been recycled and used somewhere else
|
||||
if (path != null && path.PipelineState <= PathState.Processing && path.CompleteState != PathCompleteState.Error && lastPathID == path.pathID) {
|
||||
path.FailWithError("Canceled path because a new one was requested.\n"+
|
||||
"This happens when a new path is requested from the seeker when one was already being calculated.\n" +
|
||||
"For example if a unit got a new order, you might request a new path directly instead of waiting for the now" +
|
||||
" invalid path to be calculated. Which is probably what you want.\n" +
|
||||
"If you are getting this a lot, you might want to consider how you are scheduling path requests.");
|
||||
// No callback will be sent for the canceled path
|
||||
}
|
||||
|
||||
// Set p as the active path
|
||||
path = p;
|
||||
tmpPathCallback = callback;
|
||||
|
||||
// Save the path id so we can make sure that if we cancel a path (see above) it should not have been recycled yet.
|
||||
lastPathID = path.pathID;
|
||||
|
||||
// Pre process the path
|
||||
RunModifiers(ModifierPass.PreProcess, path);
|
||||
|
||||
// Send the request to the pathfinder
|
||||
AstarPath.StartPath(path);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Starts a Multi Target Path from one start point to multiple end points.
|
||||
/// A Multi Target Path will search for all the end points in one search and will return all paths if pathsForAll is true, or only the shortest one if pathsForAll is false.
|
||||
///
|
||||
/// callback and <see cref="pathCallback"/> will be called when the path has completed. Callback will not be called if the path is canceled (e.g when a new path is requested before the previous one has completed)
|
||||
///
|
||||
/// See: Pathfinding.MultiTargetPath
|
||||
/// See: MultiTargetPathExample.cs (view in online documentation for working links) "Example of how to use multi-target-paths"
|
||||
/// </summary>
|
||||
/// <param name="start">The start point of the path</param>
|
||||
/// <param name="endPoints">The end points of the path</param>
|
||||
/// <param name="pathsForAll">Indicates whether or not a path to all end points should be searched for or only to the closest one</param>
|
||||
/// <param name="callback">The function to call when the path has been calculated</param>
|
||||
/// <param name="graphMask">Mask used to specify which graphs should be searched for close nodes. See Pathfinding.NNConstraint.graphMask.</param>
|
||||
public MultiTargetPath StartMultiTargetPath (Vector3 start, Vector3[] endPoints, bool pathsForAll, OnPathDelegate callback = null, int graphMask = -1) {
|
||||
MultiTargetPath p = MultiTargetPath.Construct(start, endPoints, null, null);
|
||||
|
||||
p.pathsForAll = pathsForAll;
|
||||
StartPath(p, callback, graphMask);
|
||||
return p;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Starts a Multi Target Path from multiple start points to a single target point.
|
||||
/// A Multi Target Path will search from all start points to the target point in one search and will return all paths if pathsForAll is true, or only the shortest one if pathsForAll is false.
|
||||
///
|
||||
/// callback and <see cref="pathCallback"/> will be called when the path has completed. Callback will not be called if the path is canceled (e.g when a new path is requested before the previous one has completed)
|
||||
///
|
||||
/// See: Pathfinding.MultiTargetPath
|
||||
/// See: MultiTargetPathExample.cs (view in online documentation for working links) "Example of how to use multi-target-paths"
|
||||
/// </summary>
|
||||
/// <param name="startPoints">The start points of the path</param>
|
||||
/// <param name="end">The end point of the path</param>
|
||||
/// <param name="pathsForAll">Indicates whether or not a path from all start points should be searched for or only to the closest one</param>
|
||||
/// <param name="callback">The function to call when the path has been calculated</param>
|
||||
/// <param name="graphMask">Mask used to specify which graphs should be searched for close nodes. See Pathfinding.NNConstraint.graphMask.</param>
|
||||
public MultiTargetPath StartMultiTargetPath (Vector3[] startPoints, Vector3 end, bool pathsForAll, OnPathDelegate callback = null, int graphMask = -1) {
|
||||
MultiTargetPath p = MultiTargetPath.Construct(startPoints, end, null, null);
|
||||
|
||||
p.pathsForAll = pathsForAll;
|
||||
StartPath(p, callback, graphMask);
|
||||
return p;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Starts a Multi Target Path.
|
||||
/// Takes a MultiTargetPath and wires everything up for it to send callbacks to the seeker for post-processing.
|
||||
///
|
||||
/// callback and <see cref="pathCallback"/> will be called when the path has completed. Callback will not be called if the path is canceled (e.g when a new path is requested before the previous one has completed)
|
||||
///
|
||||
/// See: Pathfinding.MultiTargetPath
|
||||
/// See: MultiTargetPathExample.cs (view in online documentation for working links) "Example of how to use multi-target-paths"
|
||||
///
|
||||
/// Version: Since 3.8.3 calling this method behaves identically to calling StartPath with a MultiTargetPath.
|
||||
/// Version: Since 3.8.3 this method also sets enabledTags and tagPenalties on the path object.
|
||||
///
|
||||
/// Deprecated: You can use StartPath instead of this method now. It will behave identically.
|
||||
/// </summary>
|
||||
/// <param name="p">The path to start calculating</param>
|
||||
/// <param name="callback">The function to call when the path has been calculated</param>
|
||||
/// <param name="graphMask">Mask used to specify which graphs should be searched for close nodes. See Pathfinding.NNConstraint.graphMask.</param>
|
||||
[System.Obsolete("You can use StartPath instead of this method now. It will behave identically.")]
|
||||
public MultiTargetPath StartMultiTargetPath (MultiTargetPath p, OnPathDelegate callback = null, int graphMask = -1) {
|
||||
StartPath(p, callback, graphMask);
|
||||
return p;
|
||||
}
|
||||
|
||||
#if UNITY_EDITOR
|
||||
/// <summary>Draws gizmos for the Seeker</summary>
|
||||
public void OnDrawGizmos () {
|
||||
if (lastCompletedNodePath == null || !drawGizmos) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (detailedGizmos) {
|
||||
Gizmos.color = new Color(0.7F, 0.5F, 0.1F, 0.5F);
|
||||
|
||||
if (lastCompletedNodePath != null) {
|
||||
for (int i = 0; i < lastCompletedNodePath.Count-1; i++) {
|
||||
Gizmos.DrawLine((Vector3)lastCompletedNodePath[i].position, (Vector3)lastCompletedNodePath[i+1].position);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Gizmos.color = new Color(0, 1F, 0, 1F);
|
||||
|
||||
if (lastCompletedVectorPath != null) {
|
||||
for (int i = 0; i < lastCompletedVectorPath.Count-1; i++) {
|
||||
Gizmos.DrawLine(lastCompletedVectorPath[i], lastCompletedVectorPath[i+1]);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
protected override int OnUpgradeSerializedData (int version, bool unityThread) {
|
||||
if (graphMaskCompatibility != -1) {
|
||||
Debug.Log("Loaded " + graphMaskCompatibility + " " + graphMask.value);
|
||||
graphMask = graphMaskCompatibility;
|
||||
graphMaskCompatibility = -1;
|
||||
}
|
||||
return base.OnUpgradeSerializedData(version, unityThread);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 373b52eb9bf8c40f785bb6947a1aee66
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
@ -0,0 +1,28 @@
|
||||
using UnityEngine;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Pathfinding.Examples {
|
||||
/// <summary>Helper script in the example scene 'Turn Based'</summary>
|
||||
[HelpURL("https://arongranberg.com/astar/documentation/stable/class_pathfinding_1_1_examples_1_1_turn_based_a_i.php")]
|
||||
public class TurnBasedAI : VersionedMonoBehaviour {
|
||||
public int movementPoints = 2;
|
||||
public BlockManager blockManager;
|
||||
public SingleNodeBlocker blocker;
|
||||
public GraphNode targetNode;
|
||||
public BlockManager.TraversalProvider traversalProvider;
|
||||
|
||||
void Start () {
|
||||
blocker.BlockAtCurrentPosition();
|
||||
}
|
||||
|
||||
public override void OnSyncLoad()
|
||||
{
|
||||
base.OnSyncLoad();
|
||||
// Set the traversal provider to block all nodes that are blocked by a SingleNodeBlocker
|
||||
// except the SingleNodeBlocker owned by this AI (we don't want to be blocked by ourself)
|
||||
traversalProvider = new BlockManager.TraversalProvider(blockManager, BlockManager.BlockMode.AllExceptSelector, new List<SingleNodeBlocker>() { blocker });
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8f95b80c439d6408b9afac9d013922e4
|
||||
timeCreated: 1453035991
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,629 @@
|
||||
using UnityEngine;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using Pathfinding.WindowsStore;
|
||||
using Pathfinding.Serialization;
|
||||
using Pathfinding.Util;
|
||||
#if UNITY_WINRT && !UNITY_EDITOR
|
||||
//using MarkerMetro.Unity.WinLegacy.IO;
|
||||
//using MarkerMetro.Unity.WinLegacy.Reflection;
|
||||
#endif
|
||||
|
||||
namespace Pathfinding {
|
||||
[System.Serializable]
|
||||
/// <summary>
|
||||
/// Stores the navigation graphs for the A* Pathfinding System.
|
||||
///
|
||||
/// An instance of this class is assigned to <see cref="AstarPath.data"/>. From it you can access all graphs loaded through the <see cref="graphs"/> variable.
|
||||
/// This class also handles a lot of the high level serialization.
|
||||
/// </summary>
|
||||
public class AstarData {
|
||||
/// <summary>Shortcut to AstarPath.active</summary>
|
||||
public static AstarPath active {
|
||||
get {
|
||||
return AstarPath.active;
|
||||
}
|
||||
}
|
||||
|
||||
#region Fields
|
||||
/// <summary>Shortcut to the first <see cref="NavMeshGraph"/></summary>
|
||||
public NavMeshGraph navmesh { get; private set; }
|
||||
|
||||
#if !ASTAR_NO_GRID_GRAPH
|
||||
/// <summary>Shortcut to the first <see cref="GridGraph"/></summary>
|
||||
public GridGraph gridGraph { get; private set; }
|
||||
|
||||
/// <summary>Shortcut to the first <see cref="LayerGridGraph"/>.</summary>
|
||||
public LayerGridGraph layerGridGraph { get; private set; }
|
||||
#endif
|
||||
|
||||
#if !ASTAR_NO_POINT_GRAPH
|
||||
/// <summary>Shortcut to the first <see cref="PointGraph"/>.</summary>
|
||||
public PointGraph pointGraph { get; private set; }
|
||||
#endif
|
||||
|
||||
/// <summary>Shortcut to the first <see cref="RecastGraph"/>.</summary>
|
||||
public RecastGraph recastGraph { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// All supported graph types.
|
||||
/// Populated through reflection search
|
||||
/// </summary>
|
||||
public System.Type[] graphTypes { get; private set; }
|
||||
|
||||
#if ASTAR_FAST_NO_EXCEPTIONS || UNITY_WINRT || UNITY_WEBGL
|
||||
/// <summary>
|
||||
/// Graph types to use when building with Fast But No Exceptions for iPhone.
|
||||
/// If you add any custom graph types, you need to add them to this hard-coded list.
|
||||
/// </summary>
|
||||
public static readonly System.Type[] DefaultGraphTypes = new System.Type[] {
|
||||
#if !ASTAR_NO_GRID_GRAPH
|
||||
typeof(GridGraph),
|
||||
typeof(LayerGridGraph),
|
||||
#endif
|
||||
#if !ASTAR_NO_POINT_GRAPH
|
||||
typeof(PointGraph),
|
||||
#endif
|
||||
typeof(NavMeshGraph),
|
||||
typeof(RecastGraph),
|
||||
};
|
||||
#endif
|
||||
|
||||
/// <summary>
|
||||
/// All graphs.
|
||||
/// This will be filled only after deserialization has completed.
|
||||
/// May contain null entries if graph have been removed.
|
||||
/// </summary>
|
||||
[System.NonSerialized]
|
||||
public NavGraph[] graphs = new NavGraph[0];
|
||||
|
||||
/// <summary>
|
||||
/// Serialized data for all graphs and settings.
|
||||
/// Stored as a base64 encoded string because otherwise Unity's Undo system would sometimes corrupt the byte data (because it only stores deltas).
|
||||
///
|
||||
/// This can be accessed as a byte array from the <see cref="data"/> property.
|
||||
/// </summary>
|
||||
[SerializeField]
|
||||
string dataString;
|
||||
|
||||
/// <summary>Serialized data for all graphs and settings</summary>
|
||||
private byte[] data {
|
||||
get {
|
||||
return dataString != null? System.Convert.FromBase64String(dataString) : null;
|
||||
}
|
||||
set {
|
||||
dataString = value != null? System.Convert.ToBase64String(value) : null;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Serialized data for cached startup.
|
||||
/// If set, on start the graphs will be deserialized from this file.
|
||||
/// </summary>
|
||||
public TextAsset file_cachedStartup;
|
||||
|
||||
/// <summary>
|
||||
/// Should graph-data be cached.
|
||||
/// Caching the startup means saving the whole graphs - not only the settings - to a file (<see cref="file_cachedStartup)"/> which can
|
||||
/// be loaded when the game starts. This is usually much faster than scanning the graphs when the game starts. This is configured from the editor under the "Save & Load" tab.
|
||||
///
|
||||
/// See: save-load-graphs (view in online documentation for working links)
|
||||
/// </summary>
|
||||
[SerializeField]
|
||||
public bool cacheStartup;
|
||||
|
||||
//End Serialization Settings
|
||||
|
||||
List<bool> graphStructureLocked = new List<bool>();
|
||||
|
||||
#endregion
|
||||
|
||||
public byte[] GetData() => data;
|
||||
|
||||
public void SetData (byte[] data) {
|
||||
this.data = data;
|
||||
}
|
||||
|
||||
/// <summary>Loads the graphs from memory, will load cached graphs if any exists</summary>
|
||||
public void Awake () {
|
||||
graphs = new NavGraph[0];
|
||||
|
||||
if (cacheStartup && file_cachedStartup != null) {
|
||||
LoadFromCache();
|
||||
} else {
|
||||
DeserializeGraphs();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Prevent the graph structure from changing during the time this lock is held.
|
||||
/// This prevents graphs from being added or removed and also prevents graphs from being serialized or deserialized.
|
||||
/// This is used when e.g an async scan is happening to ensure that for example a graph that is being scanned is not destroyed.
|
||||
///
|
||||
/// Each call to this method *must* be paired with exactly one call to <see cref="UnlockGraphStructure"/>.
|
||||
/// The calls may be nested.
|
||||
/// </summary>
|
||||
internal void LockGraphStructure (bool allowAddingGraphs = false) {
|
||||
graphStructureLocked.Add(allowAddingGraphs);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Allows the graph structure to change again.
|
||||
/// See: <see cref="LockGraphStructure"/>
|
||||
/// </summary>
|
||||
internal void UnlockGraphStructure () {
|
||||
if (graphStructureLocked.Count == 0) throw new System.InvalidOperationException();
|
||||
graphStructureLocked.RemoveAt(graphStructureLocked.Count - 1);
|
||||
}
|
||||
|
||||
PathProcessor.GraphUpdateLock AssertSafe (bool onlyAddingGraph = false) {
|
||||
if (graphStructureLocked.Count > 0) {
|
||||
bool allowAdding = true;
|
||||
for (int i = 0; i < graphStructureLocked.Count; i++) allowAdding &= graphStructureLocked[i];
|
||||
if (!(onlyAddingGraph && allowAdding)) throw new System.InvalidOperationException("Graphs cannot be added, removed or serialized while the graph structure is locked. This is the case when a graph is currently being scanned and when executing graph updates and work items.\nHowever as a special case, graphs can be added inside work items.");
|
||||
}
|
||||
|
||||
// Pause the pathfinding threads
|
||||
var graphLock = active.PausePathfinding();
|
||||
if (!active.IsInsideWorkItem) {
|
||||
// Make sure all graph updates and other callbacks are done
|
||||
// Only do this if this code is not being called from a work item itself as that would cause a recursive wait that could never complete.
|
||||
// There are some valid cases when this can happen. For example it may be necessary to add a new graph inside a work item.
|
||||
active.FlushWorkItems();
|
||||
|
||||
// Paths that are already calculated and waiting to be returned to the Seeker component need to be
|
||||
// processed immediately as their results usually depend on graphs that currently exist. If this was
|
||||
// not done then after destroying a graph one could get a path result with destroyed nodes in it.
|
||||
active.pathReturnQueue.ReturnPaths(false);
|
||||
}
|
||||
return graphLock;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Calls the callback with every node in all graphs.
|
||||
/// This is the easiest way to iterate through every existing node.
|
||||
///
|
||||
/// <code>
|
||||
/// AstarPath.active.data.GetNodes(node => {
|
||||
/// Debug.Log("I found a node at position " + (Vector3)node.position);
|
||||
/// });
|
||||
/// </code>
|
||||
///
|
||||
/// See: <see cref="Pathfinding.NavGraph.GetNodes"/> for getting the nodes of a single graph instead of all.
|
||||
/// See: graph-updates (view in online documentation for working links)
|
||||
/// </summary>
|
||||
public void GetNodes (System.Action<GraphNode> callback) {
|
||||
for (int i = 0; i < graphs.Length; i++) {
|
||||
if (graphs[i] != null) graphs[i].GetNodes(callback);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Updates shortcuts to the first graph of different types.
|
||||
/// Hard coding references to some graph types is not really a good thing imo. I want to keep it dynamic and flexible.
|
||||
/// But these references ease the use of the system, so I decided to keep them.
|
||||
/// </summary>
|
||||
public void UpdateShortcuts () {
|
||||
navmesh = (NavMeshGraph)FindGraphOfType(typeof(NavMeshGraph));
|
||||
|
||||
#if !ASTAR_NO_GRID_GRAPH
|
||||
gridGraph = (GridGraph)FindGraphOfType(typeof(GridGraph));
|
||||
layerGridGraph = (LayerGridGraph)FindGraphOfType(typeof(LayerGridGraph));
|
||||
#endif
|
||||
|
||||
#if !ASTAR_NO_POINT_GRAPH
|
||||
pointGraph = (PointGraph)FindGraphOfType(typeof(PointGraph));
|
||||
#endif
|
||||
|
||||
recastGraph = (RecastGraph)FindGraphOfType(typeof(RecastGraph));
|
||||
}
|
||||
|
||||
/// <summary>Load from data from <see cref="file_cachedStartup"/></summary>
|
||||
public void LoadFromCache () {
|
||||
var graphLock = AssertSafe();
|
||||
|
||||
if (file_cachedStartup != null) {
|
||||
var bytes = file_cachedStartup.bytes;
|
||||
DeserializeGraphs(bytes);
|
||||
|
||||
GraphModifier.TriggerEvent(GraphModifier.EventType.PostCacheLoad);
|
||||
} else {
|
||||
Debug.LogError("Can't load from cache since the cache is empty");
|
||||
}
|
||||
graphLock.Release();
|
||||
}
|
||||
|
||||
#region Serialization
|
||||
|
||||
/// <summary>
|
||||
/// Serializes all graphs settings to a byte array.
|
||||
/// See: DeserializeGraphs(byte[])
|
||||
/// </summary>
|
||||
public byte[] SerializeGraphs () {
|
||||
return SerializeGraphs(SerializeSettings.Settings);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Serializes all graphs settings and optionally node data to a byte array.
|
||||
/// See: DeserializeGraphs(byte[])
|
||||
/// See: Pathfinding.Serialization.SerializeSettings
|
||||
/// </summary>
|
||||
public byte[] SerializeGraphs (SerializeSettings settings) {
|
||||
return SerializeGraphs(settings, out var _);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Main serializer function.
|
||||
/// Serializes all graphs to a byte array
|
||||
/// A similar function exists in the AstarPathEditor.cs script to save additional info
|
||||
/// </summary>
|
||||
public byte[] SerializeGraphs (SerializeSettings settings, out uint checksum) {
|
||||
var graphLock = AssertSafe();
|
||||
var sr = new AstarSerializer(this, settings, active.gameObject);
|
||||
|
||||
sr.OpenSerialize();
|
||||
sr.SerializeGraphs(graphs);
|
||||
sr.SerializeExtraInfo();
|
||||
byte[] bytes = sr.CloseSerialize();
|
||||
checksum = sr.GetChecksum();
|
||||
#if ASTARDEBUG
|
||||
Debug.Log("Got a whole bunch of data, "+bytes.Length+" bytes");
|
||||
#endif
|
||||
graphLock.Release();
|
||||
return bytes;
|
||||
}
|
||||
|
||||
/// <summary>Deserializes graphs from <see cref="data"/></summary>
|
||||
public void DeserializeGraphs () {
|
||||
if (data != null) {
|
||||
DeserializeGraphs(data);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Destroys all graphs and sets graphs to null</summary>
|
||||
void ClearGraphs () {
|
||||
if (graphs == null) return;
|
||||
for (int i = 0; i < graphs.Length; i++) {
|
||||
if (graphs[i] != null) {
|
||||
((IGraphInternals)graphs[i]).OnDestroy();
|
||||
graphs[i].active = null;
|
||||
}
|
||||
}
|
||||
graphs = new NavGraph[0];
|
||||
UpdateShortcuts();
|
||||
}
|
||||
|
||||
public void OnDestroy () {
|
||||
ClearGraphs();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Deserializes graphs from the specified byte array.
|
||||
/// An error will be logged if deserialization fails.
|
||||
/// </summary>
|
||||
public void DeserializeGraphs (byte[] bytes) {
|
||||
var graphLock = AssertSafe();
|
||||
|
||||
ClearGraphs();
|
||||
DeserializeGraphsAdditive(bytes);
|
||||
graphLock.Release();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Deserializes graphs from the specified byte array additively.
|
||||
/// An error will be logged if deserialization fails.
|
||||
/// This function will add loaded graphs to the current ones.
|
||||
/// </summary>
|
||||
public void DeserializeGraphsAdditive (byte[] bytes) {
|
||||
var graphLock = AssertSafe();
|
||||
|
||||
try {
|
||||
if (bytes != null) {
|
||||
var sr = new AstarSerializer(this, active.gameObject);
|
||||
|
||||
if (sr.OpenDeserialize(bytes)) {
|
||||
DeserializeGraphsPartAdditive(sr);
|
||||
sr.CloseDeserialize();
|
||||
} else {
|
||||
Debug.Log("Invalid data file (cannot read zip).\nThe data is either corrupt or it was saved using a 3.0.x or earlier version of the system");
|
||||
}
|
||||
} else {
|
||||
throw new System.ArgumentNullException("bytes");
|
||||
}
|
||||
active.VerifyIntegrity();
|
||||
} catch (System.Exception e) {
|
||||
Debug.LogError("Caught exception while deserializing data.\n"+e);
|
||||
graphs = new NavGraph[0];
|
||||
}
|
||||
|
||||
UpdateShortcuts();
|
||||
graphLock.Release();
|
||||
}
|
||||
|
||||
/// <summary>Helper function for deserializing graphs</summary>
|
||||
void DeserializeGraphsPartAdditive (AstarSerializer sr) {
|
||||
if (graphs == null) graphs = new NavGraph[0];
|
||||
|
||||
var gr = new List<NavGraph>(graphs);
|
||||
|
||||
// Set an offset so that the deserializer will load
|
||||
// the graphs with the correct graph indexes
|
||||
sr.SetGraphIndexOffset(gr.Count);
|
||||
|
||||
if (graphTypes == null) FindGraphTypes();
|
||||
gr.AddRange(sr.DeserializeGraphs(graphTypes));
|
||||
graphs = gr.ToArray();
|
||||
|
||||
sr.DeserializeEditorSettingsCompatibility();
|
||||
sr.DeserializeExtraInfo();
|
||||
|
||||
// Assign correct graph indices.
|
||||
for (int i = 0; i < graphs.Length; i++) {
|
||||
if (graphs[i] == null) continue;
|
||||
graphs[i].GetNodes(node => node.GraphIndex = (uint)i);
|
||||
}
|
||||
|
||||
for (int i = 0; i < graphs.Length; i++) {
|
||||
for (int j = i+1; j < graphs.Length; j++) {
|
||||
if (graphs[i] != null && graphs[j] != null && graphs[i].guid == graphs[j].guid) {
|
||||
Debug.LogWarning("Guid Conflict when importing graphs additively. Imported graph will get a new Guid.\nThis message is (relatively) harmless.");
|
||||
graphs[i].guid = Pathfinding.Util.Guid.NewGuid();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sr.PostDeserialization();
|
||||
active.hierarchicalGraph.RecalculateIfNecessary();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// Find all graph types supported in this build.
|
||||
/// Using reflection, the assembly is searched for types which inherit from NavGraph.
|
||||
/// </summary>
|
||||
public void FindGraphTypes () {
|
||||
#if !ASTAR_FAST_NO_EXCEPTIONS && !UNITY_WINRT && !UNITY_WEBGL
|
||||
var graphList = new List<System.Type>();
|
||||
foreach (var assembly in System.AppDomain.CurrentDomain.GetAssemblies()) {
|
||||
System.Type[] types = null;
|
||||
try {
|
||||
types = assembly.GetTypes();
|
||||
} catch {
|
||||
// Ignore type load exceptions and things like that.
|
||||
// We might not be able to read all assemblies for some reason, but hopefully the relevant types exist in the assemblies that we can read
|
||||
continue;
|
||||
}
|
||||
|
||||
foreach (var type in types) {
|
||||
#if NETFX_CORE && !UNITY_EDITOR
|
||||
System.Type baseType = type.GetTypeInfo().BaseType;
|
||||
#else
|
||||
var baseType = type.BaseType;
|
||||
#endif
|
||||
while (baseType != null) {
|
||||
if (System.Type.Equals(baseType, typeof(NavGraph))) {
|
||||
graphList.Add(type);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
#if NETFX_CORE && !UNITY_EDITOR
|
||||
baseType = baseType.GetTypeInfo().BaseType;
|
||||
#else
|
||||
baseType = baseType.BaseType;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
graphTypes = graphList.ToArray();
|
||||
|
||||
#if ASTARDEBUG
|
||||
Debug.Log("Found "+graphTypes.Length+" graph types");
|
||||
#endif
|
||||
#else
|
||||
graphTypes = DefaultGraphTypes;
|
||||
#endif
|
||||
}
|
||||
|
||||
#region GraphCreation
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new graph instance of type type
|
||||
/// See: <see cref="CreateGraph(string)"/>
|
||||
/// </summary>
|
||||
internal NavGraph CreateGraph (System.Type type) {
|
||||
var graph = System.Activator.CreateInstance(type) as NavGraph;
|
||||
|
||||
graph.active = active;
|
||||
return graph;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds a graph of type T to the <see cref="graphs"/> array.
|
||||
/// See: runtime-graphs (view in online documentation for working links)
|
||||
/// </summary>
|
||||
public T AddGraph<T> () where T : NavGraph => AddGraph(typeof(T)) as T;
|
||||
|
||||
/// <summary>
|
||||
/// Adds a graph of type type to the <see cref="graphs"/> array.
|
||||
/// See: runtime-graphs (view in online documentation for working links)
|
||||
/// </summary>
|
||||
public NavGraph AddGraph (System.Type type) {
|
||||
NavGraph graph = null;
|
||||
|
||||
for (int i = 0; i < graphTypes.Length; i++) {
|
||||
if (System.Type.Equals(graphTypes[i], type)) {
|
||||
graph = CreateGraph(graphTypes[i]);
|
||||
}
|
||||
}
|
||||
|
||||
if (graph == null) {
|
||||
Debug.LogError("No NavGraph of type '"+type+"' could be found, "+graphTypes.Length+" graph types are avaliable");
|
||||
return null;
|
||||
}
|
||||
|
||||
AddGraph(graph);
|
||||
|
||||
return graph;
|
||||
}
|
||||
|
||||
/// <summary>Adds the specified graph to the <see cref="graphs"/> array</summary>
|
||||
void AddGraph (NavGraph graph) {
|
||||
// Make sure to not interfere with pathfinding
|
||||
var graphLock = AssertSafe(true);
|
||||
|
||||
// Try to fill in an empty position
|
||||
bool foundEmpty = false;
|
||||
|
||||
for (int i = 0; i < graphs.Length; i++) {
|
||||
if (graphs[i] == null) {
|
||||
graphs[i] = graph;
|
||||
graph.graphIndex = (uint)i;
|
||||
foundEmpty = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!foundEmpty) {
|
||||
if (graphs != null && graphs.Length >= GraphNode.MaxGraphIndex) {
|
||||
throw new System.Exception("Graph Count Limit Reached. You cannot have more than " + GraphNode.MaxGraphIndex + " graphs.");
|
||||
}
|
||||
|
||||
// Add a new entry to the list
|
||||
var graphList = new List<NavGraph>(graphs ?? new NavGraph[0]);
|
||||
graphList.Add(graph);
|
||||
graphs = graphList.ToArray();
|
||||
graph.graphIndex = (uint)(graphs.Length-1);
|
||||
}
|
||||
|
||||
UpdateShortcuts();
|
||||
graph.active = active;
|
||||
graphLock.Release();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Removes the specified graph from the <see cref="graphs"/> array and Destroys it in a safe manner.
|
||||
/// To avoid changing graph indices for the other graphs, the graph is simply nulled in the array instead
|
||||
/// of actually removing it from the array.
|
||||
/// The empty position will be reused if a new graph is added.
|
||||
///
|
||||
/// Returns: True if the graph was sucessfully removed (i.e it did exist in the <see cref="graphs"/> array). False otherwise.
|
||||
/// </summary>
|
||||
public bool RemoveGraph (NavGraph graph) {
|
||||
// Make sure the pathfinding threads are paused
|
||||
var graphLock = AssertSafe();
|
||||
|
||||
((IGraphInternals)graph).OnDestroy();
|
||||
graph.active = null;
|
||||
|
||||
int i = System.Array.IndexOf(graphs, graph);
|
||||
if (i != -1) graphs[i] = null;
|
||||
|
||||
UpdateShortcuts();
|
||||
graphLock.Release();
|
||||
return i != -1;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region GraphUtility
|
||||
|
||||
/// <summary>
|
||||
/// Returns the graph which contains the specified node.
|
||||
/// The graph must be in the <see cref="graphs"/> array.
|
||||
///
|
||||
/// Returns: Returns the graph which contains the node. Null if the graph wasn't found
|
||||
/// </summary>
|
||||
public static NavGraph GetGraph (GraphNode node) {
|
||||
if (node == null) return null;
|
||||
|
||||
AstarPath script = AstarPath.active;
|
||||
if (script == null) return null;
|
||||
|
||||
AstarData data = script.data;
|
||||
if (data == null || data.graphs == null) return null;
|
||||
|
||||
uint graphIndex = node.GraphIndex;
|
||||
|
||||
if (graphIndex >= data.graphs.Length) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return data.graphs[(int)graphIndex];
|
||||
}
|
||||
|
||||
/// <summary>Returns the first graph which satisfies the predicate. Returns null if no graph was found.</summary>
|
||||
public NavGraph FindGraph (System.Func<NavGraph, bool> predicate) {
|
||||
if (graphs != null) {
|
||||
for (int i = 0; i < graphs.Length; i++) {
|
||||
if (graphs[i] != null && predicate(graphs[i])) {
|
||||
return graphs[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>Returns the first graph of type type found in the <see cref="graphs"/> array. Returns null if no graph was found.</summary>
|
||||
public NavGraph FindGraphOfType (System.Type type) {
|
||||
return FindGraph(graph => System.Type.Equals(graph.GetType(), type));
|
||||
}
|
||||
|
||||
/// <summary>Returns the first graph which inherits from the type type. Returns null if no graph was found.</summary>
|
||||
public NavGraph FindGraphWhichInheritsFrom (System.Type type) {
|
||||
return FindGraph(graph => WindowsStoreCompatibility.GetTypeInfo(type).IsAssignableFrom(WindowsStoreCompatibility.GetTypeInfo(graph.GetType())));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Loop through this function to get all graphs of type 'type'
|
||||
/// <code>
|
||||
/// foreach (GridGraph graph in AstarPath.data.FindGraphsOfType (typeof(GridGraph))) {
|
||||
/// //Do something with the graph
|
||||
/// }
|
||||
/// </code>
|
||||
/// See: AstarPath.RegisterSafeNodeUpdate
|
||||
/// </summary>
|
||||
public IEnumerable FindGraphsOfType (System.Type type) {
|
||||
if (graphs == null) yield break;
|
||||
for (int i = 0; i < graphs.Length; i++) {
|
||||
if (graphs[i] != null && System.Type.Equals(graphs[i].GetType(), type)) {
|
||||
yield return graphs[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// All graphs which implements the UpdateableGraph interface
|
||||
/// <code> foreach (IUpdatableGraph graph in AstarPath.data.GetUpdateableGraphs ()) {
|
||||
/// //Do something with the graph
|
||||
/// } </code>
|
||||
/// See: AstarPath.AddWorkItem
|
||||
/// See: Pathfinding.IUpdatableGraph
|
||||
/// </summary>
|
||||
public IEnumerable GetUpdateableGraphs () {
|
||||
if (graphs == null) yield break;
|
||||
for (int i = 0; i < graphs.Length; i++) {
|
||||
if (graphs[i] is IUpdatableGraph) {
|
||||
yield return graphs[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Gets the index of the NavGraph in the <see cref="graphs"/> array</summary>
|
||||
public int GetGraphIndex (NavGraph graph) {
|
||||
if (graph == null) throw new System.ArgumentNullException("graph");
|
||||
|
||||
var index = -1;
|
||||
if (graphs != null) {
|
||||
index = System.Array.IndexOf(graphs, graph);
|
||||
if (index == -1) Debug.LogError("Graph doesn't exist");
|
||||
}
|
||||
return index;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 38d211caa07cb44ef886481aa1cf755c
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 960fd9020b1f74f939fee737c3c0f491
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,16 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 78396926cbbfc4ac3b48fc5fc34a87d1
|
||||
labels:
|
||||
- Pathfinder
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences:
|
||||
- gizmoSurfaceMaterial: {fileID: 2100000, guid: 5ce51318bbfb1466188b929a68a6bd3a,
|
||||
type: 2}
|
||||
- gizmoLineMaterial: {fileID: 2100000, guid: 91035448860ba4e708919485c73f7edc, type: 2}
|
||||
executionOrder: -10000
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,412 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace Pathfinding {
|
||||
[AddComponentMenu("Pathfinding/GraphUpdateScene")]
|
||||
/// <summary>
|
||||
/// Helper class for easily updating graphs.
|
||||
///
|
||||
/// To use the GraphUpdateScene component, create a new empty GameObject and add the component to it, it can be found under Components-->Pathfinding-->GraphUpdateScene.
|
||||
///
|
||||
/// The region which the component will affect is defined by creating a polygon in the scene.
|
||||
/// If you make sure you have the Position tool enabled (top-left corner of the Unity window) you can shift+click in the scene view to add more points to the polygon.
|
||||
/// You can remove points using shift+alt+click.
|
||||
/// By clicking on the points you can bring up a positioning tool. You can also open the "points" array in the inspector to set each point's coordinates manually.
|
||||
/// [Open online documentation to see images]
|
||||
/// In the inspector there are a number of variables. The first one is named "Convex", it sets if the convex hull of the points should be calculated or if the polygon should be used as-is.
|
||||
/// Using the convex hull is faster when applying the changes to the graph, but with a non-convex polygon you can specify more complicated areas.
|
||||
/// The next two variables, called "Apply On Start" and "Apply On Scan" determine when to apply the changes. If the object is in the scene from the beginning, both can be left on, it doesn't
|
||||
/// matter since the graph is also scanned at start. However if you instantiate it later in the game, you can make it apply it's setting directly, or wait until the next scan (if any).
|
||||
/// If the graph is rescanned, all GraphUpdateScene components which have the Apply On Scan variable toggled will apply their settings again to the graph since rescanning clears all previous changes.
|
||||
/// You can also make it apply it's changes using scripting.
|
||||
/// <code> GetComponent<GraphUpdateScene>().Apply (); </code>
|
||||
/// The above code will make it apply its changes to the graph (assuming a GraphUpdateScene component is attached to the same GameObject).
|
||||
///
|
||||
/// Next there is "Modify Walkability" and "Set Walkability" (which appears when "Modify Walkability" is toggled).
|
||||
/// If Modify Walkability is set, then all nodes inside the area will either be set to walkable or unwalkable depending on the value of the "Set Walkability" variable.
|
||||
///
|
||||
/// Penalty can also be applied to the nodes. A higher penalty (aka weight) makes the nodes harder to traverse so it will try to avoid those areas.
|
||||
///
|
||||
/// The tagging variables can be read more about on this page: tags (view in online documentation for working links) "Working with tags".
|
||||
///
|
||||
/// Note: The Y (up) axis of the transform that this component is attached to should be in the same direction as the up direction of the graph.
|
||||
/// So if you for example have a grid in the XY plane then the transform should have the rotation (-90,0,0).
|
||||
/// </summary>
|
||||
[HelpURL("https://arongranberg.com/astar/documentation/stable/class_pathfinding_1_1_graph_update_scene.php")]
|
||||
public class GraphUpdateScene : GraphModifier {
|
||||
/// <summary>Points which define the region to update</summary>
|
||||
public Vector3[] points;
|
||||
|
||||
/// <summary>Private cached convex hull of the <see cref="points"/></summary>
|
||||
private Vector3[] convexPoints;
|
||||
|
||||
/// <summary>
|
||||
/// Use the convex hull of the points instead of the original polygon.
|
||||
///
|
||||
/// See: https://en.wikipedia.org/wiki/Convex_hull
|
||||
/// </summary>
|
||||
public bool convex = true;
|
||||
|
||||
/// <summary>
|
||||
/// Minumum height of the bounds of the resulting Graph Update Object.
|
||||
/// Useful when all points are laid out on a plane but you still need a bounds with a height greater than zero since a
|
||||
/// zero height graph update object would usually result in no nodes being updated.
|
||||
/// </summary>
|
||||
public float minBoundsHeight = 1;
|
||||
|
||||
/// <summary>
|
||||
/// Penalty to add to nodes.
|
||||
/// Usually you need quite large values, at least 1000-10000. A higher penalty means that agents will try to avoid those nodes more.
|
||||
///
|
||||
/// Be careful when setting negative values since if a node gets a negative penalty it will underflow and instead get
|
||||
/// really large. In most cases a warning will be logged if that happens.
|
||||
///
|
||||
/// See: tags (view in online documentation for working links) for another way of applying penalties.
|
||||
/// </summary>
|
||||
public int penaltyDelta;
|
||||
|
||||
/// <summary>If true, then all affected nodes will be made walkable or unwalkable according to <see cref="setWalkability"/></summary>
|
||||
public bool modifyWalkability;
|
||||
|
||||
/// <summary>Nodes will be made walkable or unwalkable according to this value if <see cref="modifyWalkability"/> is true</summary>
|
||||
public bool setWalkability;
|
||||
|
||||
/// <summary>Apply this graph update object on start</summary>
|
||||
public bool applyOnStart = true;
|
||||
|
||||
/// <summary>Apply this graph update object whenever a graph is rescanned</summary>
|
||||
public bool applyOnScan = true;
|
||||
|
||||
/// <summary>
|
||||
/// Update node's walkability and connectivity using physics functions.
|
||||
/// For grid graphs, this will update the node's position and walkability exactly like when doing a scan of the graph.
|
||||
/// If enabled for grid graphs, <see cref="modifyWalkability"/> will be ignored.
|
||||
///
|
||||
/// For Point Graphs, this will recalculate all connections which passes through the bounds of the resulting Graph Update Object
|
||||
/// using raycasts (if enabled).
|
||||
/// </summary>
|
||||
public bool updatePhysics;
|
||||
|
||||
/// <summary>\copydoc Pathfinding::GraphUpdateObject::resetPenaltyOnPhysics</summary>
|
||||
public bool resetPenaltyOnPhysics = true;
|
||||
|
||||
/// <summary>\copydoc Pathfinding::GraphUpdateObject::updateErosion</summary>
|
||||
public bool updateErosion = true;
|
||||
|
||||
/// <summary>
|
||||
/// Should the tags of the nodes be modified.
|
||||
/// If enabled, set all nodes' tags to <see cref="setTag"/>
|
||||
/// </summary>
|
||||
public bool modifyTag;
|
||||
|
||||
/// <summary>If <see cref="modifyTag"/> is enabled, set all nodes' tags to this value</summary>
|
||||
public int setTag;
|
||||
|
||||
/// <summary>Emulates behavior from before version 4.0</summary>
|
||||
[HideInInspector]
|
||||
public bool legacyMode = false;
|
||||
|
||||
/// <summary>
|
||||
/// Private cached inversion of <see cref="setTag"/>.
|
||||
/// Used for InvertSettings()
|
||||
/// </summary>
|
||||
private int setTagInvert;
|
||||
|
||||
/// <summary>
|
||||
/// Has apply been called yet.
|
||||
/// Used to prevent applying twice when both applyOnScan and applyOnStart are enabled
|
||||
/// </summary>
|
||||
private bool firstApplied;
|
||||
|
||||
[SerializeField]
|
||||
private int serializedVersion = 0;
|
||||
|
||||
/// <summary>
|
||||
/// Use world space for coordinates.
|
||||
/// If true, the shape will not follow when moving around the transform.
|
||||
///
|
||||
/// See: <see cref="ToggleUseWorldSpace"/>
|
||||
/// </summary>
|
||||
[SerializeField]
|
||||
[UnityEngine.Serialization.FormerlySerializedAs("useWorldSpace")]
|
||||
private bool legacyUseWorldSpace;
|
||||
|
||||
/// <summary>Do some stuff at start</summary>
|
||||
public void Start () {
|
||||
if (!Application.isPlaying) return;
|
||||
|
||||
// If firstApplied is true, that means the graph was scanned during Awake.
|
||||
// So we shouldn't apply it again because then we would end up applying it two times
|
||||
if (!firstApplied && applyOnStart) {
|
||||
Apply();
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnPostScan () {
|
||||
if (applyOnScan) Apply();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Inverts all invertable settings for this GUS.
|
||||
/// Namely: penalty delta, walkability, tags.
|
||||
///
|
||||
/// Penalty delta will be changed to negative penalty delta.
|
||||
/// <see cref="setWalkability"/> will be inverted.
|
||||
/// <see cref="setTag"/> will be stored in a private variable, and the new value will be 0. When calling this function again, the saved
|
||||
/// value will be the new value.
|
||||
///
|
||||
/// Calling this function an even number of times without changing any settings in between will be identical to no change in settings.
|
||||
/// </summary>
|
||||
public virtual void InvertSettings () {
|
||||
setWalkability = !setWalkability;
|
||||
penaltyDelta = -penaltyDelta;
|
||||
if (setTagInvert == 0) {
|
||||
setTagInvert = setTag;
|
||||
setTag = 0;
|
||||
} else {
|
||||
setTag = setTagInvert;
|
||||
setTagInvert = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Recalculate convex hull.
|
||||
/// Will not do anything if <see cref="convex"/> is disabled.
|
||||
/// </summary>
|
||||
public void RecalcConvex () {
|
||||
convexPoints = convex ? Polygon.ConvexHullXZ(points) : null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Switches between using world space and using local space.
|
||||
/// Deprecated: World space can no longer be used as it does not work well with rotated graphs. Use transform.InverseTransformPoint to transform points to local space.
|
||||
/// </summary>
|
||||
[System.ObsoleteAttribute("World space can no longer be used as it does not work well with rotated graphs. Use transform.InverseTransformPoint to transform points to local space.", true)]
|
||||
void ToggleUseWorldSpace () {
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Lock all points to a specific Y value.
|
||||
/// Deprecated: The Y coordinate is no longer important. Use the position of the object instead.
|
||||
/// </summary>
|
||||
[System.ObsoleteAttribute("The Y coordinate is no longer important. Use the position of the object instead", true)]
|
||||
public void LockToY () {
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Calculates the bounds for this component.
|
||||
/// This is a relatively expensive operation, it needs to go through all points and
|
||||
/// run matrix multiplications.
|
||||
/// </summary>
|
||||
public Bounds GetBounds () {
|
||||
if (points == null || points.Length == 0) {
|
||||
Bounds bounds;
|
||||
var coll = GetComponent<Collider>();
|
||||
var coll2D = GetComponent<Collider2D>();
|
||||
var rend = GetComponent<Renderer>();
|
||||
|
||||
if (coll != null) bounds = coll.bounds;
|
||||
else if (coll2D != null) {
|
||||
bounds = coll2D.bounds;
|
||||
bounds.size = new Vector3(bounds.size.x, bounds.size.y, Mathf.Max(bounds.size.z, 1f));
|
||||
} else if (rend != null) {
|
||||
bounds = rend.bounds;
|
||||
} else {
|
||||
return new Bounds(Vector3.zero, Vector3.zero);
|
||||
}
|
||||
|
||||
if (legacyMode && bounds.size.y < minBoundsHeight) bounds.size = new Vector3(bounds.size.x, minBoundsHeight, bounds.size.z);
|
||||
return bounds;
|
||||
} else {
|
||||
if (convexPoints == null) RecalcConvex();
|
||||
return GraphUpdateShape.GetBounds(convex ? convexPoints : points, legacyMode && legacyUseWorldSpace ? Matrix4x4.identity : transform.localToWorldMatrix, minBoundsHeight);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The GraphUpdateObject which would be applied by this component.
|
||||
///
|
||||
/// No graphs are actually updated by this function. Call AstarPath.active.UpdateGraphs and pass this object if you want that.
|
||||
/// This method is useful if you want to modify the object before passing it to the UpdateGraphs function.
|
||||
///
|
||||
/// See: <see cref="Apply"/>
|
||||
/// </summary>
|
||||
public GraphUpdateObject GetGraphUpdate () {
|
||||
GraphUpdateObject guo;
|
||||
|
||||
if (points == null || points.Length == 0) {
|
||||
var polygonCollider = GetComponent<PolygonCollider2D>();
|
||||
if (polygonCollider != null) {
|
||||
var points2D = polygonCollider.points;
|
||||
Vector3[] pts = new Vector3[points2D.Length];
|
||||
for (int i = 0; i < pts.Length; i++) {
|
||||
var p = points2D[i] + polygonCollider.offset;
|
||||
pts[i] = new Vector3(p.x, 0, p.y);
|
||||
}
|
||||
|
||||
var mat = transform.localToWorldMatrix * Matrix4x4.TRS(Vector3.zero, Quaternion.Euler(-90, 0, 0), Vector3.one);
|
||||
var shape = new GraphUpdateShape(pts, convex, mat, minBoundsHeight);
|
||||
guo = new GraphUpdateObject(GetBounds());
|
||||
guo.shape = shape;
|
||||
} else {
|
||||
var bounds = GetBounds();
|
||||
if (bounds.center == Vector3.zero && bounds.size == Vector3.zero) {
|
||||
Debug.LogError("Cannot apply GraphUpdateScene, no points defined and no renderer or collider attached", this);
|
||||
return null;
|
||||
}
|
||||
|
||||
guo = new GraphUpdateObject(bounds);
|
||||
}
|
||||
} else {
|
||||
GraphUpdateShape shape;
|
||||
if (legacyMode && !legacyUseWorldSpace) {
|
||||
// Used for compatibility with older versions
|
||||
var worldPoints = new Vector3[points.Length];
|
||||
for (int i = 0; i < points.Length; i++) worldPoints[i] = transform.TransformPoint(points[i]);
|
||||
shape = new GraphUpdateShape(worldPoints, convex, Matrix4x4.identity, minBoundsHeight);
|
||||
} else {
|
||||
shape = new GraphUpdateShape(points, convex, legacyMode && legacyUseWorldSpace ? Matrix4x4.identity : transform.localToWorldMatrix, minBoundsHeight);
|
||||
}
|
||||
var bounds = shape.GetBounds();
|
||||
guo = new GraphUpdateObject(bounds);
|
||||
guo.shape = shape;
|
||||
}
|
||||
|
||||
firstApplied = true;
|
||||
|
||||
guo.modifyWalkability = modifyWalkability;
|
||||
guo.setWalkability = setWalkability;
|
||||
guo.addPenalty = penaltyDelta;
|
||||
guo.updatePhysics = updatePhysics;
|
||||
guo.updateErosion = updateErosion;
|
||||
guo.resetPenaltyOnPhysics = resetPenaltyOnPhysics;
|
||||
|
||||
guo.modifyTag = modifyTag;
|
||||
guo.setTag = setTag;
|
||||
return guo;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Updates graphs with a created GUO.
|
||||
/// Creates a Pathfinding.GraphUpdateObject with a Pathfinding.GraphUpdateShape
|
||||
/// representing the polygon of this object and update all graphs using AstarPath.UpdateGraphs.
|
||||
/// This will not update graphs immediately. See AstarPath.UpdateGraph for more info.
|
||||
/// </summary>
|
||||
public void Apply () {
|
||||
if (AstarPath.active == null) {
|
||||
Debug.LogError("There is no AstarPath object in the scene", this);
|
||||
return;
|
||||
}
|
||||
|
||||
var guo = GetGraphUpdate();
|
||||
if (guo != null) AstarPath.active.UpdateGraphs(guo);
|
||||
}
|
||||
|
||||
/// <summary>Draws some gizmos</summary>
|
||||
void OnDrawGizmos () {
|
||||
OnDrawGizmos(false);
|
||||
}
|
||||
|
||||
/// <summary>Draws some gizmos</summary>
|
||||
void OnDrawGizmosSelected () {
|
||||
OnDrawGizmos(true);
|
||||
}
|
||||
|
||||
/// <summary>Draws some gizmos</summary>
|
||||
void OnDrawGizmos (bool selected) {
|
||||
Color c = selected ? new Color(227/255f, 61/255f, 22/255f, 1.0f) : new Color(227/255f, 61/255f, 22/255f, 0.9f);
|
||||
|
||||
if (selected) {
|
||||
Gizmos.color = Color.Lerp(c, new Color(1, 1, 1, 0.2f), 0.9f);
|
||||
|
||||
Bounds b = GetBounds();
|
||||
Gizmos.DrawCube(b.center, b.size);
|
||||
Gizmos.DrawWireCube(b.center, b.size);
|
||||
}
|
||||
|
||||
if (points == null) return;
|
||||
|
||||
if (convex) c.a *= 0.5f;
|
||||
|
||||
Gizmos.color = c;
|
||||
|
||||
Matrix4x4 matrix = legacyMode && legacyUseWorldSpace ? Matrix4x4.identity : transform.localToWorldMatrix;
|
||||
|
||||
if (convex) {
|
||||
c.r -= 0.1f;
|
||||
c.g -= 0.2f;
|
||||
c.b -= 0.1f;
|
||||
|
||||
Gizmos.color = c;
|
||||
}
|
||||
|
||||
if (selected || !convex) {
|
||||
for (int i = 0; i < points.Length; i++) {
|
||||
Gizmos.DrawLine(matrix.MultiplyPoint3x4(points[i]), matrix.MultiplyPoint3x4(points[(i+1)%points.Length]));
|
||||
}
|
||||
}
|
||||
|
||||
if (convex) {
|
||||
if (convexPoints == null) RecalcConvex();
|
||||
|
||||
Gizmos.color = selected ? new Color(227/255f, 61/255f, 22/255f, 1.0f) : new Color(227/255f, 61/255f, 22/255f, 0.9f);
|
||||
|
||||
for (int i = 0; i < convexPoints.Length; i++) {
|
||||
Gizmos.DrawLine(matrix.MultiplyPoint3x4(convexPoints[i]), matrix.MultiplyPoint3x4(convexPoints[(i+1)%convexPoints.Length]));
|
||||
}
|
||||
}
|
||||
|
||||
// Draw the full 3D shape
|
||||
var pts = convex ? convexPoints : points;
|
||||
if (selected && pts != null && pts.Length > 0) {
|
||||
Gizmos.color = new Color(1, 1, 1, 0.2f);
|
||||
float miny = pts[0].y, maxy = pts[0].y;
|
||||
for (int i = 0; i < pts.Length; i++) {
|
||||
miny = Mathf.Min(miny, pts[i].y);
|
||||
maxy = Mathf.Max(maxy, pts[i].y);
|
||||
}
|
||||
var extraHeight = Mathf.Max(minBoundsHeight - (maxy - miny), 0) * 0.5f;
|
||||
miny -= extraHeight;
|
||||
maxy += extraHeight;
|
||||
|
||||
for (int i = 0; i < pts.Length; i++) {
|
||||
var next = (i+1) % pts.Length;
|
||||
var p1 = matrix.MultiplyPoint3x4(pts[i] + Vector3.up*(miny - pts[i].y));
|
||||
var p2 = matrix.MultiplyPoint3x4(pts[i] + Vector3.up*(maxy - pts[i].y));
|
||||
var p1n = matrix.MultiplyPoint3x4(pts[next] + Vector3.up*(miny - pts[next].y));
|
||||
var p2n = matrix.MultiplyPoint3x4(pts[next] + Vector3.up*(maxy - pts[next].y));
|
||||
Gizmos.DrawLine(p1, p2);
|
||||
Gizmos.DrawLine(p1, p1n);
|
||||
Gizmos.DrawLine(p2, p2n);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Disables legacy mode if it is enabled.
|
||||
/// Legacy mode is automatically enabled for components when upgrading from an earlier version than 3.8.6.
|
||||
/// </summary>
|
||||
public void DisableLegacyMode () {
|
||||
if (legacyMode) {
|
||||
legacyMode = false;
|
||||
if (legacyUseWorldSpace) {
|
||||
legacyUseWorldSpace = false;
|
||||
for (int i = 0; i < points.Length; i++) {
|
||||
points[i] = transform.InverseTransformPoint(points[i]);
|
||||
}
|
||||
RecalcConvex();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnSyncLoad()
|
||||
{
|
||||
if (serializedVersion == 0) {
|
||||
// Use the old behavior if some points are already set
|
||||
if (points != null && points.Length > 0) legacyMode = true;
|
||||
serializedVersion = 1;
|
||||
}
|
||||
base.OnSyncLoad();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: efee954c69f0d421086729bb8df1137f
|
||||
timeCreated: 1490044676
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: -221
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,143 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace Pathfinding {
|
||||
/// <summary>
|
||||
/// Defines a shape for a Pathfinding.GraphUpdateObject.
|
||||
/// The shape consists of a number of points which it can either calculate the convex hull of or use as a polygon directly.
|
||||
///
|
||||
/// A shape is essentially a 2D shape however it can be rotated arbitrarily.
|
||||
/// When a matrix and a list of points is specified in the constructor the matrix decides what direction
|
||||
/// is the 'up' direction. When checking if a point is contained in the shape, the point will be projected down
|
||||
/// on a plane where the 'up' direction is the normal and then it will check if the shape contains the point.
|
||||
///
|
||||
/// See: Pathfinding.GraphUpdateObject.shape
|
||||
/// </summary>
|
||||
public class GraphUpdateShape {
|
||||
Vector3[] _points;
|
||||
Vector3[] _convexPoints;
|
||||
bool _convex;
|
||||
Vector3 right = Vector3.right;
|
||||
Vector3 forward = Vector3.forward;
|
||||
Vector3 up = Vector3.up;
|
||||
Vector3 origin;
|
||||
public float minimumHeight;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the points of the polygon in the shape.
|
||||
/// These points should be specified in clockwise order.
|
||||
/// Will automatically calculate the convex hull if <see cref="convex"/> is set to true
|
||||
/// </summary>
|
||||
public Vector3[] points {
|
||||
get {
|
||||
return _points;
|
||||
}
|
||||
set {
|
||||
_points = value;
|
||||
if (convex) CalculateConvexHull();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets if the convex hull of the points should be calculated.
|
||||
/// Convex hulls are faster but non-convex hulls can be used to specify more complicated shapes.
|
||||
/// </summary>
|
||||
public bool convex {
|
||||
get {
|
||||
return _convex;
|
||||
}
|
||||
set {
|
||||
if (_convex != value && value) {
|
||||
CalculateConvexHull();
|
||||
}
|
||||
_convex = value;
|
||||
}
|
||||
}
|
||||
|
||||
public GraphUpdateShape () {
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Construct a shape.
|
||||
/// See: <see cref="convex"/>
|
||||
/// </summary>
|
||||
/// <param name="points">Contour of the shape in local space with respect to the matrix (i.e the shape should be in the XZ plane, the Y coordinate will only affect the bounds)</param>
|
||||
/// <param name="convex">If true, the convex hull of the points will be calculated.</param>
|
||||
/// <param name="matrix">local to world space matrix for the points. The matrix determines the up direction of the shape.</param>
|
||||
/// <param name="minimumHeight">If the points would be in the XZ plane only, the shape would not have a height and then it might not
|
||||
/// include any points inside it (as testing for inclusion is done in 3D space when updating graphs). This ensures
|
||||
/// that the shape has at least the minimum height (in the up direction that the matrix specifies).</param>
|
||||
public GraphUpdateShape (Vector3[] points, bool convex, Matrix4x4 matrix, float minimumHeight) {
|
||||
this.convex = convex;
|
||||
this.points = points;
|
||||
origin = matrix.MultiplyPoint3x4(Vector3.zero);
|
||||
right = matrix.MultiplyPoint3x4(Vector3.right) - origin;
|
||||
up = matrix.MultiplyPoint3x4(Vector3.up) - origin;
|
||||
forward = matrix.MultiplyPoint3x4(Vector3.forward) - origin;
|
||||
this.minimumHeight = minimumHeight;
|
||||
}
|
||||
|
||||
void CalculateConvexHull () {
|
||||
_convexPoints = points != null? Polygon.ConvexHullXZ(points) : null;
|
||||
}
|
||||
|
||||
/// <summary>World space bounding box of this shape</summary>
|
||||
public Bounds GetBounds () {
|
||||
return GetBounds(convex ? _convexPoints : points, right, up, forward, origin, minimumHeight);
|
||||
}
|
||||
|
||||
public static Bounds GetBounds (Vector3[] points, Matrix4x4 matrix, float minimumHeight) {
|
||||
var origin = matrix.MultiplyPoint3x4(Vector3.zero);
|
||||
var right = matrix.MultiplyPoint3x4(Vector3.right) - origin;
|
||||
var up = matrix.MultiplyPoint3x4(Vector3.up) - origin;
|
||||
var forward = matrix.MultiplyPoint3x4(Vector3.forward) - origin;
|
||||
|
||||
return GetBounds(points, right, up, forward, origin, minimumHeight);
|
||||
}
|
||||
|
||||
static Bounds GetBounds (Vector3[] points, Vector3 right, Vector3 up, Vector3 forward, Vector3 origin, float minimumHeight) {
|
||||
if (points == null || points.Length == 0) return new Bounds();
|
||||
float miny = points[0].y, maxy = points[0].y;
|
||||
for (int i = 0; i < points.Length; i++) {
|
||||
miny = Mathf.Min(miny, points[i].y);
|
||||
maxy = Mathf.Max(maxy, points[i].y);
|
||||
}
|
||||
var extraHeight = Mathf.Max(minimumHeight - (maxy - miny), 0) * 0.5f;
|
||||
miny -= extraHeight;
|
||||
maxy += extraHeight;
|
||||
|
||||
Vector3 min = right * points[0].x + up * points[0].y + forward * points[0].z;
|
||||
Vector3 max = min;
|
||||
for (int i = 0; i < points.Length; i++) {
|
||||
var p = right * points[i].x + forward * points[i].z;
|
||||
var p1 = p + up * miny;
|
||||
var p2 = p + up * maxy;
|
||||
min = Vector3.Min(min, p1);
|
||||
min = Vector3.Min(min, p2);
|
||||
max = Vector3.Max(max, p1);
|
||||
max = Vector3.Max(max, p2);
|
||||
}
|
||||
return new Bounds((min+max)*0.5F + origin, max-min);
|
||||
}
|
||||
|
||||
public bool Contains (GraphNode node) {
|
||||
return Contains((Vector3)node.position);
|
||||
}
|
||||
|
||||
public bool Contains (Vector3 point) {
|
||||
// Transform to local space (shape in the XZ plane)
|
||||
point -= origin;
|
||||
var localSpacePoint = new Vector3(Vector3.Dot(point, right)/right.sqrMagnitude, 0, Vector3.Dot(point, forward)/forward.sqrMagnitude);
|
||||
|
||||
if (convex) {
|
||||
if (_convexPoints == null) return false;
|
||||
|
||||
for (int i = 0, j = _convexPoints.Length-1; i < _convexPoints.Length; j = i, i++) {
|
||||
if (VectorMath.RightOrColinearXZ(_convexPoints[i], _convexPoints[j], localSpacePoint)) return false;
|
||||
}
|
||||
return true;
|
||||
} else {
|
||||
return _points != null && Polygon.ContainsPointXZ(_points, localSpacePoint);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1c31d3b0be14344e98aa458dc66c3a94
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: dfc976d61106d46b6a18ace94ffaea8d
|
@ -0,0 +1,122 @@
|
||||
using UnityEngine;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Pathfinding {
|
||||
[HelpURL("https://arongranberg.com/astar/documentation/stable/class_pathfinding_1_1_animation_link.php")]
|
||||
public class AnimationLink : NodeLink2 {
|
||||
public string clip;
|
||||
public float animSpeed = 1;
|
||||
public bool reverseAnim = true;
|
||||
|
||||
public GameObject referenceMesh;
|
||||
public LinkClip[] sequence;
|
||||
public string boneRoot = "bn_COG_Root";
|
||||
|
||||
[System.Serializable]
|
||||
public class LinkClip {
|
||||
public AnimationClip clip;
|
||||
public Vector3 velocity;
|
||||
public int loopCount = 1;
|
||||
|
||||
public string name {
|
||||
get {
|
||||
return clip != null ? clip.name : "";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static Transform SearchRec (Transform tr, string name) {
|
||||
int childCount = tr.childCount;
|
||||
|
||||
for (int i = 0; i < childCount; i++) {
|
||||
Transform ch = tr.GetChild(i);
|
||||
if (ch.name == name) return ch;
|
||||
else {
|
||||
Transform rec = SearchRec(ch, name);
|
||||
if (rec != null) return rec;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public void CalculateOffsets (List<Vector3> trace, out Vector3 endPosition) {
|
||||
//Vector3 opos = transform.position;
|
||||
endPosition = transform.position;
|
||||
if (referenceMesh == null) return;
|
||||
|
||||
GameObject ob = GameObject.Instantiate(referenceMesh, transform.position, transform.rotation) as GameObject;
|
||||
ob.hideFlags = HideFlags.HideAndDontSave;
|
||||
|
||||
Transform root = SearchRec(ob.transform, boneRoot);
|
||||
if (root == null) throw new System.Exception("Could not find root transform");
|
||||
|
||||
Animation anim = ob.GetComponent<Animation>();
|
||||
if (anim == null) anim = ob.AddComponent<Animation>();
|
||||
|
||||
for (int i = 0; i < sequence.Length; i++) {
|
||||
anim.AddClip(sequence[i].clip, sequence[i].clip.name);
|
||||
}
|
||||
|
||||
Vector3 prevOffset = Vector3.zero;
|
||||
Vector3 position = transform.position;
|
||||
Vector3 firstOffset = Vector3.zero;
|
||||
|
||||
for (int i = 0; i < sequence.Length; i++) {
|
||||
LinkClip c = sequence[i];
|
||||
if (c == null) {
|
||||
endPosition = position;
|
||||
return;
|
||||
}
|
||||
|
||||
anim[c.clip.name].enabled = true;
|
||||
anim[c.clip.name].weight = 1;
|
||||
|
||||
for (int repeat = 0; repeat < c.loopCount; repeat++) {
|
||||
anim[c.clip.name].normalizedTime = 0;
|
||||
anim.Sample();
|
||||
Vector3 soffset = root.position - transform.position;
|
||||
|
||||
if (i > 0) {
|
||||
position += prevOffset - soffset;
|
||||
} else {
|
||||
firstOffset = soffset;
|
||||
}
|
||||
|
||||
for (int t = 0; t <= 20; t++) {
|
||||
float tf = t/20.0f;
|
||||
anim[c.clip.name].normalizedTime = tf;
|
||||
anim.Sample();
|
||||
Vector3 tmp = position + (root.position-transform.position) + c.velocity*tf*c.clip.length;
|
||||
trace.Add(tmp);
|
||||
}
|
||||
position = position + c.velocity*1*c.clip.length;
|
||||
|
||||
anim[c.clip.name].normalizedTime = 1;
|
||||
anim.Sample();
|
||||
Vector3 eoffset = root.position - transform.position;
|
||||
prevOffset = eoffset;
|
||||
}
|
||||
|
||||
anim[c.clip.name].enabled = false;
|
||||
anim[c.clip.name].weight = 0;
|
||||
}
|
||||
|
||||
position += prevOffset - firstOffset;
|
||||
|
||||
GameObject.DestroyImmediate(ob);
|
||||
|
||||
endPosition = position;
|
||||
}
|
||||
|
||||
public override void OnDrawGizmosSelected () {
|
||||
base.OnDrawGizmosSelected();
|
||||
List<Vector3> buffer = Pathfinding.Util.ListPool<Vector3>.Claim();
|
||||
Vector3 endPosition = Vector3.zero;
|
||||
CalculateOffsets(buffer, out endPosition);
|
||||
Gizmos.color = Color.blue;
|
||||
for (int i = 0; i < buffer.Count-1; i++) {
|
||||
Gizmos.DrawLine(buffer[i], buffer[i+1]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d2e8b1fd6fa484fc29f8a26fb5e8662b
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
@ -0,0 +1,344 @@
|
||||
//#define ProfileAstar
|
||||
|
||||
using UnityEngine;
|
||||
using System.Text;
|
||||
|
||||
namespace Pathfinding {
|
||||
[AddComponentMenu("Pathfinding/Pathfinding Debugger")]
|
||||
[ExecuteInEditMode]
|
||||
/// <summary>
|
||||
/// Debugger for the A* Pathfinding Project.
|
||||
/// This class can be used to profile different parts of the pathfinding system
|
||||
/// and the whole game as well to some extent.
|
||||
///
|
||||
/// Clarification of the labels shown when enabled.
|
||||
/// All memory related things profiles <b>the whole game</b> not just the A* Pathfinding System.
|
||||
/// - Currently allocated: memory the GC (garbage collector) says the application has allocated right now.
|
||||
/// - Peak allocated: maximum measured value of the above.
|
||||
/// - Last collect peak: the last peak of 'currently allocated'.
|
||||
/// - Allocation rate: how much the 'currently allocated' value increases per second. This value is not as reliable as you can think
|
||||
/// it is often very random probably depending on how the GC thinks this application is using memory.
|
||||
/// - Collection frequency: how often the GC is called. Again, the GC might decide it is better with many small collections
|
||||
/// or with a few large collections. So you cannot really trust this variable much.
|
||||
/// - Last collect fps: FPS during the last garbage collection, the GC will lower the fps a lot.
|
||||
///
|
||||
/// - FPS: current FPS (not updated every frame for readability)
|
||||
/// - Lowest FPS (last x): As the label says, the lowest fps of the last x frames.
|
||||
///
|
||||
/// - Size: Size of the path pool.
|
||||
/// - Total created: Number of paths of that type which has been created. Pooled paths are not counted twice.
|
||||
/// If this value just keeps on growing and growing without an apparent stop, you are are either not pooling any paths
|
||||
/// or you have missed to pool some path somewhere in your code.
|
||||
///
|
||||
/// See: pooling
|
||||
///
|
||||
/// TODO: Add field showing how many graph updates are being done right now
|
||||
/// </summary>
|
||||
[HelpURL("https://arongranberg.com/astar/documentation/stable/class_pathfinding_1_1_astar_debugger.php")]
|
||||
public class AstarDebugger : VersionedMonoBehaviour {
|
||||
public int yOffset = 5;
|
||||
|
||||
public bool show = true;
|
||||
public bool showInEditor = false;
|
||||
|
||||
public bool showFPS = false;
|
||||
public bool showPathProfile = false;
|
||||
public bool showMemProfile = false;
|
||||
public bool showGraph = false;
|
||||
|
||||
public int graphBufferSize = 200;
|
||||
|
||||
/// <summary>
|
||||
/// Font to use.
|
||||
/// A monospaced font is the best
|
||||
/// </summary>
|
||||
public Font font = null;
|
||||
public int fontSize = 12;
|
||||
|
||||
StringBuilder text = new StringBuilder();
|
||||
string cachedText;
|
||||
float lastUpdate = -999;
|
||||
|
||||
private GraphPoint[] graph;
|
||||
|
||||
struct GraphPoint {
|
||||
public float fps, memory;
|
||||
public bool collectEvent;
|
||||
}
|
||||
|
||||
private float delayedDeltaTime = 1;
|
||||
private float lastCollect = 0;
|
||||
private float lastCollectNum = 0;
|
||||
private float delta = 0;
|
||||
private float lastDeltaTime = 0;
|
||||
private int allocRate = 0;
|
||||
private int lastAllocMemory = 0;
|
||||
private float lastAllocSet = -9999;
|
||||
private int allocMem = 0;
|
||||
private int collectAlloc = 0;
|
||||
private int peakAlloc = 0;
|
||||
|
||||
private int fpsDropCounterSize = 200;
|
||||
private float[] fpsDrops;
|
||||
|
||||
private Rect boxRect;
|
||||
|
||||
private GUIStyle style;
|
||||
|
||||
private Camera cam;
|
||||
|
||||
float graphWidth = 100;
|
||||
float graphHeight = 100;
|
||||
float graphOffset = 50;
|
||||
|
||||
public void Start () {
|
||||
useGUILayout = false;
|
||||
|
||||
fpsDrops = new float[fpsDropCounterSize];
|
||||
|
||||
cam = GetComponent<Camera>();
|
||||
if (cam == null) {
|
||||
cam = Camera.main;
|
||||
}
|
||||
|
||||
graph = new GraphPoint[graphBufferSize];
|
||||
|
||||
if (GetSync().Time.unscaledDeltaTime > 0) {
|
||||
for (int i = 0; i < fpsDrops.Length; i++) {
|
||||
fpsDrops[i] = 1F / GetSync().Time.unscaledDeltaTime;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int maxVecPool = 0;
|
||||
int maxNodePool = 0;
|
||||
|
||||
PathTypeDebug[] debugTypes = new PathTypeDebug[] {
|
||||
new PathTypeDebug("ABPath", () => PathPool.GetSize(typeof(ABPath)), () => PathPool.GetTotalCreated(typeof(ABPath)))
|
||||
,
|
||||
new PathTypeDebug("MultiTargetPath", () => PathPool.GetSize(typeof(MultiTargetPath)), () => PathPool.GetTotalCreated(typeof(MultiTargetPath))),
|
||||
new PathTypeDebug("RandomPath", () => PathPool.GetSize(typeof(RandomPath)), () => PathPool.GetTotalCreated(typeof(RandomPath))),
|
||||
new PathTypeDebug("FleePath", () => PathPool.GetSize(typeof(FleePath)), () => PathPool.GetTotalCreated(typeof(FleePath))),
|
||||
new PathTypeDebug("ConstantPath", () => PathPool.GetSize(typeof(ConstantPath)), () => PathPool.GetTotalCreated(typeof(ConstantPath))),
|
||||
new PathTypeDebug("FloodPath", () => PathPool.GetSize(typeof(FloodPath)), () => PathPool.GetTotalCreated(typeof(FloodPath))),
|
||||
new PathTypeDebug("FloodPathTracer", () => PathPool.GetSize(typeof(FloodPathTracer)), () => PathPool.GetTotalCreated(typeof(FloodPathTracer)))
|
||||
};
|
||||
|
||||
struct PathTypeDebug {
|
||||
string name;
|
||||
System.Func<int> getSize;
|
||||
System.Func<int> getTotalCreated;
|
||||
public PathTypeDebug (string name, System.Func<int> getSize, System.Func<int> getTotalCreated) {
|
||||
this.name = name;
|
||||
this.getSize = getSize;
|
||||
this.getTotalCreated = getTotalCreated;
|
||||
}
|
||||
|
||||
public void Print (StringBuilder text) {
|
||||
int totCreated = getTotalCreated();
|
||||
|
||||
if (totCreated > 0) {
|
||||
text.Append("\n").Append((" " + name).PadRight(25)).Append(getSize()).Append("/").Append(totCreated);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void LateUpdate () {
|
||||
if (!show || (!Application.isPlaying && !showInEditor)) return;
|
||||
|
||||
if (GetSync().Time.unscaledDeltaTime <= 0.0001f)
|
||||
return;
|
||||
|
||||
int collCount = System.GC.CollectionCount(0);
|
||||
|
||||
if (lastCollectNum != collCount) {
|
||||
lastCollectNum = collCount;
|
||||
delta = GetSync().Time.realtimeSinceStartup-lastCollect;
|
||||
lastCollect = GetSync().Time.realtimeSinceStartup;
|
||||
lastDeltaTime = GetSync().Time.unscaledDeltaTime;
|
||||
collectAlloc = allocMem;
|
||||
}
|
||||
|
||||
allocMem = (int)System.GC.GetTotalMemory(false);
|
||||
|
||||
bool collectEvent = allocMem < peakAlloc;
|
||||
peakAlloc = !collectEvent ? allocMem : peakAlloc;
|
||||
|
||||
if (GetSync().Time.realtimeSinceStartup - lastAllocSet > 0.3F || !Application.isPlaying) {
|
||||
int diff = allocMem - lastAllocMemory;
|
||||
lastAllocMemory = allocMem;
|
||||
lastAllocSet = GetSync().Time.realtimeSinceStartup;
|
||||
delayedDeltaTime = GetSync().Time.unscaledDeltaTime;
|
||||
|
||||
if (diff >= 0) {
|
||||
allocRate = diff;
|
||||
}
|
||||
}
|
||||
|
||||
if (Application.isPlaying) {
|
||||
fpsDrops[GetSync().Time.frameCount % fpsDrops.Length] = GetSync().Time.unscaledDeltaTime > 0.00001f ? 1F / GetSync().Time.unscaledDeltaTime : 0;
|
||||
int graphIndex = GetSync().Time.frameCount % graph.Length;
|
||||
graph[graphIndex].fps = GetSync().Time.unscaledDeltaTime < 0.00001f ? 1F / GetSync().Time.unscaledDeltaTime : 0;
|
||||
graph[graphIndex].collectEvent = collectEvent;
|
||||
graph[graphIndex].memory = allocMem;
|
||||
}
|
||||
|
||||
if (Application.isPlaying && cam != null && showGraph) {
|
||||
graphWidth = cam.pixelWidth*0.8f;
|
||||
|
||||
|
||||
float minMem = float.PositiveInfinity, maxMem = 0, minFPS = float.PositiveInfinity, maxFPS = 0;
|
||||
for (int i = 0; i < graph.Length; i++) {
|
||||
minMem = Mathf.Min(graph[i].memory, minMem);
|
||||
maxMem = Mathf.Max(graph[i].memory, maxMem);
|
||||
minFPS = Mathf.Min(graph[i].fps, minFPS);
|
||||
maxFPS = Mathf.Max(graph[i].fps, maxFPS);
|
||||
}
|
||||
|
||||
int currentGraphIndex = GetSync().Time.frameCount % graph.Length;
|
||||
|
||||
Matrix4x4 m = Matrix4x4.TRS(new Vector3((cam.pixelWidth - graphWidth)/2f, graphOffset, 1), Quaternion.identity, new Vector3(graphWidth, graphHeight, 1));
|
||||
|
||||
for (int i = 0; i < graph.Length-1; i++) {
|
||||
if (i == currentGraphIndex) continue;
|
||||
|
||||
DrawGraphLine(i, m, i/(float)graph.Length, (i+1)/(float)graph.Length, Mathf.InverseLerp(minMem, maxMem, graph[i].memory), Mathf.InverseLerp(minMem, maxMem, graph[i+1].memory), Color.blue);
|
||||
DrawGraphLine(i, m, i/(float)graph.Length, (i+1)/(float)graph.Length, Mathf.InverseLerp(minFPS, maxFPS, graph[i].fps), Mathf.InverseLerp(minFPS, maxFPS, graph[i+1].fps), Color.green);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DrawGraphLine (int index, Matrix4x4 m, float x1, float x2, float y1, float y2, Color color) {
|
||||
Debug.DrawLine(cam.ScreenToWorldPoint(m.MultiplyPoint3x4(new Vector3(x1, y1))), cam.ScreenToWorldPoint(m.MultiplyPoint3x4(new Vector3(x2, y2))), color);
|
||||
}
|
||||
|
||||
public void OnGUI () {
|
||||
if (!show || (!Application.isPlaying && !showInEditor)) return;
|
||||
|
||||
if (style == null) {
|
||||
style = new GUIStyle();
|
||||
style.normal.textColor = Color.white;
|
||||
style.padding = new RectOffset(5, 5, 5, 5);
|
||||
}
|
||||
|
||||
if (GetSync().Time.realtimeSinceStartup - lastUpdate > 0.5f || cachedText == null || !Application.isPlaying) {
|
||||
lastUpdate = GetSync().Time.realtimeSinceStartup;
|
||||
|
||||
boxRect = new Rect(5, yOffset, 310, 40);
|
||||
|
||||
text.Length = 0;
|
||||
text.AppendLine("A* Pathfinding Project Debugger");
|
||||
text.Append("A* Version: ").Append(AstarPath.Version.ToString());
|
||||
|
||||
if (showMemProfile) {
|
||||
boxRect.height += 200;
|
||||
|
||||
text.AppendLine();
|
||||
text.AppendLine();
|
||||
text.Append("Currently allocated".PadRight(25));
|
||||
text.Append((allocMem/1000000F).ToString("0.0 MB"));
|
||||
text.AppendLine();
|
||||
|
||||
text.Append("Peak allocated".PadRight(25));
|
||||
text.Append((peakAlloc/1000000F).ToString("0.0 MB")).AppendLine();
|
||||
|
||||
text.Append("Last collect peak".PadRight(25));
|
||||
text.Append((collectAlloc/1000000F).ToString("0.0 MB")).AppendLine();
|
||||
|
||||
|
||||
text.Append("Allocation rate".PadRight(25));
|
||||
text.Append((allocRate/1000000F).ToString("0.0 MB")).AppendLine();
|
||||
|
||||
text.Append("Collection frequency".PadRight(25));
|
||||
text.Append(delta.ToString("0.00"));
|
||||
text.Append("s\n");
|
||||
|
||||
text.Append("Last collect fps".PadRight(25));
|
||||
text.Append((1F/lastDeltaTime).ToString("0.0 fps"));
|
||||
text.Append(" (");
|
||||
text.Append(lastDeltaTime.ToString("0.000 s"));
|
||||
text.Append(")");
|
||||
}
|
||||
|
||||
if (showFPS) {
|
||||
text.AppendLine();
|
||||
text.AppendLine();
|
||||
var delayedFPS = delayedDeltaTime > 0.00001f ? 1F/delayedDeltaTime : 0;
|
||||
text.Append("FPS".PadRight(25)).Append(delayedFPS.ToString("0.0 fps"));
|
||||
|
||||
|
||||
float minFps = Mathf.Infinity;
|
||||
|
||||
for (int i = 0; i < fpsDrops.Length; i++) if (fpsDrops[i] < minFps) minFps = fpsDrops[i];
|
||||
|
||||
text.AppendLine();
|
||||
text.Append(("Lowest fps (last " + fpsDrops.Length + ")").PadRight(25)).Append(minFps.ToString("0.0"));
|
||||
}
|
||||
|
||||
if (showPathProfile) {
|
||||
AstarPath astar = AstarPath.active;
|
||||
|
||||
text.AppendLine();
|
||||
|
||||
if (astar == null) {
|
||||
text.Append("\nNo AstarPath Object In The Scene");
|
||||
} else {
|
||||
#if ProfileAstar
|
||||
double searchSpeed = (double)AstarPath.TotalSearchedNodes*10000 / (double)AstarPath.TotalSearchTime;
|
||||
text.Append("\nSearch Speed (nodes/ms) ").Append(searchSpeed.ToString("0")).Append(" ("+AstarPath.TotalSearchedNodes+" / ").Append(((double)AstarPath.TotalSearchTime/10000F).ToString("0")+")");
|
||||
#endif
|
||||
|
||||
if (Pathfinding.Util.ListPool<Vector3>.GetSize() > maxVecPool) maxVecPool = Pathfinding.Util.ListPool<Vector3>.GetSize();
|
||||
if (Pathfinding.Util.ListPool<Pathfinding.GraphNode>.GetSize() > maxNodePool) maxNodePool = Pathfinding.Util.ListPool<Pathfinding.GraphNode>.GetSize();
|
||||
|
||||
text.Append("\nPool Sizes (size/total created)");
|
||||
|
||||
for (int i = 0; i < debugTypes.Length; i++) {
|
||||
debugTypes[i].Print(text);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
cachedText = text.ToString();
|
||||
}
|
||||
|
||||
|
||||
if (font != null) {
|
||||
style.font = font;
|
||||
style.fontSize = fontSize;
|
||||
}
|
||||
|
||||
boxRect.height = style.CalcHeight(new GUIContent(cachedText), boxRect.width);
|
||||
|
||||
GUI.Box(boxRect, "");
|
||||
GUI.Label(boxRect, cachedText, style);
|
||||
|
||||
if (showGraph) {
|
||||
float minMem = float.PositiveInfinity, maxMem = 0, minFPS = float.PositiveInfinity, maxFPS = 0;
|
||||
for (int i = 0; i < graph.Length; i++) {
|
||||
minMem = Mathf.Min(graph[i].memory, minMem);
|
||||
maxMem = Mathf.Max(graph[i].memory, maxMem);
|
||||
minFPS = Mathf.Min(graph[i].fps, minFPS);
|
||||
maxFPS = Mathf.Max(graph[i].fps, maxFPS);
|
||||
}
|
||||
|
||||
float line;
|
||||
GUI.color = Color.blue;
|
||||
// Round to nearest x.x MB
|
||||
line = Mathf.RoundToInt(maxMem/(100.0f*1000));
|
||||
GUI.Label(new Rect(5, Screen.height - AstarMath.MapTo(minMem, maxMem, 0 + graphOffset, graphHeight + graphOffset, line*1000*100) - 10, 100, 20), (line/10.0f).ToString("0.0 MB"));
|
||||
|
||||
line = Mathf.Round(minMem/(100.0f*1000));
|
||||
GUI.Label(new Rect(5, Screen.height - AstarMath.MapTo(minMem, maxMem, 0 + graphOffset, graphHeight + graphOffset, line*1000*100) - 10, 100, 20), (line/10.0f).ToString("0.0 MB"));
|
||||
|
||||
GUI.color = Color.green;
|
||||
// Round to nearest x.x MB
|
||||
line = Mathf.Round(maxFPS);
|
||||
GUI.Label(new Rect(55, Screen.height - AstarMath.MapTo(minFPS, maxFPS, 0 + graphOffset, graphHeight + graphOffset, line) - 10, 100, 20), line.ToString("0 FPS"));
|
||||
|
||||
line = Mathf.Round(minFPS);
|
||||
GUI.Label(new Rect(55, Screen.height - AstarMath.MapTo(minFPS, maxFPS, 0 + graphOffset, graphHeight + graphOffset, line) - 10, 100, 20), line.ToString("0 FPS"));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5103795af2d504ea693528e938005441
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
@ -0,0 +1,123 @@
|
||||
using Plugins.JNGame.Sync.Frame.Entity;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Pathfinding {
|
||||
using Pathfinding.Util;
|
||||
|
||||
/// <summary>
|
||||
/// Policy for how often to recalculate an agent's path.
|
||||
///
|
||||
/// See: <see cref="AIBase.autoRepath"/>
|
||||
/// See: <see cref="AILerp.autoRepath"/>
|
||||
/// </summary>
|
||||
[System.Serializable]
|
||||
public class AutoRepathPolicy {
|
||||
/// <summary>Policy mode for how often to recalculate an agent's path.</summary>
|
||||
public enum Mode {
|
||||
/// <summary>
|
||||
/// Never automatically recalculate the path.
|
||||
/// Paths can be recalculated manually by for example calling <see cref="IAstarAI.SearchPath"/> or <see cref="IAstarAI.SetPath"/>.
|
||||
/// This mode is useful if you want full control of when the agent calculates its path.
|
||||
/// </summary>
|
||||
Never,
|
||||
/// <summary>
|
||||
/// Recalculate the path every <see cref="period"/> seconds.
|
||||
///
|
||||
/// This is primarily included for historical reasons, but might be useful if you want the path recalculations to happen at a very predictable rate.
|
||||
/// In most cases it is recommended to use the Dynamic mode.
|
||||
/// </summary>
|
||||
EveryNSeconds,
|
||||
/// <summary>
|
||||
/// Recalculate the path at least every <see cref="maximumPeriod"/> seconds but more often if the destination moves a lot.
|
||||
/// This mode is recommended since it allows the agent to quickly respond to new destinations without using up a lot of CPU power to calculate paths
|
||||
/// when it doesn't have to.
|
||||
///
|
||||
/// More precisely:
|
||||
/// Let C be a circle centered at the destination for the last calculated path, with a radius equal to the distance to that point divided by <see cref="sensitivity"/>.
|
||||
/// If the new destination is outside that circle the path will be immediately recalculated.
|
||||
/// Otherwise let F be the 1 - (distance from the circle's center to the new destination divided by the circle's radius).
|
||||
/// So F will be 1 if the new destination is the same as the old one and 0 if it is at the circle's edge.
|
||||
/// Recalculate the path if the time since the last path recalculation is greater than <see cref="maximumPeriod"/> multiplied by F.
|
||||
///
|
||||
/// Thus if the destination doesn't change the path will be recalculated every <see cref="maximumPeriod"/> seconds.
|
||||
/// </summary>
|
||||
Dynamic,
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Policy to use when recalculating paths.
|
||||
///
|
||||
/// See: <see cref="AutoRepathPolicy.Mode"/> for more details.
|
||||
/// </summary>
|
||||
public Mode mode = Mode.Dynamic;
|
||||
|
||||
/// <summary>Number of seconds between each automatic path recalculation for Mode.EveryNSeconds</summary>
|
||||
[UnityEngine.Serialization.FormerlySerializedAs("interval")]
|
||||
public float period = 0.5f;
|
||||
|
||||
/// <summary>
|
||||
/// How sensitive the agent should be to changes in its destination for Mode.Dynamic.
|
||||
/// A higher value means the destination has to move less for the path to be recalculated.
|
||||
///
|
||||
/// See: <see cref="Mode"/>
|
||||
/// </summary>
|
||||
public float sensitivity = 10.0f;
|
||||
|
||||
/// <summary>Maximum number of seconds between each automatic path recalculation for Mode.Dynamic</summary>
|
||||
[UnityEngine.Serialization.FormerlySerializedAs("maximumInterval")]
|
||||
public float maximumPeriod = 2.0f;
|
||||
|
||||
/// <summary>If true the sensitivity will be visualized as a circle in the scene view when the game is playing</summary>
|
||||
public bool visualizeSensitivity = false;
|
||||
|
||||
Vector3 lastDestination = new Vector3(float.PositiveInfinity, float.PositiveInfinity, float.PositiveInfinity);
|
||||
float lastRepathTime = float.NegativeInfinity;
|
||||
|
||||
/// <summary>
|
||||
/// True if the path should be recalculated according to the policy
|
||||
///
|
||||
/// The above parameters are relevant only if <see cref="mode"/> is <see cref="Mode.Dynamic"/>.
|
||||
/// </summary>
|
||||
/// <param name="position">The current position of the agent.</param>
|
||||
/// <param name="radius">The radius of the agent. You may pass 0.0 if the agent doesn't have a radius.</param>
|
||||
/// <param name="destination">The goal of the agent right now</param>
|
||||
public virtual bool ShouldRecalculatePath (Vector3 position, float radius, Vector3 destination) {
|
||||
if (mode == Mode.Never || float.IsPositiveInfinity(destination.x)) return false;
|
||||
|
||||
float timeSinceLast = JNTime.Time.time - lastRepathTime;
|
||||
if (mode == Mode.EveryNSeconds) {
|
||||
return timeSinceLast >= period;
|
||||
} else {
|
||||
// cost = change in destination / max(distance to destination, radius)
|
||||
float squaredCost = (destination - lastDestination).sqrMagnitude / Mathf.Max((position - lastDestination).sqrMagnitude, radius*radius);
|
||||
float fraction = squaredCost * (sensitivity*sensitivity);
|
||||
if (fraction > 1.0f || float.IsNaN(fraction)) return true;
|
||||
|
||||
if (timeSinceLast >= maximumPeriod*(1 - Mathf.Sqrt(fraction))) return true;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Reset the runtime variables so that the policy behaves as if the game just started</summary>
|
||||
public virtual void Reset () {
|
||||
lastRepathTime = float.NegativeInfinity;
|
||||
}
|
||||
|
||||
/// <summary>Must be called when a path request has been scheduled</summary>
|
||||
public virtual void DidRecalculatePath (Vector3 destination) {
|
||||
lastRepathTime = JNTime.Time.time;
|
||||
lastDestination = destination;
|
||||
// Randomize the repath time slightly so that all agents don't request a path at the same time
|
||||
// in the future. This is useful when there are a lot of agents instantiated at exactly the same time.
|
||||
const float JITTER_AMOUNT = 0.3f;
|
||||
lastRepathTime -= (UnityEngine.Random.value - 0.5f) * JITTER_AMOUNT * (mode == Mode.Dynamic ? maximumPeriod : period);
|
||||
}
|
||||
|
||||
public void DrawGizmos (Vector3 position, float radius) {
|
||||
if (visualizeSensitivity && !float.IsPositiveInfinity(lastDestination.x)) {
|
||||
float r = Mathf.Sqrt(Mathf.Max((position - lastDestination).sqrMagnitude, radius*radius)/(sensitivity*sensitivity));
|
||||
Draw.Gizmos.CircleXZ(lastDestination, r, Color.magenta);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2664ef60fd2811ba280670298a6d312b
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,324 @@
|
||||
#pragma warning disable 162
|
||||
#pragma warning disable 429
|
||||
#define DECREASE_KEY
|
||||
|
||||
namespace Pathfinding {
|
||||
/// <summary>
|
||||
/// Binary heap implementation.
|
||||
/// Binary heaps are really fast for ordering nodes in a way that
|
||||
/// makes it possible to get the node with the lowest F score.
|
||||
/// Also known as a priority queue.
|
||||
///
|
||||
/// This has actually been rewritten as a 4-ary heap
|
||||
/// for performance, but it's the same principle.
|
||||
///
|
||||
/// See: http://en.wikipedia.org/wiki/Binary_heap
|
||||
/// See: https://en.wikipedia.org/wiki/D-ary_heap
|
||||
/// </summary>
|
||||
public class BinaryHeap {
|
||||
/// <summary>Number of items in the tree</summary>
|
||||
public int numberOfItems;
|
||||
|
||||
/// <summary>The tree will grow by at least this factor every time it is expanded</summary>
|
||||
public float growthFactor = 2;
|
||||
|
||||
/// <summary>
|
||||
/// Number of children of each node in the tree.
|
||||
/// Different values have been tested and 4 has been empirically found to perform the best.
|
||||
/// See: https://en.wikipedia.org/wiki/D-ary_heap
|
||||
/// </summary>
|
||||
const int D = 4;
|
||||
|
||||
/// <summary>
|
||||
/// Sort nodes by G score if there is a tie when comparing the F score.
|
||||
/// Disabling this will improve pathfinding performance with around 2.5%
|
||||
/// but may break ties between paths that have the same length in a less
|
||||
/// desirable manner (only relevant for grid graphs).
|
||||
/// </summary>
|
||||
const bool SortGScores = true;
|
||||
|
||||
public const ushort NotInHeap = 0xFFFF;
|
||||
|
||||
/// <summary>Internal backing array for the heap</summary>
|
||||
private Tuple[] heap;
|
||||
|
||||
/// <summary>True if the heap does not contain any elements</summary>
|
||||
public bool isEmpty {
|
||||
get {
|
||||
return numberOfItems <= 0;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Item in the heap</summary>
|
||||
private struct Tuple {
|
||||
public PathNode node;
|
||||
public uint F;
|
||||
|
||||
public Tuple (uint f, PathNode node) {
|
||||
this.F = f;
|
||||
this.node = node;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Rounds up v so that it has remainder 1 when divided by D.
|
||||
/// I.e it is of the form n*D + 1 where n is any non-negative integer.
|
||||
/// </summary>
|
||||
static int RoundUpToNextMultipleMod1 (int v) {
|
||||
// I have a feeling there is a nicer way to do this
|
||||
return v + (4 - ((v-1) % D)) % D;
|
||||
}
|
||||
|
||||
/// <summary>Create a new heap with the specified initial capacity</summary>
|
||||
public BinaryHeap (int capacity) {
|
||||
// Make sure the size has remainder 1 when divided by D
|
||||
// This allows us to always guarantee that indices used in the Remove method
|
||||
// will never throw out of bounds exceptions
|
||||
capacity = RoundUpToNextMultipleMod1(capacity);
|
||||
|
||||
heap = new Tuple[capacity];
|
||||
numberOfItems = 0;
|
||||
}
|
||||
|
||||
/// <summary>Removes all elements from the heap</summary>
|
||||
public void Clear () {
|
||||
#if DECREASE_KEY
|
||||
// Clear all heap indices
|
||||
// This is important to avoid bugs
|
||||
for (int i = 0; i < numberOfItems; i++) {
|
||||
heap[i].node.heapIndex = NotInHeap;
|
||||
}
|
||||
#endif
|
||||
|
||||
numberOfItems = 0;
|
||||
}
|
||||
|
||||
internal PathNode GetNode (int i) {
|
||||
return heap[i].node;
|
||||
}
|
||||
|
||||
internal void SetF (int i, uint f) {
|
||||
heap[i].F = f;
|
||||
}
|
||||
|
||||
/// <summary>Expands to a larger backing array when the current one is too small</summary>
|
||||
void Expand () {
|
||||
// 65533 == 1 mod 4 and slightly smaller than 1<<16 = 65536
|
||||
int newSize = System.Math.Max(heap.Length+4, System.Math.Min(65533, (int)System.Math.Round(heap.Length*growthFactor)));
|
||||
|
||||
// Make sure the size has remainder 1 when divided by D
|
||||
// This allows us to always guarantee that indices used in the Remove method
|
||||
// will never throw out of bounds exceptions
|
||||
newSize = RoundUpToNextMultipleMod1(newSize);
|
||||
|
||||
// Check if the heap is really large
|
||||
// Also note that heaps larger than this are not supported
|
||||
// since PathNode.heapIndex is a ushort and can only store
|
||||
// values up to 65535 (NotInHeap = 65535 is reserved however)
|
||||
if (newSize > (1<<16) - 2) {
|
||||
throw new System.Exception("Binary Heap Size really large (>65534). A heap size this large is probably the cause of pathfinding running in an infinite loop. ");
|
||||
}
|
||||
|
||||
var newHeap = new Tuple[newSize];
|
||||
heap.CopyTo(newHeap, 0);
|
||||
#if ASTARDEBUG
|
||||
UnityEngine.Debug.Log("Resizing binary heap to "+newSize);
|
||||
#endif
|
||||
heap = newHeap;
|
||||
}
|
||||
|
||||
/// <summary>Adds a node to the heap</summary>
|
||||
public void Add (PathNode node) {
|
||||
if (node == null) throw new System.ArgumentNullException("node");
|
||||
|
||||
#if DECREASE_KEY
|
||||
// Check if node is already in the heap
|
||||
if (node.heapIndex != NotInHeap) {
|
||||
DecreaseKey(heap[node.heapIndex], node.heapIndex);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (numberOfItems == heap.Length) {
|
||||
Expand();
|
||||
}
|
||||
|
||||
DecreaseKey(new Tuple(0, node), (ushort)numberOfItems);
|
||||
numberOfItems++;
|
||||
}
|
||||
|
||||
void DecreaseKey (Tuple node, ushort index) {
|
||||
// This is where 'obj' is in the binary heap logically speaking
|
||||
// (for performance reasons we don't actually store it there until
|
||||
// we know the final index, that's just a waste of CPU cycles)
|
||||
int bubbleIndex = index;
|
||||
// Update F value, it might have changed since the node was originally added to the heap
|
||||
uint nodeF = node.F = node.node.F;
|
||||
uint nodeG = node.node.G;
|
||||
|
||||
while (bubbleIndex != 0) {
|
||||
// Parent node of the bubble node
|
||||
int parentIndex = (bubbleIndex-1) / D;
|
||||
|
||||
if (nodeF < heap[parentIndex].F || (SortGScores && nodeF == heap[parentIndex].F && nodeG > heap[parentIndex].node.G)) {
|
||||
// Swap the bubble node and parent node
|
||||
// (we don't really need to store the bubble node until we know the final index though
|
||||
// so we do that after the loop instead)
|
||||
heap[bubbleIndex] = heap[parentIndex];
|
||||
#if DECREASE_KEY
|
||||
heap[bubbleIndex].node.heapIndex = (ushort)bubbleIndex;
|
||||
#endif
|
||||
bubbleIndex = parentIndex;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
heap[bubbleIndex] = node;
|
||||
#if DECREASE_KEY
|
||||
node.node.heapIndex = (ushort)bubbleIndex;
|
||||
#endif
|
||||
}
|
||||
|
||||
/// <summary>Returns the node with the lowest F score from the heap</summary>
|
||||
public PathNode Remove () {
|
||||
PathNode returnItem = heap[0].node;
|
||||
|
||||
#if DECREASE_KEY
|
||||
returnItem.heapIndex = NotInHeap;
|
||||
#endif
|
||||
|
||||
numberOfItems--;
|
||||
if (numberOfItems == 0) return returnItem;
|
||||
|
||||
// Last item in the heap array
|
||||
var swapItem = heap[numberOfItems];
|
||||
var swapItemG = swapItem.node.G;
|
||||
|
||||
int swapIndex = 0, parent;
|
||||
|
||||
// Trickle upwards
|
||||
while (true) {
|
||||
parent = swapIndex;
|
||||
uint swapF = swapItem.F;
|
||||
int pd = parent * D + 1;
|
||||
|
||||
// If this holds, then the indices used
|
||||
// below are guaranteed to not throw an index out of bounds
|
||||
// exception since we choose the size of the array in that way
|
||||
if (pd <= numberOfItems) {
|
||||
// Loading all F scores here instead of inside the if statements
|
||||
// reduces data dependencies and improves performance
|
||||
uint f0 = heap[pd+0].F;
|
||||
uint f1 = heap[pd+1].F;
|
||||
uint f2 = heap[pd+2].F;
|
||||
uint f3 = heap[pd+3].F;
|
||||
|
||||
// The common case is that all children of a node are present
|
||||
// so the first comparison in each if statement below
|
||||
// will be extremely well predicted so it is essentially free
|
||||
// (I tried optimizing for the common case, but it didn't affect performance at all
|
||||
// at the expense of longer code, the CPU branch predictor is really good)
|
||||
|
||||
if (pd+0 < numberOfItems && (f0 < swapF || (SortGScores && f0 == swapF && heap[pd+0].node.G < swapItemG))) {
|
||||
swapF = f0;
|
||||
swapIndex = pd+0;
|
||||
}
|
||||
|
||||
if (pd+1 < numberOfItems && (f1 < swapF || (SortGScores && f1 == swapF && heap[pd+1].node.G < (swapIndex == parent ? swapItemG : heap[swapIndex].node.G)))) {
|
||||
swapF = f1;
|
||||
swapIndex = pd+1;
|
||||
}
|
||||
|
||||
if (pd+2 < numberOfItems && (f2 < swapF || (SortGScores && f2 == swapF && heap[pd+2].node.G < (swapIndex == parent ? swapItemG : heap[swapIndex].node.G)))) {
|
||||
swapF = f2;
|
||||
swapIndex = pd+2;
|
||||
}
|
||||
|
||||
if (pd+3 < numberOfItems && (f3 < swapF || (SortGScores && f3 == swapF && heap[pd+3].node.G < (swapIndex == parent ? swapItemG : heap[swapIndex].node.G)))) {
|
||||
swapIndex = pd+3;
|
||||
}
|
||||
}
|
||||
|
||||
// One if the parent's children are smaller or equal, swap them
|
||||
// (actually we are just pretenting we swapped them, we hold the swapData
|
||||
// in local variable and only assign it once we know the final index)
|
||||
if (parent != swapIndex) {
|
||||
heap[parent] = heap[swapIndex];
|
||||
#if DECREASE_KEY
|
||||
heap[parent].node.heapIndex = (ushort)parent;
|
||||
#endif
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Assign element to the final position
|
||||
heap[swapIndex] = swapItem;
|
||||
#if DECREASE_KEY
|
||||
swapItem.node.heapIndex = (ushort)swapIndex;
|
||||
#endif
|
||||
|
||||
// For debugging
|
||||
// Validate ();
|
||||
|
||||
return returnItem;
|
||||
}
|
||||
|
||||
void Validate () {
|
||||
for (int i = 1; i < numberOfItems; i++) {
|
||||
int parentIndex = (i-1)/D;
|
||||
if (heap[parentIndex].F > heap[i].F) {
|
||||
throw new System.Exception("Invalid state at " + i + ":" + parentIndex + " ( " + heap[parentIndex].F + " > " + heap[i].F + " ) ");
|
||||
}
|
||||
#if DECREASE_KEY
|
||||
if (heap[i].node.heapIndex != i) {
|
||||
throw new System.Exception("Invalid heap index");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Rebuilds the heap by trickeling down all items.
|
||||
/// Usually called after the hTarget on a path has been changed
|
||||
/// </summary>
|
||||
public void Rebuild () {
|
||||
#if ASTARDEBUG
|
||||
int changes = 0;
|
||||
#endif
|
||||
|
||||
for (int i = 2; i < numberOfItems; i++) {
|
||||
int bubbleIndex = i;
|
||||
var node = heap[i];
|
||||
uint nodeF = node.F;
|
||||
while (bubbleIndex != 1) {
|
||||
int parentIndex = bubbleIndex / D;
|
||||
|
||||
if (nodeF < heap[parentIndex].F) {
|
||||
heap[bubbleIndex] = heap[parentIndex];
|
||||
#if DECREASE_KEY
|
||||
heap[bubbleIndex].node.heapIndex = (ushort)bubbleIndex;
|
||||
#endif
|
||||
|
||||
heap[parentIndex] = node;
|
||||
#if DECREASE_KEY
|
||||
heap[parentIndex].node.heapIndex = (ushort)parentIndex;
|
||||
#endif
|
||||
|
||||
bubbleIndex = parentIndex;
|
||||
#if ASTARDEBUG
|
||||
changes++;
|
||||
#endif
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#if ASTARDEBUG
|
||||
UnityEngine.Debug.Log("+++ Rebuilt Heap - "+changes+" changes +++");
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: eb4299e8747f44ad2b4e086752108ea3
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
@ -0,0 +1,91 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace Pathfinding.Util {
|
||||
/// <summary>Helper methods for drawing gizmos and debug lines</summary>
|
||||
public class Draw {
|
||||
public static readonly Draw Debug = new Draw { gizmos = false };
|
||||
public static readonly Draw Gizmos = new Draw { gizmos = true };
|
||||
|
||||
bool gizmos;
|
||||
Matrix4x4 matrix = Matrix4x4.identity;
|
||||
|
||||
void SetColor (Color color) {
|
||||
if (gizmos && UnityEngine.Gizmos.color != color) UnityEngine.Gizmos.color = color;
|
||||
}
|
||||
|
||||
public void Polyline (System.Collections.Generic.List<Vector3> points, Color color, bool cycle = false) {
|
||||
for (int i = 0; i < points.Count - 1; i++) {
|
||||
Line(points[i], points[i+1], color);
|
||||
}
|
||||
if (cycle && points.Count > 1) Line(points[points.Count - 1], points[0], color);
|
||||
}
|
||||
|
||||
public void Line (Vector3 a, Vector3 b, Color color) {
|
||||
SetColor(color);
|
||||
if (gizmos) UnityEngine.Gizmos.DrawLine(matrix.MultiplyPoint3x4(a), matrix.MultiplyPoint3x4(b));
|
||||
else UnityEngine.Debug.DrawLine(matrix.MultiplyPoint3x4(a), matrix.MultiplyPoint3x4(b), color);
|
||||
}
|
||||
|
||||
public void CircleXZ (Vector3 center, float radius, Color color, float startAngle = 0f, float endAngle = 2*Mathf.PI) {
|
||||
int steps = 40;
|
||||
|
||||
#if UNITY_EDITOR
|
||||
if (gizmos) steps = (int)Mathf.Clamp(Mathf.Sqrt(radius / UnityEditor.HandleUtility.GetHandleSize((UnityEngine.Gizmos.matrix * matrix).MultiplyPoint3x4(center))) * 25, 4, 40);
|
||||
#endif
|
||||
while (startAngle > endAngle) startAngle -= 2*Mathf.PI;
|
||||
|
||||
Vector3 prev = new Vector3(Mathf.Cos(startAngle)*radius, 0, Mathf.Sin(startAngle)*radius);
|
||||
for (int i = 0; i <= steps; i++) {
|
||||
Vector3 c = new Vector3(Mathf.Cos(Mathf.Lerp(startAngle, endAngle, i/(float)steps))*radius, 0, Mathf.Sin(Mathf.Lerp(startAngle, endAngle, i/(float)steps))*radius);
|
||||
Line(center + prev, center + c, color);
|
||||
prev = c;
|
||||
}
|
||||
}
|
||||
|
||||
public void Cylinder (Vector3 position, Vector3 up, float height, float radius, Color color) {
|
||||
var tangent = Vector3.Cross(up, Vector3.one).normalized;
|
||||
|
||||
matrix = Matrix4x4.TRS(position, Quaternion.LookRotation(tangent, up), new Vector3(radius, height, radius));
|
||||
CircleXZ(Vector3.zero, 1, color);
|
||||
|
||||
if (height > 0) {
|
||||
CircleXZ(Vector3.up, 1, color);
|
||||
Line(new Vector3(1, 0, 0), new Vector3(1, 1, 0), color);
|
||||
Line(new Vector3(-1, 0, 0), new Vector3(-1, 1, 0), color);
|
||||
Line(new Vector3(0, 0, 1), new Vector3(0, 1, 1), color);
|
||||
Line(new Vector3(0, 0, -1), new Vector3(0, 1, -1), color);
|
||||
}
|
||||
|
||||
matrix = Matrix4x4.identity;
|
||||
}
|
||||
|
||||
public void CrossXZ (Vector3 position, Color color, float size = 1) {
|
||||
size *= 0.5f;
|
||||
Line(position - Vector3.right*size, position + Vector3.right*size, color);
|
||||
Line(position - Vector3.forward*size, position + Vector3.forward*size, color);
|
||||
}
|
||||
|
||||
public void Bezier (Vector3 a, Vector3 b, Color color) {
|
||||
Vector3 dir = b - a;
|
||||
|
||||
if (dir == Vector3.zero) return;
|
||||
|
||||
Vector3 normal = Vector3.Cross(Vector3.up, dir);
|
||||
Vector3 normalUp = Vector3.Cross(dir, normal);
|
||||
|
||||
normalUp = normalUp.normalized;
|
||||
normalUp *= dir.magnitude*0.1f;
|
||||
|
||||
Vector3 p1c = a + normalUp;
|
||||
Vector3 p2c = b + normalUp;
|
||||
|
||||
Vector3 prev = a;
|
||||
for (int i = 1; i <= 20; i++) {
|
||||
float t = i/20.0f;
|
||||
Vector3 p = AstarSplines.CubicBezier(a, p1c, p2c, b, t);
|
||||
Line(prev, p, color);
|
||||
prev = p;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 506739df886ce4ebb9b14b16d86b5e13
|
||||
timeCreated: 1492346087
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,105 @@
|
||||
namespace Pathfinding {
|
||||
#if UNITY_EDITOR
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
using System.Collections.Generic;
|
||||
|
||||
/// <summary>Internal utility class for looking up editor resources</summary>
|
||||
public static class EditorResourceHelper {
|
||||
/// <summary>
|
||||
/// Path to the editor assets folder for the A* Pathfinding Project. If this path turns out to be incorrect, the script will try to find the correct path
|
||||
/// See: LoadStyles
|
||||
/// </summary>
|
||||
public static string editorAssets;
|
||||
|
||||
static EditorResourceHelper () {
|
||||
// Look up editor assets directory when first accessed
|
||||
LocateEditorAssets();
|
||||
}
|
||||
|
||||
static Material surfaceMat, lineMat;
|
||||
static Texture2D handlesAALineTex;
|
||||
public static Material GizmoSurfaceMaterial {
|
||||
get {
|
||||
if (!surfaceMat) surfaceMat = UnityEditor.AssetDatabase.LoadAssetAtPath(EditorResourceHelper.editorAssets + "/Materials/Navmesh.mat", typeof(Material)) as Material;
|
||||
return surfaceMat;
|
||||
}
|
||||
}
|
||||
|
||||
public static Material GizmoLineMaterial {
|
||||
get {
|
||||
if (!lineMat) lineMat = UnityEditor.AssetDatabase.LoadAssetAtPath(EditorResourceHelper.editorAssets + "/Materials/NavmeshOutline.mat", typeof(Material)) as Material;
|
||||
return lineMat;
|
||||
}
|
||||
}
|
||||
|
||||
public static Texture2D HandlesAALineTexture {
|
||||
get {
|
||||
if (!handlesAALineTex) handlesAALineTex = Resources.Load<Texture2D>("handles_aaline");
|
||||
return handlesAALineTex;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Locates the editor assets folder in case the user has moved it</summary>
|
||||
public static bool LocateEditorAssets () {
|
||||
#if UNITY_2019_3_OR_NEWER
|
||||
var package = UnityEditor.PackageManager.PackageInfo.FindForAssembly(typeof(EditorResourceHelper).Assembly);
|
||||
if (package != null) {
|
||||
editorAssets = package.assetPath + "/Editor/EditorAssets";
|
||||
if (System.IO.File.Exists(package.resolvedPath + "/Editor/EditorAssets/AstarEditorSkinLight.guiskin")) {
|
||||
return true;
|
||||
} else {
|
||||
Debug.LogError("Could not find editor assets folder in package at " + editorAssets + ". Is the package corrupt?");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
string projectPath = Application.dataPath;
|
||||
|
||||
if (projectPath.EndsWith("/Assets")) {
|
||||
projectPath = projectPath.Remove(projectPath.Length-("Assets".Length));
|
||||
}
|
||||
|
||||
editorAssets = "Assets/AstarPathfindingProject/Editor/EditorAssets";
|
||||
if (!System.IO.File.Exists(projectPath + editorAssets + "/AstarEditorSkinLight.guiskin") && !System.IO.File.Exists(projectPath + editorAssets + "/AstarEditorSkin.guiskin")) {
|
||||
//Initiate search
|
||||
|
||||
var sdir = new System.IO.DirectoryInfo(Application.dataPath);
|
||||
|
||||
var dirQueue = new Queue<System.IO.DirectoryInfo>();
|
||||
dirQueue.Enqueue(sdir);
|
||||
|
||||
bool found = false;
|
||||
while (dirQueue.Count > 0) {
|
||||
System.IO.DirectoryInfo dir = dirQueue.Dequeue();
|
||||
if (System.IO.File.Exists(dir.FullName + "/AstarEditorSkinLight.guiskin") || System.IO.File.Exists(dir.FullName + "/AstarEditorSkin.guiskin")) {
|
||||
// Handle windows file paths
|
||||
string path = dir.FullName.Replace('\\', '/');
|
||||
found = true;
|
||||
// Remove data path from string to make it relative
|
||||
path = path.Replace(projectPath, "");
|
||||
|
||||
if (path.StartsWith("/")) {
|
||||
path = path.Remove(0, 1);
|
||||
}
|
||||
|
||||
editorAssets = path;
|
||||
return true;
|
||||
}
|
||||
var dirs = dir.GetDirectories();
|
||||
for (int i = 0; i < dirs.Length; i++) {
|
||||
dirQueue.Enqueue(dirs[i]);
|
||||
}
|
||||
}
|
||||
|
||||
if (!found) {
|
||||
Debug.LogWarning("Could not locate editor assets folder. Make sure you have imported the package correctly.\nA* Pathfinding Project");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8127bc49e9e2d42dfa7a4e057842f165
|
||||
timeCreated: 1480419306
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,13 @@
|
||||
using Pathfinding.Serialization;
|
||||
|
||||
namespace Pathfinding {
|
||||
[JsonOptIn]
|
||||
/// <summary>
|
||||
/// Base class for all graph editors.
|
||||
/// Defined here only so non-editor classes can use the <see cref="target"/> field
|
||||
/// </summary>
|
||||
public class GraphEditorBase {
|
||||
/// <summary>NavGraph this editor is exposing</summary>
|
||||
public NavGraph target;
|
||||
}
|
||||
}
|
@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 704136724bc95455ebe477f42f5c5a84
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
@ -0,0 +1,205 @@
|
||||
using UnityEngine;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Pathfinding {
|
||||
/// <summary>
|
||||
/// GraphModifier is used for modifying graphs or processing graph data based on events.
|
||||
/// This class is a simple container for a number of events.
|
||||
///
|
||||
/// Warning: Some events will be called both in play mode <b>and in editor mode</b> (at least the scan events).
|
||||
/// So make sure your code handles both cases well. You may choose to ignore editor events.
|
||||
/// See: Application.IsPlaying
|
||||
/// </summary>
|
||||
[ExecuteInEditMode]
|
||||
public abstract class GraphModifier : VersionedMonoBehaviour {
|
||||
/// <summary>All active graph modifiers</summary>
|
||||
private static GraphModifier root;
|
||||
|
||||
private GraphModifier prev;
|
||||
private GraphModifier next;
|
||||
|
||||
/// <summary>Unique persistent ID for this component, used for serialization</summary>
|
||||
[SerializeField]
|
||||
[HideInInspector]
|
||||
protected ulong uniqueID;
|
||||
|
||||
/// <summary>Maps persistent IDs to the component that uses it</summary>
|
||||
protected static Dictionary<ulong, GraphModifier> usedIDs = new Dictionary<ulong, GraphModifier>();
|
||||
|
||||
protected static List<T> GetModifiersOfType<T>() where T : GraphModifier {
|
||||
var current = root;
|
||||
var result = new List<T>();
|
||||
|
||||
while (current != null) {
|
||||
var cast = current as T;
|
||||
if (cast != null) result.Add(cast);
|
||||
current = current.next;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public static void FindAllModifiers () {
|
||||
var allModifiers = FindObjectsOfType(typeof(GraphModifier)) as GraphModifier[];
|
||||
|
||||
for (int i = 0; i < allModifiers.Length; i++) {
|
||||
if (allModifiers[i].enabled) allModifiers[i].OnEnable();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>GraphModifier event type</summary>
|
||||
public enum EventType {
|
||||
PostScan = 1 << 0,
|
||||
PreScan = 1 << 1,
|
||||
LatePostScan = 1 << 2,
|
||||
PreUpdate = 1 << 3,
|
||||
PostUpdate = 1 << 4,
|
||||
PostCacheLoad = 1 << 5
|
||||
}
|
||||
|
||||
/// <summary>Triggers an event for all active graph modifiers</summary>
|
||||
public static void TriggerEvent (GraphModifier.EventType type) {
|
||||
if (!Application.isPlaying) {
|
||||
FindAllModifiers();
|
||||
}
|
||||
|
||||
GraphModifier c = root;
|
||||
switch (type) {
|
||||
case EventType.PreScan:
|
||||
while (c != null) { c.OnPreScan(); c = c.next; }
|
||||
break;
|
||||
case EventType.PostScan:
|
||||
while (c != null) { c.OnPostScan(); c = c.next; }
|
||||
break;
|
||||
case EventType.LatePostScan:
|
||||
while (c != null) { c.OnLatePostScan(); c = c.next; }
|
||||
break;
|
||||
case EventType.PreUpdate:
|
||||
while (c != null) { c.OnGraphsPreUpdate(); c = c.next; }
|
||||
break;
|
||||
case EventType.PostUpdate:
|
||||
while (c != null) { c.OnGraphsPostUpdate(); c = c.next; }
|
||||
break;
|
||||
case EventType.PostCacheLoad:
|
||||
while (c != null) { c.OnPostCacheLoad(); c = c.next; }
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Adds this modifier to list of active modifiers</summary>
|
||||
protected virtual void OnEnable () {
|
||||
RemoveFromLinkedList();
|
||||
AddToLinkedList();
|
||||
ConfigureUniqueID();
|
||||
}
|
||||
|
||||
/// <summary>Removes this modifier from list of active modifiers</summary>
|
||||
protected virtual void OnDisable () {
|
||||
RemoveFromLinkedList();
|
||||
}
|
||||
|
||||
public override void OnSyncLoad()
|
||||
{
|
||||
base.OnSyncLoad();
|
||||
ConfigureUniqueID();
|
||||
}
|
||||
|
||||
void ConfigureUniqueID () {
|
||||
// Check if any other object is using the same uniqueID
|
||||
// In that case this object may have been duplicated
|
||||
GraphModifier usedBy;
|
||||
|
||||
if (usedIDs.TryGetValue(uniqueID, out usedBy) && usedBy != this) {
|
||||
Reset();
|
||||
}
|
||||
|
||||
usedIDs[uniqueID] = this;
|
||||
}
|
||||
|
||||
void AddToLinkedList () {
|
||||
if (root == null) {
|
||||
root = this;
|
||||
} else {
|
||||
next = root;
|
||||
root.prev = this;
|
||||
root = this;
|
||||
}
|
||||
}
|
||||
|
||||
void RemoveFromLinkedList () {
|
||||
if (root == this) {
|
||||
root = next;
|
||||
if (root != null) root.prev = null;
|
||||
} else {
|
||||
if (prev != null) prev.next = next;
|
||||
if (next != null) next.prev = prev;
|
||||
}
|
||||
prev = null;
|
||||
next = null;
|
||||
}
|
||||
|
||||
protected virtual void OnDestroy () {
|
||||
usedIDs.Remove(uniqueID);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Called right after all graphs have been scanned.
|
||||
/// FloodFill and other post processing has not been done.
|
||||
///
|
||||
/// Warning: Since OnEnable and Awake are called roughly in the same time, the only way
|
||||
/// to ensure that these scripts get this call when scanning in Awake is to
|
||||
/// set the Script Execution Order for AstarPath to some time later than default time
|
||||
/// (see Edit -> Project Settings -> Script Execution Order).
|
||||
/// TODO: Is this still relevant? A call to FindAllModifiers should have before this method is called
|
||||
/// so the above warning is probably not relevant anymore.
|
||||
///
|
||||
/// See: OnLatePostScan
|
||||
/// </summary>
|
||||
public virtual void OnPostScan () {}
|
||||
|
||||
/// <summary>
|
||||
/// Called right before graphs are going to be scanned.
|
||||
///
|
||||
/// Warning: Since OnEnable and Awake are called roughly in the same time, the only way
|
||||
/// to ensure that these scripts get this call when scanning in Awake is to
|
||||
/// set the Script Execution Order for AstarPath to some time later than default time
|
||||
/// (see Edit -> Project Settings -> Script Execution Order).
|
||||
/// TODO: Is this still relevant? A call to FindAllModifiers should have before this method is called
|
||||
/// so the above warning is probably not relevant anymore.
|
||||
///
|
||||
/// See: OnLatePostScan
|
||||
/// </summary>
|
||||
public virtual void OnPreScan () {}
|
||||
|
||||
/// <summary>
|
||||
/// Called at the end of the scanning procedure.
|
||||
/// This is the absolute last thing done by Scan.
|
||||
/// </summary>
|
||||
public virtual void OnLatePostScan () {}
|
||||
|
||||
/// <summary>
|
||||
/// Called after cached graphs have been loaded.
|
||||
/// When using cached startup, this event is analogous to OnLatePostScan and implementing scripts
|
||||
/// should do roughly the same thing for both events.
|
||||
/// </summary>
|
||||
public virtual void OnPostCacheLoad () {}
|
||||
|
||||
/// <summary>Called before graphs are updated using GraphUpdateObjects</summary>
|
||||
public virtual void OnGraphsPreUpdate () {}
|
||||
|
||||
/// <summary>
|
||||
/// Called after graphs have been updated using GraphUpdateObjects.
|
||||
/// Eventual flood filling has been done
|
||||
/// </summary>
|
||||
public virtual void OnGraphsPostUpdate () {}
|
||||
|
||||
protected override void Reset () {
|
||||
base.Reset();
|
||||
// Create a new random 64 bit value (62 bit actually because we skip negative numbers, but that's still enough by a huge margin)
|
||||
var rnd1 = (ulong)Random.Range(0, int.MaxValue);
|
||||
var rnd2 = ((ulong)Random.Range(0, int.MaxValue) << 32);
|
||||
|
||||
uniqueID = rnd1 | rnd2;
|
||||
usedIDs[uniqueID] = this;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 39897fb482672480a817862c3909a4aa
|
||||
timeCreated: 1490044676
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: -222
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,367 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Profiling;
|
||||
|
||||
namespace Pathfinding {
|
||||
using UnityEngine.Assertions;
|
||||
|
||||
#if NETFX_CORE
|
||||
using Thread = Pathfinding.WindowsStore.Thread;
|
||||
#else
|
||||
using Thread = System.Threading.Thread;
|
||||
#endif
|
||||
|
||||
class GraphUpdateProcessor {
|
||||
public event System.Action OnGraphsUpdated;
|
||||
|
||||
/// <summary>Holds graphs that can be updated</summary>
|
||||
readonly AstarPath astar;
|
||||
|
||||
#if !UNITY_WEBGL
|
||||
/// <summary>
|
||||
/// Reference to the thread which handles async graph updates.
|
||||
/// See: ProcessGraphUpdatesAsync
|
||||
/// </summary>
|
||||
Thread graphUpdateThread;
|
||||
#endif
|
||||
|
||||
/// <summary>Used for IsAnyGraphUpdateInProgress</summary>
|
||||
bool anyGraphUpdateInProgress;
|
||||
|
||||
#if UNITY_2017_3_OR_NEWER && !UNITY_WEBGL
|
||||
CustomSampler asyncUpdateProfilingSampler;
|
||||
#endif
|
||||
|
||||
/// <summary>
|
||||
/// Queue containing all waiting graph update queries. Add to this queue by using \link AddToQueue \endlink.
|
||||
/// See: AddToQueue
|
||||
/// </summary>
|
||||
readonly Queue<GraphUpdateObject> graphUpdateQueue = new Queue<GraphUpdateObject>();
|
||||
|
||||
/// <summary>Queue of all async graph updates waiting to be executed</summary>
|
||||
readonly Queue<GUOSingle> graphUpdateQueueAsync = new Queue<GUOSingle>();
|
||||
|
||||
/// <summary>Queue of all non-async graph update post events waiting to be executed</summary>
|
||||
readonly Queue<GUOSingle> graphUpdateQueuePost = new Queue<GUOSingle>();
|
||||
|
||||
/// <summary>Queue of all non-async graph updates waiting to be executed</summary>
|
||||
readonly Queue<GUOSingle> graphUpdateQueueRegular = new Queue<GUOSingle>();
|
||||
|
||||
readonly System.Threading.ManualResetEvent asyncGraphUpdatesComplete = new System.Threading.ManualResetEvent(true);
|
||||
|
||||
#if !UNITY_WEBGL
|
||||
readonly System.Threading.AutoResetEvent graphUpdateAsyncEvent = new System.Threading.AutoResetEvent(false);
|
||||
readonly System.Threading.AutoResetEvent exitAsyncThread = new System.Threading.AutoResetEvent(false);
|
||||
#endif
|
||||
|
||||
/// <summary>Returns if any graph updates are waiting to be applied</summary>
|
||||
public bool IsAnyGraphUpdateQueued { get { return graphUpdateQueue.Count > 0; } }
|
||||
|
||||
/// <summary>Returns if any graph updates are in progress</summary>
|
||||
public bool IsAnyGraphUpdateInProgress { get { return anyGraphUpdateInProgress; } }
|
||||
|
||||
/// <summary>Order type for updating graphs</summary>
|
||||
enum GraphUpdateOrder {
|
||||
GraphUpdate,
|
||||
// FloodFill
|
||||
}
|
||||
|
||||
/// <summary>Holds a single update that needs to be performed on a graph</summary>
|
||||
struct GUOSingle {
|
||||
public GraphUpdateOrder order;
|
||||
public IUpdatableGraph graph;
|
||||
public GraphUpdateObject obj;
|
||||
}
|
||||
|
||||
public GraphUpdateProcessor (AstarPath astar) {
|
||||
this.astar = astar;
|
||||
}
|
||||
|
||||
/// <summary>Work item which can be used to apply all queued updates</summary>
|
||||
public AstarWorkItem GetWorkItem () {
|
||||
return new AstarWorkItem(QueueGraphUpdatesInternal, ProcessGraphUpdates);
|
||||
}
|
||||
|
||||
public void EnableMultithreading () {
|
||||
#if !UNITY_WEBGL
|
||||
if (graphUpdateThread == null || !graphUpdateThread.IsAlive) {
|
||||
#if UNITY_2017_3_OR_NEWER && !UNITY_WEBGL
|
||||
asyncUpdateProfilingSampler = CustomSampler.Create("Graph Update");
|
||||
#endif
|
||||
|
||||
graphUpdateThread = new Thread(ProcessGraphUpdatesAsync);
|
||||
graphUpdateThread.IsBackground = true;
|
||||
|
||||
// Set the thread priority for graph updates
|
||||
// Unless compiling for windows store or windows phone which does not support it
|
||||
#if !UNITY_WINRT
|
||||
graphUpdateThread.Priority = System.Threading.ThreadPriority.Lowest;
|
||||
#endif
|
||||
graphUpdateThread.Start();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
public void DisableMultithreading () {
|
||||
#if !UNITY_WEBGL
|
||||
if (graphUpdateThread != null && graphUpdateThread.IsAlive) {
|
||||
// Resume graph update thread, will cause it to terminate
|
||||
exitAsyncThread.Set();
|
||||
|
||||
if (!graphUpdateThread.Join(5*1000)) {
|
||||
Debug.LogError("Graph update thread did not exit in 5 seconds");
|
||||
}
|
||||
|
||||
graphUpdateThread = null;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Update all graphs using the GraphUpdateObject.
|
||||
/// This can be used to, e.g make all nodes in an area unwalkable, or set them to a higher penalty.
|
||||
/// The graphs will be updated as soon as possible (with respect to AstarPath.batchGraphUpdates)
|
||||
///
|
||||
/// See: FlushGraphUpdates
|
||||
/// </summary>
|
||||
public void AddToQueue (GraphUpdateObject ob) {
|
||||
// Put the GUO in the queue
|
||||
graphUpdateQueue.Enqueue(ob);
|
||||
}
|
||||
|
||||
/// <summary>Schedules graph updates internally</summary>
|
||||
void QueueGraphUpdatesInternal () {
|
||||
while (graphUpdateQueue.Count > 0) {
|
||||
GraphUpdateObject ob = graphUpdateQueue.Dequeue();
|
||||
if (ob.internalStage != GraphUpdateObject.STAGE_PENDING) {
|
||||
Debug.LogError("Expected remaining graph updates to be pending");
|
||||
continue;
|
||||
}
|
||||
ob.internalStage = 0;
|
||||
|
||||
foreach (IUpdatableGraph g in astar.data.GetUpdateableGraphs()) {
|
||||
NavGraph gr = g as NavGraph;
|
||||
if (ob.nnConstraint == null || ob.nnConstraint.SuitableGraph(astar.data.GetGraphIndex(gr), gr)) {
|
||||
var guo = new GUOSingle();
|
||||
guo.order = GraphUpdateOrder.GraphUpdate;
|
||||
guo.obj = ob;
|
||||
guo.graph = g;
|
||||
ob.internalStage += 1;
|
||||
graphUpdateQueueRegular.Enqueue(guo);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
GraphModifier.TriggerEvent(GraphModifier.EventType.PreUpdate);
|
||||
anyGraphUpdateInProgress = true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Updates graphs.
|
||||
/// Will do some graph updates, possibly signal another thread to do them.
|
||||
/// Will only process graph updates added by QueueGraphUpdatesInternal
|
||||
///
|
||||
/// Returns: True if all graph updates have been done and pathfinding (or other tasks) may resume.
|
||||
/// False if there are still graph updates being processed or waiting in the queue.
|
||||
/// </summary>
|
||||
/// <param name="force">If true, all graph updates will be processed before this function returns. The return value
|
||||
/// will be True.</param>
|
||||
bool ProcessGraphUpdates (bool force) {
|
||||
Assert.IsTrue(anyGraphUpdateInProgress);
|
||||
|
||||
if (force) {
|
||||
asyncGraphUpdatesComplete.WaitOne();
|
||||
} else {
|
||||
#if !UNITY_WEBGL
|
||||
if (!asyncGraphUpdatesComplete.WaitOne(0)) {
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
Assert.AreEqual(graphUpdateQueueAsync.Count, 0, "Queue should be empty at this stage");
|
||||
|
||||
ProcessPostUpdates();
|
||||
if (!ProcessRegularUpdates(force)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
GraphModifier.TriggerEvent(GraphModifier.EventType.PostUpdate);
|
||||
if (OnGraphsUpdated != null) OnGraphsUpdated();
|
||||
|
||||
Assert.AreEqual(graphUpdateQueueRegular.Count, 0, "QueueRegular should be empty at this stage");
|
||||
Assert.AreEqual(graphUpdateQueueAsync.Count, 0, "QueueAsync should be empty at this stage");
|
||||
Assert.AreEqual(graphUpdateQueuePost.Count, 0, "QueuePost should be empty at this stage");
|
||||
|
||||
anyGraphUpdateInProgress = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ProcessRegularUpdates (bool force) {
|
||||
while (graphUpdateQueueRegular.Count > 0) {
|
||||
GUOSingle s = graphUpdateQueueRegular.Peek();
|
||||
|
||||
GraphUpdateThreading threading = s.graph.CanUpdateAsync(s.obj);
|
||||
|
||||
#if UNITY_WEBGL
|
||||
// Never use multithreading in WebGL
|
||||
threading &= ~GraphUpdateThreading.SeparateThread;
|
||||
#else
|
||||
// When not playing or when not using a graph update thread (or if it has crashed), everything runs in the Unity thread
|
||||
if (force || !Application.isPlaying || graphUpdateThread == null || !graphUpdateThread.IsAlive) {
|
||||
// Remove the SeparateThread flag
|
||||
threading &= ~GraphUpdateThreading.SeparateThread;
|
||||
}
|
||||
#endif
|
||||
|
||||
if ((threading & GraphUpdateThreading.UnityInit) != 0) {
|
||||
// Process async graph updates first.
|
||||
// Next call to this function will process this object so it is not dequeued now
|
||||
if (StartAsyncUpdatesIfQueued()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
s.graph.UpdateAreaInit(s.obj);
|
||||
}
|
||||
|
||||
if ((threading & GraphUpdateThreading.SeparateThread) != 0) {
|
||||
// Move GUO to async queue to be updated by another thread
|
||||
graphUpdateQueueRegular.Dequeue();
|
||||
graphUpdateQueueAsync.Enqueue(s);
|
||||
|
||||
// Don't start any more async graph updates because this update
|
||||
// requires a Unity thread function to run after it has been completed
|
||||
// but before the next update is started
|
||||
if ((threading & GraphUpdateThreading.UnityPost) != 0) {
|
||||
if (StartAsyncUpdatesIfQueued()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Unity Thread
|
||||
|
||||
if (StartAsyncUpdatesIfQueued()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
graphUpdateQueueRegular.Dequeue();
|
||||
|
||||
try {
|
||||
s.graph.UpdateArea(s.obj);
|
||||
} catch (System.Exception e) {
|
||||
Debug.LogError("Error while updating graphs\n"+e);
|
||||
}
|
||||
|
||||
if ((threading & GraphUpdateThreading.UnityPost) != 0) {
|
||||
s.graph.UpdateAreaPost(s.obj);
|
||||
}
|
||||
|
||||
s.obj.internalStage -= 1;
|
||||
UnityEngine.Assertions.Assert.IsTrue(s.obj.internalStage >= 0);
|
||||
}
|
||||
}
|
||||
|
||||
if (StartAsyncUpdatesIfQueued()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Signal the graph update thread to start processing graph updates if there are any in the <see cref="graphUpdateQueueAsync"/> queue.
|
||||
/// Returns: True if the other thread was signaled.
|
||||
/// </summary>
|
||||
bool StartAsyncUpdatesIfQueued () {
|
||||
if (graphUpdateQueueAsync.Count > 0) {
|
||||
#if UNITY_WEBGL
|
||||
throw new System.Exception("This should not happen in WebGL");
|
||||
#else
|
||||
asyncGraphUpdatesComplete.Reset();
|
||||
graphUpdateAsyncEvent.Set();
|
||||
return true;
|
||||
#endif
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void ProcessPostUpdates () {
|
||||
while (graphUpdateQueuePost.Count > 0) {
|
||||
GUOSingle s = graphUpdateQueuePost.Dequeue();
|
||||
|
||||
GraphUpdateThreading threading = s.graph.CanUpdateAsync(s.obj);
|
||||
|
||||
if ((threading & GraphUpdateThreading.UnityPost) != 0) {
|
||||
try {
|
||||
s.graph.UpdateAreaPost(s.obj);
|
||||
} catch (System.Exception e) {
|
||||
Debug.LogError("Error while updating graphs (post step)\n"+e);
|
||||
}
|
||||
}
|
||||
|
||||
s.obj.internalStage -= 1;
|
||||
UnityEngine.Assertions.Assert.IsTrue(s.obj.internalStage >= 0);
|
||||
}
|
||||
}
|
||||
|
||||
#if !UNITY_WEBGL
|
||||
/// <summary>
|
||||
/// Graph update thread.
|
||||
/// Async graph updates will be executed by this method in another thread.
|
||||
/// </summary>
|
||||
void ProcessGraphUpdatesAsync () {
|
||||
#if UNITY_2017_3_OR_NEWER
|
||||
Profiler.BeginThreadProfiling("Pathfinding", "Threaded Graph Updates");
|
||||
#endif
|
||||
|
||||
var handles = new [] { graphUpdateAsyncEvent, exitAsyncThread };
|
||||
|
||||
while (true) {
|
||||
// Wait for the next batch or exit event
|
||||
var handleIndex = WaitHandle.WaitAny(handles);
|
||||
|
||||
if (handleIndex == 1) {
|
||||
// Exit even was fired
|
||||
// Abort thread and clear queue
|
||||
while (graphUpdateQueueAsync.Count > 0) {
|
||||
var s = graphUpdateQueueAsync.Dequeue();
|
||||
s.obj.internalStage = GraphUpdateObject.STAGE_ABORTED;
|
||||
}
|
||||
asyncGraphUpdatesComplete.Set();
|
||||
#if UNITY_2017_3_OR_NEWER
|
||||
Profiler.EndThreadProfiling();
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
while (graphUpdateQueueAsync.Count > 0) {
|
||||
#if UNITY_2017_3_OR_NEWER
|
||||
asyncUpdateProfilingSampler.Begin();
|
||||
#endif
|
||||
// Note that no locking is required here because the main thread
|
||||
// cannot access it until asyncGraphUpdatesComplete is signaled
|
||||
GUOSingle aguo = graphUpdateQueueAsync.Dequeue();
|
||||
|
||||
try {
|
||||
if (aguo.order == GraphUpdateOrder.GraphUpdate) {
|
||||
aguo.graph.UpdateArea(aguo.obj);
|
||||
graphUpdateQueuePost.Enqueue(aguo);
|
||||
} else {
|
||||
throw new System.NotSupportedException("" + aguo.order);
|
||||
}
|
||||
} catch (System.Exception e) {
|
||||
Debug.LogError("Exception while updating graphs:\n"+e);
|
||||
}
|
||||
#if UNITY_2017_3_OR_NEWER
|
||||
asyncUpdateProfilingSampler.End();
|
||||
#endif
|
||||
}
|
||||
|
||||
// Done
|
||||
asyncGraphUpdatesComplete.Set();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b1798d8e7c7d54972ae8522558cbd27c
|
||||
timeCreated: 1443114816
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,274 @@
|
||||
using UnityEngine;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Pathfinding {
|
||||
using Pathfinding.Util;
|
||||
|
||||
/// <summary>
|
||||
/// Contains utility methods for getting useful information out of graph.
|
||||
/// This class works a lot with the <see cref="Pathfinding.GraphNode"/> class, a useful function to get nodes is <see cref="AstarPath.GetNearest"/>.
|
||||
///
|
||||
/// See: <see cref="AstarPath.GetNearest"/>
|
||||
/// See: <see cref="Pathfinding.GraphUpdateUtilities"/>
|
||||
/// See: <see cref="Pathfinding.PathUtilities"/>
|
||||
/// </summary>
|
||||
public static class GraphUtilities {
|
||||
/// <summary>
|
||||
/// Convenience method to get a list of all segments of the contours of a graph.
|
||||
/// Returns: A list of segments. Every 2 elements form a line segment. The first segment is (result[0], result[1]), the second one is (result[2], result[3]) etc.
|
||||
/// The line segments are oriented so that the navmesh is on the right side of the segments when seen from above.
|
||||
///
|
||||
/// This method works for navmesh, recast, grid graphs and layered grid graphs. For other graph types it will return an empty list.
|
||||
///
|
||||
/// If you need more information about how the contours are connected you can take a look at the other variants of this method.
|
||||
///
|
||||
/// <code>
|
||||
/// // Get the first graph
|
||||
/// var navmesh = AstarPath.active.graphs[0];
|
||||
///
|
||||
/// // Get all contours of the graph (works for grid, navmesh and recast graphs)
|
||||
/// var segments = GraphUtilities.GetContours(navmesh);
|
||||
///
|
||||
/// // Every 2 elements form a line segment. The first segment is (segments[0], segments[1]), the second one is (segments[2], segments[3]) etc.
|
||||
/// // The line segments are oriented so that the navmesh is on the right side of the segments when seen from above.
|
||||
/// for (int i = 0; i < segments.Count; i += 2) {
|
||||
/// var start = segments[i];
|
||||
/// var end = segments[i+1];
|
||||
/// Debug.DrawLine(start, end, Color.red, 3);
|
||||
/// }
|
||||
/// </code>
|
||||
///
|
||||
/// [Open online documentation to see images]
|
||||
/// [Open online documentation to see images]
|
||||
/// </summary>
|
||||
public static List<Vector3> GetContours (NavGraph graph) {
|
||||
List<Vector3> result = ListPool<Vector3>.Claim();
|
||||
|
||||
if (graph is INavmesh) {
|
||||
GetContours(graph as INavmesh, (vertices, cycle) => {
|
||||
for (int j = cycle ? vertices.Count - 1 : 0, i = 0; i < vertices.Count; j = i, i++) {
|
||||
result.Add((Vector3)vertices[j]);
|
||||
result.Add((Vector3)vertices[i]);
|
||||
}
|
||||
});
|
||||
#if !ASTAR_NO_GRID_GRAPH
|
||||
} else if (graph is GridGraph) {
|
||||
GetContours(graph as GridGraph, vertices => {
|
||||
for (int j = vertices.Length - 1, i = 0; i < vertices.Length; j = i, i++) {
|
||||
result.Add((Vector3)vertices[j]);
|
||||
result.Add((Vector3)vertices[i]);
|
||||
}
|
||||
}, 0);
|
||||
#endif
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Traces the contour of a navmesh.
|
||||
///
|
||||
/// [Open online documentation to see images]
|
||||
///
|
||||
/// This image is just used to illustrate the difference between chains and cycles. That it shows a grid graph is not relevant.
|
||||
/// [Open online documentation to see images]
|
||||
///
|
||||
/// See: <see cref="GetContours(NavGraph)"/>
|
||||
/// </summary>
|
||||
/// <param name="navmesh">The navmesh-like object to trace. This can be a recast or navmesh graph or it could be a single tile in one such graph.</param>
|
||||
/// <param name="results">Will be called once for each contour with the contour as a parameter as well as a boolean indicating if the contour is a cycle or a chain (see second image).</param>
|
||||
public static void GetContours (INavmesh navmesh, System.Action<List<Int3>, bool> results) {
|
||||
// Assume 3 vertices per node
|
||||
var uses = new bool[3];
|
||||
|
||||
var outline = new Dictionary<int, int>();
|
||||
var vertexPositions = new Dictionary<int, Int3>();
|
||||
var hasInEdge = new HashSet<int>();
|
||||
|
||||
navmesh.GetNodes(_node => {
|
||||
var node = _node as TriangleMeshNode;
|
||||
|
||||
uses[0] = uses[1] = uses[2] = false;
|
||||
|
||||
if (node != null) {
|
||||
// Find out which edges are shared with other nodes
|
||||
for (int j = 0; j < node.connections.Length; j++) {
|
||||
var conn = node.connections[j];
|
||||
if (conn.shapeEdge != Connection.NoSharedEdge) uses[conn.shapeEdge] = true;
|
||||
}
|
||||
|
||||
// Loop through all edges on the node
|
||||
for (int j = 0; j < 3; j++) {
|
||||
// The edge is not shared with any other node
|
||||
// I.e it is an exterior edge on the mesh
|
||||
if (!uses[j]) {
|
||||
var i1 = j;
|
||||
var i2 = (j+1) % node.GetVertexCount();
|
||||
|
||||
outline[node.GetVertexIndex(i1)] = node.GetVertexIndex(i2);
|
||||
hasInEdge.Add(node.GetVertexIndex(i2));
|
||||
vertexPositions[node.GetVertexIndex(i1)] = node.GetVertex(i1);
|
||||
vertexPositions[node.GetVertexIndex(i2)] = node.GetVertex(i2);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
Polygon.TraceContours(outline, hasInEdge, (chain, cycle) => {
|
||||
List<Int3> vertices = ListPool<Int3>.Claim();
|
||||
for (int i = 0; i < chain.Count; i++) vertices.Add(vertexPositions[chain[i]]);
|
||||
results(vertices, cycle);
|
||||
});
|
||||
}
|
||||
|
||||
#if !ASTAR_NO_GRID_GRAPH
|
||||
/// <summary>
|
||||
/// Finds all contours of a collection of nodes in a grid graph.
|
||||
///
|
||||
/// <code>
|
||||
/// var grid = AstarPath.active.data.gridGraph;
|
||||
///
|
||||
/// // Find all contours in the graph and draw them using debug lines
|
||||
/// GraphUtilities.GetContours(grid, vertices => {
|
||||
/// for (int i = 0; i < vertices.Length; i++) {
|
||||
/// Debug.DrawLine(vertices[i], vertices[(i+1)%vertices.Length], Color.red, 4);
|
||||
/// }
|
||||
/// }, 0);
|
||||
/// </code>
|
||||
///
|
||||
/// In the image below you can see the contour of a graph.
|
||||
/// [Open online documentation to see images]
|
||||
///
|
||||
/// In the image below you can see the contour of just a part of a grid graph (when the nodes parameter is supplied)
|
||||
/// [Open online documentation to see images]
|
||||
///
|
||||
/// Contour of a hexagon graph
|
||||
/// [Open online documentation to see images]
|
||||
///
|
||||
/// See: <see cref="GetContours(NavGraph)"/>
|
||||
/// </summary>
|
||||
/// <param name="grid">The grid to find the contours of</param>
|
||||
/// <param name="callback">The callback will be called once for every contour that is found with the vertices of the contour. The contour always forms a cycle.</param>
|
||||
/// <param name="yMergeThreshold">Contours will be simplified if the y coordinates for adjacent vertices differ by no more than this value.</param>
|
||||
/// <param name="nodes">Only these nodes will be searched. If this parameter is null then all nodes in the grid graph will be searched.</param>
|
||||
/// <param name="connectionFilter">Allows you to disable connections between nodes. If null, no additional filtering will be done. The filter must be symmetric, so that f(A,B) == f(B,A). A contour edge will be generated between two adjacent nodes if this function returns false for the pair.</param>
|
||||
public static void GetContours (GridGraph grid, System.Action<Vector3[]> callback, float yMergeThreshold, GridNodeBase[] nodes = null, System.Func<GraphNode, GraphNode, bool> connectionFilter = null) {
|
||||
// Set of all allowed nodes or null if all nodes are allowed
|
||||
HashSet<GridNodeBase> nodeSet = nodes != null ? new HashSet<GridNodeBase>(nodes) : null;
|
||||
|
||||
// Use all nodes if the nodes parameter is null
|
||||
if (grid is LayerGridGraph lgraph) nodes = nodes ?? lgraph.nodes;
|
||||
nodes = nodes ?? grid.nodes;
|
||||
int[] neighbourXOffsets = grid.neighbourXOffsets;
|
||||
int[] neighbourZOffsets = grid.neighbourZOffsets;
|
||||
var neighbourIndices = grid.neighbours == NumNeighbours.Six ? GridGraph.hexagonNeighbourIndices : new [] { 0, 1, 2, 3 };
|
||||
var offsetMultiplier = grid.neighbours == NumNeighbours.Six ? 1/3f : 0.5f;
|
||||
|
||||
if (nodes != null) {
|
||||
var trace = ListPool<Vector3>.Claim();
|
||||
var seenStates = new HashSet<int>();
|
||||
|
||||
for (int i = 0; i < nodes.Length; i++) {
|
||||
var startNode = nodes[i];
|
||||
// The third check is a fast check for if the node has connections in all grid directions, if it has then we can skip processing it (unless the nodes parameter was used in which case we have to handle the edge cases)
|
||||
if (startNode != null && startNode.Walkable && (!startNode.HasConnectionsToAllEightNeighbours || nodeSet != null)) {
|
||||
for (int startDir = 0; startDir < neighbourIndices.Length; startDir++) {
|
||||
int startState = (startNode.NodeIndex << 4) | startDir;
|
||||
|
||||
// Check if there is an obstacle in that direction
|
||||
var startNeighbour = startNode.GetNeighbourAlongDirection(neighbourIndices[startDir]);
|
||||
if (connectionFilter != null && startNeighbour != null && !connectionFilter(startNode, startNeighbour)) startNeighbour = null;
|
||||
|
||||
if ((startNeighbour == null || (nodeSet != null && !nodeSet.Contains(startNeighbour))) && !seenStates.Contains(startState)) {
|
||||
// Start tracing a contour here
|
||||
trace.ClearFast();
|
||||
int dir = startDir;
|
||||
GridNodeBase node = startNode;
|
||||
|
||||
while (true) {
|
||||
int state = (node.NodeIndex << 4) | dir;
|
||||
if (state == startState && trace.Count > 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
seenStates.Add(state);
|
||||
|
||||
var neighbour = node.GetNeighbourAlongDirection(neighbourIndices[dir]);
|
||||
if (connectionFilter != null && neighbour != null && !connectionFilter(node, neighbour)) neighbour = null;
|
||||
|
||||
if (neighbour == null || (nodeSet != null && !nodeSet.Contains(neighbour))) {
|
||||
// Draw edge
|
||||
var d0 = neighbourIndices[dir];
|
||||
dir = (dir + 1) % neighbourIndices.Length;
|
||||
var d1 = neighbourIndices[dir];
|
||||
|
||||
// Position in graph space of the vertex
|
||||
Vector3 graphSpacePos = new Vector3(node.XCoordinateInGrid + 0.5f, 0, node.ZCoordinateInGrid + 0.5f);
|
||||
// Offset along diagonal to get the correct XZ coordinates
|
||||
graphSpacePos.x += (neighbourXOffsets[d0] + neighbourXOffsets[d1]) * offsetMultiplier;
|
||||
graphSpacePos.z += (neighbourZOffsets[d0] + neighbourZOffsets[d1]) * offsetMultiplier;
|
||||
graphSpacePos.y = grid.transform.InverseTransform((Vector3)node.position).y;
|
||||
|
||||
if (trace.Count >= 2) {
|
||||
var v0 = trace[trace.Count-2];
|
||||
var v1 = trace[trace.Count-1];
|
||||
var v1d = v1 - v0;
|
||||
var v2d = graphSpacePos - v0;
|
||||
// Replace the previous point if it is colinear with the point just before it and just after it (the current point), because that point wouldn't add much information, but it would add CPU overhead
|
||||
if (((Mathf.Abs(v1d.x) > 0.01f || Mathf.Abs(v2d.x) > 0.01f) && (Mathf.Abs(v1d.z) > 0.01f || Mathf.Abs(v2d.z) > 0.01f)) || (Mathf.Abs(v1d.y) > yMergeThreshold || Mathf.Abs(v2d.y) > yMergeThreshold)) {
|
||||
trace.Add(graphSpacePos);
|
||||
} else {
|
||||
trace[trace.Count-1] = graphSpacePos;
|
||||
}
|
||||
} else {
|
||||
trace.Add(graphSpacePos);
|
||||
}
|
||||
} else {
|
||||
#if UNITY_EDITOR
|
||||
if (!neighbour.HasConnectionInDirection(GridNodeBase.OppositeConnectionDirection(neighbourIndices[dir]))) {
|
||||
throw new System.InvalidOperationException("Cannot calculate contour. The graph contains one-way connections. A contour is not well defined if one-way connections exist.");
|
||||
}
|
||||
#endif
|
||||
// Move
|
||||
node = neighbour;
|
||||
dir = (dir + neighbourIndices.Length/2 + 1) % neighbourIndices.Length;
|
||||
}
|
||||
}
|
||||
|
||||
// Simplify the contour a bit around the start point.
|
||||
// Otherwise we might return a cycle which was not as simplified as possible and the number of vertices
|
||||
// would depend on where in the cycle the algorithm started to traverse the contour.
|
||||
if (trace.Count >= 3) {
|
||||
var v0 = trace[trace.Count-2];
|
||||
var v1 = trace[trace.Count-1];
|
||||
var v1d = v1 - v0;
|
||||
var v2d = trace[0] - v0;
|
||||
// Replace the previous point if it is colinear with the point just before it and just after it (the current point), because that point wouldn't add much information, but it would add CPU overhead
|
||||
if (!(((Mathf.Abs(v1d.x) > 0.01f || Mathf.Abs(v2d.x) > 0.01f) && (Mathf.Abs(v1d.z) > 0.01f || Mathf.Abs(v2d.z) > 0.01f)) || (Mathf.Abs(v1d.y) > yMergeThreshold || Mathf.Abs(v2d.y) > yMergeThreshold))) {
|
||||
trace.RemoveAt(trace.Count - 1);
|
||||
}
|
||||
}
|
||||
|
||||
if (trace.Count >= 3) {
|
||||
var v0 = trace[trace.Count-1];
|
||||
var v1 = trace[0];
|
||||
var v1d = v1 - v0;
|
||||
var v2d = trace[1] - v0;
|
||||
// Replace the previous point if it is colinear with the point just before it and just after it (the current point), because that point wouldn't add much information, but it would add CPU overhead
|
||||
if (!(((Mathf.Abs(v1d.x) > 0.01f || Mathf.Abs(v2d.x) > 0.01f) && (Mathf.Abs(v1d.z) > 0.01f || Mathf.Abs(v2d.z) > 0.01f)) || (Mathf.Abs(v1d.y) > yMergeThreshold || Mathf.Abs(v2d.y) > yMergeThreshold))) {
|
||||
trace.RemoveAt(0);
|
||||
}
|
||||
}
|
||||
var result = trace.ToArray();
|
||||
grid.transform.Transform(result);
|
||||
callback(result);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ListPool<Vector3>.Release(ref trace);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: fd178834bf6c54cdb8fc5f76a039a91c
|
||||
timeCreated: 1502889881
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,348 @@
|
||||
using System.Collections.Generic;
|
||||
using Pathfinding.Util;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Profiling;
|
||||
|
||||
namespace Pathfinding {
|
||||
/// <summary>
|
||||
/// Holds a hierarchical graph to speed up certain pathfinding queries.
|
||||
///
|
||||
/// A common type of query that needs to be very fast is on the form 'is this node reachable from this other node'.
|
||||
/// This is for example used when picking the end node of a path. The end node is determined as the closest node to the end point
|
||||
/// that can be reached from the start node.
|
||||
///
|
||||
/// This data structure's primary purpose is to keep track of which connected component each node is contained in, in order to make such queries fast.
|
||||
///
|
||||
/// See: https://en.wikipedia.org/wiki/Connected_component_(graph_theory)
|
||||
///
|
||||
/// A connected component is a set of nodes such that there is a valid path between every pair of nodes in that set.
|
||||
/// Thus the query above can simply be answered by checking if they are in the same connected component.
|
||||
/// The connected component is exposed on nodes as the <see cref="Pathfinding.GraphNode.Area"/> property and on this class using the <see cref="GetArea"/> method.
|
||||
///
|
||||
/// In the image below (showing a 200x200 grid graph) each connected component is colored using a separate color.
|
||||
/// The actual color doesn't signify anything in particular however, only that they are different.
|
||||
/// [Open online documentation to see images]
|
||||
///
|
||||
/// Prior to version 4.2 the connected components were just a number stored on each node, and when a graph was updated
|
||||
/// the connected components were completely recalculated. This can be done relatively efficiently using a flood filling
|
||||
/// algorithm (see https://en.wikipedia.org/wiki/Flood_fill) however it still requires a pass through every single node
|
||||
/// which can be quite costly on larger graphs.
|
||||
///
|
||||
/// This class instead builds a much smaller graph that still respects the same connectivity as the original graph.
|
||||
/// Each node in this hierarchical graph represents a larger number of real nodes that are one single connected component.
|
||||
/// Take a look at the image below for an example. In the image each color is a separate hierarchical node, and the black connections go between the center of each hierarchical node.
|
||||
///
|
||||
/// [Open online documentation to see images]
|
||||
///
|
||||
/// With the hierarchical graph, the connected components can be calculated by flood filling the hierarchical graph instead of the real graph.
|
||||
/// Then when we need to know which connected component a node belongs to, we look up the connected component of the hierarchical node the node belongs to.
|
||||
///
|
||||
/// The benefit is not immediately obvious. The above is just a bit more complicated way to accomplish the same thing. However the real benefit comes when updating the graph.
|
||||
/// When the graph is updated, all hierarchical nodes which contain any node that was affected by the update is removed completely and then once all have been removed new hierarchical nodes are recalculated in their place.
|
||||
/// Once this is done the connected components of the whole graph can be updated by flood filling only the hierarchical graph. Since the hierarchical graph is vastly smaller than the real graph, this is significantly faster.
|
||||
///
|
||||
/// [Open online documentation to see videos]
|
||||
///
|
||||
/// So finally using all of this, the connected components of the graph can be recalculated very quickly as the graph is updated.
|
||||
/// The effect of this grows larger the larger the graph is, and the smaller the graph update is. Making a small update to a 1000x1000 grid graph is on the order of 40 times faster with these optimizations.
|
||||
/// When scanning a graph or making updates to the whole graph at the same time there is however no speed boost. In fact due to the extra complexity it is a bit slower, however after profiling the extra time seems to be mostly insignificant compared to the rest of the cost of scanning the graph.
|
||||
///
|
||||
/// [Open online documentation to see videos]
|
||||
///
|
||||
/// See: <see cref="Pathfinding.PathUtilities.IsPathPossible"/>
|
||||
/// See: <see cref="Pathfinding.NNConstraint"/>
|
||||
/// See: <see cref="Pathfinding.GraphNode.Area"/>
|
||||
/// </summary>
|
||||
public class HierarchicalGraph {
|
||||
const int Tiling = 16;
|
||||
const int MaxChildrenPerNode = Tiling * Tiling;
|
||||
const int MinChildrenPerNode = MaxChildrenPerNode/2;
|
||||
|
||||
List<GraphNode>[] children = new List<GraphNode>[0];
|
||||
List<int>[] connections = new List<int>[0];
|
||||
int[] areas = new int[0];
|
||||
byte[] dirty = new byte[0];
|
||||
|
||||
public int version { get; private set; }
|
||||
public System.Action onConnectedComponentsChanged;
|
||||
|
||||
System.Action<GraphNode> connectionCallback;
|
||||
|
||||
Queue<GraphNode> temporaryQueue = new Queue<GraphNode>();
|
||||
List<GraphNode> currentChildren = null;
|
||||
List<int> currentConnections = null;
|
||||
int currentHierarchicalNodeIndex;
|
||||
Stack<int> temporaryStack = new Stack<int>();
|
||||
|
||||
int numDirtyNodes = 0;
|
||||
GraphNode[] dirtyNodes = new GraphNode[128];
|
||||
|
||||
Stack<int> freeNodeIndices = new Stack<int>();
|
||||
|
||||
int gizmoVersion = 0;
|
||||
|
||||
public HierarchicalGraph () {
|
||||
// Cache this callback to avoid allocating a new one every time the FindHierarchicalNodeChildren method is called.
|
||||
// It is a big ugly to have to use member variables for the state information in that method, but I see no better way.
|
||||
connectionCallback = (GraphNode neighbour) => {
|
||||
var hIndex = neighbour.HierarchicalNodeIndex;
|
||||
if (hIndex == 0) {
|
||||
if (currentChildren.Count < MaxChildrenPerNode && neighbour.Walkable /* && (((GridNode)currentChildren[0]).XCoordinateInGrid/Tiling == ((GridNode)neighbour).XCoordinateInGrid/Tiling) && (((GridNode)currentChildren[0]).ZCoordinateInGrid/Tiling == ((GridNode)neighbour).ZCoordinateInGrid/Tiling)*/) {
|
||||
neighbour.HierarchicalNodeIndex = currentHierarchicalNodeIndex;
|
||||
temporaryQueue.Enqueue(neighbour);
|
||||
currentChildren.Add(neighbour);
|
||||
}
|
||||
} else if (hIndex != currentHierarchicalNodeIndex && !currentConnections.Contains(hIndex)) {
|
||||
// The Contains call can in theory be very slow as an hierarchical node may be adjacent to an arbitrary number of nodes.
|
||||
// However in practice due to how the nodes are constructed they will only be adjacent to a smallish (≈4-6) number of other nodes.
|
||||
// So a Contains call will be much faster than say a Set lookup.
|
||||
currentConnections.Add(hIndex);
|
||||
}
|
||||
};
|
||||
|
||||
Grow();
|
||||
}
|
||||
|
||||
void Grow () {
|
||||
var newChildren = new List<GraphNode>[System.Math.Max(64, children.Length*2)];
|
||||
var newConnections = new List<int>[newChildren.Length];
|
||||
var newAreas = new int[newChildren.Length];
|
||||
var newDirty = new byte[newChildren.Length];
|
||||
|
||||
children.CopyTo(newChildren, 0);
|
||||
connections.CopyTo(newConnections, 0);
|
||||
areas.CopyTo(newAreas, 0);
|
||||
dirty.CopyTo(newDirty, 0);
|
||||
|
||||
for (int i = children.Length; i < newChildren.Length; i++) {
|
||||
newChildren[i] = ListPool<GraphNode>.Claim(MaxChildrenPerNode);
|
||||
newConnections[i] = new List<int>();
|
||||
if (i > 0) freeNodeIndices.Push(i);
|
||||
}
|
||||
|
||||
children = newChildren;
|
||||
connections = newConnections;
|
||||
areas = newAreas;
|
||||
dirty = newDirty;
|
||||
}
|
||||
|
||||
int GetHierarchicalNodeIndex () {
|
||||
if (freeNodeIndices.Count == 0) Grow();
|
||||
return freeNodeIndices.Pop();
|
||||
}
|
||||
|
||||
internal void OnCreatedNode (GraphNode node) {
|
||||
if (node.NodeIndex >= dirtyNodes.Length) {
|
||||
var newDirty = new GraphNode[System.Math.Max(node.NodeIndex + 1, dirtyNodes.Length*2)];
|
||||
dirtyNodes.CopyTo(newDirty, 0);
|
||||
dirtyNodes = newDirty;
|
||||
}
|
||||
AddDirtyNode(node);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Marks this node as dirty because it's connectivity or walkability has changed.
|
||||
/// This must be called by node classes after any connectivity/walkability changes have been made to them.
|
||||
///
|
||||
/// See: <see cref="GraphNode.SetConnectivityDirty"/>
|
||||
/// </summary>
|
||||
public void AddDirtyNode (GraphNode node) {
|
||||
if (!node.IsHierarchicalNodeDirty) {
|
||||
node.IsHierarchicalNodeDirty = true;
|
||||
// While the dirtyNodes array is guaranteed to be large enough to hold all nodes in the graphs
|
||||
// the array may also end up containing many destroyed nodes. This can in rare cases cause it to go out of bounds.
|
||||
// In that case we need to go through the array and filter out any destroyed nodes while making sure to mark their
|
||||
// corresponding hierarchical nodes as being dirty.
|
||||
if (numDirtyNodes < dirtyNodes.Length) {
|
||||
dirtyNodes[numDirtyNodes] = node;
|
||||
numDirtyNodes++;
|
||||
} else {
|
||||
int maxIndex = 0;
|
||||
for (int i = numDirtyNodes - 1; i >= 0; i--) {
|
||||
if (dirtyNodes[i].Destroyed) {
|
||||
numDirtyNodes--;
|
||||
dirty[dirtyNodes[i].HierarchicalNodeIndex] = 1;
|
||||
dirtyNodes[i] = dirtyNodes[numDirtyNodes];
|
||||
dirtyNodes[numDirtyNodes] = null;
|
||||
} else {
|
||||
maxIndex = System.Math.Max(maxIndex, dirtyNodes[i].NodeIndex);
|
||||
}
|
||||
}
|
||||
if (numDirtyNodes >= dirtyNodes.Length) throw new System.Exception("Failed to compactify dirty nodes array. This should not happen. " + maxIndex + " " + numDirtyNodes + " " + dirtyNodes.Length);
|
||||
AddDirtyNode(node);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public int NumConnectedComponents { get; private set; }
|
||||
|
||||
/// <summary>Get the connected component index of a hierarchical node</summary>
|
||||
public uint GetConnectedComponent (int hierarchicalNodeIndex) {
|
||||
return (uint)areas[hierarchicalNodeIndex];
|
||||
}
|
||||
|
||||
void RemoveHierarchicalNode (int hierarchicalNode, bool removeAdjacentSmallNodes) {
|
||||
freeNodeIndices.Push(hierarchicalNode);
|
||||
var conns = connections[hierarchicalNode];
|
||||
|
||||
for (int i = 0; i < conns.Count; i++) {
|
||||
var adjacentHierarchicalNode = conns[i];
|
||||
// If dirty, this node will be removed later anyway, so don't bother doing anything with it.
|
||||
if (dirty[adjacentHierarchicalNode] != 0) continue;
|
||||
|
||||
if (removeAdjacentSmallNodes && children[adjacentHierarchicalNode].Count < MinChildrenPerNode) {
|
||||
dirty[adjacentHierarchicalNode] = 2;
|
||||
RemoveHierarchicalNode(adjacentHierarchicalNode, false);
|
||||
} else {
|
||||
// Remove the connection from the other node to this node as we are removing this node.
|
||||
connections[adjacentHierarchicalNode].Remove(hierarchicalNode);
|
||||
}
|
||||
}
|
||||
conns.Clear();
|
||||
|
||||
var nodeChildren = children[hierarchicalNode];
|
||||
|
||||
for (int i = 0; i < nodeChildren.Count; i++) {
|
||||
AddDirtyNode(nodeChildren[i]);
|
||||
}
|
||||
|
||||
nodeChildren.ClearFast();
|
||||
}
|
||||
|
||||
/// <summary>Recalculate the hierarchical graph and the connected components if any nodes have been marked as dirty</summary>
|
||||
public void RecalculateIfNecessary () {
|
||||
if (numDirtyNodes > 0) {
|
||||
Profiler.BeginSample("Recalculate Connected Components");
|
||||
for (int i = 0; i < numDirtyNodes; i++) {
|
||||
dirty[dirtyNodes[i].HierarchicalNodeIndex] = 1;
|
||||
}
|
||||
|
||||
// Remove all hierarchical nodes and then build new hierarchical nodes in their place
|
||||
// which take into account the new graph data.
|
||||
for (int i = 1; i < dirty.Length; i++) {
|
||||
if (dirty[i] == 1) RemoveHierarchicalNode(i, true);
|
||||
}
|
||||
for (int i = 1; i < dirty.Length; i++) dirty[i] = 0;
|
||||
|
||||
for (int i = 0; i < numDirtyNodes; i++) {
|
||||
dirtyNodes[i].HierarchicalNodeIndex = 0;
|
||||
}
|
||||
|
||||
for (int i = 0; i < numDirtyNodes; i++) {
|
||||
var node = dirtyNodes[i];
|
||||
// Be nice to the GC
|
||||
dirtyNodes[i] = null;
|
||||
node.IsHierarchicalNodeDirty = false;
|
||||
|
||||
if (node.HierarchicalNodeIndex == 0 && node.Walkable && !node.Destroyed) {
|
||||
FindHierarchicalNodeChildren(GetHierarchicalNodeIndex(), node);
|
||||
}
|
||||
}
|
||||
|
||||
numDirtyNodes = 0;
|
||||
// Recalculate the connected components of the hierarchical nodes
|
||||
FloodFill();
|
||||
Profiler.EndSample();
|
||||
gizmoVersion++;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Recalculate everything from scratch.
|
||||
/// This is primarily to be used for legacy code for compatibility reasons, not for any new code.
|
||||
///
|
||||
/// See: <see cref="RecalculateIfNecessary"/>
|
||||
/// </summary>
|
||||
public void RecalculateAll () {
|
||||
AstarPath.active.data.GetNodes(node => AddDirtyNode(node));
|
||||
RecalculateIfNecessary();
|
||||
}
|
||||
|
||||
/// <summary>Flood fills the graph of hierarchical nodes and assigns the same area ID to all hierarchical nodes that are in the same connected component</summary>
|
||||
void FloodFill () {
|
||||
for (int i = 0; i < areas.Length; i++) areas[i] = 0;
|
||||
|
||||
Stack<int> stack = temporaryStack;
|
||||
int currentArea = 0;
|
||||
for (int i = 1; i < areas.Length; i++) {
|
||||
// Already taken care of
|
||||
if (areas[i] != 0) continue;
|
||||
|
||||
currentArea++;
|
||||
areas[i] = currentArea;
|
||||
stack.Push(i);
|
||||
while (stack.Count > 0) {
|
||||
int node = stack.Pop();
|
||||
var conns = connections[node];
|
||||
for (int j = conns.Count - 1; j >= 0; j--) {
|
||||
var otherNode = conns[j];
|
||||
// Note: slightly important that this is != currentArea and not != 0 in case there are some connected, but not stongly connected components in the graph (this will happen in only veeery few types of games)
|
||||
if (areas[otherNode] != currentArea) {
|
||||
areas[otherNode] = currentArea;
|
||||
stack.Push(otherNode);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
NumConnectedComponents = System.Math.Max(1, currentArea + 1);
|
||||
version++;
|
||||
}
|
||||
|
||||
/// <summary>Run a BFS out from a start node and assign up to MaxChildrenPerNode nodes to the specified hierarchical node which are not already assigned to another hierarchical node</summary>
|
||||
void FindHierarchicalNodeChildren (int hierarchicalNode, GraphNode startNode) {
|
||||
// Set some state for the connectionCallback delegate to use
|
||||
currentChildren = children[hierarchicalNode];
|
||||
currentConnections = connections[hierarchicalNode];
|
||||
currentHierarchicalNodeIndex = hierarchicalNode;
|
||||
|
||||
var que = temporaryQueue;
|
||||
que.Enqueue(startNode);
|
||||
|
||||
startNode.HierarchicalNodeIndex = hierarchicalNode;
|
||||
currentChildren.Add(startNode);
|
||||
|
||||
while (que.Count > 0) {
|
||||
que.Dequeue().GetConnections(connectionCallback);
|
||||
}
|
||||
|
||||
for (int i = 0; i < currentConnections.Count; i++) {
|
||||
connections[currentConnections[i]].Add(hierarchicalNode);
|
||||
}
|
||||
|
||||
que.Clear();
|
||||
}
|
||||
|
||||
public void OnDrawGizmos (Pathfinding.Util.RetainedGizmos gizmos) {
|
||||
var hasher = new Pathfinding.Util.RetainedGizmos.Hasher(AstarPath.active);
|
||||
|
||||
hasher.AddHash(gizmoVersion);
|
||||
|
||||
if (!gizmos.Draw(hasher)) {
|
||||
var builder = ObjectPool<RetainedGizmos.Builder>.Claim();
|
||||
var centers = ArrayPool<UnityEngine.Vector3>.Claim(areas.Length);
|
||||
for (int i = 0; i < areas.Length; i++) {
|
||||
Int3 center = Int3.zero;
|
||||
var childs = children[i];
|
||||
if (childs.Count > 0) {
|
||||
for (int j = 0; j < childs.Count; j++) center += childs[j].position;
|
||||
center /= childs.Count;
|
||||
centers[i] = (UnityEngine.Vector3)center;
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < areas.Length; i++) {
|
||||
if (children[i].Count > 0) {
|
||||
for (int j = 0; j < connections[i].Count; j++) {
|
||||
if (connections[i][j] > i) {
|
||||
builder.DrawLine(centers[i], centers[connections[i][j]], UnityEngine.Color.black);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
builder.Submit(gizmos, hasher);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: aa5d6e4a6adb04d4ca9b7e735addcbd5
|
||||
timeCreated: 1535050640
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,320 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace Pathfinding {
|
||||
/// <summary>Holds a coordinate in integers</summary>
|
||||
public struct Int3 : System.IEquatable<Int3> {
|
||||
public int x;
|
||||
public int y;
|
||||
public int z;
|
||||
|
||||
//These should be set to the same value (only PrecisionFactor should be 1 divided by Precision)
|
||||
|
||||
/// <summary>
|
||||
/// Precision for the integer coordinates.
|
||||
/// One world unit is divided into [value] pieces. A value of 1000 would mean millimeter precision, a value of 1 would mean meter precision (assuming 1 world unit = 1 meter).
|
||||
/// This value affects the maximum coordinates for nodes as well as how large the cost values are for moving between two nodes.
|
||||
/// A higher value means that you also have to set all penalty values to a higher value to compensate since the normal cost of moving will be higher.
|
||||
/// </summary>
|
||||
public const int Precision = 1000;
|
||||
|
||||
/// <summary><see cref="Precision"/> as a float</summary>
|
||||
public const float FloatPrecision = 1000F;
|
||||
|
||||
/// <summary>1 divided by <see cref="Precision"/></summary>
|
||||
public const float PrecisionFactor = 0.001F;
|
||||
|
||||
public static Int3 zero { get { return new Int3(); } }
|
||||
|
||||
public Int3 (Vector3 position) {
|
||||
x = (int)System.Math.Round(position.x*FloatPrecision);
|
||||
y = (int)System.Math.Round(position.y*FloatPrecision);
|
||||
z = (int)System.Math.Round(position.z*FloatPrecision);
|
||||
}
|
||||
|
||||
public Int3 (int _x, int _y, int _z) {
|
||||
x = _x;
|
||||
y = _y;
|
||||
z = _z;
|
||||
}
|
||||
|
||||
public static bool operator == (Int3 lhs, Int3 rhs) {
|
||||
return lhs.x == rhs.x &&
|
||||
lhs.y == rhs.y &&
|
||||
lhs.z == rhs.z;
|
||||
}
|
||||
|
||||
public static bool operator != (Int3 lhs, Int3 rhs) {
|
||||
return lhs.x != rhs.x ||
|
||||
lhs.y != rhs.y ||
|
||||
lhs.z != rhs.z;
|
||||
}
|
||||
|
||||
public static explicit operator Int3 (Vector3 ob) {
|
||||
return new Int3(
|
||||
(int)System.Math.Round(ob.x*FloatPrecision),
|
||||
(int)System.Math.Round(ob.y*FloatPrecision),
|
||||
(int)System.Math.Round(ob.z*FloatPrecision)
|
||||
);
|
||||
}
|
||||
|
||||
public static explicit operator Vector3 (Int3 ob) {
|
||||
return new Vector3(ob.x*PrecisionFactor, ob.y*PrecisionFactor, ob.z*PrecisionFactor);
|
||||
}
|
||||
|
||||
public static Int3 operator - (Int3 lhs, Int3 rhs) {
|
||||
lhs.x -= rhs.x;
|
||||
lhs.y -= rhs.y;
|
||||
lhs.z -= rhs.z;
|
||||
return lhs;
|
||||
}
|
||||
|
||||
public static Int3 operator - (Int3 lhs) {
|
||||
lhs.x = -lhs.x;
|
||||
lhs.y = -lhs.y;
|
||||
lhs.z = -lhs.z;
|
||||
return lhs;
|
||||
}
|
||||
|
||||
public static Int3 operator + (Int3 lhs, Int3 rhs) {
|
||||
lhs.x += rhs.x;
|
||||
lhs.y += rhs.y;
|
||||
lhs.z += rhs.z;
|
||||
return lhs;
|
||||
}
|
||||
|
||||
public static Int3 operator * (Int3 lhs, int rhs) {
|
||||
lhs.x *= rhs;
|
||||
lhs.y *= rhs;
|
||||
lhs.z *= rhs;
|
||||
|
||||
return lhs;
|
||||
}
|
||||
|
||||
public static Int3 operator * (Int3 lhs, float rhs) {
|
||||
lhs.x = (int)System.Math.Round(lhs.x * rhs);
|
||||
lhs.y = (int)System.Math.Round(lhs.y * rhs);
|
||||
lhs.z = (int)System.Math.Round(lhs.z * rhs);
|
||||
|
||||
return lhs;
|
||||
}
|
||||
|
||||
public static Int3 operator * (Int3 lhs, double rhs) {
|
||||
lhs.x = (int)System.Math.Round(lhs.x * rhs);
|
||||
lhs.y = (int)System.Math.Round(lhs.y * rhs);
|
||||
lhs.z = (int)System.Math.Round(lhs.z * rhs);
|
||||
|
||||
return lhs;
|
||||
}
|
||||
|
||||
public static Int3 operator / (Int3 lhs, float rhs) {
|
||||
lhs.x = (int)System.Math.Round(lhs.x / rhs);
|
||||
lhs.y = (int)System.Math.Round(lhs.y / rhs);
|
||||
lhs.z = (int)System.Math.Round(lhs.z / rhs);
|
||||
return lhs;
|
||||
}
|
||||
|
||||
public int this[int i] {
|
||||
get {
|
||||
return i == 0 ? x : (i == 1 ? y : z);
|
||||
}
|
||||
set {
|
||||
if (i == 0) x = value;
|
||||
else if (i == 1) y = value;
|
||||
else z = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Angle between the vectors in radians</summary>
|
||||
public static float Angle (Int3 lhs, Int3 rhs) {
|
||||
double cos = Dot(lhs, rhs)/ ((double)lhs.magnitude*(double)rhs.magnitude);
|
||||
|
||||
cos = cos < -1 ? -1 : (cos > 1 ? 1 : cos);
|
||||
return (float)System.Math.Acos(cos);
|
||||
}
|
||||
|
||||
public static int Dot (Int3 lhs, Int3 rhs) {
|
||||
return
|
||||
lhs.x * rhs.x +
|
||||
lhs.y * rhs.y +
|
||||
lhs.z * rhs.z;
|
||||
}
|
||||
|
||||
public static long DotLong (Int3 lhs, Int3 rhs) {
|
||||
return
|
||||
(long)lhs.x * (long)rhs.x +
|
||||
(long)lhs.y * (long)rhs.y +
|
||||
(long)lhs.z * (long)rhs.z;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Normal in 2D space (XZ).
|
||||
/// Equivalent to Cross(this, Int3(0,1,0) )
|
||||
/// except that the Y coordinate is left unchanged with this operation.
|
||||
/// </summary>
|
||||
public Int3 Normal2D () {
|
||||
return new Int3(z, y, -x);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the magnitude of the vector. The magnitude is the 'length' of the vector from 0,0,0 to this point. Can be used for distance calculations:
|
||||
/// <code> Debug.Log ("Distance between 3,4,5 and 6,7,8 is: "+(new Int3(3,4,5) - new Int3(6,7,8)).magnitude); </code>
|
||||
/// </summary>
|
||||
public float magnitude {
|
||||
get {
|
||||
//It turns out that using doubles is just as fast as using ints with Mathf.Sqrt. And this can also handle larger numbers (possibly with small errors when using huge numbers)!
|
||||
|
||||
double _x = x;
|
||||
double _y = y;
|
||||
double _z = z;
|
||||
|
||||
return (float)System.Math.Sqrt(_x*_x+_y*_y+_z*_z);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Magnitude used for the cost between two nodes. The default cost between two nodes can be calculated like this:
|
||||
/// <code> int cost = (node1.position-node2.position).costMagnitude; </code>
|
||||
///
|
||||
/// This is simply the magnitude, rounded to the nearest integer
|
||||
/// </summary>
|
||||
public int costMagnitude {
|
||||
get {
|
||||
return (int)System.Math.Round(magnitude);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>The squared magnitude of the vector</summary>
|
||||
public float sqrMagnitude {
|
||||
get {
|
||||
double _x = x;
|
||||
double _y = y;
|
||||
double _z = z;
|
||||
return (float)(_x*_x+_y*_y+_z*_z);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>The squared magnitude of the vector</summary>
|
||||
public long sqrMagnitudeLong {
|
||||
get {
|
||||
long _x = x;
|
||||
long _y = y;
|
||||
long _z = z;
|
||||
return (_x*_x+_y*_y+_z*_z);
|
||||
}
|
||||
}
|
||||
|
||||
public static implicit operator string (Int3 obj) {
|
||||
return obj.ToString();
|
||||
}
|
||||
|
||||
/// <summary>Returns a nicely formatted string representing the vector</summary>
|
||||
public override string ToString () {
|
||||
return "( "+x+", "+y+", "+z+")";
|
||||
}
|
||||
|
||||
public override bool Equals (System.Object obj) {
|
||||
if (obj == null) return false;
|
||||
|
||||
var rhs = (Int3)obj;
|
||||
|
||||
return x == rhs.x &&
|
||||
y == rhs.y &&
|
||||
z == rhs.z;
|
||||
}
|
||||
|
||||
#region IEquatable implementation
|
||||
|
||||
public bool Equals (Int3 other) {
|
||||
return x == other.x && y == other.y && z == other.z;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
public override int GetHashCode () {
|
||||
return x*73856093 ^ y*19349669 ^ z*83492791;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Two Dimensional Integer Coordinate Pair</summary>
|
||||
public struct Int2 : System.IEquatable<Int2> {
|
||||
public int x;
|
||||
public int y;
|
||||
|
||||
public Int2 (int x, int y) {
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
}
|
||||
|
||||
public long sqrMagnitudeLong {
|
||||
get {
|
||||
return (long)x*(long)x+(long)y*(long)y;
|
||||
}
|
||||
}
|
||||
|
||||
public static Int2 operator - (Int2 lhs) {
|
||||
lhs.x = -lhs.x;
|
||||
lhs.y = -lhs.y;
|
||||
return lhs;
|
||||
}
|
||||
|
||||
public static Int2 operator + (Int2 a, Int2 b) {
|
||||
return new Int2(a.x+b.x, a.y+b.y);
|
||||
}
|
||||
|
||||
public static Int2 operator - (Int2 a, Int2 b) {
|
||||
return new Int2(a.x-b.x, a.y-b.y);
|
||||
}
|
||||
|
||||
public static bool operator == (Int2 a, Int2 b) {
|
||||
return a.x == b.x && a.y == b.y;
|
||||
}
|
||||
|
||||
public static bool operator != (Int2 a, Int2 b) {
|
||||
return a.x != b.x || a.y != b.y;
|
||||
}
|
||||
|
||||
/// <summary>Dot product of the two coordinates</summary>
|
||||
public static long DotLong (Int2 a, Int2 b) {
|
||||
return (long)a.x*(long)b.x + (long)a.y*(long)b.y;
|
||||
}
|
||||
|
||||
public override bool Equals (System.Object o) {
|
||||
if (o == null) return false;
|
||||
var rhs = (Int2)o;
|
||||
|
||||
return x == rhs.x && y == rhs.y;
|
||||
}
|
||||
|
||||
#region IEquatable implementation
|
||||
|
||||
public bool Equals (Int2 other) {
|
||||
return x == other.x && y == other.y;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
public override int GetHashCode () {
|
||||
return x*49157+y*98317;
|
||||
}
|
||||
|
||||
public static Int2 Min (Int2 a, Int2 b) {
|
||||
return new Int2(System.Math.Min(a.x, b.x), System.Math.Min(a.y, b.y));
|
||||
}
|
||||
|
||||
public static Int2 Max (Int2 a, Int2 b) {
|
||||
return new Int2(System.Math.Max(a.x, b.x), System.Math.Max(a.y, b.y));
|
||||
}
|
||||
|
||||
public static Int2 FromInt3XZ (Int3 o) {
|
||||
return new Int2(o.x, o.z);
|
||||
}
|
||||
|
||||
public static Int3 ToInt3XZ (Int2 o) {
|
||||
return new Int3(o.x, 0, o.y);
|
||||
}
|
||||
|
||||
public override string ToString () {
|
||||
return "("+x+", " +y+")";
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5826dd4a1809b448291582cd06deadc1
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
@ -0,0 +1,174 @@
|
||||
using UnityEngine;
|
||||
using System.Collections;
|
||||
|
||||
namespace Pathfinding.Util {
|
||||
public static class MovementUtilities {
|
||||
/// <summary>
|
||||
/// Clamps the velocity to the max speed and optionally the forwards direction.
|
||||
///
|
||||
/// Note that all vectors are 2D vectors, not 3D vectors.
|
||||
///
|
||||
/// Returns: The clamped velocity in world units per second.
|
||||
/// </summary>
|
||||
/// <param name="velocity">Desired velocity of the character. In world units per second.</param>
|
||||
/// <param name="maxSpeed">Max speed of the character. In world units per second.</param>
|
||||
/// <param name="slowdownFactor">Value between 0 and 1 which determines how much slower the character should move than normal.
|
||||
/// Normally 1 but should go to 0 when the character approaches the end of the path.</param>
|
||||
/// <param name="slowWhenNotFacingTarget">Prevent the velocity from being too far away from the forward direction of the character
|
||||
/// and slow the character down if the desired velocity is not in the same direction as the forward vector.</param>
|
||||
/// <param name="forward">Forward direction of the character. Used together with the slowWhenNotFacingTarget parameter.</param>
|
||||
public static Vector2 ClampVelocity (Vector2 velocity, float maxSpeed, float slowdownFactor, bool slowWhenNotFacingTarget, Vector2 forward) {
|
||||
// Max speed to use for this frame
|
||||
var currentMaxSpeed = maxSpeed * slowdownFactor;
|
||||
|
||||
// Check if the agent should slow down in case it is not facing the direction it wants to move in
|
||||
if (slowWhenNotFacingTarget && (forward.x != 0 || forward.y != 0)) {
|
||||
float currentSpeed;
|
||||
var normalizedVelocity = VectorMath.Normalize(velocity, out currentSpeed);
|
||||
float dot = Vector2.Dot(normalizedVelocity, forward);
|
||||
|
||||
// Lower the speed when the character's forward direction is not pointing towards the desired velocity
|
||||
// 1 when velocity is in the same direction as forward
|
||||
// 0.2 when they point in the opposite directions
|
||||
float directionSpeedFactor = Mathf.Clamp(dot+0.707f, 0.2f, 1.0f);
|
||||
currentMaxSpeed *= directionSpeedFactor;
|
||||
currentSpeed = Mathf.Min(currentSpeed, currentMaxSpeed);
|
||||
|
||||
// Angle between the forwards direction of the character and our desired velocity
|
||||
float angle = Mathf.Acos(Mathf.Clamp(dot, -1, 1));
|
||||
|
||||
// Clamp the angle to 20 degrees
|
||||
// We cannot keep the velocity exactly in the forwards direction of the character
|
||||
// because we use the rotation to determine in which direction to rotate and if
|
||||
// the velocity would always be in the forwards direction of the character then
|
||||
// the character would never rotate.
|
||||
// Allow larger angles when near the end of the path to prevent oscillations.
|
||||
angle = Mathf.Min(angle, (20f + 180f*(1 - slowdownFactor*slowdownFactor))*Mathf.Deg2Rad);
|
||||
|
||||
float sin = Mathf.Sin(angle);
|
||||
float cos = Mathf.Cos(angle);
|
||||
|
||||
// Determine if we should rotate clockwise or counter-clockwise to move towards the current velocity
|
||||
sin *= Mathf.Sign(normalizedVelocity.x*forward.y - normalizedVelocity.y*forward.x);
|
||||
// Rotate the #forward vector by #angle radians
|
||||
// The rotation is done using an inlined rotation matrix.
|
||||
// See https://en.wikipedia.org/wiki/Rotation_matrix
|
||||
return new Vector2(forward.x*cos + forward.y*sin, forward.y*cos - forward.x*sin) * currentSpeed;
|
||||
} else {
|
||||
return Vector2.ClampMagnitude(velocity, currentMaxSpeed);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Calculate an acceleration to move deltaPosition units and get there with approximately a velocity of targetVelocity</summary>
|
||||
public static Vector2 CalculateAccelerationToReachPoint (Vector2 deltaPosition, Vector2 targetVelocity, Vector2 currentVelocity, float forwardsAcceleration, float rotationSpeed, float maxSpeed, Vector2 forwardsVector) {
|
||||
// Guard against div by zero
|
||||
if (forwardsAcceleration <= 0) return Vector2.zero;
|
||||
|
||||
float currentSpeed = currentVelocity.magnitude;
|
||||
|
||||
// Convert rotation speed to an acceleration
|
||||
// See https://en.wikipedia.org/wiki/Centripetal_force
|
||||
var sidewaysAcceleration = currentSpeed * rotationSpeed * Mathf.Deg2Rad;
|
||||
|
||||
// To avoid weird behaviour when the rotation speed is very low we allow the agent to accelerate sideways without rotating much
|
||||
// if the rotation speed is very small. Also guards against division by zero.
|
||||
sidewaysAcceleration = Mathf.Max(sidewaysAcceleration, forwardsAcceleration);
|
||||
|
||||
// Transform coordinates to local space where +X is the forwards direction
|
||||
// This is essentially equivalent to Transform.InverseTransformDirection.
|
||||
deltaPosition = VectorMath.ComplexMultiplyConjugate(deltaPosition, forwardsVector);
|
||||
targetVelocity = VectorMath.ComplexMultiplyConjugate(targetVelocity, forwardsVector);
|
||||
currentVelocity = VectorMath.ComplexMultiplyConjugate(currentVelocity, forwardsVector);
|
||||
float ellipseSqrFactorX = 1 / (forwardsAcceleration*forwardsAcceleration);
|
||||
float ellipseSqrFactorY = 1 / (sidewaysAcceleration*sidewaysAcceleration);
|
||||
|
||||
// If the target velocity is zero we can use a more fancy approach
|
||||
// and calculate a nicer path.
|
||||
// In particular, this is the case at the end of the path.
|
||||
if (targetVelocity == Vector2.zero) {
|
||||
// Run a binary search over the time to get to the target point.
|
||||
float mn = 0.01f;
|
||||
float mx = 10;
|
||||
while (mx - mn > 0.01f) {
|
||||
var time = (mx + mn) * 0.5f;
|
||||
|
||||
// Given that we want to move deltaPosition units from out current position, that our current velocity is given
|
||||
// and that when we reach the target we want our velocity to be zero. Also assume that our acceleration will
|
||||
// vary linearly during the slowdown. Then we can calculate what our acceleration should be during this frame.
|
||||
|
||||
//{ t = time
|
||||
//{ deltaPosition = vt + at^2/2 + qt^3/6
|
||||
//{ 0 = v + at + qt^2/2
|
||||
//{ solve for a
|
||||
// a = acceleration vector
|
||||
// q = derivative of the acceleration vector
|
||||
var a = (6*deltaPosition - 4*time*currentVelocity)/(time*time);
|
||||
var q = 6*(time*currentVelocity - 2*deltaPosition)/(time*time*time);
|
||||
|
||||
// Make sure the acceleration is not greater than our maximum allowed acceleration.
|
||||
// If it is we increase the time we want to use to get to the target
|
||||
// and if it is not, we decrease the time to get there faster.
|
||||
// Since the acceleration is described by acceleration = a + q*t
|
||||
// we only need to check at t=0 and t=time.
|
||||
// Note that the acceleration limit is described by an ellipse, not a circle.
|
||||
var nextA = a + q*time;
|
||||
if (a.x*a.x*ellipseSqrFactorX + a.y*a.y*ellipseSqrFactorY > 1.0f || nextA.x*nextA.x*ellipseSqrFactorX + nextA.y*nextA.y*ellipseSqrFactorY > 1.0f) {
|
||||
mn = time;
|
||||
} else {
|
||||
mx = time;
|
||||
}
|
||||
}
|
||||
|
||||
var finalAcceleration = (6*deltaPosition - 4*mx*currentVelocity)/(mx*mx);
|
||||
|
||||
// Boosting
|
||||
{
|
||||
// The trajectory calculated above has a tendency to use very wide arcs
|
||||
// and that does unfortunately not look particularly good in some cases.
|
||||
// Here we amplify the component of the acceleration that is perpendicular
|
||||
// to our current velocity. This will make the agent turn towards the
|
||||
// target quicker.
|
||||
// How much amplification to use. Value is unitless.
|
||||
const float Boost = 1;
|
||||
finalAcceleration.y *= 1 + Boost;
|
||||
|
||||
// Clamp the velocity to the maximum acceleration.
|
||||
// Note that the maximum acceleration constraint is shaped like an ellipse, not like a circle.
|
||||
float ellipseMagnitude = finalAcceleration.x*finalAcceleration.x*ellipseSqrFactorX + finalAcceleration.y*finalAcceleration.y*ellipseSqrFactorY;
|
||||
if (ellipseMagnitude > 1.0f) finalAcceleration /= Mathf.Sqrt(ellipseMagnitude);
|
||||
}
|
||||
|
||||
return VectorMath.ComplexMultiply(finalAcceleration, forwardsVector);
|
||||
} else {
|
||||
// Here we try to move towards the next waypoint which has been modified slightly using our
|
||||
// desired velocity at that point so that the agent will more smoothly round the corner.
|
||||
|
||||
// How much to strive for making sure we reach the target point with the target velocity. Unitless.
|
||||
const float TargetVelocityWeight = 0.5f;
|
||||
|
||||
// Limit to how much to care about the target velocity. Value is in seconds.
|
||||
// This prevents the character from moving away from the path too much when the target point is far away
|
||||
const float TargetVelocityWeightLimit = 1.5f;
|
||||
float targetSpeed;
|
||||
var normalizedTargetVelocity = VectorMath.Normalize(targetVelocity, out targetSpeed);
|
||||
|
||||
var distance = deltaPosition.magnitude;
|
||||
var targetPoint = deltaPosition - normalizedTargetVelocity * System.Math.Min(TargetVelocityWeight * distance * targetSpeed / (currentSpeed + targetSpeed), maxSpeed*TargetVelocityWeightLimit);
|
||||
|
||||
// How quickly the agent will try to reach the velocity that we want it to have.
|
||||
// We need this to prevent oscillations and jitter which is what happens if
|
||||
// we let the constant go towards zero. Value is in seconds.
|
||||
const float TimeToReachDesiredVelocity = 0.1f;
|
||||
// TODO: Clamp to ellipse using more accurate acceleration (use rotation speed as well)
|
||||
var finalAcceleration = (targetPoint.normalized*maxSpeed - currentVelocity) * (1f/TimeToReachDesiredVelocity);
|
||||
|
||||
// Clamp the velocity to the maximum acceleration.
|
||||
// Note that the maximum acceleration constraint is shaped like an ellipse, not like a circle.
|
||||
float ellipseMagnitude = finalAcceleration.x*finalAcceleration.x*ellipseSqrFactorX + finalAcceleration.y*finalAcceleration.y*ellipseSqrFactorY;
|
||||
if (ellipseMagnitude > 1.0f) finalAcceleration /= Mathf.Sqrt(ellipseMagnitude);
|
||||
|
||||
return VectorMath.ComplexMultiply(finalAcceleration, forwardsVector);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0a6cffd9895f94907aa43f18b0904587
|
||||
timeCreated: 1490097740
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,157 @@
|
||||
using UnityEngine;
|
||||
#if UNITY_EDITOR
|
||||
using UnityEditor;
|
||||
#endif
|
||||
|
||||
namespace Pathfinding {
|
||||
using Pathfinding.Util;
|
||||
|
||||
/// <summary>
|
||||
/// Connects two nodes with a direct connection.
|
||||
/// It is not possible to detect this link when following a path (which may be good or bad), for that you can use NodeLink2.
|
||||
///
|
||||
/// [Open online documentation to see images]
|
||||
///
|
||||
/// See: editing-graphs (view in online documentation for working links)
|
||||
/// </summary>
|
||||
[AddComponentMenu("Pathfinding/Link")]
|
||||
[HelpURL("https://arongranberg.com/astar/documentation/stable/class_pathfinding_1_1_node_link.php")]
|
||||
public class NodeLink : GraphModifier {
|
||||
/// <summary>End position of the link</summary>
|
||||
public Transform end;
|
||||
|
||||
/// <summary>
|
||||
/// The connection will be this times harder/slower to traverse.
|
||||
/// Note that values lower than one will not always make the pathfinder choose this path instead of another path even though this one should
|
||||
/// lead to a lower total cost unless you also adjust the Heuristic Scale in A* Inspector -> Settings -> Pathfinding or disable the heuristic altogether.
|
||||
/// </summary>
|
||||
public float costFactor = 1.0f;
|
||||
|
||||
/// <summary>Make a one-way connection</summary>
|
||||
public bool oneWay = false;
|
||||
|
||||
/// <summary>Delete existing connection instead of adding one</summary>
|
||||
public bool deleteConnection = false;
|
||||
|
||||
public Transform Start {
|
||||
get { return transform; }
|
||||
}
|
||||
|
||||
public Transform End {
|
||||
get { return end; }
|
||||
}
|
||||
|
||||
public override void OnPostScan () {
|
||||
if (AstarPath.active.isScanning) {
|
||||
InternalOnPostScan();
|
||||
} else {
|
||||
AstarPath.active.AddWorkItem(new AstarWorkItem(force => {
|
||||
InternalOnPostScan();
|
||||
return true;
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
public void InternalOnPostScan () {
|
||||
Apply();
|
||||
}
|
||||
|
||||
public override void OnGraphsPostUpdate () {
|
||||
if (!AstarPath.active.isScanning) {
|
||||
AstarPath.active.AddWorkItem(new AstarWorkItem(force => {
|
||||
InternalOnPostScan();
|
||||
return true;
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void Apply () {
|
||||
if (Start == null || End == null || AstarPath.active == null) return;
|
||||
|
||||
GraphNode startNode = AstarPath.active.GetNearest(Start.position).node;
|
||||
GraphNode endNode = AstarPath.active.GetNearest(End.position).node;
|
||||
|
||||
if (startNode == null || endNode == null) return;
|
||||
|
||||
|
||||
if (deleteConnection) {
|
||||
startNode.RemoveConnection(endNode);
|
||||
if (!oneWay)
|
||||
endNode.RemoveConnection(startNode);
|
||||
} else {
|
||||
uint cost = (uint)System.Math.Round((startNode.position-endNode.position).costMagnitude*costFactor);
|
||||
|
||||
startNode.AddConnection(endNode, cost);
|
||||
if (!oneWay)
|
||||
endNode.AddConnection(startNode, cost);
|
||||
}
|
||||
}
|
||||
|
||||
public void OnDrawGizmos () {
|
||||
if (Start == null || End == null) return;
|
||||
|
||||
Draw.Gizmos.Bezier(Start.position, End.position, deleteConnection ? Color.red : Color.green);
|
||||
}
|
||||
|
||||
#if UNITY_EDITOR
|
||||
[UnityEditor.MenuItem("Edit/Pathfinding/Link Pair %&l")]
|
||||
public static void LinkObjects () {
|
||||
Transform[] tfs = Selection.transforms;
|
||||
if (tfs.Length == 2) {
|
||||
LinkObjects(tfs[0], tfs[1], false);
|
||||
}
|
||||
SceneView.RepaintAll();
|
||||
}
|
||||
|
||||
[UnityEditor.MenuItem("Edit/Pathfinding/Unlink Pair %&u")]
|
||||
public static void UnlinkObjects () {
|
||||
Transform[] tfs = Selection.transforms;
|
||||
if (tfs.Length == 2) {
|
||||
LinkObjects(tfs[0], tfs[1], true);
|
||||
}
|
||||
SceneView.RepaintAll();
|
||||
}
|
||||
|
||||
[UnityEditor.MenuItem("Edit/Pathfinding/Delete Links on Selected %&b")]
|
||||
public static void DeleteLinks () {
|
||||
Transform[] tfs = Selection.transforms;
|
||||
for (int i = 0; i < tfs.Length; i++) {
|
||||
NodeLink[] conns = tfs[i].GetComponents<NodeLink>();
|
||||
for (int j = 0; j < conns.Length; j++) DestroyImmediate(conns[j]);
|
||||
}
|
||||
SceneView.RepaintAll();
|
||||
}
|
||||
|
||||
public static void LinkObjects (Transform a, Transform b, bool removeConnection) {
|
||||
NodeLink connecting = null;
|
||||
|
||||
NodeLink[] conns = a.GetComponents<NodeLink>();
|
||||
for (int i = 0; i < conns.Length; i++) {
|
||||
if (conns[i].end == b) {
|
||||
connecting = conns[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
conns = b.GetComponents<NodeLink>();
|
||||
for (int i = 0; i < conns.Length; i++) {
|
||||
if (conns[i].end == a) {
|
||||
connecting = conns[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (removeConnection) {
|
||||
if (connecting != null) DestroyImmediate(connecting);
|
||||
} else {
|
||||
if (connecting == null) {
|
||||
connecting = a.gameObject.AddComponent<NodeLink>();
|
||||
connecting.end = b;
|
||||
} else {
|
||||
connecting.deleteConnection = !connecting.deleteConnection;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ca327ce4e754a4597a70fb963758f8bd
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
@ -0,0 +1,308 @@
|
||||
using UnityEngine;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Pathfinding {
|
||||
using Pathfinding.Util;
|
||||
|
||||
/// <summary>
|
||||
/// Connects two nodes via two intermediate point nodes.
|
||||
/// In contrast to the NodeLink component, this link type will not connect the nodes directly
|
||||
/// instead it will create two point nodes at the start and end position of this link and connect
|
||||
/// through those nodes.
|
||||
///
|
||||
/// If the closest node to this object is called A and the closest node to the end transform is called
|
||||
/// D, then it will create one point node at this object's position (call it B) and one point node at
|
||||
/// the position of the end transform (call it C), it will then connect A to B, B to C and C to D.
|
||||
///
|
||||
/// This link type is possible to detect while following since it has these special point nodes in the middle.
|
||||
/// The link corresponding to one of those intermediate nodes can be retrieved using the <see cref="GetNodeLink"/> method
|
||||
/// which can be of great use if you want to, for example, play a link specific animation when reaching the link.
|
||||
///
|
||||
/// See: The example scene RecastExample2 contains a few links which you can take a look at to see how they are used.
|
||||
/// </summary>
|
||||
[AddComponentMenu("Pathfinding/Link2")]
|
||||
[HelpURL("https://arongranberg.com/astar/documentation/stable/class_pathfinding_1_1_node_link2.php")]
|
||||
public class NodeLink2 : GraphModifier {
|
||||
protected static Dictionary<GraphNode, NodeLink2> reference = new Dictionary<GraphNode, NodeLink2>();
|
||||
public static NodeLink2 GetNodeLink (GraphNode node) {
|
||||
NodeLink2 v;
|
||||
|
||||
reference.TryGetValue(node, out v);
|
||||
return v;
|
||||
}
|
||||
|
||||
/// <summary>End position of the link</summary>
|
||||
public Transform end;
|
||||
|
||||
/// <summary>
|
||||
/// The connection will be this times harder/slower to traverse.
|
||||
/// Note that values lower than 1 will not always make the pathfinder choose this path instead of another path even though this one should
|
||||
/// lead to a lower total cost unless you also adjust the Heuristic Scale in A* Inspector -> Settings -> Pathfinding or disable the heuristic altogether.
|
||||
/// </summary>
|
||||
public float costFactor = 1.0f;
|
||||
|
||||
/// <summary>Make a one-way connection</summary>
|
||||
public bool oneWay = false;
|
||||
|
||||
public Transform StartTransform {
|
||||
get { return transform; }
|
||||
}
|
||||
|
||||
public Transform EndTransform {
|
||||
get { return end; }
|
||||
}
|
||||
|
||||
public PointNode startNode { get; private set; }
|
||||
public PointNode endNode { get; private set; }
|
||||
GraphNode connectedNode1, connectedNode2;
|
||||
Vector3 clamped1, clamped2;
|
||||
bool postScanCalled = false;
|
||||
|
||||
[System.Obsolete("Use startNode instead (lowercase s)")]
|
||||
public GraphNode StartNode {
|
||||
get { return startNode; }
|
||||
}
|
||||
|
||||
[System.Obsolete("Use endNode instead (lowercase e)")]
|
||||
public GraphNode EndNode {
|
||||
get { return endNode; }
|
||||
}
|
||||
|
||||
public override void OnPostScan () {
|
||||
InternalOnPostScan();
|
||||
}
|
||||
|
||||
public void InternalOnPostScan () {
|
||||
if (EndTransform == null || StartTransform == null) return;
|
||||
|
||||
#if ASTAR_NO_POINT_GRAPH
|
||||
throw new System.Exception("Point graph is not included. Check your A* optimization settings.");
|
||||
#else
|
||||
if (AstarPath.active.data.pointGraph == null) {
|
||||
var graph = AstarPath.active.data.AddGraph(typeof(PointGraph)) as PointGraph;
|
||||
graph.name = "PointGraph (used for node links)";
|
||||
}
|
||||
|
||||
if (startNode != null && startNode.Destroyed) {
|
||||
reference.Remove(startNode);
|
||||
startNode = null;
|
||||
}
|
||||
|
||||
if (endNode != null && endNode.Destroyed) {
|
||||
reference.Remove(endNode);
|
||||
endNode = null;
|
||||
}
|
||||
|
||||
// Create new nodes on the point graph
|
||||
if (startNode == null) startNode = AstarPath.active.data.pointGraph.AddNode((Int3)StartTransform.position);
|
||||
if (endNode == null) endNode = AstarPath.active.data.pointGraph.AddNode((Int3)EndTransform.position);
|
||||
|
||||
connectedNode1 = null;
|
||||
connectedNode2 = null;
|
||||
|
||||
if (startNode == null || endNode == null) {
|
||||
startNode = null;
|
||||
endNode = null;
|
||||
return;
|
||||
}
|
||||
|
||||
postScanCalled = true;
|
||||
reference[startNode] = this;
|
||||
reference[endNode] = this;
|
||||
Apply(true);
|
||||
#endif
|
||||
}
|
||||
|
||||
public override void OnGraphsPostUpdate () {
|
||||
// Don't bother running it now since OnPostScan will be called later anyway
|
||||
if (AstarPath.active.isScanning)
|
||||
return;
|
||||
|
||||
if (connectedNode1 != null && connectedNode1.Destroyed) {
|
||||
connectedNode1 = null;
|
||||
}
|
||||
if (connectedNode2 != null && connectedNode2.Destroyed) {
|
||||
connectedNode2 = null;
|
||||
}
|
||||
|
||||
if (!postScanCalled) {
|
||||
OnPostScan();
|
||||
} else {
|
||||
Apply(false);
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnEnable () {
|
||||
base.OnEnable();
|
||||
|
||||
#if !ASTAR_NO_POINT_GRAPH
|
||||
if (Application.isPlaying && AstarPath.active != null && AstarPath.active.data != null && AstarPath.active.data.pointGraph != null && !AstarPath.active.isScanning) {
|
||||
// Call OnGraphsPostUpdate as soon as possible when it is safe to update the graphs
|
||||
AstarPath.active.AddWorkItem(OnGraphsPostUpdate);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
protected override void OnDisable () {
|
||||
base.OnDisable();
|
||||
|
||||
postScanCalled = false;
|
||||
|
||||
if (startNode != null) reference.Remove(startNode);
|
||||
if (endNode != null) reference.Remove(endNode);
|
||||
|
||||
if (startNode != null && endNode != null) {
|
||||
startNode.RemoveConnection(endNode);
|
||||
endNode.RemoveConnection(startNode);
|
||||
|
||||
if (connectedNode1 != null && connectedNode2 != null) {
|
||||
startNode.RemoveConnection(connectedNode1);
|
||||
connectedNode1.RemoveConnection(startNode);
|
||||
|
||||
endNode.RemoveConnection(connectedNode2);
|
||||
connectedNode2.RemoveConnection(endNode);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void RemoveConnections (GraphNode node) {
|
||||
//TODO, might be better to replace connection
|
||||
node.ClearConnections(true);
|
||||
}
|
||||
|
||||
[ContextMenu("Recalculate neighbours")]
|
||||
void ContextApplyForce () {
|
||||
if (Application.isPlaying) {
|
||||
Apply(true);
|
||||
}
|
||||
}
|
||||
|
||||
public void Apply (bool forceNewCheck) {
|
||||
//TODO
|
||||
//This function assumes that connections from the n1,n2 nodes never need to be removed in the future (e.g because the nodes move or something)
|
||||
NNConstraint nn = NNConstraint.None;
|
||||
int graph = (int)startNode.GraphIndex;
|
||||
|
||||
//Search all graphs but the one which start and end nodes are on
|
||||
nn.graphMask = ~(1 << graph);
|
||||
|
||||
startNode.SetPosition((Int3)StartTransform.position);
|
||||
endNode.SetPosition((Int3)EndTransform.position);
|
||||
|
||||
RemoveConnections(startNode);
|
||||
RemoveConnections(endNode);
|
||||
|
||||
uint cost = (uint)Mathf.RoundToInt(((Int3)(StartTransform.position-EndTransform.position)).costMagnitude*costFactor);
|
||||
startNode.AddConnection(endNode, cost);
|
||||
endNode.AddConnection(startNode, cost);
|
||||
|
||||
if (connectedNode1 == null || forceNewCheck) {
|
||||
var info = AstarPath.active.GetNearest(StartTransform.position, nn);
|
||||
connectedNode1 = info.node;
|
||||
clamped1 = info.position;
|
||||
}
|
||||
|
||||
if (connectedNode2 == null || forceNewCheck) {
|
||||
var info = AstarPath.active.GetNearest(EndTransform.position, nn);
|
||||
connectedNode2 = info.node;
|
||||
clamped2 = info.position;
|
||||
}
|
||||
|
||||
if (connectedNode2 == null || connectedNode1 == null) return;
|
||||
|
||||
//Add connections between nodes, or replace old connections if existing
|
||||
connectedNode1.AddConnection(startNode, (uint)Mathf.RoundToInt(((Int3)(clamped1 - StartTransform.position)).costMagnitude*costFactor));
|
||||
if (!oneWay) connectedNode2.AddConnection(endNode, (uint)Mathf.RoundToInt(((Int3)(clamped2 - EndTransform.position)).costMagnitude*costFactor));
|
||||
|
||||
if (!oneWay) startNode.AddConnection(connectedNode1, (uint)Mathf.RoundToInt(((Int3)(clamped1 - StartTransform.position)).costMagnitude*costFactor));
|
||||
endNode.AddConnection(connectedNode2, (uint)Mathf.RoundToInt(((Int3)(clamped2 - EndTransform.position)).costMagnitude*costFactor));
|
||||
}
|
||||
|
||||
private readonly static Color GizmosColor = new Color(206.0f/255.0f, 136.0f/255.0f, 48.0f/255.0f, 0.5f);
|
||||
private readonly static Color GizmosColorSelected = new Color(235.0f/255.0f, 123.0f/255.0f, 32.0f/255.0f, 1.0f);
|
||||
|
||||
public virtual void OnDrawGizmosSelected () {
|
||||
OnDrawGizmos(true);
|
||||
}
|
||||
|
||||
public void OnDrawGizmos () {
|
||||
OnDrawGizmos(false);
|
||||
}
|
||||
|
||||
public void OnDrawGizmos (bool selected) {
|
||||
Color color = selected ? GizmosColorSelected : GizmosColor;
|
||||
|
||||
if (StartTransform != null) {
|
||||
Draw.Gizmos.CircleXZ(StartTransform.position, 0.4f, color);
|
||||
}
|
||||
if (EndTransform != null) {
|
||||
Draw.Gizmos.CircleXZ(EndTransform.position, 0.4f, color);
|
||||
}
|
||||
|
||||
if (StartTransform != null && EndTransform != null) {
|
||||
Draw.Gizmos.Bezier(StartTransform.position, EndTransform.position, color);
|
||||
if (selected) {
|
||||
Vector3 cross = Vector3.Cross(Vector3.up, (EndTransform.position-StartTransform.position)).normalized;
|
||||
Draw.Gizmos.Bezier(StartTransform.position+cross*0.1f, EndTransform.position+cross*0.1f, color);
|
||||
Draw.Gizmos.Bezier(StartTransform.position-cross*0.1f, EndTransform.position-cross*0.1f, color);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal static void SerializeReferences (Pathfinding.Serialization.GraphSerializationContext ctx) {
|
||||
var links = GetModifiersOfType<NodeLink2>();
|
||||
|
||||
ctx.writer.Write(links.Count);
|
||||
foreach (var link in links) {
|
||||
ctx.writer.Write(link.uniqueID);
|
||||
ctx.SerializeNodeReference(link.startNode);
|
||||
ctx.SerializeNodeReference(link.endNode);
|
||||
ctx.SerializeNodeReference(link.connectedNode1);
|
||||
ctx.SerializeNodeReference(link.connectedNode2);
|
||||
ctx.SerializeVector3(link.clamped1);
|
||||
ctx.SerializeVector3(link.clamped2);
|
||||
ctx.writer.Write(link.postScanCalled);
|
||||
}
|
||||
}
|
||||
|
||||
internal static void DeserializeReferences (Pathfinding.Serialization.GraphSerializationContext ctx) {
|
||||
int count = ctx.reader.ReadInt32();
|
||||
|
||||
for (int i = 0; i < count; i++) {
|
||||
var linkID = ctx.reader.ReadUInt64();
|
||||
var startNode = ctx.DeserializeNodeReference();
|
||||
var endNode = ctx.DeserializeNodeReference();
|
||||
var connectedNode1 = ctx.DeserializeNodeReference();
|
||||
var connectedNode2 = ctx.DeserializeNodeReference();
|
||||
var clamped1 = ctx.DeserializeVector3();
|
||||
var clamped2 = ctx.DeserializeVector3();
|
||||
var postScanCalled = ctx.reader.ReadBoolean();
|
||||
|
||||
GraphModifier link;
|
||||
if (usedIDs.TryGetValue(linkID, out link)) {
|
||||
var link2 = link as NodeLink2;
|
||||
if (link2 != null) {
|
||||
if (startNode != null) reference[startNode] = link2;
|
||||
if (endNode != null) reference[endNode] = link2;
|
||||
|
||||
// If any nodes happened to be registered right now
|
||||
if (link2.startNode != null) reference.Remove(link2.startNode);
|
||||
if (link2.endNode != null) reference.Remove(link2.endNode);
|
||||
|
||||
link2.startNode = startNode as PointNode;
|
||||
link2.endNode = endNode as PointNode;
|
||||
link2.connectedNode1 = connectedNode1;
|
||||
link2.connectedNode2 = connectedNode2;
|
||||
link2.postScanCalled = postScanCalled;
|
||||
link2.clamped1 = clamped1;
|
||||
link2.clamped2 = clamped2;
|
||||
} else {
|
||||
throw new System.Exception("Tried to deserialize a NodeLink2 reference, but the link was not of the correct type or it has been destroyed.\nIf a NodeLink2 is included in serialized graph data, the same NodeLink2 component must be present in the scene when loading the graph data.");
|
||||
}
|
||||
} else {
|
||||
throw new System.Exception("Tried to deserialize a NodeLink2 reference, but the link could not be found in the scene.\nIf a NodeLink2 is included in serialized graph data, the same NodeLink2 component must be present in the scene when loading the graph data.");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: bd2cfff5dfa8c4244aa00fea9675adb2
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
@ -0,0 +1,308 @@
|
||||
using UnityEngine;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Pathfinding {
|
||||
using Pathfinding.Util;
|
||||
|
||||
public class NodeLink3Node : PointNode {
|
||||
public NodeLink3 link;
|
||||
public Vector3 portalA;
|
||||
public Vector3 portalB;
|
||||
|
||||
public NodeLink3Node (AstarPath active) : base(active) {}
|
||||
|
||||
public override bool GetPortal (GraphNode other, List<Vector3> left, List<Vector3> right, bool backwards) {
|
||||
if (this.connections.Length < 2) return false;
|
||||
|
||||
if (this.connections.Length != 2) throw new System.Exception("Invalid NodeLink3Node. Expected 2 connections, found " + this.connections.Length);
|
||||
|
||||
if (left != null) {
|
||||
left.Add(portalA);
|
||||
right.Add(portalB);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public GraphNode GetOther (GraphNode a) {
|
||||
if (this.connections.Length < 2) return null;
|
||||
if (this.connections.Length != 2) throw new System.Exception("Invalid NodeLink3Node. Expected 2 connections, found " + this.connections.Length);
|
||||
|
||||
return a == connections[0].node ? (connections[1].node as NodeLink3Node).GetOtherInternal(this) : (connections[0].node as NodeLink3Node).GetOtherInternal(this);
|
||||
}
|
||||
|
||||
GraphNode GetOtherInternal (GraphNode a) {
|
||||
if (this.connections.Length < 2) return null;
|
||||
return a == connections[0].node ? connections[1].node : connections[0].node;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Connects two TriangleMeshNodes (recast/navmesh graphs) as if they had shared an edge.
|
||||
/// Note: Usually you do not want to use this type of link, you want to use NodeLink2 or NodeLink (sorry for the not so descriptive names).
|
||||
/// </summary>
|
||||
[AddComponentMenu("Pathfinding/Link3")]
|
||||
[HelpURL("https://arongranberg.com/astar/documentation/stable/class_pathfinding_1_1_node_link3.php")]
|
||||
public class NodeLink3 : GraphModifier {
|
||||
protected static Dictionary<GraphNode, NodeLink3> reference = new Dictionary<GraphNode, NodeLink3>();
|
||||
public static NodeLink3 GetNodeLink (GraphNode node) {
|
||||
reference.TryGetValue(node, out NodeLink3 v);
|
||||
return v;
|
||||
}
|
||||
|
||||
/// <summary>End position of the link</summary>
|
||||
public Transform end;
|
||||
|
||||
/// <summary>
|
||||
/// The connection will be this times harder/slower to traverse.
|
||||
/// Note that values lower than one will not always make the pathfinder choose this path instead of another path even though this one should
|
||||
/// lead to a lower total cost unless you also adjust the Heuristic Scale in A* Inspector -> Settings -> Pathfinding or disable the heuristic altogether.
|
||||
/// </summary>
|
||||
public float costFactor = 1.0f;
|
||||
|
||||
public Transform StartTransform {
|
||||
get { return transform; }
|
||||
}
|
||||
|
||||
public Transform EndTransform {
|
||||
get { return end; }
|
||||
}
|
||||
|
||||
NodeLink3Node startNode;
|
||||
NodeLink3Node endNode;
|
||||
MeshNode connectedNode1, connectedNode2;
|
||||
Vector3 clamped1, clamped2;
|
||||
bool postScanCalled = false;
|
||||
|
||||
public GraphNode StartNode {
|
||||
get { return startNode; }
|
||||
}
|
||||
|
||||
public GraphNode EndNode {
|
||||
get { return endNode; }
|
||||
}
|
||||
|
||||
public override void OnPostScan () {
|
||||
if (AstarPath.active.isScanning) {
|
||||
InternalOnPostScan();
|
||||
} else {
|
||||
AstarPath.active.AddWorkItem(new AstarWorkItem(force => {
|
||||
InternalOnPostScan();
|
||||
return true;
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
public void InternalOnPostScan () {
|
||||
#if !ASTAR_NO_POINT_GRAPH
|
||||
if (AstarPath.active.data.pointGraph == null) {
|
||||
AstarPath.active.data.AddGraph(typeof(PointGraph));
|
||||
}
|
||||
|
||||
//Get nearest nodes from the first point graph, assuming both start and end transforms are nodes
|
||||
startNode = AstarPath.active.data.pointGraph.AddNode(new NodeLink3Node(AstarPath.active), (Int3)StartTransform.position);
|
||||
startNode.link = this;
|
||||
endNode = AstarPath.active.data.pointGraph.AddNode(new NodeLink3Node(AstarPath.active), (Int3)EndTransform.position);
|
||||
endNode.link = this;
|
||||
#else
|
||||
throw new System.Exception("Point graphs are not included. Check your A* Optimization settings.");
|
||||
#endif
|
||||
connectedNode1 = null;
|
||||
connectedNode2 = null;
|
||||
|
||||
if (startNode == null || endNode == null) {
|
||||
startNode = null;
|
||||
endNode = null;
|
||||
return;
|
||||
}
|
||||
|
||||
postScanCalled = true;
|
||||
reference[startNode] = this;
|
||||
reference[endNode] = this;
|
||||
Apply(true);
|
||||
}
|
||||
|
||||
public override void OnGraphsPostUpdate () {
|
||||
if (!AstarPath.active.isScanning) {
|
||||
if (connectedNode1 != null && connectedNode1.Destroyed) {
|
||||
connectedNode1 = null;
|
||||
}
|
||||
if (connectedNode2 != null && connectedNode2.Destroyed) {
|
||||
connectedNode2 = null;
|
||||
}
|
||||
|
||||
if (!postScanCalled) {
|
||||
OnPostScan();
|
||||
} else {
|
||||
//OnPostScan will also call this method
|
||||
Apply(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnEnable () {
|
||||
base.OnEnable();
|
||||
|
||||
#if !ASTAR_NO_POINT_GRAPH
|
||||
if (Application.isPlaying && AstarPath.active != null && AstarPath.active.data != null && AstarPath.active.data.pointGraph != null) {
|
||||
OnGraphsPostUpdate();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
protected override void OnDisable () {
|
||||
base.OnDisable();
|
||||
|
||||
postScanCalled = false;
|
||||
|
||||
if (startNode != null) reference.Remove(startNode);
|
||||
if (endNode != null) reference.Remove(endNode);
|
||||
|
||||
if (startNode != null && endNode != null) {
|
||||
startNode.RemoveConnection(endNode);
|
||||
endNode.RemoveConnection(startNode);
|
||||
|
||||
if (connectedNode1 != null && connectedNode2 != null) {
|
||||
startNode.RemoveConnection(connectedNode1);
|
||||
connectedNode1.RemoveConnection(startNode);
|
||||
|
||||
endNode.RemoveConnection(connectedNode2);
|
||||
connectedNode2.RemoveConnection(endNode);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void RemoveConnections (GraphNode node) {
|
||||
//TODO, might be better to replace connection
|
||||
node.ClearConnections(true);
|
||||
}
|
||||
|
||||
[ContextMenu("Recalculate neighbours")]
|
||||
void ContextApplyForce () {
|
||||
if (Application.isPlaying) {
|
||||
Apply(true);
|
||||
}
|
||||
}
|
||||
|
||||
public void Apply (bool forceNewCheck) {
|
||||
//TODO
|
||||
//This function assumes that connections from the n1,n2 nodes never need to be removed in the future (e.g because the nodes move or something)
|
||||
NNConstraint nn = NNConstraint.None;
|
||||
|
||||
nn.distanceXZ = true;
|
||||
int graph = (int)startNode.GraphIndex;
|
||||
|
||||
//Search all graphs but the one which start and end nodes are on
|
||||
nn.graphMask = ~(1 << graph);
|
||||
|
||||
bool same = true;
|
||||
|
||||
{
|
||||
var info = AstarPath.active.GetNearest(StartTransform.position, nn);
|
||||
same &= info.node == connectedNode1 && info.node != null;
|
||||
connectedNode1 = info.node as MeshNode;
|
||||
clamped1 = info.position;
|
||||
if (connectedNode1 != null) Debug.DrawRay((Vector3)connectedNode1.position, Vector3.up*5, Color.red);
|
||||
}
|
||||
|
||||
{
|
||||
var info = AstarPath.active.GetNearest(EndTransform.position, nn);
|
||||
same &= info.node == connectedNode2 && info.node != null;
|
||||
connectedNode2 = info.node as MeshNode;
|
||||
clamped2 = info.position;
|
||||
if (connectedNode2 != null) Debug.DrawRay((Vector3)connectedNode2.position, Vector3.up*5, Color.cyan);
|
||||
}
|
||||
|
||||
if (connectedNode2 == null || connectedNode1 == null) return;
|
||||
|
||||
startNode.SetPosition((Int3)StartTransform.position);
|
||||
endNode.SetPosition((Int3)EndTransform.position);
|
||||
|
||||
if (same && !forceNewCheck) return;
|
||||
|
||||
RemoveConnections(startNode);
|
||||
RemoveConnections(endNode);
|
||||
|
||||
uint cost = (uint)Mathf.RoundToInt(((Int3)(StartTransform.position-EndTransform.position)).costMagnitude*costFactor);
|
||||
startNode.AddConnection(endNode, cost);
|
||||
endNode.AddConnection(startNode, cost);
|
||||
|
||||
Int3 dir = connectedNode2.position - connectedNode1.position;
|
||||
|
||||
for (int a = 0; a < connectedNode1.GetVertexCount(); a++) {
|
||||
Int3 va1 = connectedNode1.GetVertex(a);
|
||||
Int3 va2 = connectedNode1.GetVertex((a+1) % connectedNode1.GetVertexCount());
|
||||
|
||||
if (Int3.DotLong((va2-va1).Normal2D(), dir) > 0) continue;
|
||||
|
||||
for (int b = 0; b < connectedNode2.GetVertexCount(); b++) {
|
||||
Int3 vb1 = connectedNode2.GetVertex(b);
|
||||
Int3 vb2 = connectedNode2.GetVertex((b+1) % connectedNode2.GetVertexCount());
|
||||
|
||||
if (Int3.DotLong((vb2-vb1).Normal2D(), dir) < 0) continue;
|
||||
|
||||
if (Int3.Angle((vb2-vb1), (va2-va1)) > (170.0/360.0f)*Mathf.PI*2) {
|
||||
float t1 = 0;
|
||||
float t2 = 1;
|
||||
|
||||
t2 = System.Math.Min(t2, VectorMath.ClosestPointOnLineFactor(va1, va2, vb1));
|
||||
t1 = System.Math.Max(t1, VectorMath.ClosestPointOnLineFactor(va1, va2, vb2));
|
||||
|
||||
if (t2 < t1) {
|
||||
Debug.LogError("Something went wrong! " + t1 + " " + t2 + " " + va1 + " " + va2 + " " + vb1 + " " + vb2+"\nTODO, how can this happen?");
|
||||
} else {
|
||||
Vector3 pa = (Vector3)(va2-va1)*t1 + (Vector3)va1;
|
||||
Vector3 pb = (Vector3)(va2-va1)*t2 + (Vector3)va1;
|
||||
|
||||
startNode.portalA = pa;
|
||||
startNode.portalB = pb;
|
||||
|
||||
endNode.portalA = pb;
|
||||
endNode.portalB = pa;
|
||||
|
||||
//Add connections between nodes, or replace old connections if existing
|
||||
connectedNode1.AddConnection(startNode, (uint)Mathf.RoundToInt(((Int3)(clamped1 - StartTransform.position)).costMagnitude*costFactor));
|
||||
connectedNode2.AddConnection(endNode, (uint)Mathf.RoundToInt(((Int3)(clamped2 - EndTransform.position)).costMagnitude*costFactor));
|
||||
|
||||
startNode.AddConnection(connectedNode1, (uint)Mathf.RoundToInt(((Int3)(clamped1 - StartTransform.position)).costMagnitude*costFactor));
|
||||
endNode.AddConnection(connectedNode2, (uint)Mathf.RoundToInt(((Int3)(clamped2 - EndTransform.position)).costMagnitude*costFactor));
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private readonly static Color GizmosColor = new Color(206.0f/255.0f, 136.0f/255.0f, 48.0f/255.0f, 0.5f);
|
||||
private readonly static Color GizmosColorSelected = new Color(235.0f/255.0f, 123.0f/255.0f, 32.0f/255.0f, 1.0f);
|
||||
|
||||
public virtual void OnDrawGizmosSelected () {
|
||||
OnDrawGizmos(true);
|
||||
}
|
||||
|
||||
public void OnDrawGizmos () {
|
||||
OnDrawGizmos(false);
|
||||
}
|
||||
|
||||
public void OnDrawGizmos (bool selected) {
|
||||
Color col = selected ? GizmosColorSelected : GizmosColor;
|
||||
|
||||
if (StartTransform != null) {
|
||||
Draw.Gizmos.CircleXZ(StartTransform.position, 0.4f, col);
|
||||
}
|
||||
if (EndTransform != null) {
|
||||
Draw.Gizmos.CircleXZ(EndTransform.position, 0.4f, col);
|
||||
}
|
||||
|
||||
if (StartTransform != null && EndTransform != null) {
|
||||
Draw.Gizmos.Bezier(StartTransform.position, EndTransform.position, col);
|
||||
if (selected) {
|
||||
Vector3 cross = Vector3.Cross(Vector3.up, (EndTransform.position-StartTransform.position)).normalized;
|
||||
Draw.Gizmos.Bezier(StartTransform.position+cross*0.1f, EndTransform.position+cross*0.1f, col);
|
||||
Draw.Gizmos.Bezier(StartTransform.position-cross*0.1f, EndTransform.position-cross*0.1f, col);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3850d0dc2bead45568e6b5bbcc011606
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
@ -0,0 +1,206 @@
|
||||
using UnityEngine;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Pathfinding.Util {
|
||||
/// <summary>Interpolates along a sequence of points</summary>
|
||||
public class PathInterpolator {
|
||||
List<Vector3> path;
|
||||
|
||||
float distanceToSegmentStart;
|
||||
float currentDistance;
|
||||
float currentSegmentLength = float.PositiveInfinity;
|
||||
float totalDistance = float.PositiveInfinity;
|
||||
|
||||
/// <summary>Current position</summary>
|
||||
public virtual Vector3 position {
|
||||
get {
|
||||
float t = currentSegmentLength > 0.0001f ? (currentDistance - distanceToSegmentStart) / currentSegmentLength : 0f;
|
||||
return Vector3.Lerp(path[segmentIndex], path[segmentIndex+1], t);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Last point in the path</summary>
|
||||
public Vector3 endPoint {
|
||||
get {
|
||||
return path[path.Count-1];
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Tangent of the curve at the current position</summary>
|
||||
public Vector3 tangent {
|
||||
get {
|
||||
return path[segmentIndex+1] - path[segmentIndex];
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Remaining distance until the end of the path</summary>
|
||||
public float remainingDistance {
|
||||
get {
|
||||
return totalDistance - distance;
|
||||
}
|
||||
set {
|
||||
distance = totalDistance - value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Traversed distance from the start of the path</summary>
|
||||
public float distance {
|
||||
get {
|
||||
return currentDistance;
|
||||
}
|
||||
set {
|
||||
currentDistance = value;
|
||||
|
||||
while (currentDistance < distanceToSegmentStart && segmentIndex > 0) PrevSegment();
|
||||
while (currentDistance > distanceToSegmentStart + currentSegmentLength && segmentIndex < path.Count - 2) NextSegment();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Current segment.
|
||||
/// The start and end points of the segment are path[value] and path[value+1].
|
||||
/// </summary>
|
||||
public int segmentIndex { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// True if this instance has a path set.
|
||||
/// See: SetPath
|
||||
/// </summary>
|
||||
public bool valid {
|
||||
get {
|
||||
return path != null;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Appends the remaining path between <see cref="position"/> and <see cref="endPoint"/> to buffer</summary>
|
||||
public void GetRemainingPath (List<Vector3> buffer) {
|
||||
if (!valid) throw new System.Exception("PathInterpolator is not valid");
|
||||
buffer.Add(position);
|
||||
for (int i = segmentIndex+1; i < path.Count; i++) {
|
||||
buffer.Add(path[i]);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Set the path to interpolate along.
|
||||
/// This will reset all interpolation variables.
|
||||
/// </summary>
|
||||
public void SetPath (List<Vector3> path) {
|
||||
this.path = path;
|
||||
currentDistance = 0;
|
||||
segmentIndex = 0;
|
||||
distanceToSegmentStart = 0;
|
||||
|
||||
if (path == null) {
|
||||
totalDistance = float.PositiveInfinity;
|
||||
currentSegmentLength = float.PositiveInfinity;
|
||||
return;
|
||||
}
|
||||
|
||||
if (path.Count < 2) throw new System.ArgumentException("Path must have a length of at least 2");
|
||||
|
||||
currentSegmentLength = (path[1] - path[0]).magnitude;
|
||||
totalDistance = 0f;
|
||||
|
||||
var prev = path[0];
|
||||
for (int i = 1; i < path.Count; i++) {
|
||||
var current = path[i];
|
||||
totalDistance += (current - prev).magnitude;
|
||||
prev = current;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Move to the specified segment and move a fraction of the way to the next segment</summary>
|
||||
public void MoveToSegment (int index, float fractionAlongSegment) {
|
||||
if (path == null) return;
|
||||
if (index < 0 || index >= path.Count - 1) throw new System.ArgumentOutOfRangeException("index");
|
||||
while (segmentIndex > index) PrevSegment();
|
||||
while (segmentIndex < index) NextSegment();
|
||||
distance = distanceToSegmentStart + Mathf.Clamp01(fractionAlongSegment) * currentSegmentLength;
|
||||
}
|
||||
|
||||
/// <summary>Move as close as possible to the specified point</summary>
|
||||
public void MoveToClosestPoint (Vector3 point) {
|
||||
if (path == null) return;
|
||||
|
||||
float bestDist = float.PositiveInfinity;
|
||||
float bestFactor = 0f;
|
||||
int bestIndex = 0;
|
||||
|
||||
for (int i = 0; i < path.Count-1; i++) {
|
||||
float factor = VectorMath.ClosestPointOnLineFactor(path[i], path[i+1], point);
|
||||
Vector3 closest = Vector3.Lerp(path[i], path[i+1], factor);
|
||||
float dist = (point - closest).sqrMagnitude;
|
||||
|
||||
if (dist < bestDist) {
|
||||
bestDist = dist;
|
||||
bestFactor = factor;
|
||||
bestIndex = i;
|
||||
}
|
||||
}
|
||||
|
||||
MoveToSegment(bestIndex, bestFactor);
|
||||
}
|
||||
|
||||
public void MoveToLocallyClosestPoint (Vector3 point, bool allowForwards = true, bool allowBackwards = true) {
|
||||
if (path == null) return;
|
||||
|
||||
while (allowForwards && segmentIndex < path.Count - 2 && (path[segmentIndex+1] - point).sqrMagnitude <= (path[segmentIndex] - point).sqrMagnitude) {
|
||||
NextSegment();
|
||||
}
|
||||
|
||||
while (allowBackwards && segmentIndex > 0 && (path[segmentIndex-1] - point).sqrMagnitude <= (path[segmentIndex] - point).sqrMagnitude) {
|
||||
PrevSegment();
|
||||
}
|
||||
|
||||
// Check the distances to the two segments extending from the vertex path[segmentIndex]
|
||||
// and pick the position on those segments that is closest to the #point parameter.
|
||||
float factor1 = 0, factor2 = 0, d1 = float.PositiveInfinity, d2 = float.PositiveInfinity;
|
||||
if (segmentIndex > 0) {
|
||||
factor1 = VectorMath.ClosestPointOnLineFactor(path[segmentIndex-1], path[segmentIndex], point);
|
||||
d1 = (Vector3.Lerp(path[segmentIndex-1], path[segmentIndex], factor1) - point).sqrMagnitude;
|
||||
}
|
||||
|
||||
if (segmentIndex < path.Count - 1) {
|
||||
factor2 = VectorMath.ClosestPointOnLineFactor(path[segmentIndex], path[segmentIndex+1], point);
|
||||
d2 = (Vector3.Lerp(path[segmentIndex], path[segmentIndex+1], factor2) - point).sqrMagnitude;
|
||||
}
|
||||
|
||||
if (d1 < d2) MoveToSegment(segmentIndex - 1, factor1);
|
||||
else MoveToSegment(segmentIndex, factor2);
|
||||
}
|
||||
|
||||
public void MoveToCircleIntersection2D (Vector3 circleCenter3D, float radius, IMovementPlane transform) {
|
||||
if (path == null) return;
|
||||
|
||||
// Move forwards as long as we are getting closer to circleCenter3D
|
||||
while (segmentIndex < path.Count - 2 && VectorMath.ClosestPointOnLineFactor(path[segmentIndex], path[segmentIndex+1], circleCenter3D) > 1) {
|
||||
NextSegment();
|
||||
}
|
||||
|
||||
var circleCenter = transform.ToPlane(circleCenter3D);
|
||||
|
||||
// Move forwards as long as the current segment endpoint is within the circle
|
||||
while (segmentIndex < path.Count - 2 && (transform.ToPlane(path[segmentIndex+1]) - circleCenter).sqrMagnitude <= radius*radius) {
|
||||
NextSegment();
|
||||
}
|
||||
|
||||
// Calculate the intersection with the circle. This involves some math.
|
||||
var factor = VectorMath.LineCircleIntersectionFactor(circleCenter, transform.ToPlane(path[segmentIndex]), transform.ToPlane(path[segmentIndex+1]), radius);
|
||||
// Move to the intersection point
|
||||
MoveToSegment(segmentIndex, factor);
|
||||
}
|
||||
|
||||
protected virtual void PrevSegment () {
|
||||
segmentIndex--;
|
||||
currentSegmentLength = (path[segmentIndex+1] - path[segmentIndex]).magnitude;
|
||||
distanceToSegmentStart -= currentSegmentLength;
|
||||
}
|
||||
|
||||
protected virtual void NextSegment () {
|
||||
segmentIndex++;
|
||||
distanceToSegmentStart += currentSegmentLength;
|
||||
currentSegmentLength = (path[segmentIndex+1] - path[segmentIndex]).magnitude;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9c0392dbc5e744ee28e7b9ee81aea1e2
|
||||
timeCreated: 1490125383
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,551 @@
|
||||
using UnityEngine;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
using UnityEngine.Profiling;
|
||||
|
||||
namespace Pathfinding {
|
||||
#if NETFX_CORE
|
||||
using Thread = Pathfinding.WindowsStore.Thread;
|
||||
#else
|
||||
using Thread = System.Threading.Thread;
|
||||
#endif
|
||||
|
||||
public class PathProcessor {
|
||||
public event System.Action<Path> OnPathPreSearch;
|
||||
public event System.Action<Path> OnPathPostSearch;
|
||||
public event System.Action OnQueueUnblocked;
|
||||
|
||||
internal readonly ThreadControlQueue queue;
|
||||
readonly AstarPath astar;
|
||||
readonly PathReturnQueue returnQueue;
|
||||
|
||||
readonly PathHandler[] pathHandlers;
|
||||
|
||||
/// <summary>References to each of the pathfinding threads</summary>
|
||||
readonly Thread[] threads;
|
||||
|
||||
/// <summary>
|
||||
/// When no multithreading is used, the IEnumerator is stored here.
|
||||
/// When no multithreading is used, a coroutine is used instead. It is not directly called with StartCoroutine
|
||||
/// but a separate function has just a while loop which increments the main IEnumerator.
|
||||
/// This is done so other functions can step the thread forward at any time, without having to wait for Unity to update it.
|
||||
/// See: CalculatePaths
|
||||
/// See: CalculatePathsHandler
|
||||
/// </summary>
|
||||
IEnumerator threadCoroutine;
|
||||
|
||||
/// <summary>
|
||||
/// Holds the next node index which has not been used by any previous node.
|
||||
/// See: nodeIndexPool
|
||||
/// </summary>
|
||||
int nextNodeIndex = 1;
|
||||
|
||||
/// <summary>
|
||||
/// Holds indices for nodes that have been destroyed.
|
||||
/// To avoid trashing a lot of memory structures when nodes are
|
||||
/// frequently deleted and created, node indices are reused.
|
||||
/// </summary>
|
||||
readonly Stack<int> nodeIndexPool = new Stack<int>();
|
||||
|
||||
readonly List<int> locks = new List<int>();
|
||||
int nextLockID = 0;
|
||||
|
||||
#if UNITY_2017_3_OR_NEWER
|
||||
CustomSampler profilingSampler;
|
||||
#endif
|
||||
|
||||
/// <summary>
|
||||
/// Number of parallel pathfinders.
|
||||
/// Returns the number of concurrent processes which can calculate paths at once.
|
||||
/// When using multithreading, this will be the number of threads, if not using multithreading it is always 1 (since only 1 coroutine is used).
|
||||
/// See: threadInfos
|
||||
/// See: IsUsingMultithreading
|
||||
/// </summary>
|
||||
public int NumThreads {
|
||||
get {
|
||||
return pathHandlers.Length;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Returns whether or not multithreading is used</summary>
|
||||
public bool IsUsingMultithreading {
|
||||
get {
|
||||
return threads != null;
|
||||
}
|
||||
}
|
||||
|
||||
internal PathProcessor (AstarPath astar, PathReturnQueue returnQueue, int processors, bool multithreaded) {
|
||||
this.astar = astar;
|
||||
this.returnQueue = returnQueue;
|
||||
|
||||
if (processors < 0) {
|
||||
throw new System.ArgumentOutOfRangeException("processors");
|
||||
}
|
||||
|
||||
if (!multithreaded && processors != 1) {
|
||||
throw new System.Exception("Only a single non-multithreaded processor is allowed");
|
||||
}
|
||||
|
||||
// Set up path queue with the specified number of receivers
|
||||
queue = new ThreadControlQueue(processors);
|
||||
pathHandlers = new PathHandler[processors];
|
||||
|
||||
for (int i = 0; i < processors; i++) {
|
||||
pathHandlers[i] = new PathHandler(i, processors);
|
||||
}
|
||||
|
||||
if (multithreaded) {
|
||||
#if UNITY_2017_3_OR_NEWER
|
||||
profilingSampler = CustomSampler.Create("Calculating Path");
|
||||
#endif
|
||||
|
||||
threads = new Thread[processors];
|
||||
|
||||
// Start lots of threads
|
||||
for (int i = 0; i < processors; i++) {
|
||||
var pathHandler = pathHandlers[i];
|
||||
threads[i] = new Thread(() => CalculatePathsThreaded(pathHandler));
|
||||
#if !UNITY_SWITCH || UNITY_EDITOR
|
||||
// Note: Setting the thread name seems to crash when deploying for Switch: https://forum.arongranberg.com/t/path-processor-crashing-nintendo-switch-build/6584
|
||||
threads[i].Name = "Pathfinding Thread " + i;
|
||||
#endif
|
||||
threads[i].IsBackground = true;
|
||||
threads[i].Start();
|
||||
}
|
||||
} else {
|
||||
// Start coroutine if not using multithreading
|
||||
threadCoroutine = CalculatePaths(pathHandlers[0]);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Prevents pathfinding from running while held</summary>
|
||||
public struct GraphUpdateLock {
|
||||
PathProcessor pathProcessor;
|
||||
int id;
|
||||
|
||||
public GraphUpdateLock (PathProcessor pathProcessor, bool block) {
|
||||
this.pathProcessor = pathProcessor;
|
||||
Profiler.BeginSample("Pausing pathfinding");
|
||||
id = pathProcessor.Lock(block);
|
||||
Profiler.EndSample();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// True while this lock is preventing the pathfinding threads from processing more paths.
|
||||
/// Note that the pathfinding threads may not be paused yet (if this lock was obtained using PausePathfinding(false)).
|
||||
/// </summary>
|
||||
public bool Held {
|
||||
get {
|
||||
return pathProcessor != null && pathProcessor.locks.Contains(id);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Allow pathfinding to start running again if no other locks are still held</summary>
|
||||
public void Release () {
|
||||
pathProcessor.Unlock(id);
|
||||
}
|
||||
}
|
||||
|
||||
int Lock (bool block) {
|
||||
queue.Block();
|
||||
|
||||
if (block) {
|
||||
while (!queue.AllReceiversBlocked) {
|
||||
if (IsUsingMultithreading) {
|
||||
Thread.Sleep(1);
|
||||
} else {
|
||||
TickNonMultithreaded();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
nextLockID++;
|
||||
locks.Add(nextLockID);
|
||||
return nextLockID;
|
||||
}
|
||||
|
||||
void Unlock (int id) {
|
||||
if (!locks.Remove(id)) {
|
||||
throw new System.ArgumentException("This lock has already been released");
|
||||
}
|
||||
|
||||
// Check if there are no remaining active locks
|
||||
if (locks.Count == 0) {
|
||||
if (OnQueueUnblocked != null) OnQueueUnblocked();
|
||||
|
||||
queue.Unblock();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Prevents pathfinding threads from starting to calculate any new paths.
|
||||
///
|
||||
/// Returns: A lock object. You need to call Unlock on that object to allow pathfinding to resume.
|
||||
///
|
||||
/// Note: In most cases this should not be called from user code.
|
||||
/// </summary>
|
||||
/// <param name="block">If true, this call will block until all pathfinding threads are paused.
|
||||
/// otherwise the threads will be paused as soon as they are done with what they are currently doing.</param>
|
||||
public GraphUpdateLock PausePathfinding (bool block) {
|
||||
return new GraphUpdateLock(this, block);
|
||||
}
|
||||
|
||||
public void TickNonMultithreaded () {
|
||||
// Process paths
|
||||
if (threadCoroutine != null) {
|
||||
try {
|
||||
threadCoroutine.MoveNext();
|
||||
} catch (System.Exception e) {
|
||||
//This will kill pathfinding
|
||||
threadCoroutine = null;
|
||||
|
||||
// Queue termination exceptions should be ignored, they are supposed to kill the thread
|
||||
if (!(e is ThreadControlQueue.QueueTerminationException)) {
|
||||
Debug.LogException(e);
|
||||
Debug.LogError("Unhandled exception during pathfinding. Terminating.");
|
||||
queue.TerminateReceivers();
|
||||
|
||||
// This will throw an exception supposed to kill the thread
|
||||
try {
|
||||
queue.PopNoBlock(false);
|
||||
} catch {}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Calls 'Join' on each of the threads to block until they have completed</summary>
|
||||
public void JoinThreads () {
|
||||
if (threads != null) {
|
||||
for (int i = 0; i < threads.Length; i++) {
|
||||
if (!threads[i].Join(200)) {
|
||||
Debug.LogError("Could not terminate pathfinding thread["+i+"] in 200ms, trying Thread.Abort");
|
||||
threads[i].Abort();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Calls 'Abort' on each of the threads</summary>
|
||||
public void AbortThreads () {
|
||||
if (threads == null) return;
|
||||
for (int i = 0; i < threads.Length; i++) {
|
||||
if (threads[i] != null && threads[i].IsAlive) threads[i].Abort();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a new global node index.
|
||||
/// Warning: This method should not be called directly. It is used by the GraphNode constructor.
|
||||
/// </summary>
|
||||
public int GetNewNodeIndex () {
|
||||
return nodeIndexPool.Count > 0 ? nodeIndexPool.Pop() : nextNodeIndex++;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes temporary path data for a node.
|
||||
/// Warning: This method should not be called directly. It is used by the GraphNode constructor.
|
||||
/// </summary>
|
||||
public void InitializeNode (GraphNode node) {
|
||||
if (!queue.AllReceiversBlocked) {
|
||||
throw new System.Exception("Trying to initialize a node when it is not safe to initialize any nodes. Must be done during a graph update. See https://arongranberg.com/astar/docs/graphupdates.html#direct");
|
||||
}
|
||||
|
||||
for (int i = 0; i < pathHandlers.Length; i++) {
|
||||
pathHandlers[i].InitializeNode(node);
|
||||
}
|
||||
|
||||
astar.hierarchicalGraph.OnCreatedNode(node);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Destroyes the given node.
|
||||
/// This is to be called after the node has been disconnected from the graph so that it cannot be reached from any other nodes.
|
||||
/// It should only be called during graph updates, that is when the pathfinding threads are either not running or paused.
|
||||
///
|
||||
/// Warning: This method should not be called by user code. It is used internally by the system.
|
||||
/// </summary>
|
||||
public void DestroyNode (GraphNode node) {
|
||||
if (node.NodeIndex == -1) return;
|
||||
|
||||
nodeIndexPool.Push(node.NodeIndex);
|
||||
|
||||
for (int i = 0; i < pathHandlers.Length; i++) {
|
||||
pathHandlers[i].DestroyNode(node);
|
||||
}
|
||||
|
||||
astar.hierarchicalGraph.AddDirtyNode(node);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Main pathfinding method (multithreaded).
|
||||
/// This method will calculate the paths in the pathfinding queue when multithreading is enabled.
|
||||
///
|
||||
/// See: CalculatePaths
|
||||
/// See: StartPath
|
||||
/// </summary>
|
||||
void CalculatePathsThreaded (PathHandler pathHandler) {
|
||||
#if UNITY_2017_3_OR_NEWER
|
||||
UnityEngine.Profiling.Profiler.BeginThreadProfiling("Pathfinding", "Pathfinding thread #" + (pathHandler.threadID+1));
|
||||
#endif
|
||||
|
||||
#if !ASTAR_FAST_BUT_NO_EXCEPTIONS
|
||||
try {
|
||||
#endif
|
||||
|
||||
// Max number of ticks we are allowed to continue working in one run.
|
||||
// One tick is 1/10000 of a millisecond.
|
||||
// We need to check once in a while if the thread should be stopped.
|
||||
long maxTicks = (long)(10*10000);
|
||||
long targetTick = System.DateTime.UtcNow.Ticks + maxTicks;
|
||||
while (true) {
|
||||
// The path we are currently calculating
|
||||
Path path = queue.Pop();
|
||||
#if UNITY_2017_3_OR_NEWER
|
||||
profilingSampler.Begin();
|
||||
#endif
|
||||
// Access the internal implementation methods
|
||||
IPathInternals ipath = (IPathInternals)path;
|
||||
|
||||
|
||||
ipath.PrepareBase(pathHandler);
|
||||
|
||||
// Now processing the path
|
||||
// Will advance to Processing
|
||||
ipath.AdvanceState(PathState.Processing);
|
||||
|
||||
// Call some callbacks
|
||||
if (OnPathPreSearch != null) {
|
||||
OnPathPreSearch(path);
|
||||
}
|
||||
|
||||
// Tick for when the path started, used for calculating how long time the calculation took
|
||||
long startTicks = System.DateTime.UtcNow.Ticks;
|
||||
|
||||
// Prepare the path
|
||||
ipath.Prepare();
|
||||
|
||||
|
||||
if (path.CompleteState == PathCompleteState.NotCalculated) {
|
||||
// For visualization purposes, we set the last computed path to p, so we can view debug info on it in the editor (scene view).
|
||||
astar.debugPathData = ipath.PathHandler;
|
||||
astar.debugPathID = path.pathID;
|
||||
|
||||
|
||||
// Initialize the path, now ready to begin search
|
||||
ipath.Initialize();
|
||||
|
||||
|
||||
// Loop while the path has not been fully calculated
|
||||
while (path.CompleteState == PathCompleteState.NotCalculated) {
|
||||
// Do some work on the path calculation.
|
||||
// The function will return when it has taken too much time
|
||||
// or when it has finished calculation
|
||||
ipath.CalculateStep(targetTick);
|
||||
|
||||
targetTick = System.DateTime.UtcNow.Ticks + maxTicks;
|
||||
|
||||
// Cancel function (and thus the thread) if no more paths should be accepted.
|
||||
// This is done when the A* object is about to be destroyed
|
||||
// The path is returned and then this function will be terminated
|
||||
if (queue.IsTerminating) {
|
||||
path.FailWithError("AstarPath object destroyed");
|
||||
}
|
||||
}
|
||||
|
||||
path.duration = (System.DateTime.UtcNow.Ticks - startTicks)*0.0001F;
|
||||
|
||||
#if ProfileAstar
|
||||
System.Threading.Interlocked.Increment(ref AstarPath.PathsCompleted);
|
||||
System.Threading.Interlocked.Add(ref AstarPath.TotalSearchTime, System.DateTime.UtcNow.Ticks - startTicks);
|
||||
#endif
|
||||
}
|
||||
|
||||
// Cleans up node tagging and other things
|
||||
ipath.Cleanup();
|
||||
|
||||
|
||||
if (path.immediateCallback != null) path.immediateCallback(path);
|
||||
|
||||
if (OnPathPostSearch != null) {
|
||||
OnPathPostSearch(path);
|
||||
}
|
||||
|
||||
// Push the path onto the return stack
|
||||
// It will be detected by the main Unity thread and returned as fast as possible (the next late update hopefully)
|
||||
returnQueue.Enqueue(path);
|
||||
|
||||
// Will advance to ReturnQueue
|
||||
ipath.AdvanceState(PathState.ReturnQueue);
|
||||
|
||||
#if UNITY_2017_3_OR_NEWER
|
||||
profilingSampler.End();
|
||||
#endif
|
||||
}
|
||||
#if !ASTAR_FAST_BUT_NO_EXCEPTIONS
|
||||
}
|
||||
catch (System.Exception e) {
|
||||
#if !NETFX_CORE
|
||||
if (e is ThreadAbortException || e is ThreadControlQueue.QueueTerminationException)
|
||||
#else
|
||||
if (e is ThreadControlQueue.QueueTerminationException)
|
||||
#endif
|
||||
{
|
||||
if (astar.logPathResults == PathLog.Heavy)
|
||||
Debug.LogWarning("Shutting down pathfinding thread #" + pathHandler.threadID);
|
||||
return;
|
||||
}
|
||||
Debug.LogException(e);
|
||||
Debug.LogError("Unhandled exception during pathfinding. Terminating.");
|
||||
// Unhandled exception, kill pathfinding
|
||||
queue.TerminateReceivers();
|
||||
} finally {
|
||||
#if UNITY_2017_3_OR_NEWER
|
||||
UnityEngine.Profiling.Profiler.EndThreadProfiling();
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
Debug.LogError("Error : This part should never be reached.");
|
||||
queue.ReceiverTerminated();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Main pathfinding method.
|
||||
/// This method will calculate the paths in the pathfinding queue.
|
||||
///
|
||||
/// See: CalculatePathsThreaded
|
||||
/// See: StartPath
|
||||
/// </summary>
|
||||
IEnumerator CalculatePaths (PathHandler pathHandler) {
|
||||
// Max number of ticks before yielding/sleeping
|
||||
long maxTicks = (long)(astar.maxFrameTime*10000);
|
||||
long targetTick = System.DateTime.UtcNow.Ticks + maxTicks;
|
||||
|
||||
while (true) {
|
||||
// The path we are currently calculating
|
||||
Path p = null;
|
||||
|
||||
|
||||
// Try to get the next path to be calculated
|
||||
bool blockedBefore = false;
|
||||
while (p == null) {
|
||||
try {
|
||||
p = queue.PopNoBlock(blockedBefore);
|
||||
blockedBefore |= p == null;
|
||||
} catch (ThreadControlQueue.QueueTerminationException) {
|
||||
yield break;
|
||||
}
|
||||
|
||||
if (p == null) {
|
||||
yield return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
IPathInternals ip = (IPathInternals)p;
|
||||
|
||||
// Max number of ticks we are allowed to continue working in one run
|
||||
// One tick is 1/10000 of a millisecond
|
||||
maxTicks = (long)(astar.maxFrameTime*10000);
|
||||
|
||||
ip.PrepareBase(pathHandler);
|
||||
|
||||
// Now processing the path
|
||||
// Will advance to Processing
|
||||
ip.AdvanceState(PathState.Processing);
|
||||
|
||||
// Call some callbacks
|
||||
// It needs to be stored in a local variable to avoid race conditions
|
||||
var tmpOnPathPreSearch = OnPathPreSearch;
|
||||
if (tmpOnPathPreSearch != null) tmpOnPathPreSearch(p);
|
||||
|
||||
// Tick for when the path started, used for calculating how long time the calculation took
|
||||
long startTicks = System.DateTime.UtcNow.Ticks;
|
||||
long totalTicks = 0;
|
||||
|
||||
|
||||
//Prepare the path
|
||||
ip.Prepare();
|
||||
|
||||
// Check if the Prepare call caused the path to complete
|
||||
// If this happens the path usually failed
|
||||
if (p.CompleteState == PathCompleteState.NotCalculated) {
|
||||
// For debug uses, we set the last computed path to p, so we can view debug info on it in the editor (scene view).
|
||||
astar.debugPathData = ip.PathHandler;
|
||||
astar.debugPathID = p.pathID;
|
||||
|
||||
// Initialize the path, now ready to begin search
|
||||
ip.Initialize();
|
||||
|
||||
// The error can turn up in the Init function
|
||||
while (p.CompleteState == PathCompleteState.NotCalculated) {
|
||||
// Do some work on the path calculation.
|
||||
// The function will return when it has taken too much time
|
||||
// or when it has finished calculation
|
||||
|
||||
ip.CalculateStep(targetTick);
|
||||
|
||||
|
||||
// If the path has finished calculation, we can break here directly instead of sleeping
|
||||
// Improves latency
|
||||
if (p.CompleteState != PathCompleteState.NotCalculated) break;
|
||||
|
||||
totalTicks += System.DateTime.UtcNow.Ticks-startTicks;
|
||||
// Yield/sleep so other threads can work
|
||||
|
||||
yield return null;
|
||||
|
||||
startTicks = System.DateTime.UtcNow.Ticks;
|
||||
|
||||
// Cancel function (and thus the thread) if no more paths should be accepted.
|
||||
// This is done when the A* object is about to be destroyed
|
||||
// The path is returned and then this function will be terminated (see similar IF statement higher up in the function)
|
||||
if (queue.IsTerminating) {
|
||||
p.FailWithError("AstarPath object destroyed");
|
||||
}
|
||||
|
||||
targetTick = System.DateTime.UtcNow.Ticks + maxTicks;
|
||||
}
|
||||
|
||||
totalTicks += System.DateTime.UtcNow.Ticks-startTicks;
|
||||
p.duration = totalTicks*0.0001F;
|
||||
|
||||
#if ProfileAstar
|
||||
System.Threading.Interlocked.Increment(ref AstarPath.PathsCompleted);
|
||||
#endif
|
||||
}
|
||||
|
||||
// Cleans up node tagging and other things
|
||||
ip.Cleanup();
|
||||
|
||||
|
||||
// Call the immediate callback
|
||||
// It needs to be stored in a local variable to avoid race conditions
|
||||
var tmpImmediateCallback = p.immediateCallback;
|
||||
if (tmpImmediateCallback != null) tmpImmediateCallback(p);
|
||||
|
||||
|
||||
// It needs to be stored in a local variable to avoid race conditions
|
||||
var tmpOnPathPostSearch = OnPathPostSearch;
|
||||
if (tmpOnPathPostSearch != null) tmpOnPathPostSearch(p);
|
||||
|
||||
|
||||
// Push the path onto the return stack
|
||||
// It will be detected by the main Unity thread and returned as fast as possible (the next late update)
|
||||
returnQueue.Enqueue(p);
|
||||
|
||||
ip.AdvanceState(PathState.ReturnQueue);
|
||||
|
||||
|
||||
// Wait a bit if we have calculated a lot of paths
|
||||
if (System.DateTime.UtcNow.Ticks > targetTick) {
|
||||
yield return null;
|
||||
targetTick = System.DateTime.UtcNow.Ticks + maxTicks;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user