mirror of
https://gitee.com/jisol/jisol-game/
synced 2025-06-26 11:24:46 +00:00
提交Unity 联机Pro
This commit is contained in:
parent
f00193b000
commit
894100ae37
3
JNFrame2/.gitignore
vendored
Normal file
3
JNFrame2/.gitignore
vendored
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
Library/
|
||||||
|
Temp/
|
||||||
|
APK/
|
822
JNFrame2/AimingRig.csproj
Normal file
822
JNFrame2/AimingRig.csproj
Normal file
@ -0,0 +1,822 @@
|
|||||||
|
<?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>{7e65388c-f6a7-49e7-107c-67d307ad886b}</ProjectGuid>
|
||||||
|
<ProjectTypeGuids>{E097FAD1-6243-4DAD-9C02-E9B9EFC3FFC1};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
|
||||||
|
<OutputType>Library</OutputType>
|
||||||
|
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||||
|
<AssemblyName>AimingRig</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\AimingRig\</OutputPath>
|
||||||
|
<DefineConstants>UNITY_2021_3_35;UNITY_2021_3;UNITY_2021;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;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_UNET;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_UNET;ENABLE_CLOUD_SERVICES_BUILD;ENABLE_CLOUD_LICENSE;ENABLE_EDITOR_HUB_LICENSE;ENABLE_WEBSOCKET_CLIENT;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;PLATFORM_STANDALONE;TEXTCORE_1_0_OR_NEWER;PLATFORM_STANDALONE_WIN;UNITY_STANDALONE_WIN;UNITY_STANDALONE;ENABLE_RUNTIME_GI;ENABLE_MOVIES;ENABLE_NETWORK;ENABLE_NVIDIA;ENABLE_CRUNCH_TEXTURE_COMPRESSION;ENABLE_UNITY_GAME_SERVICES_ANALYTICS_SUPPORT;ENABLE_OUT_OF_PROCESS_CRASH_HANDLER;ENABLE_CLUSTER_SYNC;ENABLE_CLUSTERINPUT;PLATFORM_UPDATES_TIME_OUTSIDE_OF_PLAYER_LOOP;GFXDEVICE_WAITFOREVENT_MESSAGEPUMP;ENABLE_WEBSOCKET_HOST;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;CINEMACHINE_UGUI;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>
|
||||||
|
<Compile Include="Assets\Samples\Cinemachine\2.10.1\Cinemachine Example Scenes\Scenes\AimingRig\AimReticle.cs" />
|
||||||
|
<None Include="Assets\Samples\Cinemachine\2.10.1\Cinemachine Example Scenes\Scenes\AimingRig\AimingRig.asmdef" />
|
||||||
|
<Reference Include="UnityEngine">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\Managed\UnityEngine\UnityEngine.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="UnityEngine.AIModule">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\Managed\UnityEngine\UnityEngine.AIModule.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="UnityEngine.ARModule">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\Managed\UnityEngine\UnityEngine.ARModule.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="UnityEngine.AccessibilityModule">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\Managed\UnityEngine\UnityEngine.AccessibilityModule.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="UnityEngine.AndroidJNIModule">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\Managed\UnityEngine\UnityEngine.AndroidJNIModule.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="UnityEngine.AnimationModule">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\Managed\UnityEngine\UnityEngine.AnimationModule.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="UnityEngine.AssetBundleModule">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\Managed\UnityEngine\UnityEngine.AssetBundleModule.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="UnityEngine.AudioModule">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\Managed\UnityEngine\UnityEngine.AudioModule.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="UnityEngine.ClothModule">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\Managed\UnityEngine\UnityEngine.ClothModule.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="UnityEngine.ClusterInputModule">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\Managed\UnityEngine\UnityEngine.ClusterInputModule.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="UnityEngine.ClusterRendererModule">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\Managed\UnityEngine\UnityEngine.ClusterRendererModule.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="UnityEngine.CoreModule">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\Managed\UnityEngine\UnityEngine.CoreModule.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="UnityEngine.CrashReportingModule">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\Managed\UnityEngine\UnityEngine.CrashReportingModule.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="UnityEngine.DSPGraphModule">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\Managed\UnityEngine\UnityEngine.DSPGraphModule.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="UnityEngine.DirectorModule">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\Managed\UnityEngine\UnityEngine.DirectorModule.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="UnityEngine.GIModule">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\Managed\UnityEngine\UnityEngine.GIModule.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="UnityEngine.GameCenterModule">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\Managed\UnityEngine\UnityEngine.GameCenterModule.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="UnityEngine.GridModule">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\Managed\UnityEngine\UnityEngine.GridModule.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="UnityEngine.HotReloadModule">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\Managed\UnityEngine\UnityEngine.HotReloadModule.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="UnityEngine.IMGUIModule">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\Managed\UnityEngine\UnityEngine.IMGUIModule.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="UnityEngine.ImageConversionModule">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\Managed\UnityEngine\UnityEngine.ImageConversionModule.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="UnityEngine.InputModule">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\Managed\UnityEngine\UnityEngine.InputModule.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="UnityEngine.InputLegacyModule">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\Managed\UnityEngine\UnityEngine.InputLegacyModule.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="UnityEngine.JSONSerializeModule">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\Managed\UnityEngine\UnityEngine.JSONSerializeModule.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="UnityEngine.LocalizationModule">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\Managed\UnityEngine\UnityEngine.LocalizationModule.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="UnityEngine.ParticleSystemModule">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\Managed\UnityEngine\UnityEngine.ParticleSystemModule.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="UnityEngine.PerformanceReportingModule">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\Managed\UnityEngine\UnityEngine.PerformanceReportingModule.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="UnityEngine.PhysicsModule">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\Managed\UnityEngine\UnityEngine.PhysicsModule.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="UnityEngine.Physics2DModule">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\Managed\UnityEngine\UnityEngine.Physics2DModule.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="UnityEngine.ProfilerModule">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\Managed\UnityEngine\UnityEngine.ProfilerModule.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="UnityEngine.RuntimeInitializeOnLoadManagerInitializerModule">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\Managed\UnityEngine\UnityEngine.RuntimeInitializeOnLoadManagerInitializerModule.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="UnityEngine.ScreenCaptureModule">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\Managed\UnityEngine\UnityEngine.ScreenCaptureModule.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="UnityEngine.SharedInternalsModule">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\Managed\UnityEngine\UnityEngine.SharedInternalsModule.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="UnityEngine.SpriteMaskModule">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\Managed\UnityEngine\UnityEngine.SpriteMaskModule.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="UnityEngine.SpriteShapeModule">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\Managed\UnityEngine\UnityEngine.SpriteShapeModule.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="UnityEngine.StreamingModule">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\Managed\UnityEngine\UnityEngine.StreamingModule.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="UnityEngine.SubstanceModule">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\Managed\UnityEngine\UnityEngine.SubstanceModule.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="UnityEngine.SubsystemsModule">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\Managed\UnityEngine\UnityEngine.SubsystemsModule.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="UnityEngine.TLSModule">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\Managed\UnityEngine\UnityEngine.TLSModule.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="UnityEngine.TerrainModule">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\Managed\UnityEngine\UnityEngine.TerrainModule.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="UnityEngine.TerrainPhysicsModule">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\Managed\UnityEngine\UnityEngine.TerrainPhysicsModule.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="UnityEngine.TextCoreFontEngineModule">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\Managed\UnityEngine\UnityEngine.TextCoreFontEngineModule.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="UnityEngine.TextCoreTextEngineModule">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\Managed\UnityEngine\UnityEngine.TextCoreTextEngineModule.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="UnityEngine.TextRenderingModule">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\Managed\UnityEngine\UnityEngine.TextRenderingModule.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="UnityEngine.TilemapModule">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\Managed\UnityEngine\UnityEngine.TilemapModule.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="UnityEngine.UIModule">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\Managed\UnityEngine\UnityEngine.UIModule.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="UnityEngine.UIElementsModule">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\Managed\UnityEngine\UnityEngine.UIElementsModule.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="UnityEngine.UIElementsNativeModule">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\Managed\UnityEngine\UnityEngine.UIElementsNativeModule.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="UnityEngine.UNETModule">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\Managed\UnityEngine\UnityEngine.UNETModule.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="UnityEngine.UmbraModule">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\Managed\UnityEngine\UnityEngine.UmbraModule.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="UnityEngine.UnityAnalyticsModule">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\Managed\UnityEngine\UnityEngine.UnityAnalyticsModule.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="UnityEngine.UnityAnalyticsCommonModule">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\Managed\UnityEngine\UnityEngine.UnityAnalyticsCommonModule.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="UnityEngine.UnityConnectModule">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\Managed\UnityEngine\UnityEngine.UnityConnectModule.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="UnityEngine.UnityCurlModule">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\Managed\UnityEngine\UnityEngine.UnityCurlModule.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="UnityEngine.UnityTestProtocolModule">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\Managed\UnityEngine\UnityEngine.UnityTestProtocolModule.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="UnityEngine.UnityWebRequestModule">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\Managed\UnityEngine\UnityEngine.UnityWebRequestModule.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="UnityEngine.UnityWebRequestAssetBundleModule">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\Managed\UnityEngine\UnityEngine.UnityWebRequestAssetBundleModule.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="UnityEngine.UnityWebRequestAudioModule">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\Managed\UnityEngine\UnityEngine.UnityWebRequestAudioModule.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="UnityEngine.UnityWebRequestTextureModule">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\Managed\UnityEngine\UnityEngine.UnityWebRequestTextureModule.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="UnityEngine.UnityWebRequestWWWModule">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\Managed\UnityEngine\UnityEngine.UnityWebRequestWWWModule.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="UnityEngine.VFXModule">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\Managed\UnityEngine\UnityEngine.VFXModule.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="UnityEngine.VRModule">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\Managed\UnityEngine\UnityEngine.VRModule.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="UnityEngine.VehiclesModule">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\Managed\UnityEngine\UnityEngine.VehiclesModule.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="UnityEngine.VideoModule">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\Managed\UnityEngine\UnityEngine.VideoModule.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="UnityEngine.VirtualTexturingModule">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\Managed\UnityEngine\UnityEngine.VirtualTexturingModule.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="UnityEngine.WindModule">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\Managed\UnityEngine\UnityEngine.WindModule.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="UnityEngine.XRModule">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\Managed\UnityEngine\UnityEngine.XRModule.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="UnityEditor">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\Managed\UnityEngine\UnityEditor.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="UnityEditor.CoreModule">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\Managed\UnityEngine\UnityEditor.CoreModule.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="UnityEditor.DeviceSimulatorModule">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\Managed\UnityEngine\UnityEditor.DeviceSimulatorModule.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="UnityEditor.DiagnosticsModule">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\Managed\UnityEngine\UnityEditor.DiagnosticsModule.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="UnityEditor.GraphViewModule">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\Managed\UnityEngine\UnityEditor.GraphViewModule.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="UnityEditor.PackageManagerUIModule">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\Managed\UnityEngine\UnityEditor.PackageManagerUIModule.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="UnityEditor.QuickSearchModule">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\Managed\UnityEngine\UnityEditor.QuickSearchModule.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="UnityEditor.SceneTemplateModule">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\Managed\UnityEngine\UnityEditor.SceneTemplateModule.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="UnityEditor.TextCoreFontEngineModule">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\Managed\UnityEngine\UnityEditor.TextCoreFontEngineModule.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="UnityEditor.TextCoreTextEngineModule">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\Managed\UnityEngine\UnityEditor.TextCoreTextEngineModule.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="UnityEditor.UIBuilderModule">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\Managed\UnityEngine\UnityEditor.UIBuilderModule.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="UnityEditor.UIElementsModule">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\Managed\UnityEngine\UnityEditor.UIElementsModule.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="UnityEditor.UIElementsSamplesModule">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\Managed\UnityEngine\UnityEditor.UIElementsSamplesModule.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="UnityEditor.UIServiceModule">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\Managed\UnityEngine\UnityEditor.UIServiceModule.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="UnityEditor.UnityConnectModule">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\Managed\UnityEngine\UnityEditor.UnityConnectModule.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="UnityEditor.Graphs">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\Managed\UnityEditor.Graphs.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="UnityEditor.Android.Extensions">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\PlaybackEngines\AndroidPlayer\UnityEditor.Android.Extensions.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="UnityEditor.WindowsStandalone.Extensions">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\PlaybackEngines\WindowsStandaloneSupport\UnityEditor.WindowsStandalone.Extensions.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="Sherlog">
|
||||||
|
<HintPath>E:\project\JNFrame2\Assets\JNGame\Plugins\Sherlog\Sherlog.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="TCPeasy">
|
||||||
|
<HintPath>E:\project\JNFrame2\Assets\JNGame\Plugins\TCPeasy\TCPeasy.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="DotNetty.Common">
|
||||||
|
<HintPath>E:\project\JNFrame2\Assets\Packages\DotNetty.Common.0.7.6\lib\netstandard2.0\DotNetty.Common.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="DesperateDevs.Threading">
|
||||||
|
<HintPath>E:\project\JNFrame2\Assets\JNGame\Plugins\DesperateDevs\DesperateDevs.Threading.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="Google.Protobuf">
|
||||||
|
<HintPath>E:\project\JNFrame2\Assets\Packages\Google.Protobuf.3.27.3\lib\netstandard2.0\Google.Protobuf.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="Jenny">
|
||||||
|
<HintPath>E:\project\JNFrame2\Assets\JNGame\Plugins\Jenny\Editor\Jenny.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="Microsoft.Extensions.Options">
|
||||||
|
<HintPath>E:\project\JNFrame2\Assets\Packages\Microsoft.Extensions.Options.5.0.0\lib\netstandard2.0\Microsoft.Extensions.Options.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="Jenny.Generator">
|
||||||
|
<HintPath>E:\project\JNFrame2\Assets\JNGame\Plugins\Jenny\Editor\Jenny.Generator.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="Unity.VisualScripting.IonicZip">
|
||||||
|
<HintPath>E:\project\JNFrame2\Library\PackageCache\com.unity.visualscripting@1.9.1\Editor\VisualScripting.Core\Dependencies\DotNetZip\Unity.VisualScripting.IonicZip.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="Microsoft.Extensions.DependencyInjection">
|
||||||
|
<HintPath>E:\project\JNFrame2\Assets\Packages\Microsoft.Extensions.DependencyInjection.5.0.0\lib\netstandard2.1\Microsoft.Extensions.DependencyInjection.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="unityplastic">
|
||||||
|
<HintPath>E:\project\JNFrame2\Library\PackageCache\com.unity.collab-proxy@2.2.0\Lib\Editor\PlasticSCM\unityplastic.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="DotNetty.Transport">
|
||||||
|
<HintPath>E:\project\JNFrame2\Assets\Packages\DotNetty.Transport.0.7.6\lib\netstandard2.0\DotNetty.Transport.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="log4netPlastic">
|
||||||
|
<HintPath>E:\project\JNFrame2\Library\PackageCache\com.unity.collab-proxy@2.2.0\Lib\Editor\PlasticSCM\log4netPlastic.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="Newtonsoft.Json">
|
||||||
|
<HintPath>E:\project\JNFrame2\Assets\Packages\Newtonsoft.Json.13.0.3\lib\netstandard2.0\Newtonsoft.Json.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="Microsoft.Extensions.Logging">
|
||||||
|
<HintPath>E:\project\JNFrame2\Assets\Packages\Microsoft.Extensions.Logging.5.0.0\lib\netstandard2.1\Microsoft.Extensions.Logging.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="DOTween">
|
||||||
|
<HintPath>E:\project\JNFrame2\Assets\Plugins\Demigiant\DOTween\DOTween.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="ReportGeneratorMerged">
|
||||||
|
<HintPath>E:\project\JNFrame2\Library\PackageCache\com.unity.testtools.codecoverage@1.2.5\lib\ReportGenerator\ReportGeneratorMerged.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="NugetForUnity">
|
||||||
|
<HintPath>E:\project\JNFrame2\Assets\NuGet\Editor\NugetForUnity.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="DesperateDevs.Reflection">
|
||||||
|
<HintPath>E:\project\JNFrame2\Assets\JNGame\Plugins\DesperateDevs\DesperateDevs.Reflection.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="DesperateDevs.Caching">
|
||||||
|
<HintPath>E:\project\JNFrame2\Assets\JNGame\Plugins\DesperateDevs\DesperateDevs.Caching.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="DesperateDevs.Extensions">
|
||||||
|
<HintPath>E:\project\JNFrame2\Assets\JNGame\Plugins\DesperateDevs\DesperateDevs.Extensions.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="DesperateDevs.Serialization">
|
||||||
|
<HintPath>E:\project\JNFrame2\Assets\JNGame\Plugins\DesperateDevs\DesperateDevs.Serialization.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="Sherlog.Appenders">
|
||||||
|
<HintPath>E:\project\JNFrame2\Assets\JNGame\Plugins\Sherlog\Sherlog.Appenders.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="Jenny.Plugins">
|
||||||
|
<HintPath>E:\project\JNFrame2\Assets\JNGame\Plugins\Jenny\Editor\Jenny\Jenny.Plugins.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="Unity.Plastic.Newtonsoft.Json">
|
||||||
|
<HintPath>E:\project\JNFrame2\Library\PackageCache\com.unity.collab-proxy@2.2.0\Lib\Editor\PlasticSCM\Unity.Plastic.Newtonsoft.Json.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System.Runtime.CompilerServices.Unsafe">
|
||||||
|
<HintPath>E:\project\JNFrame2\Assets\Packages\System.Runtime.CompilerServices.Unsafe.5.0.0\lib\netstandard2.0\System.Runtime.CompilerServices.Unsafe.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="Microsoft.Extensions.DependencyInjection.Abstractions">
|
||||||
|
<HintPath>E:\project\JNFrame2\Assets\Packages\Microsoft.Extensions.DependencyInjection.Abstractions.5.0.0\lib\netstandard2.0\Microsoft.Extensions.DependencyInjection.Abstractions.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System.Collections.Immutable">
|
||||||
|
<HintPath>E:\project\JNFrame2\Assets\Packages\System.Collections.Immutable.1.5.0\lib\netstandard2.0\System.Collections.Immutable.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="Microsoft.Extensions.Primitives">
|
||||||
|
<HintPath>E:\project\JNFrame2\Assets\Packages\Microsoft.Extensions.Primitives.5.0.0\lib\netstandard2.0\Microsoft.Extensions.Primitives.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="DesperateDevs.Unity.Editor">
|
||||||
|
<HintPath>E:\project\JNFrame2\Assets\JNGame\Plugins\DesperateDevs\Editor\DesperateDevs.Unity.Editor.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="Unity.Plastic.Antlr3.Runtime">
|
||||||
|
<HintPath>E:\project\JNFrame2\Library\PackageCache\com.unity.collab-proxy@2.2.0\Lib\Editor\PlasticSCM\Unity.Plastic.Antlr3.Runtime.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="Unity.VisualScripting.YamlDotNet">
|
||||||
|
<HintPath>E:\project\JNFrame2\Library\PackageCache\com.unity.visualscripting@1.9.1\Editor\VisualScripting.Core\Dependencies\YamlDotNet\Unity.VisualScripting.YamlDotNet.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="Microsoft.Extensions.Logging.Abstractions">
|
||||||
|
<HintPath>E:\project\JNFrame2\Assets\Packages\Microsoft.Extensions.Logging.Abstractions.5.0.0\lib\netstandard2.0\Microsoft.Extensions.Logging.Abstractions.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="DesperateDevs.Unity">
|
||||||
|
<HintPath>E:\project\JNFrame2\Assets\JNGame\Plugins\DesperateDevs\DesperateDevs.Unity.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="DOTweenEditor">
|
||||||
|
<HintPath>E:\project\JNFrame2\Assets\Plugins\Demigiant\DOTween\Editor\DOTweenEditor.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="Unity.VisualScripting.TextureAssets">
|
||||||
|
<HintPath>E:\project\JNFrame2\Library\PackageCache\com.unity.visualscripting@1.9.1\Editor\VisualScripting.Core\EditorAssetResources\Unity.VisualScripting.TextureAssets.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="Sherlog.Formatters">
|
||||||
|
<HintPath>E:\project\JNFrame2\Assets\JNGame\Plugins\Sherlog\Sherlog.Formatters.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="DotNetty.Codecs">
|
||||||
|
<HintPath>E:\project\JNFrame2\Assets\Packages\DotNetty.Codecs.0.7.6\lib\netstandard2.0\DotNetty.Codecs.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System.Diagnostics.DiagnosticSource">
|
||||||
|
<HintPath>E:\project\JNFrame2\Assets\Packages\System.Diagnostics.DiagnosticSource.5.0.0\lib\netstandard1.3\System.Diagnostics.DiagnosticSource.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="DotNetty.Buffers">
|
||||||
|
<HintPath>E:\project\JNFrame2\Assets\Packages\DotNetty.Buffers.0.7.6\lib\netstandard2.0\DotNetty.Buffers.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="Jenny.Plugins.Unity">
|
||||||
|
<HintPath>E:\project\JNFrame2\Assets\JNGame\Plugins\Jenny\Editor\Jenny\Jenny.Plugins.Unity.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="Unity.VisualScripting.Antlr3.Runtime">
|
||||||
|
<HintPath>E:\project\JNFrame2\Library\PackageCache\com.unity.visualscripting@1.9.1\Runtime\VisualScripting.Flow\Dependencies\NCalc\Unity.VisualScripting.Antlr3.Runtime.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="DotNetty.Handlers">
|
||||||
|
<HintPath>E:\project\JNFrame2\Assets\Packages\DotNetty.Handlers.0.7.6\lib\netstandard2.0\DotNetty.Handlers.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="Jenny.Generator.Unity.Editor">
|
||||||
|
<HintPath>E:\project\JNFrame2\Assets\JNGame\Plugins\Jenny\Editor\Jenny.Generator.Unity.Editor.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="Unity.Android.Types">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\PlaybackEngines\AndroidPlayer\Unity.Android.Types.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="Unity.Android.Gradle">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\PlaybackEngines\AndroidPlayer\Unity.Android.Gradle.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="netstandard">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\NetStandard\ref\2.1.0\netstandard.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="Microsoft.Win32.Primitives">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\Microsoft.Win32.Primitives.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System.AppContext">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.AppContext.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System.Buffers">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Buffers.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System.Collections.Concurrent">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Collections.Concurrent.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System.Collections">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Collections.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System.Collections.NonGeneric">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Collections.NonGeneric.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System.Collections.Specialized">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Collections.Specialized.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System.ComponentModel">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.ComponentModel.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System.ComponentModel.EventBasedAsync">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.ComponentModel.EventBasedAsync.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System.ComponentModel.Primitives">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.ComponentModel.Primitives.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System.ComponentModel.TypeConverter">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.ComponentModel.TypeConverter.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System.Console">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Console.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System.Data.Common">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Data.Common.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System.Diagnostics.Contracts">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Diagnostics.Contracts.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System.Diagnostics.Debug">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Diagnostics.Debug.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System.Diagnostics.FileVersionInfo">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Diagnostics.FileVersionInfo.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System.Diagnostics.Process">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Diagnostics.Process.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System.Diagnostics.StackTrace">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Diagnostics.StackTrace.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System.Diagnostics.TextWriterTraceListener">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Diagnostics.TextWriterTraceListener.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System.Diagnostics.Tools">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Diagnostics.Tools.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System.Diagnostics.TraceSource">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Diagnostics.TraceSource.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System.Diagnostics.Tracing">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Diagnostics.Tracing.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System.Drawing.Primitives">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Drawing.Primitives.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System.Dynamic.Runtime">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Dynamic.Runtime.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System.Globalization.Calendars">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Globalization.Calendars.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System.Globalization">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Globalization.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System.Globalization.Extensions">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Globalization.Extensions.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System.IO.Compression">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.IO.Compression.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System.IO.Compression.ZipFile">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.IO.Compression.ZipFile.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System.IO">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.IO.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System.IO.FileSystem">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.IO.FileSystem.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System.IO.FileSystem.DriveInfo">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\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\2021.3.35f1\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\2021.3.35f1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.IO.FileSystem.Watcher.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System.IO.IsolatedStorage">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.IO.IsolatedStorage.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System.IO.MemoryMappedFiles">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.IO.MemoryMappedFiles.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System.IO.Pipes">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.IO.Pipes.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System.IO.UnmanagedMemoryStream">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.IO.UnmanagedMemoryStream.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System.Linq">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Linq.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System.Linq.Expressions">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Linq.Expressions.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System.Linq.Parallel">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Linq.Parallel.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System.Linq.Queryable">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Linq.Queryable.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System.Memory">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Memory.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System.Net.Http">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Net.Http.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System.Net.NameResolution">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Net.NameResolution.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System.Net.NetworkInformation">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Net.NetworkInformation.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System.Net.Ping">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Net.Ping.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System.Net.Primitives">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Net.Primitives.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System.Net.Requests">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Net.Requests.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System.Net.Security">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Net.Security.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System.Net.Sockets">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Net.Sockets.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System.Net.WebHeaderCollection">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Net.WebHeaderCollection.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System.Net.WebSockets.Client">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Net.WebSockets.Client.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System.Net.WebSockets">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Net.WebSockets.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System.Numerics.Vectors">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Numerics.Vectors.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System.ObjectModel">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.ObjectModel.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System.Reflection.DispatchProxy">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Reflection.DispatchProxy.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System.Reflection">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Reflection.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System.Reflection.Emit">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Reflection.Emit.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System.Reflection.Emit.ILGeneration">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\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\2021.3.35f1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Reflection.Emit.Lightweight.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System.Reflection.Extensions">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Reflection.Extensions.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System.Reflection.Primitives">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Reflection.Primitives.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System.Resources.Reader">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Resources.Reader.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System.Resources.ResourceManager">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Resources.ResourceManager.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System.Resources.Writer">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Resources.Writer.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System.Runtime.CompilerServices.VisualC">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Runtime.CompilerServices.VisualC.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System.Runtime">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Runtime.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System.Runtime.Extensions">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Runtime.Extensions.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System.Runtime.Handles">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Runtime.Handles.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System.Runtime.InteropServices">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Runtime.InteropServices.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System.Runtime.InteropServices.RuntimeInformation">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Runtime.InteropServices.RuntimeInformation.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System.Runtime.Numerics">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Runtime.Numerics.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System.Runtime.Serialization.Formatters">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\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\2021.3.35f1\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\2021.3.35f1\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\2021.3.35f1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Runtime.Serialization.Xml.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System.Security.Claims">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Security.Claims.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System.Security.Cryptography.Algorithms">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\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\2021.3.35f1\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\2021.3.35f1\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\2021.3.35f1\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\2021.3.35f1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Security.Cryptography.X509Certificates.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System.Security.Principal">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Security.Principal.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System.Security.SecureString">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Security.SecureString.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System.Text.Encoding">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Text.Encoding.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System.Text.Encoding.Extensions">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Text.Encoding.Extensions.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System.Text.RegularExpressions">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Text.RegularExpressions.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System.Threading">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Threading.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System.Threading.Overlapped">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Threading.Overlapped.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System.Threading.Tasks">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Threading.Tasks.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System.Threading.Tasks.Extensions">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\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\2021.3.35f1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Threading.Tasks.Parallel.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System.Threading.Thread">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Threading.Thread.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System.Threading.ThreadPool">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Threading.ThreadPool.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System.Threading.Timer">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Threading.Timer.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System.ValueTuple">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.ValueTuple.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System.Xml.ReaderWriter">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Xml.ReaderWriter.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System.Xml.XDocument">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Xml.XDocument.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System.Xml.XmlDocument">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Xml.XmlDocument.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System.Xml.XmlSerializer">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Xml.XmlSerializer.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System.Xml.XPath">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Xml.XPath.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System.Xml.XPath.XDocument">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\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\2021.3.35f1\Editor\Data\NetStandard\Extensions\2.0.0\System.Runtime.InteropServices.WindowsRuntime.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="mscorlib">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\NetStandard\compat\2.1.0\shims\netfx\mscorlib.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System.ComponentModel.Composition">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\NetStandard\compat\2.1.0\shims\netfx\System.ComponentModel.Composition.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System.Core">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\NetStandard\compat\2.1.0\shims\netfx\System.Core.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System.Data">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\NetStandard\compat\2.1.0\shims\netfx\System.Data.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\NetStandard\compat\2.1.0\shims\netfx\System.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System.Drawing">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\NetStandard\compat\2.1.0\shims\netfx\System.Drawing.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System.IO.Compression.FileSystem">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\NetStandard\compat\2.1.0\shims\netfx\System.IO.Compression.FileSystem.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System.Net">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\NetStandard\compat\2.1.0\shims\netfx\System.Net.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System.Numerics">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\NetStandard\compat\2.1.0\shims\netfx\System.Numerics.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System.Runtime.Serialization">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\NetStandard\compat\2.1.0\shims\netfx\System.Runtime.Serialization.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System.ServiceModel.Web">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\NetStandard\compat\2.1.0\shims\netfx\System.ServiceModel.Web.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System.Transactions">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\NetStandard\compat\2.1.0\shims\netfx\System.Transactions.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System.Web">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\NetStandard\compat\2.1.0\shims\netfx\System.Web.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System.Windows">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\NetStandard\compat\2.1.0\shims\netfx\System.Windows.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System.Xml">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\NetStandard\compat\2.1.0\shims\netfx\System.Xml.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System.Xml.Linq">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\NetStandard\compat\2.1.0\shims\netfx\System.Xml.Linq.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System.Xml.Serialization">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\NetStandard\compat\2.1.0\shims\netfx\System.Xml.Serialization.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="UnityEditor.UI">
|
||||||
|
<HintPath>E:\project\JNFrame2\Library\ScriptAssemblies\UnityEditor.UI.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="UnityEngine.UI">
|
||||||
|
<HintPath>E:\project\JNFrame2\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>
|
1013
JNFrame2/Assembly-CSharp-Editor-firstpass.csproj
Normal file
1013
JNFrame2/Assembly-CSharp-Editor-firstpass.csproj
Normal file
File diff suppressed because it is too large
Load Diff
1011
JNFrame2/Assembly-CSharp-Editor.csproj
Normal file
1011
JNFrame2/Assembly-CSharp-Editor.csproj
Normal file
File diff suppressed because it is too large
Load Diff
895
JNFrame2/Assembly-CSharp-firstpass.csproj
Normal file
895
JNFrame2/Assembly-CSharp-firstpass.csproj
Normal file
@ -0,0 +1,895 @@
|
|||||||
|
<?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>{082457fe-fcb4-40d1-c6ce-98e6d3097f89}</ProjectGuid>
|
||||||
|
<ProjectTypeGuids>{E097FAD1-6243-4DAD-9C02-E9B9EFC3FFC1};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
|
||||||
|
<OutputType>Library</OutputType>
|
||||||
|
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||||
|
<AssemblyName>Assembly-CSharp-firstpass</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\Assembly-CSharp-firstpass\</OutputPath>
|
||||||
|
<DefineConstants>UNITY_2021_3_35;UNITY_2021_3;UNITY_2021;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;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_UNET;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_UNET;ENABLE_CLOUD_SERVICES_BUILD;ENABLE_CLOUD_LICENSE;ENABLE_EDITOR_HUB_LICENSE;ENABLE_WEBSOCKET_CLIENT;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;PLATFORM_STANDALONE;TEXTCORE_1_0_OR_NEWER;PLATFORM_STANDALONE_WIN;UNITY_STANDALONE_WIN;UNITY_STANDALONE;ENABLE_RUNTIME_GI;ENABLE_MOVIES;ENABLE_NETWORK;ENABLE_NVIDIA;ENABLE_CRUNCH_TEXTURE_COMPRESSION;ENABLE_UNITY_GAME_SERVICES_ANALYTICS_SUPPORT;ENABLE_OUT_OF_PROCESS_CRASH_HANDLER;ENABLE_CLUSTER_SYNC;ENABLE_CLUSTERINPUT;PLATFORM_UPDATES_TIME_OUTSIDE_OF_PLAYER_LOOP;GFXDEVICE_WAITFOREVENT_MESSAGEPUMP;ENABLE_WEBSOCKET_HOST;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;CSHARP_7_OR_LATER;CSHARP_7_3_OR_NEWER</DefineConstants>
|
||||||
|
<ErrorReport>prompt</ErrorReport>
|
||||||
|
<WarningLevel>4</WarningLevel>
|
||||||
|
<NoWarn>0169,0649</NoWarn>
|
||||||
|
<AllowUnsafeBlocks>True</AllowUnsafeBlocks>
|
||||||
|
<TreatWarningsAsErrors>False</TreatWarningsAsErrors>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup>
|
||||||
|
<NoConfig>true</NoConfig>
|
||||||
|
<NoStdLib>true</NoStdLib>
|
||||||
|
<AddAdditionalExplicitAssemblyReferences>false</AddAdditionalExplicitAssemblyReferences>
|
||||||
|
<ImplicitlyExpandNETStandardFacades>false</ImplicitlyExpandNETStandardFacades>
|
||||||
|
<ImplicitlyExpandDesignTimeFacades>false</ImplicitlyExpandDesignTimeFacades>
|
||||||
|
</PropertyGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Compile Include="Assets\Plugins\Demigiant\DOTween\Modules\DOTweenModulePhysics2D.cs" />
|
||||||
|
<Compile Include="Assets\Plugins\Demigiant\DOTween\Modules\DOTweenModuleUI.cs" />
|
||||||
|
<Compile Include="Assets\Plugins\Demigiant\DOTween\Modules\DOTweenModuleUnityVersion.cs" />
|
||||||
|
<Compile Include="Assets\Plugins\Demigiant\DOTween\Modules\DOTweenModuleEPOOutline.cs" />
|
||||||
|
<Compile Include="Assets\Plugins\Demigiant\DOTween\Modules\DOTweenModuleUtils.cs" />
|
||||||
|
<Compile Include="Assets\Plugins\Demigiant\DOTween\Modules\DOTweenModulePhysics.cs" />
|
||||||
|
<Compile Include="Assets\Plugins\Demigiant\DOTween\Modules\DOTweenModuleSprite.cs" />
|
||||||
|
<Compile Include="Assets\Plugins\Demigiant\DOTween\Modules\DOTweenModuleAudio.cs" />
|
||||||
|
<None Include="Assets\Plugins\UniTask\package.json" />
|
||||||
|
<None Include="Assets\Plugins\Demigiant\DOTween\readme.txt" />
|
||||||
|
<Reference Include="UnityEngine">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\Managed\UnityEngine\UnityEngine.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="UnityEngine.AIModule">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\Managed\UnityEngine\UnityEngine.AIModule.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="UnityEngine.ARModule">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\Managed\UnityEngine\UnityEngine.ARModule.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="UnityEngine.AccessibilityModule">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\Managed\UnityEngine\UnityEngine.AccessibilityModule.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="UnityEngine.AndroidJNIModule">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\Managed\UnityEngine\UnityEngine.AndroidJNIModule.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="UnityEngine.AnimationModule">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\Managed\UnityEngine\UnityEngine.AnimationModule.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="UnityEngine.AssetBundleModule">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\Managed\UnityEngine\UnityEngine.AssetBundleModule.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="UnityEngine.AudioModule">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\Managed\UnityEngine\UnityEngine.AudioModule.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="UnityEngine.ClothModule">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\Managed\UnityEngine\UnityEngine.ClothModule.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="UnityEngine.ClusterInputModule">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\Managed\UnityEngine\UnityEngine.ClusterInputModule.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="UnityEngine.ClusterRendererModule">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\Managed\UnityEngine\UnityEngine.ClusterRendererModule.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="UnityEngine.CoreModule">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\Managed\UnityEngine\UnityEngine.CoreModule.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="UnityEngine.CrashReportingModule">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\Managed\UnityEngine\UnityEngine.CrashReportingModule.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="UnityEngine.DSPGraphModule">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\Managed\UnityEngine\UnityEngine.DSPGraphModule.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="UnityEngine.DirectorModule">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\Managed\UnityEngine\UnityEngine.DirectorModule.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="UnityEngine.GIModule">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\Managed\UnityEngine\UnityEngine.GIModule.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="UnityEngine.GameCenterModule">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\Managed\UnityEngine\UnityEngine.GameCenterModule.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="UnityEngine.GridModule">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\Managed\UnityEngine\UnityEngine.GridModule.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="UnityEngine.HotReloadModule">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\Managed\UnityEngine\UnityEngine.HotReloadModule.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="UnityEngine.IMGUIModule">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\Managed\UnityEngine\UnityEngine.IMGUIModule.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="UnityEngine.ImageConversionModule">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\Managed\UnityEngine\UnityEngine.ImageConversionModule.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="UnityEngine.InputModule">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\Managed\UnityEngine\UnityEngine.InputModule.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="UnityEngine.InputLegacyModule">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\Managed\UnityEngine\UnityEngine.InputLegacyModule.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="UnityEngine.JSONSerializeModule">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\Managed\UnityEngine\UnityEngine.JSONSerializeModule.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="UnityEngine.LocalizationModule">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\Managed\UnityEngine\UnityEngine.LocalizationModule.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="UnityEngine.ParticleSystemModule">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\Managed\UnityEngine\UnityEngine.ParticleSystemModule.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="UnityEngine.PerformanceReportingModule">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\Managed\UnityEngine\UnityEngine.PerformanceReportingModule.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="UnityEngine.PhysicsModule">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\Managed\UnityEngine\UnityEngine.PhysicsModule.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="UnityEngine.Physics2DModule">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\Managed\UnityEngine\UnityEngine.Physics2DModule.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="UnityEngine.ProfilerModule">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\Managed\UnityEngine\UnityEngine.ProfilerModule.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="UnityEngine.RuntimeInitializeOnLoadManagerInitializerModule">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\Managed\UnityEngine\UnityEngine.RuntimeInitializeOnLoadManagerInitializerModule.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="UnityEngine.ScreenCaptureModule">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\Managed\UnityEngine\UnityEngine.ScreenCaptureModule.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="UnityEngine.SharedInternalsModule">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\Managed\UnityEngine\UnityEngine.SharedInternalsModule.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="UnityEngine.SpriteMaskModule">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\Managed\UnityEngine\UnityEngine.SpriteMaskModule.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="UnityEngine.SpriteShapeModule">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\Managed\UnityEngine\UnityEngine.SpriteShapeModule.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="UnityEngine.StreamingModule">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\Managed\UnityEngine\UnityEngine.StreamingModule.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="UnityEngine.SubstanceModule">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\Managed\UnityEngine\UnityEngine.SubstanceModule.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="UnityEngine.SubsystemsModule">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\Managed\UnityEngine\UnityEngine.SubsystemsModule.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="UnityEngine.TLSModule">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\Managed\UnityEngine\UnityEngine.TLSModule.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="UnityEngine.TerrainModule">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\Managed\UnityEngine\UnityEngine.TerrainModule.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="UnityEngine.TerrainPhysicsModule">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\Managed\UnityEngine\UnityEngine.TerrainPhysicsModule.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="UnityEngine.TextCoreFontEngineModule">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\Managed\UnityEngine\UnityEngine.TextCoreFontEngineModule.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="UnityEngine.TextCoreTextEngineModule">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\Managed\UnityEngine\UnityEngine.TextCoreTextEngineModule.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="UnityEngine.TextRenderingModule">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\Managed\UnityEngine\UnityEngine.TextRenderingModule.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="UnityEngine.TilemapModule">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\Managed\UnityEngine\UnityEngine.TilemapModule.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="UnityEngine.UIModule">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\Managed\UnityEngine\UnityEngine.UIModule.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="UnityEngine.UIElementsModule">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\Managed\UnityEngine\UnityEngine.UIElementsModule.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="UnityEngine.UIElementsNativeModule">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\Managed\UnityEngine\UnityEngine.UIElementsNativeModule.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="UnityEngine.UNETModule">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\Managed\UnityEngine\UnityEngine.UNETModule.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="UnityEngine.UmbraModule">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\Managed\UnityEngine\UnityEngine.UmbraModule.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="UnityEngine.UnityAnalyticsModule">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\Managed\UnityEngine\UnityEngine.UnityAnalyticsModule.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="UnityEngine.UnityAnalyticsCommonModule">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\Managed\UnityEngine\UnityEngine.UnityAnalyticsCommonModule.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="UnityEngine.UnityConnectModule">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\Managed\UnityEngine\UnityEngine.UnityConnectModule.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="UnityEngine.UnityCurlModule">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\Managed\UnityEngine\UnityEngine.UnityCurlModule.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="UnityEngine.UnityTestProtocolModule">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\Managed\UnityEngine\UnityEngine.UnityTestProtocolModule.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="UnityEngine.UnityWebRequestModule">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\Managed\UnityEngine\UnityEngine.UnityWebRequestModule.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="UnityEngine.UnityWebRequestAssetBundleModule">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\Managed\UnityEngine\UnityEngine.UnityWebRequestAssetBundleModule.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="UnityEngine.UnityWebRequestAudioModule">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\Managed\UnityEngine\UnityEngine.UnityWebRequestAudioModule.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="UnityEngine.UnityWebRequestTextureModule">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\Managed\UnityEngine\UnityEngine.UnityWebRequestTextureModule.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="UnityEngine.UnityWebRequestWWWModule">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\Managed\UnityEngine\UnityEngine.UnityWebRequestWWWModule.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="UnityEngine.VFXModule">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\Managed\UnityEngine\UnityEngine.VFXModule.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="UnityEngine.VRModule">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\Managed\UnityEngine\UnityEngine.VRModule.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="UnityEngine.VehiclesModule">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\Managed\UnityEngine\UnityEngine.VehiclesModule.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="UnityEngine.VideoModule">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\Managed\UnityEngine\UnityEngine.VideoModule.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="UnityEngine.VirtualTexturingModule">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\Managed\UnityEngine\UnityEngine.VirtualTexturingModule.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="UnityEngine.WindModule">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\Managed\UnityEngine\UnityEngine.WindModule.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="UnityEngine.XRModule">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\Managed\UnityEngine\UnityEngine.XRModule.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="UnityEditor">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\Managed\UnityEngine\UnityEditor.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="UnityEditor.CoreModule">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\Managed\UnityEngine\UnityEditor.CoreModule.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="UnityEditor.DeviceSimulatorModule">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\Managed\UnityEngine\UnityEditor.DeviceSimulatorModule.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="UnityEditor.DiagnosticsModule">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\Managed\UnityEngine\UnityEditor.DiagnosticsModule.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="UnityEditor.GraphViewModule">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\Managed\UnityEngine\UnityEditor.GraphViewModule.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="UnityEditor.PackageManagerUIModule">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\Managed\UnityEngine\UnityEditor.PackageManagerUIModule.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="UnityEditor.QuickSearchModule">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\Managed\UnityEngine\UnityEditor.QuickSearchModule.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="UnityEditor.SceneTemplateModule">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\Managed\UnityEngine\UnityEditor.SceneTemplateModule.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="UnityEditor.TextCoreFontEngineModule">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\Managed\UnityEngine\UnityEditor.TextCoreFontEngineModule.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="UnityEditor.TextCoreTextEngineModule">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\Managed\UnityEngine\UnityEditor.TextCoreTextEngineModule.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="UnityEditor.UIBuilderModule">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\Managed\UnityEngine\UnityEditor.UIBuilderModule.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="UnityEditor.UIElementsModule">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\Managed\UnityEngine\UnityEditor.UIElementsModule.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="UnityEditor.UIElementsSamplesModule">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\Managed\UnityEngine\UnityEditor.UIElementsSamplesModule.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="UnityEditor.UIServiceModule">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\Managed\UnityEngine\UnityEditor.UIServiceModule.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="UnityEditor.UnityConnectModule">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\Managed\UnityEngine\UnityEditor.UnityConnectModule.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="Sherlog">
|
||||||
|
<HintPath>E:\project\JNFrame2\Assets\JNGame\Plugins\Sherlog\Sherlog.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="TCPeasy">
|
||||||
|
<HintPath>E:\project\JNFrame2\Assets\JNGame\Plugins\TCPeasy\TCPeasy.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="DotNetty.Common">
|
||||||
|
<HintPath>E:\project\JNFrame2\Assets\Packages\DotNetty.Common.0.7.6\lib\netstandard2.0\DotNetty.Common.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="DesperateDevs.Threading">
|
||||||
|
<HintPath>E:\project\JNFrame2\Assets\JNGame\Plugins\DesperateDevs\DesperateDevs.Threading.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="Google.Protobuf">
|
||||||
|
<HintPath>E:\project\JNFrame2\Assets\Packages\Google.Protobuf.3.27.3\lib\netstandard2.0\Google.Protobuf.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="Microsoft.Extensions.Options">
|
||||||
|
<HintPath>E:\project\JNFrame2\Assets\Packages\Microsoft.Extensions.Options.5.0.0\lib\netstandard2.0\Microsoft.Extensions.Options.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="Microsoft.Extensions.DependencyInjection">
|
||||||
|
<HintPath>E:\project\JNFrame2\Assets\Packages\Microsoft.Extensions.DependencyInjection.5.0.0\lib\netstandard2.1\Microsoft.Extensions.DependencyInjection.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="DotNetty.Transport">
|
||||||
|
<HintPath>E:\project\JNFrame2\Assets\Packages\DotNetty.Transport.0.7.6\lib\netstandard2.0\DotNetty.Transport.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="Newtonsoft.Json">
|
||||||
|
<HintPath>E:\project\JNFrame2\Assets\Packages\Newtonsoft.Json.13.0.3\lib\netstandard2.0\Newtonsoft.Json.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="Microsoft.Extensions.Logging">
|
||||||
|
<HintPath>E:\project\JNFrame2\Assets\Packages\Microsoft.Extensions.Logging.5.0.0\lib\netstandard2.1\Microsoft.Extensions.Logging.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="DOTween">
|
||||||
|
<HintPath>E:\project\JNFrame2\Assets\Plugins\Demigiant\DOTween\DOTween.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="ReportGeneratorMerged">
|
||||||
|
<HintPath>E:\project\JNFrame2\Library\PackageCache\com.unity.testtools.codecoverage@1.2.5\lib\ReportGenerator\ReportGeneratorMerged.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="DesperateDevs.Reflection">
|
||||||
|
<HintPath>E:\project\JNFrame2\Assets\JNGame\Plugins\DesperateDevs\DesperateDevs.Reflection.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="DesperateDevs.Caching">
|
||||||
|
<HintPath>E:\project\JNFrame2\Assets\JNGame\Plugins\DesperateDevs\DesperateDevs.Caching.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="DesperateDevs.Extensions">
|
||||||
|
<HintPath>E:\project\JNFrame2\Assets\JNGame\Plugins\DesperateDevs\DesperateDevs.Extensions.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="DesperateDevs.Serialization">
|
||||||
|
<HintPath>E:\project\JNFrame2\Assets\JNGame\Plugins\DesperateDevs\DesperateDevs.Serialization.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="Sherlog.Appenders">
|
||||||
|
<HintPath>E:\project\JNFrame2\Assets\JNGame\Plugins\Sherlog\Sherlog.Appenders.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System.Runtime.CompilerServices.Unsafe">
|
||||||
|
<HintPath>E:\project\JNFrame2\Assets\Packages\System.Runtime.CompilerServices.Unsafe.5.0.0\lib\netstandard2.0\System.Runtime.CompilerServices.Unsafe.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="Microsoft.Extensions.DependencyInjection.Abstractions">
|
||||||
|
<HintPath>E:\project\JNFrame2\Assets\Packages\Microsoft.Extensions.DependencyInjection.Abstractions.5.0.0\lib\netstandard2.0\Microsoft.Extensions.DependencyInjection.Abstractions.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System.Collections.Immutable">
|
||||||
|
<HintPath>E:\project\JNFrame2\Assets\Packages\System.Collections.Immutable.1.5.0\lib\netstandard2.0\System.Collections.Immutable.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="Microsoft.Extensions.Primitives">
|
||||||
|
<HintPath>E:\project\JNFrame2\Assets\Packages\Microsoft.Extensions.Primitives.5.0.0\lib\netstandard2.0\Microsoft.Extensions.Primitives.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="Microsoft.Extensions.Logging.Abstractions">
|
||||||
|
<HintPath>E:\project\JNFrame2\Assets\Packages\Microsoft.Extensions.Logging.Abstractions.5.0.0\lib\netstandard2.0\Microsoft.Extensions.Logging.Abstractions.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="DesperateDevs.Unity">
|
||||||
|
<HintPath>E:\project\JNFrame2\Assets\JNGame\Plugins\DesperateDevs\DesperateDevs.Unity.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="Sherlog.Formatters">
|
||||||
|
<HintPath>E:\project\JNFrame2\Assets\JNGame\Plugins\Sherlog\Sherlog.Formatters.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="DotNetty.Codecs">
|
||||||
|
<HintPath>E:\project\JNFrame2\Assets\Packages\DotNetty.Codecs.0.7.6\lib\netstandard2.0\DotNetty.Codecs.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System.Diagnostics.DiagnosticSource">
|
||||||
|
<HintPath>E:\project\JNFrame2\Assets\Packages\System.Diagnostics.DiagnosticSource.5.0.0\lib\netstandard1.3\System.Diagnostics.DiagnosticSource.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="DotNetty.Buffers">
|
||||||
|
<HintPath>E:\project\JNFrame2\Assets\Packages\DotNetty.Buffers.0.7.6\lib\netstandard2.0\DotNetty.Buffers.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="Unity.VisualScripting.Antlr3.Runtime">
|
||||||
|
<HintPath>E:\project\JNFrame2\Library\PackageCache\com.unity.visualscripting@1.9.1\Runtime\VisualScripting.Flow\Dependencies\NCalc\Unity.VisualScripting.Antlr3.Runtime.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="DotNetty.Handlers">
|
||||||
|
<HintPath>E:\project\JNFrame2\Assets\Packages\DotNetty.Handlers.0.7.6\lib\netstandard2.0\DotNetty.Handlers.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="Unity.Android.Types">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\PlaybackEngines\AndroidPlayer\Unity.Android.Types.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="Unity.Android.Gradle">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\PlaybackEngines\AndroidPlayer\Unity.Android.Gradle.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="netstandard">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\NetStandard\ref\2.1.0\netstandard.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="Microsoft.Win32.Primitives">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\Microsoft.Win32.Primitives.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System.AppContext">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.AppContext.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System.Buffers">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Buffers.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System.Collections.Concurrent">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Collections.Concurrent.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System.Collections">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Collections.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System.Collections.NonGeneric">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Collections.NonGeneric.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System.Collections.Specialized">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Collections.Specialized.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System.ComponentModel">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.ComponentModel.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System.ComponentModel.EventBasedAsync">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.ComponentModel.EventBasedAsync.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System.ComponentModel.Primitives">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.ComponentModel.Primitives.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System.ComponentModel.TypeConverter">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.ComponentModel.TypeConverter.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System.Console">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Console.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System.Data.Common">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Data.Common.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System.Diagnostics.Contracts">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Diagnostics.Contracts.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System.Diagnostics.Debug">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Diagnostics.Debug.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System.Diagnostics.FileVersionInfo">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Diagnostics.FileVersionInfo.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System.Diagnostics.Process">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Diagnostics.Process.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System.Diagnostics.StackTrace">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Diagnostics.StackTrace.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System.Diagnostics.TextWriterTraceListener">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Diagnostics.TextWriterTraceListener.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System.Diagnostics.Tools">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Diagnostics.Tools.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System.Diagnostics.TraceSource">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Diagnostics.TraceSource.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System.Diagnostics.Tracing">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Diagnostics.Tracing.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System.Drawing.Primitives">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Drawing.Primitives.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System.Dynamic.Runtime">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Dynamic.Runtime.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System.Globalization.Calendars">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Globalization.Calendars.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System.Globalization">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Globalization.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System.Globalization.Extensions">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Globalization.Extensions.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System.IO.Compression">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.IO.Compression.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System.IO.Compression.ZipFile">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.IO.Compression.ZipFile.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System.IO">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.IO.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System.IO.FileSystem">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.IO.FileSystem.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System.IO.FileSystem.DriveInfo">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\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\2021.3.35f1\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\2021.3.35f1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.IO.FileSystem.Watcher.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System.IO.IsolatedStorage">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.IO.IsolatedStorage.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System.IO.MemoryMappedFiles">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.IO.MemoryMappedFiles.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System.IO.Pipes">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.IO.Pipes.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System.IO.UnmanagedMemoryStream">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.IO.UnmanagedMemoryStream.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System.Linq">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Linq.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System.Linq.Expressions">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Linq.Expressions.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System.Linq.Parallel">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Linq.Parallel.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System.Linq.Queryable">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Linq.Queryable.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System.Memory">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Memory.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System.Net.Http">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Net.Http.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System.Net.NameResolution">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Net.NameResolution.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System.Net.NetworkInformation">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Net.NetworkInformation.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System.Net.Ping">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Net.Ping.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System.Net.Primitives">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Net.Primitives.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System.Net.Requests">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Net.Requests.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System.Net.Security">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Net.Security.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System.Net.Sockets">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Net.Sockets.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System.Net.WebHeaderCollection">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Net.WebHeaderCollection.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System.Net.WebSockets.Client">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Net.WebSockets.Client.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System.Net.WebSockets">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Net.WebSockets.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System.Numerics.Vectors">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Numerics.Vectors.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System.ObjectModel">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.ObjectModel.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System.Reflection.DispatchProxy">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Reflection.DispatchProxy.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System.Reflection">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Reflection.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System.Reflection.Emit">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Reflection.Emit.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System.Reflection.Emit.ILGeneration">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\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\2021.3.35f1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Reflection.Emit.Lightweight.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System.Reflection.Extensions">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Reflection.Extensions.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System.Reflection.Primitives">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Reflection.Primitives.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System.Resources.Reader">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Resources.Reader.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System.Resources.ResourceManager">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Resources.ResourceManager.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System.Resources.Writer">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Resources.Writer.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System.Runtime.CompilerServices.VisualC">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Runtime.CompilerServices.VisualC.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System.Runtime">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Runtime.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System.Runtime.Extensions">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Runtime.Extensions.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System.Runtime.Handles">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Runtime.Handles.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System.Runtime.InteropServices">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Runtime.InteropServices.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System.Runtime.InteropServices.RuntimeInformation">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Runtime.InteropServices.RuntimeInformation.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System.Runtime.Numerics">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Runtime.Numerics.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System.Runtime.Serialization.Formatters">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\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\2021.3.35f1\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\2021.3.35f1\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\2021.3.35f1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Runtime.Serialization.Xml.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System.Security.Claims">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Security.Claims.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System.Security.Cryptography.Algorithms">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\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\2021.3.35f1\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\2021.3.35f1\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\2021.3.35f1\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\2021.3.35f1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Security.Cryptography.X509Certificates.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System.Security.Principal">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Security.Principal.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System.Security.SecureString">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Security.SecureString.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System.Text.Encoding">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Text.Encoding.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System.Text.Encoding.Extensions">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Text.Encoding.Extensions.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System.Text.RegularExpressions">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Text.RegularExpressions.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System.Threading">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Threading.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System.Threading.Overlapped">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Threading.Overlapped.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System.Threading.Tasks">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Threading.Tasks.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System.Threading.Tasks.Extensions">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\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\2021.3.35f1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Threading.Tasks.Parallel.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System.Threading.Thread">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Threading.Thread.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System.Threading.ThreadPool">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Threading.ThreadPool.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System.Threading.Timer">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Threading.Timer.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System.ValueTuple">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.ValueTuple.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System.Xml.ReaderWriter">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Xml.ReaderWriter.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System.Xml.XDocument">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Xml.XDocument.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System.Xml.XmlDocument">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Xml.XmlDocument.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System.Xml.XmlSerializer">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Xml.XmlSerializer.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System.Xml.XPath">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\NetStandard\compat\2.1.0\shims\netstandard\System.Xml.XPath.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System.Xml.XPath.XDocument">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\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\2021.3.35f1\Editor\Data\NetStandard\Extensions\2.0.0\System.Runtime.InteropServices.WindowsRuntime.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="mscorlib">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\NetStandard\compat\2.1.0\shims\netfx\mscorlib.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System.ComponentModel.Composition">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\NetStandard\compat\2.1.0\shims\netfx\System.ComponentModel.Composition.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System.Core">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\NetStandard\compat\2.1.0\shims\netfx\System.Core.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System.Data">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\NetStandard\compat\2.1.0\shims\netfx\System.Data.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\NetStandard\compat\2.1.0\shims\netfx\System.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System.Drawing">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\NetStandard\compat\2.1.0\shims\netfx\System.Drawing.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System.IO.Compression.FileSystem">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\NetStandard\compat\2.1.0\shims\netfx\System.IO.Compression.FileSystem.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System.Net">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\NetStandard\compat\2.1.0\shims\netfx\System.Net.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System.Numerics">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\NetStandard\compat\2.1.0\shims\netfx\System.Numerics.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System.Runtime.Serialization">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\NetStandard\compat\2.1.0\shims\netfx\System.Runtime.Serialization.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System.ServiceModel.Web">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\NetStandard\compat\2.1.0\shims\netfx\System.ServiceModel.Web.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System.Transactions">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\NetStandard\compat\2.1.0\shims\netfx\System.Transactions.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System.Web">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\NetStandard\compat\2.1.0\shims\netfx\System.Web.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System.Windows">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\NetStandard\compat\2.1.0\shims\netfx\System.Windows.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System.Xml">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\NetStandard\compat\2.1.0\shims\netfx\System.Xml.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System.Xml.Linq">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\NetStandard\compat\2.1.0\shims\netfx\System.Xml.Linq.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System.Xml.Serialization">
|
||||||
|
<HintPath>D:\Unity\2021.3.35f1\Editor\Data\NetStandard\compat\2.1.0\shims\netfx\System.Xml.Serialization.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="Unity.VisualScripting.Flow.Editor">
|
||||||
|
<HintPath>E:\project\JNFrame2\Library\ScriptAssemblies\Unity.VisualScripting.Flow.Editor.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="Unity.VSCode.Editor">
|
||||||
|
<HintPath>E:\project\JNFrame2\Library\ScriptAssemblies\Unity.VSCode.Editor.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="Unity.TextMeshPro.Editor">
|
||||||
|
<HintPath>E:\project\JNFrame2\Library\ScriptAssemblies\Unity.TextMeshPro.Editor.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="Unity.VisualStudio.Editor">
|
||||||
|
<HintPath>E:\project\JNFrame2\Library\ScriptAssemblies\Unity.VisualStudio.Editor.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="Unity.Performance.Profile-Analyzer.Editor">
|
||||||
|
<HintPath>E:\project\JNFrame2\Library\ScriptAssemblies\Unity.Performance.Profile-Analyzer.Editor.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="Unity.TestTools.CodeCoverage.Editor.OpenCover.Model">
|
||||||
|
<HintPath>E:\project\JNFrame2\Library\ScriptAssemblies\Unity.TestTools.CodeCoverage.Editor.OpenCover.Model.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="Unity.Timeline">
|
||||||
|
<HintPath>E:\project\JNFrame2\Library\ScriptAssemblies\Unity.Timeline.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="Unity.VisualScripting.Core.Editor">
|
||||||
|
<HintPath>E:\project\JNFrame2\Library\ScriptAssemblies\Unity.VisualScripting.Core.Editor.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="Unity.TextMeshPro">
|
||||||
|
<HintPath>E:\project\JNFrame2\Library\ScriptAssemblies\Unity.TextMeshPro.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="Unity.VisualScripting.State.Editor">
|
||||||
|
<HintPath>E:\project\JNFrame2\Library\ScriptAssemblies\Unity.VisualScripting.State.Editor.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="Unity.VisualScripting.SettingsProvider.Editor">
|
||||||
|
<HintPath>E:\project\JNFrame2\Library\ScriptAssemblies\Unity.VisualScripting.SettingsProvider.Editor.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="Unity.TestTools.CodeCoverage.Editor.OpenCover.Mono.Reflection">
|
||||||
|
<HintPath>E:\project\JNFrame2\Library\ScriptAssemblies\Unity.TestTools.CodeCoverage.Editor.OpenCover.Mono.Reflection.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="UnityEditor.UI">
|
||||||
|
<HintPath>E:\project\JNFrame2\Library\ScriptAssemblies\UnityEditor.UI.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="Unity.PlasticSCM.Editor">
|
||||||
|
<HintPath>E:\project\JNFrame2\Library\ScriptAssemblies\Unity.PlasticSCM.Editor.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="Unity.Rider.Editor">
|
||||||
|
<HintPath>E:\project\JNFrame2\Library\ScriptAssemblies\Unity.Rider.Editor.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="Unity.VisualScripting.Flow">
|
||||||
|
<HintPath>E:\project\JNFrame2\Library\ScriptAssemblies\Unity.VisualScripting.Flow.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="UnityEngine.UI">
|
||||||
|
<HintPath>E:\project\JNFrame2\Library\ScriptAssemblies\UnityEngine.UI.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="Unity.VisualScripting.Core">
|
||||||
|
<HintPath>E:\project\JNFrame2\Library\ScriptAssemblies\Unity.VisualScripting.Core.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="Unity.EditorCoroutines.Editor">
|
||||||
|
<HintPath>E:\project\JNFrame2\Library\ScriptAssemblies\Unity.EditorCoroutines.Editor.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="Cinemachine">
|
||||||
|
<HintPath>E:\project\JNFrame2\Library\ScriptAssemblies\Cinemachine.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="com.unity.cinemachine.editor">
|
||||||
|
<HintPath>E:\project\JNFrame2\Library\ScriptAssemblies\com.unity.cinemachine.editor.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="Unity.VisualScripting.Shared.Editor">
|
||||||
|
<HintPath>E:\project\JNFrame2\Library\ScriptAssemblies\Unity.VisualScripting.Shared.Editor.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="Unity.Timeline.Editor">
|
||||||
|
<HintPath>E:\project\JNFrame2\Library\ScriptAssemblies\Unity.Timeline.Editor.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="Unity.AI.Navigation">
|
||||||
|
<HintPath>E:\project\JNFrame2\Library\ScriptAssemblies\Unity.AI.Navigation.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="Unity.AI.Navigation.Editor">
|
||||||
|
<HintPath>E:\project\JNFrame2\Library\ScriptAssemblies\Unity.AI.Navigation.Editor.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="Unity.TestTools.CodeCoverage.Editor">
|
||||||
|
<HintPath>E:\project\JNFrame2\Library\ScriptAssemblies\Unity.TestTools.CodeCoverage.Editor.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="Unity.VisualScripting.State">
|
||||||
|
<HintPath>E:\project\JNFrame2\Library\ScriptAssemblies\Unity.VisualScripting.State.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="BestHTTP.csproj">
|
||||||
|
<Project>{eb14efbc-e264-9b0a-c04d-d1e93cdf5a63}</Project>
|
||||||
|
<Name>BestHTTP</Name>
|
||||||
|
</ProjectReference>
|
||||||
|
<ProjectReference Include="StompyRobot.SRF.Editor.csproj">
|
||||||
|
<Project>{33448493-9d07-9e6d-e65e-d48b790a1dbf}</Project>
|
||||||
|
<Name>StompyRobot.SRF.Editor</Name>
|
||||||
|
</ProjectReference>
|
||||||
|
<ProjectReference Include="StompyRobot.SRDebugger.csproj">
|
||||||
|
<Project>{786227ef-f2d4-16aa-9b5e-f745e7520e98}</Project>
|
||||||
|
<Name>StompyRobot.SRDebugger</Name>
|
||||||
|
</ProjectReference>
|
||||||
|
<ProjectReference Include="StompyRobot.SRDebugger.Editor.csproj">
|
||||||
|
<Project>{9722de7c-517b-fffe-d423-d313eadf5149}</Project>
|
||||||
|
<Name>StompyRobot.SRDebugger.Editor</Name>
|
||||||
|
</ProjectReference>
|
||||||
|
<ProjectReference Include="UniTask.DOTween.csproj">
|
||||||
|
<Project>{694241c5-b793-03a0-1887-6d1b1abd5716}</Project>
|
||||||
|
<Name>UniTask.DOTween</Name>
|
||||||
|
</ProjectReference>
|
||||||
|
<ProjectReference Include="UniTask.Linq.csproj">
|
||||||
|
<Project>{168b694c-7d58-d228-f9a3-02235c192fc5}</Project>
|
||||||
|
<Name>UniTask.Linq</Name>
|
||||||
|
</ProjectReference>
|
||||||
|
<ProjectReference Include="UniTask.TextMeshPro.csproj">
|
||||||
|
<Project>{023a0336-4680-7ca2-9149-a72dd59bbaf2}</Project>
|
||||||
|
<Name>UniTask.TextMeshPro</Name>
|
||||||
|
</ProjectReference>
|
||||||
|
<ProjectReference Include="AimingRig.csproj">
|
||||||
|
<Project>{7e65388c-f6a7-49e7-107c-67d307ad886b}</Project>
|
||||||
|
<Name>AimingRig</Name>
|
||||||
|
</ProjectReference>
|
||||||
|
<ProjectReference Include="UniTask.csproj">
|
||||||
|
<Project>{bf8742e6-eee2-4cf6-3e82-d12e15802154}</Project>
|
||||||
|
<Name>UniTask</Name>
|
||||||
|
</ProjectReference>
|
||||||
|
<ProjectReference Include="UniTask.Addressables.csproj">
|
||||||
|
<Project>{928a2a75-dd5e-391a-39b4-3b93706f64ec}</Project>
|
||||||
|
<Name>UniTask.Addressables</Name>
|
||||||
|
</ProjectReference>
|
||||||
|
<ProjectReference Include="StompyRobot.SRF.csproj">
|
||||||
|
<Project>{356a0975-52a0-edee-67e5-a8751d23d388}</Project>
|
||||||
|
<Name>StompyRobot.SRF</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>
|
1553
JNFrame2/Assembly-CSharp.csproj
Normal file
1553
JNFrame2/Assembly-CSharp.csproj
Normal file
File diff suppressed because it is too large
Load Diff
3
JNFrame2/Assets/Generated.meta
Normal file
3
JNFrame2/Assets/Generated.meta
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: ee3ebe76e6e141f79efa7b2f63ac1bce
|
||||||
|
timeCreated: 1712545142
|
109
JNFrame2/Assets/Generated/Feature.cs
Normal file
109
JNFrame2/Assets/Generated/Feature.cs
Normal file
@ -0,0 +1,109 @@
|
|||||||
|
//------------------------------------------------------------------------------
|
||||||
|
// <auto-generated>
|
||||||
|
// This code was generated by Entitas.VisualDebugging.CodeGeneration.Plugins.FeatureClassGenerator.
|
||||||
|
//
|
||||||
|
// Changes to this file may cause incorrect behavior and will be lost if
|
||||||
|
// the code is regenerated.
|
||||||
|
// </auto-generated>
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
#if (!ENTITAS_DISABLE_VISUAL_DEBUGGING && UNITY_EDITOR)
|
||||||
|
|
||||||
|
public class Feature : Entitas.VisualDebugging.Unity.DebugSystems {
|
||||||
|
|
||||||
|
public Feature(string name) : base(name) {
|
||||||
|
}
|
||||||
|
|
||||||
|
public Feature() : base(true) {
|
||||||
|
var typeName = DesperateDevs.Extensions.TypeExtension.ToCompilableString(GetType());
|
||||||
|
var shortType = DesperateDevs.Extensions.TypeExtension.ShortTypeName(typeName);
|
||||||
|
var readableType = DesperateDevs.Extensions.StringExtension.ToSpacedCamelCase(shortType);
|
||||||
|
initialize(readableType);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#elif (!ENTITAS_DISABLE_DEEP_PROFILING && DEVELOPMENT_BUILD)
|
||||||
|
|
||||||
|
public class Feature : Entitas.Systems {
|
||||||
|
|
||||||
|
System.Collections.Generic.List<string> _initializeSystemNames;
|
||||||
|
System.Collections.Generic.List<string> _executeSystemNames;
|
||||||
|
System.Collections.Generic.List<string> _cleanupSystemNames;
|
||||||
|
System.Collections.Generic.List<string> _tearDownSystemNames;
|
||||||
|
|
||||||
|
public Feature(string name) : this() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public Feature() {
|
||||||
|
_initializeSystemNames = new System.Collections.Generic.List<string>();
|
||||||
|
_executeSystemNames = new System.Collections.Generic.List<string>();
|
||||||
|
_cleanupSystemNames = new System.Collections.Generic.List<string>();
|
||||||
|
_tearDownSystemNames = new System.Collections.Generic.List<string>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public override Entitas.Systems Add(Entitas.ISystem system) {
|
||||||
|
var systemName = system.GetType().FullName;
|
||||||
|
|
||||||
|
if (system is Entitas.IInitializeSystem) {
|
||||||
|
_initializeSystemNames.Add(systemName);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (system is Entitas.IExecuteSystem) {
|
||||||
|
_executeSystemNames.Add(systemName);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (system is Entitas.ICleanupSystem) {
|
||||||
|
_cleanupSystemNames.Add(systemName);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (system is Entitas.ITearDownSystem) {
|
||||||
|
_tearDownSystemNames.Add(systemName);
|
||||||
|
}
|
||||||
|
|
||||||
|
return base.Add(system);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Initialize() {
|
||||||
|
for (int i = 0; i < _initializeSystems.Count; i++) {
|
||||||
|
UnityEngine.Profiling.Profiler.BeginSample(_initializeSystemNames[i]);
|
||||||
|
_initializeSystems[i].Initialize();
|
||||||
|
UnityEngine.Profiling.Profiler.EndSample();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Execute() {
|
||||||
|
for (int i = 0; i < _executeSystems.Count; i++) {
|
||||||
|
UnityEngine.Profiling.Profiler.BeginSample(_executeSystemNames[i]);
|
||||||
|
_executeSystems[i].Execute();
|
||||||
|
UnityEngine.Profiling.Profiler.EndSample();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Cleanup() {
|
||||||
|
for (int i = 0; i < _cleanupSystems.Count; i++) {
|
||||||
|
UnityEngine.Profiling.Profiler.BeginSample(_cleanupSystemNames[i]);
|
||||||
|
_cleanupSystems[i].Cleanup();
|
||||||
|
UnityEngine.Profiling.Profiler.EndSample();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void TearDown() {
|
||||||
|
for (int i = 0; i < _tearDownSystems.Count; i++) {
|
||||||
|
UnityEngine.Profiling.Profiler.BeginSample(_tearDownSystemNames[i]);
|
||||||
|
_tearDownSystems[i].TearDown();
|
||||||
|
UnityEngine.Profiling.Profiler.EndSample();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
public class Feature : Entitas.Systems {
|
||||||
|
|
||||||
|
public Feature(string name) {
|
||||||
|
}
|
||||||
|
|
||||||
|
public Feature() {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
3
JNFrame2/Assets/Generated/Feature.cs.meta
Normal file
3
JNFrame2/Assets/Generated/Feature.cs.meta
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 1b3a7a38d8a04dc4b203b39287615992
|
||||||
|
timeCreated: 1712545153
|
8
JNFrame2/Assets/JNGame.meta
Normal file
8
JNFrame2/Assets/JNGame.meta
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 262a8509f1a5bf741b5f85a2139411fe
|
||||||
|
folderAsset: yes
|
||||||
|
DefaultImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
3
JNFrame2/Assets/JNGame/EntitasExtend.meta
Normal file
3
JNFrame2/Assets/JNGame/EntitasExtend.meta
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 2dc2b025cc73430e8ca2ddb34aff461d
|
||||||
|
timeCreated: 1715159440
|
44
JNFrame2/Assets/JNGame/EntitasExtend/JNLookup.cs
Normal file
44
JNFrame2/Assets/JNGame/EntitasExtend/JNLookup.cs
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using Entitas;
|
||||||
|
using JNGame.Util.Types;
|
||||||
|
|
||||||
|
namespace JNGame.EntitasExtend
|
||||||
|
{
|
||||||
|
public abstract class JNLookup
|
||||||
|
{
|
||||||
|
|
||||||
|
private int _index = 0;
|
||||||
|
|
||||||
|
public int Count => _index + 1;
|
||||||
|
|
||||||
|
public int Next()
|
||||||
|
{
|
||||||
|
return _index++;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private readonly KeyValue<int, Type> _types = new();
|
||||||
|
|
||||||
|
public JNLookup()
|
||||||
|
{
|
||||||
|
BindIndex();
|
||||||
|
BindType(_types);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected abstract void BindIndex();
|
||||||
|
protected abstract void BindType(KeyValue<int, Type> types);
|
||||||
|
|
||||||
|
//查询下标
|
||||||
|
public int GetIndex(Type type)
|
||||||
|
{
|
||||||
|
return _types.Value2Key(type);
|
||||||
|
}
|
||||||
|
//查询下标
|
||||||
|
public int GetIndex<T>()
|
||||||
|
{
|
||||||
|
return _types.Value2Key(typeof(T));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
3
JNFrame2/Assets/JNGame/EntitasExtend/JNLookup.cs.meta
Normal file
3
JNFrame2/Assets/JNGame/EntitasExtend/JNLookup.cs.meta
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 2bc1af669bc0434ba4c21616d82b4c40
|
||||||
|
timeCreated: 1720750362
|
10
JNFrame2/Assets/JNGame/EntitasExtend/JNSystemLoad.cs
Normal file
10
JNFrame2/Assets/JNGame/EntitasExtend/JNSystemLoad.cs
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
using Cysharp.Threading.Tasks;
|
||||||
|
using Entitas;
|
||||||
|
|
||||||
|
namespace JNGame.EntitasExtend
|
||||||
|
{
|
||||||
|
public class JNSystemLoad : ISystem
|
||||||
|
{
|
||||||
|
public virtual async UniTask Init(){}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,3 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: df35cc9e536a41b6901e0184f24421a4
|
||||||
|
timeCreated: 1715159481
|
44
JNFrame2/Assets/JNGame/JNetGame.cs
Normal file
44
JNFrame2/Assets/JNGame/JNetGame.cs
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
using System;
|
||||||
|
using Cysharp.Threading.Tasks;
|
||||||
|
using JNGame.Util;
|
||||||
|
using Plugins.JNGame.System;
|
||||||
|
|
||||||
|
namespace JNGame
|
||||||
|
{
|
||||||
|
public class JNetGame : SingletonScene<JNetGame>
|
||||||
|
{
|
||||||
|
private SystemBase[] _systems;
|
||||||
|
public async UniTask Init(SystemBase[] systems)
|
||||||
|
{
|
||||||
|
_systems = systems;
|
||||||
|
foreach (var system in _systems)
|
||||||
|
{
|
||||||
|
if (system is not null)
|
||||||
|
{
|
||||||
|
await system.OnInit();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Close()
|
||||||
|
{
|
||||||
|
if (_systems is not null)
|
||||||
|
{
|
||||||
|
foreach (var system in _systems)
|
||||||
|
{
|
||||||
|
system?.OnClose();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnApplicationQuit()
|
||||||
|
{
|
||||||
|
Close();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnDispose()
|
||||||
|
{
|
||||||
|
Close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
3
JNFrame2/Assets/JNGame/JNetGame.cs.meta
Normal file
3
JNFrame2/Assets/JNGame/JNetGame.cs.meta
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 251a7edbf0764857b9a7c6d80ce1cdd3
|
||||||
|
timeCreated: 1721384755
|
3
JNFrame2/Assets/JNGame/Map.meta
Normal file
3
JNFrame2/Assets/JNGame/Map.meta
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 2506063f96674267bf87277fdf1884ff
|
||||||
|
timeCreated: 1715151805
|
3
JNFrame2/Assets/JNGame/Map/2DPathFinding.meta
Normal file
3
JNFrame2/Assets/JNGame/Map/2DPathFinding.meta
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 414fc775b19c49b987762f028d6b815a
|
||||||
|
timeCreated: 1715152183
|
8
JNFrame2/Assets/JNGame/Map/2DPathFinding/BSP.meta
Normal file
8
JNFrame2/Assets/JNGame/Map/2DPathFinding/BSP.meta
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 34971619b0c1f46b4b29e418d346d483
|
||||||
|
folderAsset: yes
|
||||||
|
DefaultImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
131
JNFrame2/Assets/JNGame/Map/2DPathFinding/BSP/BspTree.UnityExt.cs
Normal file
131
JNFrame2/Assets/JNGame/Map/2DPathFinding/BSP/BspTree.UnityExt.cs
Normal file
@ -0,0 +1,131 @@
|
|||||||
|
|
||||||
|
// 定义BspTree的Unity可视化扩展
|
||||||
|
|
||||||
|
//#define SHOW_BSP_TREE_GIZOMS
|
||||||
|
#if UNITY_EDITOR // && SHOW_BSP_TREE_GIZOMS
|
||||||
|
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using JNGame.Math;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
namespace JNGame.PathFinding
|
||||||
|
{
|
||||||
|
// BspTreeNode的调试信息
|
||||||
|
public partial class BspTreeNode
|
||||||
|
{
|
||||||
|
public static int s_AutoIncretID = 0;
|
||||||
|
|
||||||
|
public int debugNodeId;
|
||||||
|
public BspTreeNode()
|
||||||
|
{
|
||||||
|
debugNodeId = ++s_AutoIncretID;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// BspTree的可视化绘制
|
||||||
|
public partial class BspTree
|
||||||
|
{
|
||||||
|
#region Debug Gizoms
|
||||||
|
public static Transform s_DebugTrans;
|
||||||
|
public static Material s_DebugMat;
|
||||||
|
|
||||||
|
public void DebugDraw()
|
||||||
|
{
|
||||||
|
var tran = DrawNode(m_RootNode, 0, s_DebugTrans);
|
||||||
|
tran.transform.position += Vector3.up * 0.05f;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Vector3 Hash13(int id)
|
||||||
|
{
|
||||||
|
var val = (Mathf.Sin(15741.254f * id) + 1) / 2;
|
||||||
|
var val2 = (Mathf.Sin(7331.5147f * id) + 1) / 2;
|
||||||
|
var val3 = (Mathf.Sin(24317.433f * id) + 1) / 2;
|
||||||
|
return new Vector3(val, val2, val3);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Transform DrawNode(BspTreeNode node, int depth, Transform parent)
|
||||||
|
{
|
||||||
|
var val = Hash13(node.debugNodeId);
|
||||||
|
Color color = new Color(val.x, val.y, val.z, 1);
|
||||||
|
if (node.IsLeaf)
|
||||||
|
{
|
||||||
|
var tran = CreateGo(node.debugNodeId.ToString(), node.tris, color).transform;
|
||||||
|
tran.SetParent(parent, true);
|
||||||
|
return tran;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var tran = CreateGo(node.debugNodeId.ToString(), node.splitLine, color).transform;
|
||||||
|
tran.SetParent(parent, true);
|
||||||
|
|
||||||
|
DrawNode(node.LeftChild, depth + 1, tran);
|
||||||
|
DrawNode(node.RightChild, depth + 1, tran);
|
||||||
|
return tran;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private GameObject CreateGo(string name, in SplitLine plane, in Color color)
|
||||||
|
{
|
||||||
|
return new GameObject(name);
|
||||||
|
#if false
|
||||||
|
var dir = plane.Direction.Normalized;
|
||||||
|
var or = plane.vertexA;
|
||||||
|
var s = or - dir * worldSize;
|
||||||
|
var e = or + dir * worldSize;
|
||||||
|
var perp = new LVector2(-dir.y, dir.x);
|
||||||
|
const float lineSize = 0.3f;
|
||||||
|
var s1 = perp * lineSize.ToLFloat() + s;
|
||||||
|
var e1 = perp * lineSize.ToLFloat() + e;
|
||||||
|
List<Vector3> vertices = new List<Vector3>();
|
||||||
|
List<int> tirs = new List<int>();
|
||||||
|
vertices.Add(s.ToVector3XZ());
|
||||||
|
vertices.Add(e.ToVector3XZ());
|
||||||
|
vertices.Add(e1.ToVector3XZ());
|
||||||
|
vertices.Add(s1.ToVector3XZ());
|
||||||
|
int triIdx = 0;
|
||||||
|
tirs.Add(0);
|
||||||
|
tirs.Add(1);
|
||||||
|
tirs.Add(2);
|
||||||
|
tirs.Add(0);
|
||||||
|
tirs.Add(2);
|
||||||
|
tirs.Add(3);
|
||||||
|
return CreateGo(name, vertices, tirs, color);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
private GameObject CreateGo(string name, List<TriangleRef> allRawTriangle, in Color color)
|
||||||
|
{
|
||||||
|
List<Vector3> vertices = new List<Vector3>();
|
||||||
|
List<int> tirs = new List<int>();
|
||||||
|
int triIdx = 0;
|
||||||
|
foreach (var tri in allRawTriangle)
|
||||||
|
{
|
||||||
|
vertices.Add(tri.vertexA.ToVector3XZ());
|
||||||
|
vertices.Add(tri.vertexB.ToVector3XZ());
|
||||||
|
vertices.Add(tri.vertexC.ToVector3XZ());
|
||||||
|
tirs.Add(triIdx++);
|
||||||
|
tirs.Add(triIdx++);
|
||||||
|
tirs.Add(triIdx++);
|
||||||
|
}
|
||||||
|
|
||||||
|
return CreateGo(name, vertices, tirs, color);
|
||||||
|
}
|
||||||
|
|
||||||
|
private GameObject CreateGo(string name, List<Vector3> vertices, List<int> tirs, in Color color)
|
||||||
|
{
|
||||||
|
var go = new GameObject(name);
|
||||||
|
var render = go.AddComponent<MeshRenderer>();
|
||||||
|
var mat = new Material(s_DebugMat) { color = color };
|
||||||
|
render.material = mat;
|
||||||
|
|
||||||
|
var tempMesh = new Mesh();
|
||||||
|
tempMesh.vertices = vertices.ToArray();
|
||||||
|
tempMesh.triangles = tirs.ToArray();
|
||||||
|
go.AddComponent<MeshFilter>().mesh = tempMesh;
|
||||||
|
return go;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: ba3cb62d3cc64ae4a94be3cbd1bf6ef8
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
63
JNFrame2/Assets/JNGame/Map/2DPathFinding/BSP/BspTree.cs
Normal file
63
JNFrame2/Assets/JNGame/Map/2DPathFinding/BSP/BspTree.cs
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using JNGame.Math;
|
||||||
|
|
||||||
|
namespace JNGame.PathFinding
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 二叉空间分割树
|
||||||
|
/// </summary>
|
||||||
|
public partial class BspTree
|
||||||
|
{
|
||||||
|
private readonly List<TriangleRef> m_AllTriangle = new List<TriangleRef>();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 根节点
|
||||||
|
/// </summary>
|
||||||
|
private BspTreeNode m_RootNode;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 查找点邻接三角形的缓存,每次查找都会清理,外部不可缓存此列表,只可一次性使用
|
||||||
|
/// </summary>
|
||||||
|
private readonly List<int> m_TempNeareastTrianges = new List<int>(16);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 构造二叉空间分割树
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="rawTriangles">原始的三角形数据</param>
|
||||||
|
public void Init(List<NavTriangle> rawTriangles)
|
||||||
|
{
|
||||||
|
foreach (var tri in rawTriangles)
|
||||||
|
{
|
||||||
|
m_AllTriangle.Add(new TriangleRef(tri));
|
||||||
|
}
|
||||||
|
|
||||||
|
m_RootNode = new BspTreeNode();
|
||||||
|
m_RootNode.Init(m_AllTriangle);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 根据位置检索BSP树,快速定位点所在三角形区域
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="pos"></param>
|
||||||
|
/// <param name="nearTriangleIndices"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public int GetTriangle(in LVector3 pos, out List<int> nearTriangleIndices)
|
||||||
|
{
|
||||||
|
m_TempNeareastTrianges.Clear();
|
||||||
|
var pos2d = pos.ToLVector2XZ();
|
||||||
|
int triangleIndex = m_RootNode.GetTriangle(pos2d, out _, out List<TriangleRef> nearTriangles);
|
||||||
|
if (triangleIndex == -1)
|
||||||
|
{ // 未找到落位的三角形,说明在阻挡内,获取阻挡周边的一些三角形
|
||||||
|
for (int i = 0; i < nearTriangles.Count; ++i)
|
||||||
|
{
|
||||||
|
if (!m_TempNeareastTrianges.Contains(nearTriangles[i].index))
|
||||||
|
{
|
||||||
|
m_TempNeareastTrianges.Add(nearTriangles[i].index);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
nearTriangleIndices = m_TempNeareastTrianges;
|
||||||
|
return triangleIndex;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
11
JNFrame2/Assets/JNGame/Map/2DPathFinding/BSP/BspTree.cs.meta
Normal file
11
JNFrame2/Assets/JNGame/Map/2DPathFinding/BSP/BspTree.cs.meta
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 477985406605c4a0c9d9718247233d1d
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
315
JNFrame2/Assets/JNGame/Map/2DPathFinding/BSP/BspTreeNode.cs
Normal file
315
JNFrame2/Assets/JNGame/Map/2DPathFinding/BSP/BspTreeNode.cs
Normal file
@ -0,0 +1,315 @@
|
|||||||
|
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using JNGame.Math;
|
||||||
|
|
||||||
|
namespace JNGame.PathFinding
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 二叉空间分割树节点
|
||||||
|
/// </summary>
|
||||||
|
public partial class BspTreeNode
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 划分到三角形数小于此则停止,可以性能测试下,选择一个合适的值
|
||||||
|
/// </summary>
|
||||||
|
private const int kMinTriangleCount = 3;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 找到树叶节点,向上取三层,获取包含的三角形,用于查找落位阻挡点的临近三角形
|
||||||
|
/// </summary>
|
||||||
|
private const int kNearestDeepSearch = 3;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 当前节点中包含的三角形数据
|
||||||
|
/// </summary>
|
||||||
|
public List<TriangleRef> tris;
|
||||||
|
/// <summary>
|
||||||
|
/// 当前节点的子节点
|
||||||
|
/// </summary>
|
||||||
|
private BspTreeNode[] m_Children;
|
||||||
|
/// <summary>
|
||||||
|
/// 当前节点的树深
|
||||||
|
/// </summary>
|
||||||
|
public int depth = 0;
|
||||||
|
/// <summary>
|
||||||
|
/// 节点的切割线
|
||||||
|
/// </summary>
|
||||||
|
public SplitLine splitLine;
|
||||||
|
/// <summary>
|
||||||
|
/// 是否是叶子节点
|
||||||
|
/// </summary>
|
||||||
|
public bool IsLeaf => m_Children == null;
|
||||||
|
/// <summary>
|
||||||
|
/// 左子树
|
||||||
|
/// </summary>
|
||||||
|
public BspTreeNode LeftChild => m_Children?[0];
|
||||||
|
/// <summary>
|
||||||
|
/// 右子树
|
||||||
|
/// </summary>
|
||||||
|
public BspTreeNode RightChild => m_Children?[1];
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取指定坐标所在的三角形索引
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="pos"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public int GetTriangle(in LVector2 pos, out int searchDeep, out List<TriangleRef> triangeGroup)
|
||||||
|
{
|
||||||
|
if (IsLeaf)
|
||||||
|
{
|
||||||
|
searchDeep = -1;
|
||||||
|
triangeGroup = null;
|
||||||
|
foreach (var tri in tris)
|
||||||
|
{
|
||||||
|
if (tri.Contain(pos))
|
||||||
|
{
|
||||||
|
return tri.index;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
searchDeep = kNearestDeepSearch;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var isLeft = LVector2.Cross(splitLine.vertexB - splitLine.vertexA, pos - splitLine.vertexA) >= 0;
|
||||||
|
if (isLeft)
|
||||||
|
{
|
||||||
|
int targetIndex = LeftChild.GetTriangle(pos, out searchDeep, out triangeGroup);
|
||||||
|
if (targetIndex == -1)
|
||||||
|
{
|
||||||
|
--searchDeep;
|
||||||
|
if (searchDeep == 0)
|
||||||
|
{
|
||||||
|
triangeGroup = tris;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return targetIndex;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
int targetIndex = RightChild.GetTriangle(pos, out searchDeep, out triangeGroup);
|
||||||
|
if (targetIndex == -1)
|
||||||
|
{
|
||||||
|
--searchDeep;
|
||||||
|
if (searchDeep == 0)
|
||||||
|
{
|
||||||
|
triangeGroup = tris;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return targetIndex;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 初始化二叉空间树的节点
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="tris"></param>
|
||||||
|
/// <param name="depth"></param>
|
||||||
|
public void Init(List<TriangleRef> tris, int depth = 0)
|
||||||
|
{
|
||||||
|
this.depth = depth;
|
||||||
|
this.tris = tris;
|
||||||
|
|
||||||
|
if (tris.Count <= kMinTriangleCount)
|
||||||
|
{ // 三角形数少于指标,停止
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (depth > 20)
|
||||||
|
{ // 树深超过20层,停止
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// 选择分割线
|
||||||
|
splitLine = PickSplitLine(tris);
|
||||||
|
m_Children = new BspTreeNode[] { new BspTreeNode(), new BspTreeNode() };
|
||||||
|
var lTris = new List<TriangleRef>();
|
||||||
|
var rTris = new List<TriangleRef>();
|
||||||
|
foreach (var tri in tris)
|
||||||
|
{
|
||||||
|
var val = SplitLine.GetSplitResult(in splitLine, tri);
|
||||||
|
if (val == EnumSplitType.Left)
|
||||||
|
{ // 三角形位于切割线左侧,加入左子树三角形列表
|
||||||
|
lTris.Add(tri);
|
||||||
|
}
|
||||||
|
else if (val == EnumSplitType.Right)
|
||||||
|
{ // 三角形位于切割线右侧,加入右子树三角形列表
|
||||||
|
rTris.Add(tri);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{ // 切割线经过三角形,将三角形分为几个多边形
|
||||||
|
SplitTriangle(lTris, rTris, tri);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
LeftChild.Init(lTris, depth + 1);
|
||||||
|
RightChild.Init(rTris, depth + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
private readonly List<LVector2> m_RightVerts = new List<LVector2>();
|
||||||
|
private readonly List<LVector2> m_LeftVerts = new List<LVector2>();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 将三角形按切割线切割为若干个三角形
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="lTris"></param>
|
||||||
|
/// <param name="rTris"></param>
|
||||||
|
/// <param name="tri"></param>
|
||||||
|
private void SplitTriangle(List<TriangleRef> lTris, List<TriangleRef> rTris, TriangleRef tri)
|
||||||
|
{
|
||||||
|
int numVerts = 3;
|
||||||
|
m_RightVerts.Clear();
|
||||||
|
m_LeftVerts.Clear();
|
||||||
|
var a = tri[2];
|
||||||
|
var aSide = SplitLine.ClassifyPointToPlane(splitLine, a);
|
||||||
|
for (int i = 0; i < numVerts; i++)
|
||||||
|
{
|
||||||
|
var b = tri[i];
|
||||||
|
var bSide = SplitLine.ClassifyPointToPlane(splitLine, b);
|
||||||
|
if (bSide == EnumSplitType.Right)
|
||||||
|
{
|
||||||
|
if (aSide == EnumSplitType.Left)
|
||||||
|
{
|
||||||
|
var p = SplitLine.GetIntersectPoint(a, b, splitLine.vertexA, splitLine.vertexB);
|
||||||
|
m_RightVerts.Add(p);
|
||||||
|
m_LeftVerts.Add(p);
|
||||||
|
}
|
||||||
|
else if (aSide == EnumSplitType.OnPlane)
|
||||||
|
{
|
||||||
|
if (m_RightVerts.Count == 0 || a != m_RightVerts[m_RightVerts.Count - 1])
|
||||||
|
{
|
||||||
|
m_RightVerts.Add(a);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
m_RightVerts.Add(b);
|
||||||
|
}
|
||||||
|
else if (bSide == EnumSplitType.Left)
|
||||||
|
{
|
||||||
|
if (aSide == EnumSplitType.Right)
|
||||||
|
{
|
||||||
|
var p = SplitLine.GetIntersectPoint(a, b, splitLine.vertexA, splitLine.vertexB);
|
||||||
|
m_RightVerts.Add(p);
|
||||||
|
m_LeftVerts.Add(p);
|
||||||
|
}
|
||||||
|
else if (aSide == EnumSplitType.OnPlane)
|
||||||
|
{
|
||||||
|
if (m_LeftVerts.Count == 0 || a != m_LeftVerts[m_LeftVerts.Count - 1])
|
||||||
|
{
|
||||||
|
m_LeftVerts.Add(a);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
m_LeftVerts.Add(b);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (aSide == EnumSplitType.Right)
|
||||||
|
{
|
||||||
|
if (!(m_RightVerts.Count == 3 && b == m_RightVerts[0]))
|
||||||
|
{
|
||||||
|
m_RightVerts.Add(b);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (aSide == EnumSplitType.Left)
|
||||||
|
{
|
||||||
|
if (!(m_LeftVerts.Count == 3 && b == m_LeftVerts[0]))
|
||||||
|
{
|
||||||
|
m_LeftVerts.Add(b);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
a = b;
|
||||||
|
aSide = bSide;
|
||||||
|
}
|
||||||
|
|
||||||
|
//push into tri list
|
||||||
|
if (m_LeftVerts.Count >= 3)
|
||||||
|
{
|
||||||
|
if (m_LeftVerts.Count == 3)
|
||||||
|
{
|
||||||
|
AddTriangle(lTris, m_LeftVerts[0], m_LeftVerts[1], m_LeftVerts[2], tri);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Debug.Assert(m_LeftVerts.Count == 4);
|
||||||
|
AddTriangle(lTris, m_LeftVerts[0], m_LeftVerts[1], m_LeftVerts[2], tri);
|
||||||
|
AddTriangle(lTris, m_LeftVerts[0], m_LeftVerts[2], m_LeftVerts[3], tri);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_RightVerts.Count >= 3)
|
||||||
|
{
|
||||||
|
if (m_RightVerts.Count == 3)
|
||||||
|
{
|
||||||
|
AddTriangle(rTris, m_RightVerts[0], m_RightVerts[1], m_RightVerts[2], tri);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Debug.Assert(m_RightVerts.Count == 4);
|
||||||
|
AddTriangle(rTris, m_RightVerts[0], m_RightVerts[1], m_RightVerts[2], tri);
|
||||||
|
AddTriangle(rTris, m_RightVerts[0], m_RightVerts[2], m_RightVerts[3], tri);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void AddTriangle(List<TriangleRef> triangles, in LVector2 vertexA, in LVector2 vertexB, in LVector2 vertexC, TriangleRef tri)
|
||||||
|
{
|
||||||
|
if (vertexA == vertexB || vertexB == vertexC || vertexC == vertexA) { return; }
|
||||||
|
triangles.Add(new TriangleRef(vertexA, vertexB, vertexC, tri));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 选择一条合适的切割线
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="tris">待切割的三角形集合</param>
|
||||||
|
/// <returns></returns>
|
||||||
|
private static SplitLine PickSplitLine(List<TriangleRef> tris)
|
||||||
|
{
|
||||||
|
int minScore = int.MinValue;
|
||||||
|
int minLCount = 0;
|
||||||
|
int minRCount = 0;
|
||||||
|
SplitLine bestLine = new SplitLine();
|
||||||
|
int[] splitCounter = new int[(int)EnumSplitType.EnumCount]; // 每次切割,三角形位于切割线左右和线上的次数统计
|
||||||
|
var tirCount = tris.Count;
|
||||||
|
foreach (var tri in tris)
|
||||||
|
{ // 遍历所有三角形的边框线,作为切割线来切割空间,计算每次切割的分数,从而选取最优的分割线
|
||||||
|
foreach (var borderLine in tri.borders)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < (int)EnumSplitType.EnumCount; i++)
|
||||||
|
{
|
||||||
|
splitCounter[i] = 0;
|
||||||
|
}
|
||||||
|
foreach (var otherTri in tris)
|
||||||
|
{
|
||||||
|
var val = (int)SplitLine.GetSplitResult(borderLine, otherTri);
|
||||||
|
splitCounter[val]++;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Clock wise =>Left ++ CCW=>Right++// self tri is on the left
|
||||||
|
var leftCount = splitCounter[(int)EnumSplitType.Left];
|
||||||
|
var rightCount = splitCounter[(int)EnumSplitType.Right];
|
||||||
|
var splitCount = splitCounter[(int)EnumSplitType.OnPlane];
|
||||||
|
if ((leftCount == 0 || rightCount == 0) && (leftCount + rightCount) == tirCount)
|
||||||
|
{
|
||||||
|
// 所有的三角形都在同一侧,忽略
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// 根据切割线左右的三角形数,以及切割的三角形数,计算本次分割的得分
|
||||||
|
var balanceVal = LMath.Abs(leftCount - rightCount);
|
||||||
|
var sameVal = LMath.Min(leftCount, rightCount);
|
||||||
|
int score = sameVal * 3 - balanceVal - splitCount * 2;
|
||||||
|
if (score > minScore)
|
||||||
|
{ // 选取得分最高的作为切割线
|
||||||
|
minLCount = leftCount;
|
||||||
|
minRCount = rightCount;
|
||||||
|
minScore = score;
|
||||||
|
bestLine = borderLine;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return bestLine;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 133bf2d5724b64ac0945954588c88155
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
10
JNFrame2/Assets/JNGame/Map/2DPathFinding/BSP/ESplitType.cs
Normal file
10
JNFrame2/Assets/JNGame/Map/2DPathFinding/BSP/ESplitType.cs
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
namespace JNGame.PathFinding
|
||||||
|
{
|
||||||
|
public enum EnumSplitType
|
||||||
|
{
|
||||||
|
Left,
|
||||||
|
Right,
|
||||||
|
OnPlane,
|
||||||
|
EnumCount
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: b9b5e74642ed142cd83c3453ce2d5894
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
115
JNFrame2/Assets/JNGame/Map/2DPathFinding/BSP/SplitLine.cs
Normal file
115
JNFrame2/Assets/JNGame/Map/2DPathFinding/BSP/SplitLine.cs
Normal file
@ -0,0 +1,115 @@
|
|||||||
|
using JNGame.Math;
|
||||||
|
|
||||||
|
namespace JNGame.PathFinding
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 二叉空间树的切割线
|
||||||
|
/// </summary>
|
||||||
|
public struct SplitLine
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 切割线起点
|
||||||
|
/// </summary>
|
||||||
|
public LVector2 vertexA;
|
||||||
|
/// <summary>
|
||||||
|
/// 切割线终点
|
||||||
|
/// </summary>
|
||||||
|
public LVector2 vertexB;
|
||||||
|
/// <summary>
|
||||||
|
/// 切割线方向
|
||||||
|
/// </summary>
|
||||||
|
public readonly LVector2 Direction => vertexB - vertexA;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 构造切割线
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="vertexA"></param>
|
||||||
|
/// <param name="vertexB"></param>
|
||||||
|
public SplitLine(in LVector2 vertexA, in LVector2 vertexB)
|
||||||
|
{
|
||||||
|
this.vertexA = vertexA;
|
||||||
|
this.vertexB = vertexB;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取三角形的切割结果
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="line">切割线</param>
|
||||||
|
/// <param name="tri">切割三角形</param>
|
||||||
|
/// <returns>切割线左侧、右侧或经过切割线</returns>
|
||||||
|
public static EnumSplitType GetSplitResult(in SplitLine line, TriangleRef tri)
|
||||||
|
{
|
||||||
|
var lineDir = line.Direction;
|
||||||
|
// 三角形三个顶点与切割线的位置关系
|
||||||
|
var valA = LVector2.Cross(lineDir, tri.vertexA - line.vertexA);
|
||||||
|
var valB = LVector2.Cross(lineDir, tri.vertexB - line.vertexA);
|
||||||
|
var valC = LVector2.Cross(lineDir, tri.vertexC - line.vertexA);
|
||||||
|
|
||||||
|
var isRight = false;
|
||||||
|
if (valA != 0) isRight = valA < 0;
|
||||||
|
if (valB != 0) isRight = valB < 0;
|
||||||
|
if (valC != 0) isRight = valC < 0;
|
||||||
|
|
||||||
|
var isA = valA <= 0;
|
||||||
|
var isB = valB <= 0;
|
||||||
|
var isC = valC <= 0;
|
||||||
|
if (isA == isB && isB == isC)
|
||||||
|
{
|
||||||
|
return isRight ? EnumSplitType.Right : EnumSplitType.Left;
|
||||||
|
}
|
||||||
|
|
||||||
|
isA = valA >= 0;
|
||||||
|
isB = valB >= 0;
|
||||||
|
isC = valC >= 0;
|
||||||
|
if (isA == isB && isB == isC)
|
||||||
|
{
|
||||||
|
return isRight ? EnumSplitType.Right : EnumSplitType.Left;
|
||||||
|
}
|
||||||
|
|
||||||
|
return EnumSplitType.OnPlane;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取顶点和切割线的位置关系
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="line">切割线</param>
|
||||||
|
/// <param name="vertex">顶点</param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static EnumSplitType ClassifyPointToPlane(in SplitLine line, in LVector2 vertex)
|
||||||
|
{
|
||||||
|
var val = LVector2.Cross(line.Direction, vertex - line.vertexA);
|
||||||
|
if (val == 0)
|
||||||
|
{
|
||||||
|
return EnumSplitType.OnPlane;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return val < 0 ? EnumSplitType.Right : EnumSplitType.Left;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 计算p0p1,p2p3的交点
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="p0"></param>
|
||||||
|
/// <param name="p1"></param>
|
||||||
|
/// <param name="p2"></param>
|
||||||
|
/// <param name="p3"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static LVector2 GetIntersectPoint(in LVector2 p0, in LVector2 p1, in LVector2 p2, in LVector2 p3)
|
||||||
|
{
|
||||||
|
var diff = p2 - p0;
|
||||||
|
var d1 = p1 - p0;
|
||||||
|
var d2 = p3 - p2;
|
||||||
|
var demo = LMath.Cross(d1, d2); //det
|
||||||
|
if (LMath.Abs(demo) < LFloat.EPSILON)
|
||||||
|
{
|
||||||
|
// 叉积结果为0,说明两个向量平行
|
||||||
|
return p0;
|
||||||
|
}
|
||||||
|
|
||||||
|
var t1 = LMath.Cross(diff, d2) / demo; // Cross2D(diff,-d2)
|
||||||
|
return p0 + (p1 - p0) * t1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 6a160827a7e254845beb3b10a0644f26
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
137
JNFrame2/Assets/JNGame/Map/2DPathFinding/BSP/TriangleRef.cs
Normal file
137
JNFrame2/Assets/JNGame/Map/2DPathFinding/BSP/TriangleRef.cs
Normal file
@ -0,0 +1,137 @@
|
|||||||
|
using System;
|
||||||
|
// using JNGame.Collision2D;
|
||||||
|
using JNGame.Math;
|
||||||
|
// using Debug = JNGame.Logging.Debug;
|
||||||
|
|
||||||
|
namespace JNGame.PathFinding
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 导航三角形在二叉空间分割树中的引用
|
||||||
|
/// <para>一个导航三角形可能会被树分割为多个三角形引用</para>
|
||||||
|
/// </summary>
|
||||||
|
public class TriangleRef
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 当前三角形引用关联的导航三角形索引
|
||||||
|
/// </summary>
|
||||||
|
public int index;
|
||||||
|
/// <summary>
|
||||||
|
/// 三角形顶点A
|
||||||
|
/// </summary>
|
||||||
|
public LVector2 vertexA;
|
||||||
|
/// <summary>
|
||||||
|
/// 三角形顶点B
|
||||||
|
/// </summary>
|
||||||
|
public LVector2 vertexB;
|
||||||
|
/// <summary>
|
||||||
|
/// 三角形顶点C
|
||||||
|
/// </summary>
|
||||||
|
public LVector2 vertexC;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 是否是分割的三角形
|
||||||
|
/// </summary>
|
||||||
|
public bool IsSplit { get; private set; } = false;
|
||||||
|
/// <summary>
|
||||||
|
/// 三角形的边框
|
||||||
|
/// </summary>
|
||||||
|
public SplitLine[] borders;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 根据下标获取三角形的顶点,合法下标0/1/2
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="index"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
/// <exception cref="IndexOutOfRangeException"></exception>
|
||||||
|
public LVector2 this[int index]
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return index switch
|
||||||
|
{
|
||||||
|
0 => vertexA,
|
||||||
|
1 => vertexB,
|
||||||
|
2 => vertexC,
|
||||||
|
_ => throw new IndexOutOfRangeException("vector idx invalid" + index),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 根据原始导航三角形创建引用
|
||||||
|
/// <para>由此构造的三角形引用认为是未切割过的三角形</para>
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="srcTriangle">原始的导航三角形</param>
|
||||||
|
public TriangleRef(NavTriangle srcTriangle)
|
||||||
|
: this(srcTriangle.vertexA.ToLVector2XZ(), srcTriangle.vertexB.ToLVector2XZ(), srcTriangle.vertexC.ToLVector2XZ(), srcTriangle.index)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 根据分割的三个顶点和原始导航三角形创建引用
|
||||||
|
/// <para>由此构造的三角形引用认为是切割过的三角形</para>
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="vertexA">三角形顶点A</param>
|
||||||
|
/// <param name="vertexB">三角形顶点B</param>
|
||||||
|
/// <param name="vertexC">三角形顶点C</param>
|
||||||
|
/// <param name="srcTriangle">原始的导航三角形</param>
|
||||||
|
public TriangleRef(in LVector2 vertexA, in LVector2 vertexB, in LVector2 vertexC, TriangleRef srcTriangle)
|
||||||
|
: this(vertexA, vertexB, vertexC, srcTriangle.index)
|
||||||
|
{
|
||||||
|
IsSplit = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 私有构造
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="vertexA">三角形顶点A</param>
|
||||||
|
/// <param name="vertexB">三角形顶点B</param>
|
||||||
|
/// <param name="vertexC">三角形顶点C</param>
|
||||||
|
/// <param name="idx">引用的导航三角形索引</param>
|
||||||
|
private TriangleRef(in LVector2 vertexA, in LVector2 vertexB, in LVector2 vertexC, int idx)
|
||||||
|
{
|
||||||
|
this.vertexA = vertexA;
|
||||||
|
this.vertexB = vertexB;
|
||||||
|
this.vertexC = vertexC;
|
||||||
|
index = idx;
|
||||||
|
borders = new SplitLine[]
|
||||||
|
{
|
||||||
|
new SplitLine(vertexA, vertexB),
|
||||||
|
new SplitLine(vertexB, vertexC),
|
||||||
|
new SplitLine(vertexC, vertexA)
|
||||||
|
};
|
||||||
|
//check valid
|
||||||
|
CheckValid();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 三角形三点不可重合
|
||||||
|
/// </summary>
|
||||||
|
private void CheckValid()
|
||||||
|
{
|
||||||
|
for (int i = 0; i < 3; i++)
|
||||||
|
{
|
||||||
|
if (borders[i].Direction == LVector2.Zero)
|
||||||
|
{
|
||||||
|
// Debug.Assert(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 判断点是否在此三角形内
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="pos"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public bool Contain(in LVector2 pos)
|
||||||
|
{
|
||||||
|
// ABC三个顶点绕序为顺时针,三个叉积都需要为负,则点在三角形内
|
||||||
|
var isRightA = LVector2.Cross(vertexB - vertexA, pos - vertexA) > 0;
|
||||||
|
if (isRightA) return false;
|
||||||
|
var isRightB = LVector2.Cross(vertexC - vertexB, pos - vertexB) > 0;
|
||||||
|
if (isRightB) return false;
|
||||||
|
var isRightC = LVector2.Cross(vertexA - vertexC, pos - vertexC) > 0;
|
||||||
|
if (isRightC) return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 63961ae30f8cb4ca7a519fa7a7cdc394
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
3
JNFrame2/Assets/JNGame/Map/2DPathFinding/Editor.meta
Normal file
3
JNFrame2/Assets/JNGame/Map/2DPathFinding/Editor.meta
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: ac4ba6c0084f4da4adc250c858781ae4
|
||||||
|
timeCreated: 1715151823
|
@ -0,0 +1,325 @@
|
|||||||
|
|
||||||
|
using System.IO;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using JNGame.Map;
|
||||||
|
using Unity.AI.Navigation;
|
||||||
|
using UnityEngine;
|
||||||
|
using UnityEditor;
|
||||||
|
using JNGame.Math;
|
||||||
|
using JNGame.Util;
|
||||||
|
|
||||||
|
namespace JNGame.Game.Editor
|
||||||
|
{
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 简易地图数据导出器
|
||||||
|
/// </summary>
|
||||||
|
[CustomEditor(typeof(GenMapConfigHelper))]
|
||||||
|
public class MapConfigExporter : UnityEditor.Editor
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 导出地图数据存储路径
|
||||||
|
/// </summary>
|
||||||
|
private string m_ExportMapFolder;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 原始Unity烘焙的导航网格数据
|
||||||
|
/// </summary>
|
||||||
|
private UnityEngine.AI.NavMeshTriangulation m_OriginNavMeshTriangulation;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 优化后的Unity烘焙的导航网格数据
|
||||||
|
/// </summary>
|
||||||
|
private UnityEngine.AI.NavMeshTriangulation m_OptimizeNavMeshTriangulation;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 地图配置生成器辅助
|
||||||
|
/// </summary>
|
||||||
|
private GenMapConfigHelper m_GenMapCfgHelper;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 运行时使用的地图数据
|
||||||
|
/// </summary>
|
||||||
|
private StaticMapData m_MapData;
|
||||||
|
|
||||||
|
private void OnEnable()
|
||||||
|
{
|
||||||
|
m_ExportMapFolder = UnityEngine.Application.dataPath + "/Resources/Battle/Map/NavMesh/";
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void OnInspectorGUI()
|
||||||
|
{
|
||||||
|
base.OnInspectorGUI();
|
||||||
|
m_GenMapCfgHelper = target as GenMapConfigHelper;
|
||||||
|
if (GUILayout.Button("构建地图配置"))
|
||||||
|
{
|
||||||
|
if (m_GenMapCfgHelper == null) { return; }
|
||||||
|
// 检查地图导出目录是否存在,不存在则创建
|
||||||
|
if (!Directory.Exists(m_ExportMapFolder))
|
||||||
|
{
|
||||||
|
Directory.CreateDirectory(m_ExportMapFolder);
|
||||||
|
Debug.LogWarning($"导出路径 = {m_ExportMapFolder} 不存在,先创建导出目录!");
|
||||||
|
}
|
||||||
|
m_MapData = new StaticMapData();
|
||||||
|
m_MapData.mapID = m_GenMapCfgHelper.mapID;
|
||||||
|
m_MapData.mapName = string.IsNullOrEmpty(m_GenMapCfgHelper.mapName) ? $"Map_{m_MapData.mapID}" : m_GenMapCfgHelper.mapName;
|
||||||
|
// 导出地图导航数据
|
||||||
|
ExportNavMeshData();
|
||||||
|
// 地图数据写入文件
|
||||||
|
StaticMapDataToFile(m_MapData);
|
||||||
|
AssetDatabase.Refresh();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (GUILayout.Button("地图可视化"))
|
||||||
|
{
|
||||||
|
// m_GenMapCfgHelper.MapVisualize();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 导出地图的导航网格数据
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="mapRootNode"></param>
|
||||||
|
/// <param name="mapCfg"></param>
|
||||||
|
public void ExportNavMeshData()
|
||||||
|
{
|
||||||
|
NavMeshSurface navMeshSurface = m_GenMapCfgHelper.navMeshSurface;
|
||||||
|
navMeshSurface.gameObject.SetActive(false);
|
||||||
|
// 通过Unity构建原生的导航网格数据
|
||||||
|
// navMeshSurface.BuildNavMesh();
|
||||||
|
Profiler.ResetElapseTime();
|
||||||
|
UnityEngine.AI.NavMeshDataInstance handle = UnityEngine.AI.NavMesh.AddNavMeshData(navMeshSurface.navMeshData);
|
||||||
|
m_OriginNavMeshTriangulation = UnityEngine.AI.NavMesh.CalculateTriangulation();
|
||||||
|
Profiler.LogElapseTime("[构建导航网格]");
|
||||||
|
// 优化Unity的NavMesh数据
|
||||||
|
OptimizeNavMeshTriangulation();
|
||||||
|
Profiler.LogElapseTime("[优化导航网格]");
|
||||||
|
// 导出游戏使用的导航网格数据
|
||||||
|
float minX = float.MaxValue;
|
||||||
|
float maxX = float.MinValue;
|
||||||
|
float minZ = float.MaxValue;
|
||||||
|
float maxZ = float.MinValue;
|
||||||
|
foreach (var vertex in m_OptimizeNavMeshTriangulation.vertices)
|
||||||
|
{
|
||||||
|
if (vertex.x > maxX) maxX = vertex.x;
|
||||||
|
if (vertex.x < minX) minX = vertex.x;
|
||||||
|
if (vertex.y > maxX) maxX = vertex.y;
|
||||||
|
if (vertex.y < minX) minX = vertex.y;
|
||||||
|
if (vertex.z > maxZ) maxZ = vertex.z;
|
||||||
|
if (vertex.z < minZ) minZ = vertex.z;
|
||||||
|
}
|
||||||
|
m_MapData.navMeshData = new PathFinding.NavMeshData
|
||||||
|
{
|
||||||
|
mapID = m_MapData.mapID,
|
||||||
|
radius = navMeshSurface.GetBuildSettings().agentRadius.ToLFloat(),
|
||||||
|
xMin = minX.ToLFloat(),
|
||||||
|
zMin = minZ.ToLFloat(),
|
||||||
|
xMax = maxX.ToLFloat(),
|
||||||
|
zMax = maxZ.ToLFloat(),
|
||||||
|
pathTriangles = m_OptimizeNavMeshTriangulation.indices
|
||||||
|
};
|
||||||
|
MergeVertices(m_MapData, m_OptimizeNavMeshTriangulation.vertices);
|
||||||
|
Profiler.LogElapseTime("[合并导航网格]");
|
||||||
|
navMeshSurface.gameObject.SetActive(true);
|
||||||
|
// 移除导航网格数据
|
||||||
|
handle.Remove();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 过滤落在阻挡区域的NavMesh顶点
|
||||||
|
/// </summary>
|
||||||
|
private void OptimizeNavMeshTriangulation()
|
||||||
|
{
|
||||||
|
NavMeshSurface navMeshSurface = m_GenMapCfgHelper.navMeshSurface;
|
||||||
|
NavMeshStaticObstacle[] obstacles = navMeshSurface.gameObject.GetComponentsInChildren<NavMeshStaticObstacle>();
|
||||||
|
m_OptimizeNavMeshTriangulation = m_OriginNavMeshTriangulation;
|
||||||
|
// for (int i = 0; i < m_OptimizeNavMeshTriangulation.vertices.Length; ++i)
|
||||||
|
// {
|
||||||
|
// Vector3 point = m_OptimizeNavMeshTriangulation.vertices[i];
|
||||||
|
// m_OptimizeNavMeshTriangulation.vertices[i] = new Vector3(point.x, 0, point.z);
|
||||||
|
// }
|
||||||
|
if (obstacles == null || obstacles.Length == 0) { return; }
|
||||||
|
List<Vector3> vertices = m_OriginNavMeshTriangulation.vertices.ToList();
|
||||||
|
List<int> indices = m_OriginNavMeshTriangulation.indices.ToList();
|
||||||
|
List<int> delVertexIndices = new List<int>();
|
||||||
|
// 遍历顶点,筛选在阻挡中的顶点
|
||||||
|
for (int i = 0; i < vertices.Count; ++i)
|
||||||
|
{
|
||||||
|
for (int j = 0; j < obstacles.Length; ++j)
|
||||||
|
{
|
||||||
|
if (obstacles[j].IsInObstacle(new Vector3(vertices[i].x, 0, vertices[i].z)))
|
||||||
|
{
|
||||||
|
delVertexIndices.Add(i);
|
||||||
|
break; //
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 移除阻挡内的导航网格顶点,更新索引
|
||||||
|
for (int i = delVertexIndices.Count - 1; i >= 0; --i)
|
||||||
|
{
|
||||||
|
vertices.RemoveAt(delVertexIndices[i]);
|
||||||
|
for (int j = 0; j < indices.Count; ++j)
|
||||||
|
{
|
||||||
|
if (indices[j] == delVertexIndices[i])
|
||||||
|
{
|
||||||
|
indices[j] = -1;
|
||||||
|
}
|
||||||
|
else if (indices[j] > delVertexIndices[i])
|
||||||
|
{
|
||||||
|
--indices[j];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 移除所有标记的索引
|
||||||
|
for (int j = indices.Count - 1; j >= 0; --j)
|
||||||
|
{
|
||||||
|
if (indices[j] == -1)
|
||||||
|
{
|
||||||
|
indices.RemoveAt(j);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
m_OptimizeNavMeshTriangulation = m_OriginNavMeshTriangulation;
|
||||||
|
m_OptimizeNavMeshTriangulation.vertices = vertices.ToArray();
|
||||||
|
m_OptimizeNavMeshTriangulation.indices = indices.ToArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 将Unity生成导航网格顶点数据合并到地图导航数据中
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="mapData">目标地图文件</param>
|
||||||
|
/// <param name="pathVertices">Unity生成的导航网格顶点数据</param>
|
||||||
|
private void MergeVertices(StaticMapData mapData, Vector3[] pathVertices)
|
||||||
|
{
|
||||||
|
var rawCount = pathVertices.Length;
|
||||||
|
var rawVertices = pathVertices;
|
||||||
|
double minGap = 0.05;
|
||||||
|
var dictHashCache = new Dictionary<double, List<Vector3>>();
|
||||||
|
|
||||||
|
double Hash31(Vector3 vec)
|
||||||
|
{
|
||||||
|
return (long)(((double)vec.sqrMagnitude) / minGap) * minGap;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CanMerge(double hash, Vector3 vertex)
|
||||||
|
{
|
||||||
|
bool canMerge = false;
|
||||||
|
for (int j = -1; j <= 1; j++)
|
||||||
|
{
|
||||||
|
var nearHash = hash + minGap * j;
|
||||||
|
if (dictHashCache.TryGetValue(nearHash, out var lst))
|
||||||
|
{
|
||||||
|
foreach (var ver in lst)
|
||||||
|
{
|
||||||
|
if ((ver - vertex).sqrMagnitude < minGap)
|
||||||
|
{
|
||||||
|
canMerge = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (canMerge) break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return canMerge;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < rawVertices.Length; i++)
|
||||||
|
{
|
||||||
|
var vertex = rawVertices[i];
|
||||||
|
var hash = Hash31(vertex);
|
||||||
|
bool canMerge = CanMerge(hash, vertex);
|
||||||
|
if (!canMerge)
|
||||||
|
{
|
||||||
|
if (dictHashCache.TryGetValue(hash, out var lst))
|
||||||
|
{
|
||||||
|
lst.Add(vertex);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
dictHashCache.Add(hash, new List<Vector3>() { vertex });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var newVertices = new List<Vector3>();
|
||||||
|
var pos2Idx = new Dictionary<Vector3, int>();
|
||||||
|
int posIds = 0;
|
||||||
|
foreach (var pair in dictHashCache)
|
||||||
|
{
|
||||||
|
foreach (var vec in pair.Value)
|
||||||
|
{
|
||||||
|
newVertices.Add(vec);
|
||||||
|
pos2Idx.Add(vec, posIds++);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mapData.navMeshData.pathVertices = newVertices.ToArray().ToLVecArray();
|
||||||
|
var rawIdxs = mapData.navMeshData.pathTriangles;
|
||||||
|
var newIdxs = new int[mapData.navMeshData.pathTriangles.Length];
|
||||||
|
for (int i = 0; i < rawIdxs.Length; i++)
|
||||||
|
{
|
||||||
|
var rawVertex = rawVertices[rawIdxs[i]];
|
||||||
|
var hash = Hash31(rawVertex);
|
||||||
|
bool merged = false;
|
||||||
|
for (int j = -1; j <= 1; j++)
|
||||||
|
{
|
||||||
|
var nearHash = hash + minGap * j;
|
||||||
|
if (dictHashCache.TryGetValue(nearHash, out var lst))
|
||||||
|
{
|
||||||
|
foreach (var ver in lst)
|
||||||
|
{
|
||||||
|
if ((ver - rawVertex).magnitude < minGap)
|
||||||
|
{
|
||||||
|
newIdxs[i] = pos2Idx[ver];
|
||||||
|
merged = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (merged) break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!merged)
|
||||||
|
{
|
||||||
|
Debug.LogError($"hehe can not find merge point" + rawVertex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//check the same
|
||||||
|
for (int i = 0; i < rawIdxs.Length; i++)
|
||||||
|
{
|
||||||
|
var rawPos = rawVertices[rawIdxs[i]];
|
||||||
|
var newPos = newVertices[newIdxs[i]];
|
||||||
|
if (rawPos != newPos)
|
||||||
|
{
|
||||||
|
var diff = (rawPos - newPos).sqrMagnitude;
|
||||||
|
if (diff > 0.01f)
|
||||||
|
{
|
||||||
|
Debug.LogError("Miss match pos rawPos:{rawPos} newPos:{newPos} diff = " + diff);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mapData.navMeshData.pathTriangles = newIdxs;
|
||||||
|
Debug.Log($"MergeVertices {rawCount}->{mapData.navMeshData.pathVertices.Length}");
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 地图数据写入到文件中
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="filename"></param>
|
||||||
|
/// <param name="mapData"></param>
|
||||||
|
private void StaticMapDataToFile(StaticMapData staticMapData)
|
||||||
|
{
|
||||||
|
string strMapDataJsonData = JsonUtil.ToJson(staticMapData);
|
||||||
|
Profiler.LogElapseTime("[构建地图Json数据]");
|
||||||
|
string strMapDataPath = m_ExportMapFolder + m_MapData.mapName + ".navmesh.json";
|
||||||
|
using (StreamWriter sw = new StreamWriter(strMapDataPath))
|
||||||
|
{
|
||||||
|
sw.Write(strMapDataJsonData);
|
||||||
|
}
|
||||||
|
Profiler.LogElapseTime("[写入地图文件]");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,3 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 3b9429c876a94cdf85e1829719847076
|
||||||
|
timeCreated: 1715151925
|
@ -0,0 +1,24 @@
|
|||||||
|
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
namespace JNGame.Game.Editor
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 地图编辑时静态阻挡的标记,运行时无用
|
||||||
|
/// </summary>
|
||||||
|
public class NavMeshStaticObstacle : MonoBehaviour
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 判读点是否在阻挡内
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="position"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public bool IsInObstacle(in Vector3 position)
|
||||||
|
{
|
||||||
|
MeshFilter meshFilter = GetComponent<MeshFilter>();
|
||||||
|
if (meshFilter == null || meshFilter.sharedMesh == null) { return false; }
|
||||||
|
Vector3 localPosition = transform.worldToLocalMatrix.MultiplyPoint(position);
|
||||||
|
return meshFilter.sharedMesh.bounds.Contains(localPosition);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,3 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: d90ecad448df4047b9f38f928cc9e15b
|
||||||
|
timeCreated: 1715153091
|
@ -0,0 +1,83 @@
|
|||||||
|
|
||||||
|
using UnityEngine;
|
||||||
|
using JNGame.Math;
|
||||||
|
|
||||||
|
namespace JNGame.Map
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 地图数据
|
||||||
|
/// </summary>
|
||||||
|
[System.Serializable]
|
||||||
|
public class StaticMapData
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 地图ID
|
||||||
|
/// </summary>
|
||||||
|
public int mapID;
|
||||||
|
/// <summary>
|
||||||
|
/// 地图名
|
||||||
|
/// </summary>
|
||||||
|
public string mapName;
|
||||||
|
/// <summary>
|
||||||
|
/// 地图导航网格数据
|
||||||
|
/// </summary>
|
||||||
|
public PathFinding.NavMeshData navMeshData;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 生成地图配置逻辑数据的脚步,仅作为编辑器导出地图场景数据的入口,运行时无作用
|
||||||
|
/// </summary>
|
||||||
|
public class GenMapConfigHelper : MonoBehaviour
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 地图ID
|
||||||
|
/// </summary>
|
||||||
|
public int mapID;
|
||||||
|
/// <summary>
|
||||||
|
/// 地图名
|
||||||
|
/// </summary>
|
||||||
|
public string mapName;
|
||||||
|
/// <summary>
|
||||||
|
/// Unity的Navigation组件
|
||||||
|
/// </summary>
|
||||||
|
public Unity.AI.Navigation.NavMeshSurface navMeshSurface;
|
||||||
|
|
||||||
|
|
||||||
|
private void OnDrawGizmos()
|
||||||
|
{
|
||||||
|
// if (m_MapConfig == null) { return; }
|
||||||
|
// DrawNavMesh();
|
||||||
|
}
|
||||||
|
|
||||||
|
// private void DrawNavMesh()
|
||||||
|
// {
|
||||||
|
// if (m_MapConfig == null || m_MapConfig.navMeshData == null || m_MapConfig.navMeshData.pathTriangles == null) { return; }
|
||||||
|
// int i = 0;
|
||||||
|
// Gizmos.color = Color.green;
|
||||||
|
// while (i < m_MapConfig.navMeshData.pathTriangles.Length)
|
||||||
|
// {
|
||||||
|
// int aIndex = m_MapConfig.navMeshData.pathTriangles[i++];
|
||||||
|
// int bIndex = m_MapConfig.navMeshData.pathTriangles[i++];
|
||||||
|
// int cIndex = m_MapConfig.navMeshData.pathTriangles[i++];
|
||||||
|
|
||||||
|
// Vector3 vertexA = m_MapConfig.navMeshData.pathVertices[aIndex].ToVector3();
|
||||||
|
// Vector3 vertexB = m_MapConfig.navMeshData.pathVertices[bIndex].ToVector3();
|
||||||
|
// Vector3 vertexC = m_MapConfig.navMeshData.pathVertices[cIndex].ToVector3();
|
||||||
|
|
||||||
|
// Gizmos.DrawLine(vertexA, vertexB);
|
||||||
|
// Gizmos.DrawLine(vertexB, vertexC);
|
||||||
|
// Gizmos.DrawLine(vertexC, vertexA);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// Gizmos.color = Color.blue;
|
||||||
|
// Vector3 bottomLeft = new LVector3(m_MapConfig.navMeshData.xMin, 0.ToLFloat(), m_MapConfig.navMeshData.zMin).ToVector3();
|
||||||
|
// Vector3 bottomRight = new LVector3(m_MapConfig.navMeshData.xMax, 0.ToLFloat(), m_MapConfig.navMeshData.zMin).ToVector3();
|
||||||
|
// Vector3 topLeft = new LVector3(m_MapConfig.navMeshData.xMin, 0.ToLFloat(), m_MapConfig.navMeshData.zMax).ToVector3();
|
||||||
|
// Vector3 topRight = new LVector3(m_MapConfig.navMeshData.xMax, 0.ToLFloat(), m_MapConfig.navMeshData.zMax).ToVector3();
|
||||||
|
// Gizmos.DrawLine(bottomLeft, bottomRight);
|
||||||
|
// Gizmos.DrawLine(bottomLeft, topLeft);
|
||||||
|
// Gizmos.DrawLine(bottomRight, topRight);
|
||||||
|
// Gizmos.DrawLine(topLeft, topRight);
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,3 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: c7bfc1bbc6a14b83a73b6c061d4f8227
|
||||||
|
timeCreated: 1715151863
|
8
JNFrame2/Assets/JNGame/Map/2DPathFinding/NavMesh.meta
Normal file
8
JNFrame2/Assets/JNGame/Map/2DPathFinding/NavMesh.meta
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 7f7bde9205575458d94afea935c783d8
|
||||||
|
folderAsset: yes
|
||||||
|
DefaultImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
@ -0,0 +1,8 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 6fa8733a350b745f291097ea3eb01303
|
||||||
|
folderAsset: yes
|
||||||
|
DefaultImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
@ -0,0 +1,242 @@
|
|||||||
|
using JNGame.Math;
|
||||||
|
|
||||||
|
namespace JNGame.PathFinding
|
||||||
|
{
|
||||||
|
public static class GeometryUtil
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Projects a point to a line segment.
|
||||||
|
/// <para>This implementation is thread-safe.</para>
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="nearest">输出:点point在线段的投影点</param>
|
||||||
|
/// <param name="start">线段起点</param>
|
||||||
|
/// <param name="end">线段终点</param>
|
||||||
|
/// <param name="point">被投影的原始点</param>
|
||||||
|
/// <returns>投影点与原始点的距离平方</returns>
|
||||||
|
public static LFloat NearestSegmentPointSquareDistance(ref LVector3 nearest, in LVector3 start, in LVector3 end, in LVector3 point)
|
||||||
|
{
|
||||||
|
nearest = start;
|
||||||
|
// 线段AB
|
||||||
|
var abX = end.x - start.x;
|
||||||
|
var abY = end.y - start.y;
|
||||||
|
var abZ = end.z - start.z;
|
||||||
|
// 线段AB的长度平方
|
||||||
|
var abLen2 = abX * abX + abY * abY + abZ * abZ;
|
||||||
|
if (abLen2 > 0)
|
||||||
|
{ // Avoid NaN due to the indeterminate form 0/0
|
||||||
|
// 投影点在线段上的比例位置
|
||||||
|
var t = ((point.x - start.x) * abX + (point.y - start.y) * abY + (point.z - start.z) * abZ) / abLen2;
|
||||||
|
var s = LMath.Clamp01(t);
|
||||||
|
nearest.x += abX * s;
|
||||||
|
nearest.y += abY * s;
|
||||||
|
nearest.z += abZ * s;
|
||||||
|
}
|
||||||
|
return LVector3.Distance2(nearest, point);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Find the closest point on the triangle, given a measure point.
|
||||||
|
/// This is the optimized algorithm taken from the book "Real-Time Collision Detection".
|
||||||
|
/// <para>This implementation is NOT thread-safe.</para>
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="vertexA"></param>
|
||||||
|
/// <param name="vertexB"></param>
|
||||||
|
/// <param name="vertexC"></param>
|
||||||
|
/// <param name="p"></param>
|
||||||
|
/// <param name="_out"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static LFloat GetClosestPointOnTriangle(in LVector3 vertexA, in LVector3 vertexB, in LVector3 vertexC, in LVector3 p, ref LVector3 _out)
|
||||||
|
{
|
||||||
|
// Check if P in vertex region outside A
|
||||||
|
var ab = vertexB - vertexA;
|
||||||
|
var ac = vertexC - vertexA;
|
||||||
|
var ap = p - vertexA;
|
||||||
|
var d1 = LVector3.Dot(ab, ap);
|
||||||
|
var d2 = LVector3.Dot(ac, ap);
|
||||||
|
if (d1 <= 0 && d2 <= 0)
|
||||||
|
{
|
||||||
|
_out = vertexA;
|
||||||
|
return LVector3.Distance2(p, vertexA);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if P in vertex region outside B
|
||||||
|
var bp = p - vertexB;
|
||||||
|
var d3 = LVector3.Dot(ab, bp);
|
||||||
|
var d4 = LVector3.Dot(ac, bp);
|
||||||
|
if (d3 >= 0 && d4 <= d3)
|
||||||
|
{
|
||||||
|
_out = vertexB;
|
||||||
|
return LVector3.Distance2(p, vertexB);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if P in edge region of AB, if so return projection of P onto AB
|
||||||
|
var vc = d1 * d4 - d3 * d2;
|
||||||
|
if (vc <= 0 && d1 >= 0 && d3 <= 0)
|
||||||
|
{
|
||||||
|
var v = d1 / (d1 - d3);
|
||||||
|
_out = vertexA + ab * v; // barycentric coordinates (1-v,v,0)
|
||||||
|
return LVector3.Distance2(p, _out);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if P in vertex region outside C
|
||||||
|
var cp = p - vertexC;
|
||||||
|
var d5 = LVector3.Dot(ab, cp);
|
||||||
|
var d6 = LVector3.Dot(ac, cp);
|
||||||
|
if (d6 >= 0 && d5 <= d6)
|
||||||
|
{
|
||||||
|
_out = vertexC;
|
||||||
|
return LVector3.Distance2(p, vertexC);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if P in edge region of AC, if so return projection of P onto AC
|
||||||
|
var vb = d5 * d2 - d1 * d6;
|
||||||
|
if (vb <= 0 && d2 >= 0 && d6 <= 0)
|
||||||
|
{
|
||||||
|
var w = d2 / (d2 - d6);
|
||||||
|
_out = vertexA + ac * w; // barycentric coordinates (1-w,0,w)
|
||||||
|
return LVector3.Distance2(_out, p);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if P in edge region of BC, if so return projection of P onto BC
|
||||||
|
var va = d3 * d6 - d5 * d4;
|
||||||
|
if (va <= 0 && (d4 - d3) >= 0 && (d5 - d6) >= 0)
|
||||||
|
{
|
||||||
|
var w = (d4 - d3) / ((d4 - d3) + (d5 - d6));
|
||||||
|
_out = vertexB + (vertexC - vertexB) * w; // barycentric coordinates (0,1-w,w)
|
||||||
|
return LVector3.Distance2(_out, p);
|
||||||
|
}
|
||||||
|
|
||||||
|
// P inside face region. Compute Q through its barycentric coordinates (u,v,w)
|
||||||
|
var denom = 1 / (va + vb + vc);
|
||||||
|
{
|
||||||
|
LFloat v = vb * denom;
|
||||||
|
LFloat w = vc * denom;
|
||||||
|
_out = vertexA + ab * v + ac * w;
|
||||||
|
}
|
||||||
|
return LVector3.Distance2(_out, p);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static bool IntersectRayTriangle(Ray ray, in LVector3 vertexA, in LVector3 vertexB, in LVector3 vertexC, out LVector3 intersection)
|
||||||
|
{
|
||||||
|
intersection = LVector3.Zero;
|
||||||
|
// AB边向量
|
||||||
|
LVector3 edgeAB = vertexB - vertexA;
|
||||||
|
// AC边向量
|
||||||
|
LVector3 edgeAC = vertexC - vertexA;
|
||||||
|
|
||||||
|
LVector3 pvec = LVector3.Cross(ray.direction, edgeAC);
|
||||||
|
LFloat det = LVector3.Dot(edgeAB, pvec);
|
||||||
|
if (LMath.Abs(det) <= LFloat.EPSILON)
|
||||||
|
{
|
||||||
|
var p = new Plane(vertexA, vertexB, vertexC);
|
||||||
|
if (p.TestPoint(ray.origin) == EnumPlaneSide.OnPlane && IsPointInTriangle(ray.origin, vertexA, vertexB, vertexC))
|
||||||
|
{
|
||||||
|
intersection = ray.origin;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
det = 1 / det;
|
||||||
|
|
||||||
|
LVector3 tvec = ray.origin - vertexA;
|
||||||
|
LFloat u = LVector3.Dot(tvec, pvec) * det;
|
||||||
|
if (u < 0 || u > 1)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
LVector3 qvec = LVector3.Cross(tvec, edgeAB);
|
||||||
|
LFloat v = LVector3.Dot(ray.direction, qvec) * det;
|
||||||
|
if (v < 0 || u + v > 1)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
LFloat t = LVector3.Dot(edgeAC, qvec) * det;
|
||||||
|
if (t < 0)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (LMath.Abs(t) <= LFloat.EPSILON)
|
||||||
|
{
|
||||||
|
intersection = ray.origin;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
intersection = ray.GetEndPoint(t);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 检测点point是否在三角形ABC内(重心法)
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="point"></param>
|
||||||
|
/// <param name="vertexA"></param>
|
||||||
|
/// <param name="vertexB"></param>
|
||||||
|
/// <param name="vertexC"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static bool IsPointInTriangle(in LVector3 point, in LVector3 vertexA, in LVector3 vertexB, in LVector3 vertexC)
|
||||||
|
{
|
||||||
|
var vPA = vertexA - point;
|
||||||
|
var vPB = vertexB - point;
|
||||||
|
var vPC = vertexC - point;
|
||||||
|
|
||||||
|
var ab = LVector3.Dot(vPA, vPB);
|
||||||
|
var ac = LVector3.Dot(vPA, vPC);
|
||||||
|
var bc = LVector3.Dot(vPB, vPC);
|
||||||
|
var cc = LVector3.Dot(vPC, vPC);
|
||||||
|
|
||||||
|
if (bc * ac - cc * ab < 0)
|
||||||
|
return false;
|
||||||
|
var bb = LVector3.Dot(vPB, vPB);
|
||||||
|
if (ab * bc - ac * bb < 0)
|
||||||
|
return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 计算点P是否在有向直线AB的左侧,返回值>0s说明在左侧
|
||||||
|
/// <para>Computes the signed distance from a line connecting the
|
||||||
|
/// specified points to a specified point.</para>
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="linePointA">直线上一点A</param>
|
||||||
|
/// <param name="linePointB">直线上一点B</param>
|
||||||
|
/// <param name="p">查询点P</param>
|
||||||
|
/// <returns>Positive when the point p lies to the left of the line ab.</returns>
|
||||||
|
public static LFloat IsLineLeft(in LVector2 linePointA, in LVector2 linePointB, in LVector2 p)
|
||||||
|
{
|
||||||
|
return LMath.Cross(linePointA - p, linePointB - linePointA);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 返回点P到直线AB的距离平方
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="linePointA">直线上一点A</param>
|
||||||
|
/// <param name="linePointB">直线上一点B</param>
|
||||||
|
/// <param name="pointP">点P</param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static LFloat SqrDistPointLineSegment(in LVector2 linePointA, in LVector2 linePointB, in LVector2 pointP)
|
||||||
|
{
|
||||||
|
LFloat r = LMath.Dot(pointP - linePointA, linePointB - linePointA) / (linePointB - linePointA).SqrMagnitude;
|
||||||
|
|
||||||
|
if (r < LFloat.Zero)
|
||||||
|
{
|
||||||
|
return (pointP - linePointA).SqrMagnitude;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (r > LFloat.One)
|
||||||
|
{
|
||||||
|
return (pointP - linePointB).SqrMagnitude;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (pointP - (linePointA + r * (linePointB - linePointA))).SqrMagnitude;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 36c93c611b97d4495b67967418da8216
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
@ -0,0 +1,158 @@
|
|||||||
|
using JNGame.Math;
|
||||||
|
|
||||||
|
namespace JNGame.PathFinding
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 平面的数据结构
|
||||||
|
/// </summary>
|
||||||
|
public class Plane
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 平面法向量,单位向量,法向量方向为面的正面
|
||||||
|
/// </summary>
|
||||||
|
public LVector3 normal = LVector3.Zero;
|
||||||
|
/// <summary>
|
||||||
|
/// 平面到原点的距离
|
||||||
|
/// </summary>
|
||||||
|
public LFloat distFromOrigin = LFloat.Zero;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 默认构造
|
||||||
|
/// </summary>
|
||||||
|
public Plane() { }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 拷贝构造
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="plane"></param>
|
||||||
|
public Plane(Plane plane)
|
||||||
|
{
|
||||||
|
this.normal = plane.normal;
|
||||||
|
this.distFromOrigin = plane.distFromOrigin;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 方向向量和平面到原点的距离构成平面
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="normal">平面的方向向量</param>
|
||||||
|
/// <param name="distance">平面到原点的距离</param>
|
||||||
|
public Plane(in LVector3 normal, LFloat distance)
|
||||||
|
{
|
||||||
|
this.normal = normal.Normalized;
|
||||||
|
this.distFromOrigin = distance;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 方向向量和平面内一点构成平面
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="normal">平面的方向向量</param>
|
||||||
|
/// <param name="point">平面内一点,也可视为原点到平面内一点的向量</param>
|
||||||
|
public Plane(in LVector3 normal, in LVector3 point)
|
||||||
|
{
|
||||||
|
this.normal = normal.Normalized;
|
||||||
|
this.distFromOrigin = -LVector3.Dot(this.normal, point);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 三个点构成一个平面
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="point1"></param>
|
||||||
|
/// <param name="point2"></param>
|
||||||
|
/// <param name="point3"></param>
|
||||||
|
public Plane(in LVector3 point1, in LVector3 point2, in LVector3 point3)
|
||||||
|
{
|
||||||
|
Set(point1, point2, point3);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 根据三个点,设置平面信息
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="point1"></param>
|
||||||
|
/// <param name="point2"></param>
|
||||||
|
/// <param name="point3"></param>
|
||||||
|
public void Set(in LVector3 point1, in LVector3 point2, in LVector3 point3)
|
||||||
|
{
|
||||||
|
LVector3 vector12 = point2 - point1; // 点1指向点2的向量
|
||||||
|
LVector3 vector23 = point3 - point2; // 点2指向点3的向量
|
||||||
|
normal = LVector3.Cross(vector12, vector23).Normalized;
|
||||||
|
// 规定原点在面的背面,因此距离为负
|
||||||
|
distFromOrigin = -LVector3.Dot(point1, normal);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 根据点和法线,设置平面信息
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="point"></param>
|
||||||
|
/// <param name="normal"></param>
|
||||||
|
public void Set(in LVector3 point, in LVector3 normal)
|
||||||
|
{
|
||||||
|
this.normal = normal.Normalized;
|
||||||
|
distFromOrigin = -LVector3.Dot(point, normal);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 根据点和法线,设置平面信息
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="pointX"></param>
|
||||||
|
/// <param name="pointY"></param>
|
||||||
|
/// <param name="pointZ"></param>
|
||||||
|
/// <param name="norX"></param>
|
||||||
|
/// <param name="norY"></param>
|
||||||
|
/// <param name="norZ"></param>
|
||||||
|
public void Set(LFloat pointX, LFloat pointY, LFloat pointZ, LFloat norX, LFloat norY, LFloat norZ)
|
||||||
|
{
|
||||||
|
this.normal = new LVector3(norX, norY, norZ).Normalized;
|
||||||
|
distFromOrigin = -(pointX * norX + pointY * norY + pointZ * norZ);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 计算平面到点的距离
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="point"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public LFloat Distance(in LVector3 point)
|
||||||
|
{
|
||||||
|
// 点在normal方向的投影距离 + 面到原点的距离。根据符号,可判断点在面的哪一侧
|
||||||
|
return LVector3.Dot(normal, point) + distFromOrigin;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 测试点位于平面的哪一面
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="point"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public EnumPlaneSide TestPoint(in LVector3 point)
|
||||||
|
{
|
||||||
|
LFloat dist = Distance(in point);
|
||||||
|
|
||||||
|
if (dist == 0)
|
||||||
|
return EnumPlaneSide.OnPlane;
|
||||||
|
else if (dist < 0)
|
||||||
|
return EnumPlaneSide.Back;
|
||||||
|
else
|
||||||
|
return EnumPlaneSide.Front;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 是否位于正面
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="direction"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public bool IsFrontFacing(in LVector3 direction)
|
||||||
|
{
|
||||||
|
LFloat dot = LVector3.Dot(normal, direction);
|
||||||
|
return dot <= 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Reset()
|
||||||
|
{
|
||||||
|
normal = LVector3.Zero;
|
||||||
|
distFromOrigin = LFloat.Zero;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override string ToString()
|
||||||
|
{
|
||||||
|
return normal.ToString() + ", " + distFromOrigin;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 555aac364a42943c4993c540358381df
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
@ -0,0 +1,50 @@
|
|||||||
|
using JNGame.Math;
|
||||||
|
|
||||||
|
namespace JNGame.PathFinding
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 射线数据结构
|
||||||
|
/// </summary>
|
||||||
|
public class Ray
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 射线起点
|
||||||
|
/// </summary>
|
||||||
|
public LVector3 origin = LVector3.Zero;
|
||||||
|
/// <summary>
|
||||||
|
/// 射线方向,单位向量
|
||||||
|
/// </summary>
|
||||||
|
public LVector3 direction = LVector3.Zero;
|
||||||
|
|
||||||
|
public Ray() { }
|
||||||
|
|
||||||
|
public Ray(Ray ray)
|
||||||
|
{
|
||||||
|
this.origin = ray.origin;
|
||||||
|
this.direction = ray.direction;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Ray(in LVector3 origin, in LVector3 direction)
|
||||||
|
{
|
||||||
|
this.origin = origin;
|
||||||
|
this.direction = direction.Normalized;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LVector3 GetEndPoint(LFloat distance)
|
||||||
|
{
|
||||||
|
return origin + direction * distance;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Reset()
|
||||||
|
{
|
||||||
|
origin = LVector3.Zero;
|
||||||
|
direction = LVector3.Zero;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** {@inheritDoc} */
|
||||||
|
public override string ToString()
|
||||||
|
{
|
||||||
|
return "ray [" + origin + ":" + direction + "]";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 07d36ae82dda2434da808db57664e965
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
@ -0,0 +1,8 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 884e8e78a03eb4ca1bcdcc561b57c387
|
||||||
|
folderAsset: yes
|
||||||
|
DefaultImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
@ -0,0 +1,32 @@
|
|||||||
|
using JNGame.Math;
|
||||||
|
|
||||||
|
namespace JNGame.PathFinding
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 节点的边邻接关系接口定义
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="TNode">图元节点类型</typeparam>
|
||||||
|
public interface IConnection<TNode>
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 邻接关系的移动消耗
|
||||||
|
/// <para>Returns the non-negative cost of this connection</para>
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
LFloat GetCost();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 邻接关系的起始节点
|
||||||
|
/// <para>Returns the node that this connection came from</para>
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>返回图元节点</returns>
|
||||||
|
TNode GetFromNode();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 邻接关系指向的节点
|
||||||
|
/// <para>Returns the node that this connection leads to</para>
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>返回图元节点</returns>
|
||||||
|
TNode GetToNode();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 7fb05d24110ca4f9091409c8ff0b0220
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
@ -0,0 +1,20 @@
|
|||||||
|
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace JNGame.PathFinding
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 图接口,图是一系列节点的集合,每个节点有邻接关系的列表
|
||||||
|
/// <para> A graph is a collection of nodes, each one having a collection of outgoing {@link Connection connections}. </para>
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="TNode">图元节点类型</typeparam>
|
||||||
|
public interface IGraph<TNode>
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 获取当前节点的邻接关系
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="fromNode">the node whose outgoing connections will be returned</param>
|
||||||
|
/// <returns>the array of connections outgoing from the given node.</returns>
|
||||||
|
List<IConnection<TNode>> GetConnections(TNode fromNode);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 086d1303386de40d395759867571b2a9
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
@ -0,0 +1,32 @@
|
|||||||
|
|
||||||
|
namespace JNGame.PathFinding
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// A graph for the {@link IndexedAStarPathFinder}.
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="TNode">Type of node</typeparam>
|
||||||
|
public interface IIndexedGraph<TNode> : IGraph<TNode>
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 获取节点在图中的索引
|
||||||
|
/// <para>Returns the unique index of the given node.</para>
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="node">the node whose index will be returned</param>
|
||||||
|
/// <returns>return the unique index of the given node.</returns>
|
||||||
|
int GetIndex(TNode node);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取图中的节点总数
|
||||||
|
/// <para>Returns the number of nodes in this graph.</para>
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
int GetNodeCount();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 根据节点索引获取图元节点
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="index"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
TNode GetNode(int index);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 46150180c48a24416979310fdc726856
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
@ -0,0 +1,161 @@
|
|||||||
|
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using JNGame.Math;
|
||||||
|
|
||||||
|
namespace JNGame.PathFinding
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// <para> 导航网格数据 </para>
|
||||||
|
/// <para> 从Unity的NavMesh中导出,经过定点库转化 </para>
|
||||||
|
/// </summary>
|
||||||
|
[System.Serializable]
|
||||||
|
public class NavMeshData
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// NavMeshData关联的关卡地图ID
|
||||||
|
/// </summary>
|
||||||
|
public int mapID;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 移动单位的包围盒半径,在烘焙导航网格时判断是否可通过
|
||||||
|
/// <para> 如果有包围盒半径差别特别大的,需要生成多份的导航网格数据供不同体型的可移动单位使用 </para>
|
||||||
|
/// </summary>
|
||||||
|
public LFloat radius = LFloat.Half;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// X轴方向最小位置坐标
|
||||||
|
/// </summary>
|
||||||
|
public LFloat xMin;
|
||||||
|
/// <summary>
|
||||||
|
/// Z轴方向最小位置坐标
|
||||||
|
/// </summary>
|
||||||
|
public LFloat zMin;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// X轴方向最大位置坐标
|
||||||
|
/// </summary>
|
||||||
|
public LFloat xMax;
|
||||||
|
/// <summary>
|
||||||
|
/// Z轴方向最大位置坐标
|
||||||
|
/// </summary>
|
||||||
|
public LFloat zMax;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 宽,X轴方向最小位置到最大位置的距离
|
||||||
|
/// </summary>
|
||||||
|
public LFloat Width => LMath.Abs(xMax - xMin);
|
||||||
|
/// <summary>
|
||||||
|
/// 高,Z轴方向最小位置到最大位置的距离
|
||||||
|
/// </summary>
|
||||||
|
public LFloat Height => LMath.Abs(zMax - zMin);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 行走区域的顶点坐标
|
||||||
|
/// </summary>
|
||||||
|
public LVector3[] pathVertices;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 构成行走区域的三角形索引
|
||||||
|
/// </summary>
|
||||||
|
public int[] pathTriangles;
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 数据检测,客户端的顶点坐标和三角形数据有可能是重复的
|
||||||
|
/// <para>TODO 小三角形合并成大三角形或多边形;判断顶点是否在寻路层中,寻路层中的顶点不能作为路径点;两点所连线段是否穿过阻挡区,不穿过,直接获取坐标点</para>
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="scale">缩放比例</param>
|
||||||
|
public void Check(int scale)
|
||||||
|
{
|
||||||
|
FixSameVertex(pathTriangles, pathVertices);
|
||||||
|
ScaleVertex(pathVertices, scale);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 缩放顶点坐标,进行地图的缩放
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="vertices">顶点集合</param>
|
||||||
|
/// <param name="scale">缩放比例</param>
|
||||||
|
private void ScaleVertex(LVector3[] vertices, int scale)
|
||||||
|
{
|
||||||
|
if (vertices == null || scale == 1)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var lscale = scale.ToLFloat();
|
||||||
|
for (int i = 0; i < vertices.Length; i++)
|
||||||
|
{
|
||||||
|
vertices[i].x += (-this.xMin); // 缩放移动
|
||||||
|
vertices[i].z += (-this.zMin);
|
||||||
|
vertices[i] = vertices[i] * lscale;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 重复顶点坐标,坐标相同的下标修改为一致
|
||||||
|
/// <para>unity的NavMeshData有一些共边的三角形,共边的三角形其实不是连通关系,共边的三角形只是他们共同构成一个凸多边形,并且这种共边的三角形,全部都是扇形排列。</para>
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="indexs">索引数据</param>
|
||||||
|
/// <param name="vertices">顶点数据</param>
|
||||||
|
private void FixSameVertex(int[] indexs, LVector3[] vertices)
|
||||||
|
{
|
||||||
|
if (indexs == null || vertices == null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// 缓存顶点-索引映射
|
||||||
|
Dictionary<LVector3, int> cacheVertices = new Dictionary<LVector3, int>();
|
||||||
|
// 检测路径重复点
|
||||||
|
for (int i = 0; i < vertices.Length; ++i)
|
||||||
|
{
|
||||||
|
// 重复出现的坐标
|
||||||
|
if (cacheVertices.ContainsKey(vertices[i]))
|
||||||
|
{
|
||||||
|
for (int j = 0; j < indexs.Length; j++)
|
||||||
|
{
|
||||||
|
if (indexs[j] == i)
|
||||||
|
{ // 修正重复的坐标
|
||||||
|
indexs[j] = cacheVertices[vertices[i]];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
cacheVertices.Add(vertices[i], i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public int[] GetPathTriangles()
|
||||||
|
{
|
||||||
|
return pathTriangles;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SetPathTriangles(int[] pathTriangles)
|
||||||
|
{
|
||||||
|
this.pathTriangles = pathTriangles;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LVector3[] GetPathVertices()
|
||||||
|
{
|
||||||
|
return pathVertices;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SetPathVertices(LVector3[] pathVertices)
|
||||||
|
{
|
||||||
|
this.pathVertices = pathVertices;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int GetMapID()
|
||||||
|
{
|
||||||
|
return mapID;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SetMapID(int mapID)
|
||||||
|
{
|
||||||
|
this.mapID = mapID;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: d4d0cc4c1d59a45f488d5ab7693a8572
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
@ -0,0 +1,23 @@
|
|||||||
|
using JNGame.Math;
|
||||||
|
|
||||||
|
namespace JNGame.PathFinding
|
||||||
|
{
|
||||||
|
public static class NavTriangleExtension
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 基于r,f的值,获取三角形内的一点
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="triangle"></param>
|
||||||
|
/// <param name="r">点在三角形AB边的比值[0, 1]之间</param>
|
||||||
|
/// <param name="f">点在三角形BC边的比值[0, 1]之间</param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static LVector3 GetVertex(this NavTriangle triangle, LFloat r, LFloat f)
|
||||||
|
{
|
||||||
|
LVector3 vecAB = triangle.vertexB - triangle.vertexA;
|
||||||
|
LVector3 vecBC = triangle.vertexC - triangle.vertexB;
|
||||||
|
LFloat x = vecAB.x * r + vecBC.x * r * f + triangle.vertexA.x;
|
||||||
|
LFloat z = vecAB.z * r + vecBC.z * r * f + triangle.vertexA.z;
|
||||||
|
return new LVector3(x, LFloat.Zero, z);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 49e7da5e90cc551448aa1c8cdedb2148
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
@ -0,0 +1,127 @@
|
|||||||
|
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using JNGame.Math;
|
||||||
|
|
||||||
|
namespace JNGame.PathFinding
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 导航网格中的三角形数据结构
|
||||||
|
/// <para>三个顶点ABC,按照A->B->C->A的绕序。是顺时针绕序</para>
|
||||||
|
/// </summary>
|
||||||
|
public class NavTriangle
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 三角形序号
|
||||||
|
/// </summary>
|
||||||
|
public int index;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 三角形顶点A
|
||||||
|
/// </summary>
|
||||||
|
public LVector3 vertexA;
|
||||||
|
/// <summary>
|
||||||
|
/// 三角形顶点B
|
||||||
|
/// </summary>
|
||||||
|
public LVector3 vertexB;
|
||||||
|
/// <summary>
|
||||||
|
/// 三角形顶点C
|
||||||
|
/// </summary>
|
||||||
|
public LVector3 vertexC;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 三角形Y轴高度,取三个顶点的平均高度
|
||||||
|
/// </summary>
|
||||||
|
public LFloat y;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 三角形中心点
|
||||||
|
/// </summary>
|
||||||
|
public LVector3 center;
|
||||||
|
|
||||||
|
// /// <summary>
|
||||||
|
// /// 三角形顶点的索引
|
||||||
|
// /// </summary>
|
||||||
|
// public int[] vectorIndices;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 三角形的邻接边关系集合
|
||||||
|
/// </summary>
|
||||||
|
public List<IConnection<NavTriangle>> connections;
|
||||||
|
|
||||||
|
public NavTriangle(in LVector3 vertexA, in LVector3 vertexB, in LVector3 vertexC, int index)
|
||||||
|
{
|
||||||
|
this.vertexA = vertexA;
|
||||||
|
this.vertexB = vertexB;
|
||||||
|
this.vertexC = vertexC;
|
||||||
|
this.y = (vertexA.y + vertexB.y + vertexC.y) / 3;
|
||||||
|
this.index = index;
|
||||||
|
this.center = (vertexA + vertexB + vertexC) / 3;
|
||||||
|
this.connections = new List<IConnection<NavTriangle>>();
|
||||||
|
// this.vectorIndices = vectorIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 判断点是否在三角形内
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="point"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public bool IsInnerPoint(LVector3 point)
|
||||||
|
{
|
||||||
|
bool res = PointInLineLeft(vertexA, vertexB, point);
|
||||||
|
if (res != PointInLineLeft(vertexB, vertexC, point))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (res != PointInLineLeft(vertexC, vertexA, point))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Cross2D(vertexA, vertexB, vertexC) == 0)
|
||||||
|
{
|
||||||
|
//三点共线
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static LFloat Cross2D(LVector3 fromPoint, LVector3 toPoint, LVector3 p)
|
||||||
|
{
|
||||||
|
return (toPoint.x - fromPoint.x) * (p.z - fromPoint.z) - (toPoint.z - fromPoint.z) * (p.x - fromPoint.x);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static bool PointInLineLeft(LVector3 fromPoint, LVector3 toPoint, LVector3 p)
|
||||||
|
{
|
||||||
|
return Cross2D(fromPoint, toPoint, p) > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override int GetHashCode()
|
||||||
|
{
|
||||||
|
int prime = 31;
|
||||||
|
int result = 1;
|
||||||
|
result = prime * result + index;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override bool Equals(object obj)
|
||||||
|
{
|
||||||
|
if (this == obj)
|
||||||
|
return true;
|
||||||
|
if (obj == null)
|
||||||
|
return false;
|
||||||
|
if (GetType() != obj.GetType())
|
||||||
|
return false;
|
||||||
|
NavTriangle other = (NavTriangle)obj;
|
||||||
|
if (index != other.index)
|
||||||
|
return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override string ToString()
|
||||||
|
{
|
||||||
|
return "Triangle [index=" + index + ", vertexA=" + vertexA + ", vertexB=" + vertexB + ", vertexC=" + vertexC + ", center=" + center + ", connections=" + connections.Count + "]";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 1b4e6ea59290a47898b80b6d06b31483
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
@ -0,0 +1,111 @@
|
|||||||
|
using System.Text;
|
||||||
|
using JNGame.Math;
|
||||||
|
|
||||||
|
namespace JNGame.PathFinding
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 三角形节点的共享(邻接)边关系
|
||||||
|
/// </summary>
|
||||||
|
public class TriangleEdge : IConnection<NavTriangle>
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 源三角形
|
||||||
|
/// </summary>
|
||||||
|
public NavTriangle fromNode;
|
||||||
|
/// <summary>
|
||||||
|
/// 指向的三角形,可为空,为空说明该边没有邻接三角形
|
||||||
|
/// </summary>
|
||||||
|
public NavTriangle toNode;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 三角形邻接边的顶点A,边起点,绕序同三角形的绕序
|
||||||
|
/// </summary>
|
||||||
|
public LVector3 vertexA;
|
||||||
|
/// <summary>
|
||||||
|
/// 三角形邻接边的顶点B,边终点,绕序同三角形的绕序
|
||||||
|
/// </summary>
|
||||||
|
public LVector3 vertexB;
|
||||||
|
|
||||||
|
public TriangleEdge()
|
||||||
|
{
|
||||||
|
this.fromNode = null;
|
||||||
|
this.toNode = null;
|
||||||
|
this.vertexA = LVector3.Zero;
|
||||||
|
this.vertexB = LVector3.Zero;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 构建三角形节点的邻接边
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="fromNode">边起点三角形</param>
|
||||||
|
/// <param name="toNode">边终点三角形</param>
|
||||||
|
/// <param name="vertexA">边连接的两个三角形的共享边的顶点</param>
|
||||||
|
/// <param name="vertexB">边连接的两个三角形的共享边的顶点</param>
|
||||||
|
public TriangleEdge(NavTriangle fromNode, NavTriangle toNode, in LVector3 vertexA, in LVector3 vertexB)
|
||||||
|
{
|
||||||
|
this.fromNode = fromNode;
|
||||||
|
this.toNode = toNode;
|
||||||
|
this.vertexA = vertexA;
|
||||||
|
this.vertexB = vertexB;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LFloat GetCost()
|
||||||
|
{
|
||||||
|
// 邻边的消耗固定为1
|
||||||
|
return LFloat.One;
|
||||||
|
}
|
||||||
|
|
||||||
|
public NavTriangle GetFromNode()
|
||||||
|
{
|
||||||
|
return fromNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
public NavTriangle GetToNode()
|
||||||
|
{
|
||||||
|
return toNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 更新成员属性
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="fromNode"></param>
|
||||||
|
/// <param name="toNode"></param>
|
||||||
|
/// <param name="vertexA"></param>
|
||||||
|
/// <param name="vertexB"></param>
|
||||||
|
public void Set(NavTriangle fromNode, NavTriangle toNode, in LVector3 vertexA, in LVector3 vertexB)
|
||||||
|
{
|
||||||
|
this.fromNode = fromNode;
|
||||||
|
this.toNode = toNode;
|
||||||
|
this.vertexA = vertexA;
|
||||||
|
this.vertexB = vertexB;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 清理成员属性
|
||||||
|
/// </summary>
|
||||||
|
public void Clear()
|
||||||
|
{
|
||||||
|
this.fromNode = null;
|
||||||
|
this.toNode = null;
|
||||||
|
this.vertexA = LVector3.Zero;
|
||||||
|
this.vertexB = LVector3.Zero;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool IsValid()
|
||||||
|
{
|
||||||
|
return fromNode != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override string ToString()
|
||||||
|
{
|
||||||
|
StringBuilder sb = new StringBuilder("Edge{");
|
||||||
|
sb.Append("fromNode=").Append(fromNode.index);
|
||||||
|
//sb.Append(", toNode=").Append(toNode == null ? "null" : toNode.index);
|
||||||
|
sb.Append(", VertexA=").Append(vertexA);
|
||||||
|
sb.Append(", VertexB=").Append(vertexB);
|
||||||
|
sb.Append('}');
|
||||||
|
return sb.ToString();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 23cebc1b22ecc4befabcaec093f97db5
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
@ -0,0 +1,557 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using JNGame.Math;
|
||||||
|
using Profiler = JNGame.Util.Profiler;
|
||||||
|
|
||||||
|
namespace JNGame.PathFinding
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 以三角形为图节点的索引图数据结构
|
||||||
|
/// </summary>
|
||||||
|
public partial class TriangleGraph : IIndexedGraph<NavTriangle>
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 存储共边三角形共边关系
|
||||||
|
/// <para>Class for storing the edge connection data between two adjacent triangles.</para>
|
||||||
|
/// </summary>
|
||||||
|
public class IndexConnection
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// <para>共边顶点索引1,绕序的起点</para>
|
||||||
|
/// The vertex indices which makes up the edge shared between two triangles.
|
||||||
|
/// </summary>
|
||||||
|
public int edgeVertexIndex1;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// <para>共边顶点索引2,绕序的终点</para>
|
||||||
|
/// The vertex indices which makes up the edge shared between two triangles.
|
||||||
|
/// </summary>
|
||||||
|
public int edgeVertexIndex2;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// <para>共边的三角形索引1</para>
|
||||||
|
/// The indices of the two triangles sharing this edge.
|
||||||
|
/// </summary>
|
||||||
|
public int fromTriIndex;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// <para>共边的三角形索引2</para>
|
||||||
|
/// The indices of the two triangles sharing this edge.
|
||||||
|
public int toTriIndex;
|
||||||
|
|
||||||
|
public IndexConnection(int sharedEdgeVertex1Index, int sharedEdgeVertex2Index, int fromTriIndex, int toTriIndex)
|
||||||
|
{
|
||||||
|
this.edgeVertexIndex1 = sharedEdgeVertex1Index;
|
||||||
|
this.edgeVertexIndex2 = sharedEdgeVertex2Index;
|
||||||
|
this.fromTriIndex = fromTriIndex;
|
||||||
|
this.toTriIndex = toTriIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override string ToString()
|
||||||
|
{
|
||||||
|
return "IndexConnection [edgeVertexIndex1=" + edgeVertexIndex1 + ", edgeVertexIndex2=" +
|
||||||
|
edgeVertexIndex2
|
||||||
|
+ ", fromTriIndex=" + fromTriIndex + ", toTriIndex=" + toTriIndex + "]";
|
||||||
|
}
|
||||||
|
|
||||||
|
public override int GetHashCode()
|
||||||
|
{
|
||||||
|
int prime = 31;
|
||||||
|
int result = 1;
|
||||||
|
result = prime * result + edgeVertexIndex1;
|
||||||
|
result = prime * result + edgeVertexIndex2;
|
||||||
|
result = prime * result + fromTriIndex;
|
||||||
|
result = prime * result + toTriIndex;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override bool Equals(object obj)
|
||||||
|
{
|
||||||
|
if (this == obj)
|
||||||
|
return true;
|
||||||
|
if (obj == null)
|
||||||
|
return false;
|
||||||
|
if (GetType() != obj.GetType())
|
||||||
|
return false;
|
||||||
|
IndexConnection other = (IndexConnection)obj;
|
||||||
|
if (edgeVertexIndex1 != other.edgeVertexIndex1)
|
||||||
|
return false;
|
||||||
|
if (edgeVertexIndex2 != other.edgeVertexIndex2)
|
||||||
|
return false;
|
||||||
|
if (fromTriIndex != other.fromTriIndex)
|
||||||
|
return false;
|
||||||
|
if (toTriIndex != other.toTriIndex)
|
||||||
|
return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 导航网格数据,从文件读取
|
||||||
|
/// </summary>
|
||||||
|
private readonly NavMeshData m_NavMeshData;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 根据导航网格数据,生成的三角形
|
||||||
|
/// </summary>
|
||||||
|
private readonly List<NavTriangle> m_Triangles = new List<NavTriangle>();
|
||||||
|
public List<NavTriangle> Triangles => m_Triangles;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 三角形的邻接边关系映射表 [Key, Value] = [三角形对象,共边的连接关系]
|
||||||
|
/// <para>与m_IsolatedEdgesMap应该是严格互补的</para>
|
||||||
|
/// </summary>
|
||||||
|
private readonly Dictionary<NavTriangle, List<IConnection<NavTriangle>>> m_SharedEdges;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 三角形的独边关系映射表 [Key, Value] = [三角形对象,无邻边的连接关系]
|
||||||
|
/// <para>与m_SharedEdges应该是严格互补的</para>
|
||||||
|
/// </summary>
|
||||||
|
private readonly Dictionary<NavTriangle, List<IConnection<NavTriangle>>> m_IsolatedEdgesMap;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// BSP树,通过空间分割快速查找点所在的三角形
|
||||||
|
/// </summary>
|
||||||
|
private readonly BspTree m_BspTree;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 导航三角形中独边总数
|
||||||
|
/// </summary>
|
||||||
|
private readonly int m_NumDisconnectedEdges;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 导航三角形中共享边总数
|
||||||
|
/// </summary>
|
||||||
|
private readonly int m_NumConnectedEdges;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 导航三角形中所有的边总数
|
||||||
|
/// </summary>
|
||||||
|
private readonly int m_NumTotalEdges;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 构造以三角形为节点的图数据结构
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="navMeshData">导航网格数据</param>
|
||||||
|
/// <param name="scale">缩放比例,默认:1</param>
|
||||||
|
public TriangleGraph(NavMeshData navMeshData, int scale = 1)
|
||||||
|
{
|
||||||
|
m_NavMeshData = navMeshData;
|
||||||
|
// 检测导航网格数据中重复的顶点,并按需求对顶点进行缩放
|
||||||
|
m_NavMeshData.Check(scale);
|
||||||
|
// 根据导航网格数据构建三角形
|
||||||
|
var pathTriangles = CreateTriangles();
|
||||||
|
// 计算所有三角形的共边关系
|
||||||
|
var pathIndexConnections = GetIndexConnections(navMeshData.pathTriangles);
|
||||||
|
// 创建三角形邻边数据表
|
||||||
|
m_SharedEdges = CreateSharedEdgesMap(pathIndexConnections, pathTriangles, navMeshData.pathVertices);
|
||||||
|
// 创建三角形独边数据表
|
||||||
|
m_IsolatedEdgesMap = CreateIsolatedEdgesMap(m_SharedEdges);
|
||||||
|
// 创建BSP树,耗时
|
||||||
|
m_BspTree = new BspTree();
|
||||||
|
m_BspTree.Init(pathTriangles);
|
||||||
|
// 统计独边的总数
|
||||||
|
foreach (var edges in m_IsolatedEdgesMap.Values)
|
||||||
|
{
|
||||||
|
m_NumDisconnectedEdges += edges.Count;
|
||||||
|
}
|
||||||
|
// 统计共享边的总数
|
||||||
|
foreach (var edges in m_SharedEdges.Values)
|
||||||
|
{
|
||||||
|
m_NumConnectedEdges += edges.Count;
|
||||||
|
}
|
||||||
|
m_NumConnectedEdges /= 2; // 相邻的三角形各有一条相互的共享边连接数据,因此需要/2
|
||||||
|
// 导航三角形中所有边的总数
|
||||||
|
m_NumTotalEdges = m_NumConnectedEdges + m_NumDisconnectedEdges;
|
||||||
|
|
||||||
|
// Debug.Log("CreateTriangleGraph Success! mapId{0} triangles{1} totalEdges{2} connEdges{3} disConnEdges{4}", navMeshData.mapID, m_Triangles.Count
|
||||||
|
// , m_NumTotalEdges, m_NumConnectedEdges, m_NumDisconnectedEdges);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取当前三角形的邻接边数据
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="fromNode">查询的三角形节点</param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public List<IConnection<NavTriangle>> GetConnections(NavTriangle fromNode)
|
||||||
|
{
|
||||||
|
return m_SharedEdges.TryGetValue(fromNode, out var val) ? val : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int GetIndex(NavTriangle node)
|
||||||
|
{
|
||||||
|
return node.index;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int GetNodeCount()
|
||||||
|
{
|
||||||
|
return m_SharedEdges.Count;
|
||||||
|
}
|
||||||
|
|
||||||
|
public NavTriangle GetNode(int index)
|
||||||
|
{
|
||||||
|
if (index < 0 || index >= m_Triangles.Count)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return m_Triangles[index];
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 遍历NavMeshData的顶点数组和索引数组,构建三角形
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
private List<NavTriangle> CreateTriangles()
|
||||||
|
{
|
||||||
|
var vertexIndexs = m_NavMeshData.GetPathTriangles();
|
||||||
|
var vertices = m_NavMeshData.GetPathVertices();
|
||||||
|
int triangleIndex = 0; // 三角形下标
|
||||||
|
int length = vertexIndexs.Length - 3;
|
||||||
|
for (int i = 0; i <= length;)
|
||||||
|
{
|
||||||
|
int aIndex = vertexIndexs[i++];
|
||||||
|
int bIndex = vertexIndexs[i++];
|
||||||
|
int cIndex = vertexIndexs[i++];
|
||||||
|
NavTriangle triangle = new NavTriangle(vertices[aIndex], vertices[bIndex], vertices[cIndex], triangleIndex++);
|
||||||
|
m_Triangles.Add(triangle);
|
||||||
|
}
|
||||||
|
return m_Triangles;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取所有三角形的共享边关系
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="indices">顶点索引</param>
|
||||||
|
/// <returns></returns>
|
||||||
|
private static HashSet<IndexConnection> GetIndexConnections(int[] indices)
|
||||||
|
{
|
||||||
|
var indexConnections = new HashSet<IndexConnection>();
|
||||||
|
int[] edge = { -1, -1 }; // 隐含三角形顶点绕序,0是绕序的起点,1是绕序的终点
|
||||||
|
int i = 0;
|
||||||
|
int j, a0, a1, a2, b0, b1, b2, triAIndex, triBIndex;
|
||||||
|
while (i < indices.Length)
|
||||||
|
{
|
||||||
|
triAIndex = i / 3; // A三角形索引
|
||||||
|
a0 = indices[i++]; // 构成A三角形的三个顶点索引
|
||||||
|
a1 = indices[i++];
|
||||||
|
a2 = indices[i++];
|
||||||
|
j = i; // 第二个三角形从A三角形之后开始计算,A三角形之前的连接关系已经在之前的循环中计算过了
|
||||||
|
while (j < indices.Length)
|
||||||
|
{
|
||||||
|
triBIndex = j / 3; // B三角形索引
|
||||||
|
b0 = indices[j++]; // 构成B三角形的三个顶点索引
|
||||||
|
b1 = indices[j++];
|
||||||
|
b2 = indices[j++];
|
||||||
|
|
||||||
|
if (HasSharedEdgeIndices(a0, a1, a2, b0, b1, b2, edge))
|
||||||
|
{
|
||||||
|
// 两个有共享边的三角形,三角形A和三角形B共享边的绕序必定是相反的
|
||||||
|
var indexConnection1 = new IndexConnection(edge[0], edge[1], triAIndex, triBIndex);
|
||||||
|
var indexConnection2 = new IndexConnection(edge[1], edge[0], triBIndex, triAIndex);
|
||||||
|
indexConnections.Add(indexConnection1);
|
||||||
|
indexConnections.Add(indexConnection2);
|
||||||
|
edge[0] = -1;
|
||||||
|
edge[1] = -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Debug.Log("连接个数:{0}", indexConnections.Count);
|
||||||
|
return indexConnections;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 检测两个三角形是否有共享边,有两个共享索引,说明两个三角形存在共边
|
||||||
|
/// <para> Checks if the two triangles have shared vertex indices.</para>
|
||||||
|
/// <para>The edge will always follow the vertex winding order of the triangle A. Since all
|
||||||
|
/// triangles have the same winding order, triangle A should have the opposite
|
||||||
|
/// edge direction to triangle B.</para>
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="a0">三角形A顶点0索引</param>
|
||||||
|
/// <param name="a1">三角形A顶点1索引</param>
|
||||||
|
/// <param name="a2">三角形A顶点2索引</param>
|
||||||
|
/// <param name="b0">三角形B顶点0索引</param>
|
||||||
|
/// <param name="b1">三角形B顶点1索引</param>
|
||||||
|
/// <param name="b2">三角形B顶点2索引</param>
|
||||||
|
/// <param name="edge">输出:[共边顶点索引1, 共边顶点索引2]</param>
|
||||||
|
/// <returns>bool: 是否存在共边</returns>
|
||||||
|
private static bool HasSharedEdgeIndices(int a0, int a1, int a2, int b0, int b1, int b2, int[] edge)
|
||||||
|
{
|
||||||
|
bool match0 = (a0 == b0 || a0 == b1 || a0 == b2);
|
||||||
|
bool match1 = (a1 == b0 || a1 == b1 || a1 == b2);
|
||||||
|
if (!match0 && !match1)
|
||||||
|
{ // 无两个共享点
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else if (match0 && match1)
|
||||||
|
{
|
||||||
|
edge[0] = a0; // 保证三角形绕序一致,0->1->2
|
||||||
|
edge[1] = a1;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool match2 = (a2 == b0 || a2 == b1 || a2 == b2);
|
||||||
|
if (match0 && match2)
|
||||||
|
{
|
||||||
|
edge[0] = a2; // 保证三角形绕序一致,0->1->2
|
||||||
|
edge[1] = a0;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else if (match1 && match2)
|
||||||
|
{
|
||||||
|
edge[0] = a1; // 保证三角形绕序一致,0->1->2
|
||||||
|
edge[1] = a2;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 创建三角形共享边映射表 [Key, Value] = [三角形对象,共边的连接关系]
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="indexConnections">共享边关系集合</param>
|
||||||
|
/// <param name="triangles">三角形集合</param>
|
||||||
|
/// <param name="vertices">顶点集合</param>
|
||||||
|
/// <returns></returns>
|
||||||
|
private static Dictionary<NavTriangle, List<IConnection<NavTriangle>>> CreateSharedEdgesMap(
|
||||||
|
HashSet<IndexConnection> indexConnections, List<NavTriangle> triangles, LVector3[] vertices)
|
||||||
|
{
|
||||||
|
var connectionMap = new Dictionary<NavTriangle, List<IConnection<NavTriangle>>>();
|
||||||
|
|
||||||
|
foreach (NavTriangle triangle in triangles)
|
||||||
|
{
|
||||||
|
connectionMap.Add(triangle, new List<IConnection<NavTriangle>>());
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (IndexConnection indexConnection in indexConnections)
|
||||||
|
{
|
||||||
|
var fromNode = triangles[indexConnection.fromTriIndex];
|
||||||
|
var toNode = triangles[indexConnection.toTriIndex];
|
||||||
|
var edgeVertexA = vertices[indexConnection.edgeVertexIndex1];
|
||||||
|
var edgeVertexB = vertices[indexConnection.edgeVertexIndex2];
|
||||||
|
var edge = new TriangleEdge(fromNode, toNode, edgeVertexA, edgeVertexB);
|
||||||
|
connectionMap[fromNode].Add(edge);
|
||||||
|
fromNode.connections.Add(edge);
|
||||||
|
//Debug.Log("Triangle:{0}-->{1} {2}-->{3}", fromNode.index, toNode.index, fromNode, toNode);
|
||||||
|
}
|
||||||
|
|
||||||
|
return connectionMap;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 创建三角形的没有邻接边的关系映射表
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="connectionMap">邻边关系集合</param>
|
||||||
|
/// <returns>无邻边关系映射表</returns>
|
||||||
|
private static Dictionary<NavTriangle, List<IConnection<NavTriangle>>> CreateIsolatedEdgesMap(
|
||||||
|
Dictionary<NavTriangle, List<IConnection<NavTriangle>>> connectionMap)
|
||||||
|
{
|
||||||
|
var disconnectionMap = new Dictionary<NavTriangle, List<IConnection<NavTriangle>>>();
|
||||||
|
|
||||||
|
foreach (NavTriangle tri in connectionMap.Keys)
|
||||||
|
{
|
||||||
|
var connectedEdges = connectionMap[tri];
|
||||||
|
// 没有邻接边的关系集合
|
||||||
|
var disconnectedEdges = new List<IConnection<NavTriangle>>();
|
||||||
|
disconnectionMap.Add(tri, disconnectedEdges);
|
||||||
|
|
||||||
|
if (connectedEdges.Count < 3)
|
||||||
|
{ // This triangle does not have all edges connected to other triangles
|
||||||
|
bool ab = true; // 三角形顶点AB边没有邻接边
|
||||||
|
bool bc = true; // 三角形顶点BC边没有邻接边
|
||||||
|
bool ca = true; // 三角形顶点CA边没有邻接边
|
||||||
|
foreach (var item in connectedEdges)
|
||||||
|
{
|
||||||
|
var edge = item as TriangleEdge;
|
||||||
|
if (edge.vertexA == tri.vertexA && edge.vertexB == tri.vertexB)
|
||||||
|
{
|
||||||
|
ab = false; // AB边在邻接边关系集合中,标记置为false
|
||||||
|
}
|
||||||
|
else if (edge.vertexA == tri.vertexB && edge.vertexB == tri.vertexC)
|
||||||
|
{
|
||||||
|
bc = false; // BC边在邻接边关系集合中,标记置为false
|
||||||
|
}
|
||||||
|
else if (edge.vertexA == tri.vertexC && edge.vertexB == tri.vertexA)
|
||||||
|
{
|
||||||
|
ca = false; // CA边在邻接边关系集合中,标记置为false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 没有邻边三角形的,加入没有邻边集合中
|
||||||
|
if (ab)
|
||||||
|
{
|
||||||
|
disconnectedEdges.Add(new TriangleEdge(tri, null, tri.vertexA, tri.vertexB));
|
||||||
|
}
|
||||||
|
if (bc)
|
||||||
|
{
|
||||||
|
disconnectedEdges.Add(new TriangleEdge(tri, null, tri.vertexB, tri.vertexC));
|
||||||
|
}
|
||||||
|
if (ca)
|
||||||
|
{
|
||||||
|
disconnectedEdges.Add(new TriangleEdge(tri, null, tri.vertexC, tri.vertexA));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 断言所有边关系的总和必定为三角形边数
|
||||||
|
int totalEdges = connectedEdges.Count + disconnectedEdges.Count;
|
||||||
|
// Debug.Assert(totalEdges == 3, "Wrong number of edges ({0}) in triangle {1}", totalEdges, tri.index);
|
||||||
|
}
|
||||||
|
|
||||||
|
return disconnectionMap;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 根据点位置获取所在的三角形
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="point"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public NavTriangle GetTriangle(in LVector3 point)
|
||||||
|
{
|
||||||
|
Profiler.BeginSample("InternalGetTriangle");
|
||||||
|
var ret = InternalGetTriangle(in point, out _);
|
||||||
|
Profiler.EndSample();
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 根据点位置获取所在的三角形,如果点不在,则获取邻接的三角形,并输出在三角形上的邻接点
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="point"></param>
|
||||||
|
/// <param name="pointOnTriangle">三角形上邻接point的点</param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public NavTriangle GetTriangleOrNeareastTriangle(in LVector3 point, out LVector3 pointOnTriangle)
|
||||||
|
{
|
||||||
|
Profiler.BeginSample("GetTriangleOrNearestTriangle");
|
||||||
|
var ret = InternalGetTriangle(in point, out List<int> nearTriangles);
|
||||||
|
if (ret == null)
|
||||||
|
{
|
||||||
|
// 不在三角形内,找最近的一个三角形
|
||||||
|
LFloat minDist = LFloat.FLT_MAX;
|
||||||
|
LVector2 pointInVec2 = point.ToLVector2XZ();
|
||||||
|
for (int i = 0; i < nearTriangles.Count; ++i)
|
||||||
|
{
|
||||||
|
int triangleIndex = nearTriangles[i];
|
||||||
|
NavTriangle triangle = m_Triangles[triangleIndex];
|
||||||
|
if (m_IsolatedEdgesMap.TryGetValue(triangle, out List<IConnection<NavTriangle>> isolatedEdges))
|
||||||
|
{
|
||||||
|
// 查找独边,找邻接三角形
|
||||||
|
TriangleEdge edge = InternalGetNearestEdge(pointInVec2, isolatedEdges, out LFloat outSqrDistMin);
|
||||||
|
if (outSqrDistMin < minDist)
|
||||||
|
{
|
||||||
|
ret = edge.fromNode;
|
||||||
|
minDist = outSqrDistMin;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pointOnTriangle = LVector3.Zero;
|
||||||
|
if (ret != null)
|
||||||
|
{
|
||||||
|
GeometryUtil.GetClosestPointOnTriangle(ret.vertexA, ret.vertexB, ret.vertexC, point, ref pointOnTriangle);
|
||||||
|
// 稍微向三角形方向内部一点,避免严格在边上,三角形落位判断问题
|
||||||
|
pointOnTriangle = point + (pointOnTriangle - point) * new LFloat(true, 1010000);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
pointOnTriangle = point;
|
||||||
|
}
|
||||||
|
Profiler.EndSample();
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取最邻接目标点的共享边
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="navTriangle"></param>
|
||||||
|
/// <param name="position"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public TriangleEdge GetNearestSharedEdge(NavTriangle navTriangle, in LVector3 position)
|
||||||
|
{
|
||||||
|
if (m_SharedEdges.TryGetValue(navTriangle, out List<IConnection<NavTriangle>> outConnections))
|
||||||
|
{
|
||||||
|
return InternalGetNearestEdge(position.ToLVector2XZ(), outConnections, out _);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取最邻接目标点的阻挡边
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="navTriangle"></param>
|
||||||
|
/// <param name="position"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public TriangleEdge GetNeareastIsolatedEdge(NavTriangle navTriangle, in LVector3 position)
|
||||||
|
{
|
||||||
|
if (m_IsolatedEdgesMap.TryGetValue(navTriangle, out List<IConnection<NavTriangle>> outConnections))
|
||||||
|
{
|
||||||
|
return InternalGetNearestEdge(position.ToLVector2XZ(), outConnections, out _);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取最邻接目标点的三角形边,不考虑阻挡还是共享
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="navTriangle"></param>
|
||||||
|
/// <param name="position"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public TriangleEdge GetNearestEdge(NavTriangle navTriangle, in LVector3 position)
|
||||||
|
{
|
||||||
|
// 最近的共享边
|
||||||
|
TriangleEdge nearestSharedEdge = null;
|
||||||
|
LFloat sharedEdgeSqrDist = LFloat.FLT_MAX;
|
||||||
|
if (m_SharedEdges.TryGetValue(navTriangle, out List<IConnection<NavTriangle>> outSharedConnections))
|
||||||
|
{
|
||||||
|
nearestSharedEdge = InternalGetNearestEdge(position.ToLVector2XZ(), outSharedConnections, out sharedEdgeSqrDist);
|
||||||
|
}
|
||||||
|
// 最近的阻挡边
|
||||||
|
TriangleEdge nearestIsolatedEdge = null;
|
||||||
|
LFloat osolatedEdgeSqrDist = LFloat.FLT_MAX;
|
||||||
|
if (m_IsolatedEdgesMap.TryGetValue(navTriangle, out List<IConnection<NavTriangle>> outIsolatedConnections))
|
||||||
|
{
|
||||||
|
nearestIsolatedEdge = InternalGetNearestEdge(position.ToLVector2XZ(), outIsolatedConnections, out osolatedEdgeSqrDist);
|
||||||
|
}
|
||||||
|
// 选取最近的返回
|
||||||
|
return sharedEdgeSqrDist < osolatedEdgeSqrDist ? nearestSharedEdge : nearestIsolatedEdge;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取点落位的三角形,若为空,会附带点附近的一些三角形
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="point"></param>
|
||||||
|
/// <param name="nearTriangles"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
private NavTriangle InternalGetTriangle(in LVector3 point, out List<int> nearTriangles)
|
||||||
|
{
|
||||||
|
// 通过Bsp空间分割树查找点所在的三角形
|
||||||
|
var index = m_BspTree.GetTriangle(point, out nearTriangles);
|
||||||
|
if (index >= 0 && index < m_Triangles.Count)
|
||||||
|
{
|
||||||
|
return m_Triangles[index];
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取距离指定位置最近的边
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="position">目标位置</param>
|
||||||
|
/// <param name="edges">边集合</param>
|
||||||
|
/// <param name="outSqrDistMin">输出最短距离</param>
|
||||||
|
/// <returns></returns>
|
||||||
|
private TriangleEdge InternalGetNearestEdge(in LVector2 position, List<IConnection<NavTriangle>> edges, out LFloat outSqrDistMin)
|
||||||
|
{
|
||||||
|
outSqrDistMin = LFloat.FLT_MAX;
|
||||||
|
if (edges == null || edges.Count <= 0) { return null; }
|
||||||
|
TriangleEdge targetEdge = null;
|
||||||
|
foreach (IConnection<NavTriangle> connection in edges)
|
||||||
|
{
|
||||||
|
if (connection is not TriangleEdge edge) { continue; }
|
||||||
|
LFloat sprDist = GeometryUtil.SqrDistPointLineSegment(edge.vertexA.ToLVector2XZ(), edge.vertexB.ToLVector2XZ(), position);
|
||||||
|
if (sprDist < outSqrDistMin)
|
||||||
|
{
|
||||||
|
targetEdge = edge;
|
||||||
|
outSqrDistMin = sprDist;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return targetEdge;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 68a7ecd59eb0548cf9676b742a1855b8
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
@ -0,0 +1,69 @@
|
|||||||
|
#if UNITY_5_3_OR_NEWER
|
||||||
|
|
||||||
|
using JNGame.Math;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
namespace JNGame.PathFinding
|
||||||
|
{
|
||||||
|
public partial class TriangleNavMesh
|
||||||
|
{
|
||||||
|
#if UNITY_EDITOR
|
||||||
|
|
||||||
|
public void DebugVisualize()
|
||||||
|
{
|
||||||
|
m_Graph.DebugVisualize();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void DrawGizmos()
|
||||||
|
{
|
||||||
|
m_Graph.DrawGizmos();
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
public partial class TriangleGraph
|
||||||
|
{
|
||||||
|
#if UNITY_EDITOR
|
||||||
|
|
||||||
|
public void DebugVisualize()
|
||||||
|
{
|
||||||
|
m_BspTree.DebugDraw();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void DrawGizmos()
|
||||||
|
{
|
||||||
|
if (m_NavMeshData == null || m_NavMeshData.pathTriangles == null) { return; }
|
||||||
|
int i = 0;
|
||||||
|
Gizmos.color = Color.green;
|
||||||
|
while (i < m_NavMeshData.pathTriangles.Length)
|
||||||
|
{
|
||||||
|
int aIndex = m_NavMeshData.pathTriangles[i++];
|
||||||
|
int bIndex = m_NavMeshData.pathTriangles[i++];
|
||||||
|
int cIndex = m_NavMeshData.pathTriangles[i++];
|
||||||
|
|
||||||
|
Vector3 vertexA = m_NavMeshData.pathVertices[aIndex].ToVector3();
|
||||||
|
Vector3 vertexB = m_NavMeshData.pathVertices[bIndex].ToVector3();
|
||||||
|
Vector3 vertexC = m_NavMeshData.pathVertices[cIndex].ToVector3();
|
||||||
|
|
||||||
|
Gizmos.DrawLine(vertexA, vertexB);
|
||||||
|
Gizmos.DrawLine(vertexB, vertexC);
|
||||||
|
Gizmos.DrawLine(vertexC, vertexA);
|
||||||
|
}
|
||||||
|
|
||||||
|
Gizmos.color = Color.blue;
|
||||||
|
Vector3 bottomLeft = new LVector3(m_NavMeshData.xMin, 0.ToLFloat(), m_NavMeshData.zMin).ToVector3();
|
||||||
|
Vector3 bottomRight = new LVector3(m_NavMeshData.xMax, 0.ToLFloat(), m_NavMeshData.zMin).ToVector3();
|
||||||
|
Vector3 topLeft = new LVector3(m_NavMeshData.xMin, 0.ToLFloat(), m_NavMeshData.zMax).ToVector3();
|
||||||
|
Vector3 topRight = new LVector3(m_NavMeshData.xMax, 0.ToLFloat(), m_NavMeshData.zMax).ToVector3();
|
||||||
|
Gizmos.DrawLine(bottomLeft, bottomRight);
|
||||||
|
Gizmos.DrawLine(bottomLeft, topLeft);
|
||||||
|
Gizmos.DrawLine(bottomRight, topRight);
|
||||||
|
Gizmos.DrawLine(topLeft, topRight);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: b08810f156faa684f92fa3cd9cb54c14
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
@ -0,0 +1,205 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using JNGame.Math;
|
||||||
|
using JNGame.Util;
|
||||||
|
|
||||||
|
namespace JNGame.PathFinding
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 边查找过滤枚举
|
||||||
|
/// </summary>
|
||||||
|
[System.Flags]
|
||||||
|
public enum EnumEdgeFilter
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 共享边
|
||||||
|
/// </summary>
|
||||||
|
kFilterShared = 1,
|
||||||
|
/// <summary>
|
||||||
|
/// 独边
|
||||||
|
/// </summary>
|
||||||
|
kFilterIsolated = 2,
|
||||||
|
/// <summary>
|
||||||
|
/// 全部边
|
||||||
|
/// </summary>
|
||||||
|
kFilterAll = kFilterShared | kFilterIsolated
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 以三角形为图元的导航网格
|
||||||
|
/// </summary>
|
||||||
|
public partial class TriangleNavMesh
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 三角形图元节点组成的图
|
||||||
|
/// </summary>
|
||||||
|
private readonly TriangleGraph m_Graph;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 路径查找器
|
||||||
|
/// </summary>
|
||||||
|
private readonly IndexedAStarPathFinder<NavTriangle> m_PathFinder;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 寻路启发器
|
||||||
|
/// </summary>
|
||||||
|
private readonly TriangleHeuristic m_Heuristic;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 寻路坐标描述结果的缓存,每次寻路都会被清理和覆盖,外部不可直接使用本对象
|
||||||
|
/// </summary>
|
||||||
|
private readonly TrianglePointPath m_TempPointPath = new TrianglePointPath();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 寻路节点描述结果的缓存,每次寻路都会被清理和覆盖,外部不可直接使用本对象
|
||||||
|
/// </summary>
|
||||||
|
private readonly TriangleEdgeGraphPath m_TempGraphPath = new TriangleEdgeGraphPath();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 构造导航网格
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="jsonNavMeshData">导航网格数据,Json格式字符串</param>
|
||||||
|
/// <param name="scale"></param>
|
||||||
|
public TriangleNavMesh(string jsonNavMeshData, int scale = 1)
|
||||||
|
{
|
||||||
|
var data = JsonUtil.ToObject<NavMeshData>(jsonNavMeshData);
|
||||||
|
m_Graph = new TriangleGraph(data, scale);
|
||||||
|
m_PathFinder = new IndexedAStarPathFinder<NavTriangle>(m_Graph, true);
|
||||||
|
m_Heuristic = new TriangleHeuristic();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 构造导航网格
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="navMeshData">导航网格数据</param>
|
||||||
|
/// <param name="scale"></param>
|
||||||
|
public TriangleNavMesh(NavMeshData navMeshData, int scale = 1)
|
||||||
|
{
|
||||||
|
m_Graph = new TriangleGraph(navMeshData, scale);
|
||||||
|
m_PathFinder = new IndexedAStarPathFinder<NavTriangle>(m_Graph, true);
|
||||||
|
m_Heuristic = new TriangleHeuristic();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 搜索从起点fromPoint到终点toPoint的路径
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="fromPoint">起点位置</param>
|
||||||
|
/// <param name="toPoint">终点位置</param>
|
||||||
|
/// <param name="allowFixToPoint">是否运行修正终点坐标,如果终点在阻挡内,使用阻挡边的邻接点作为终点</param>
|
||||||
|
/// <returns>路径经过的坐标点列表</returns>
|
||||||
|
public List<LVector3> FindPath(in LVector3 fromPoint, in LVector3 toPoint, bool allowFixToPoint = false)
|
||||||
|
{
|
||||||
|
// 清理结果缓存
|
||||||
|
m_TempPointPath.Clear();
|
||||||
|
m_TempGraphPath.Clear();
|
||||||
|
// 查找目标路径
|
||||||
|
bool find = FindPath(fromPoint, toPoint, m_TempGraphPath, allowFixToPoint);
|
||||||
|
if (!find)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
// 节点路径描述转化为坐标路径描述
|
||||||
|
// m_TempPointPath.CalculateForGraphPath(m_TempGraphPath, false);
|
||||||
|
// Profiler.BeginSample("PathTranslate");
|
||||||
|
m_TempPointPath.CalculateForGraphPath(m_TempGraphPath, false);
|
||||||
|
// Profiler.EndSample();
|
||||||
|
return m_TempPointPath.GetVectors();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 搜索从fromPoint到toPoint的路径,路径结果用路径经过的图上的边或结点表示
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="fromPoint">起点位置</param>
|
||||||
|
/// <param name="toPoint">终点位置</param>
|
||||||
|
/// <param name="allowFixToPoint">是否运行修正终点坐标,如果终点在阻挡内,使用阻挡边的邻接点作为终点</param>
|
||||||
|
/// <param name="path">结果路径</param>
|
||||||
|
/// <returns>是否成功找出路径</returns>
|
||||||
|
private bool FindPath(in LVector3 fromPoint, in LVector3 toPoint, TriangleEdgeGraphPath path, bool allowFixToPoint)
|
||||||
|
{
|
||||||
|
// 获取起始点和目标点所在的三角形节点
|
||||||
|
NavTriangle fromTriangle = m_Graph.GetTriangle(in fromPoint);
|
||||||
|
LVector3 toPointFixed = toPoint;
|
||||||
|
NavTriangle toTriangle = allowFixToPoint ? m_Graph.GetTriangleOrNeareastTriangle(in toPoint, out toPointFixed)
|
||||||
|
: m_Graph.GetTriangle(in toPoint);
|
||||||
|
// 验证输入合法性
|
||||||
|
if (fromTriangle == null)
|
||||||
|
{
|
||||||
|
//Debug.LogWarning("TriangleNavMesh.FindPath Failed! fromPoint = {0} valid!", fromPoint);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (toTriangle == null)
|
||||||
|
{
|
||||||
|
//Debug.LogWarning("TriangleNavMesh.FindPath Failed! toPoint = {0} valid!", toPoint);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
// Profiler.BeginSample("AStarPathFinder");
|
||||||
|
// 搜索路径
|
||||||
|
bool result = m_PathFinder.SearchPath(fromTriangle, toTriangle, m_Heuristic, path);
|
||||||
|
if (result)
|
||||||
|
{
|
||||||
|
path.startPoint = fromPoint;
|
||||||
|
path.endPoint = toPointFixed;
|
||||||
|
path.startTriangle = fromTriangle;
|
||||||
|
}
|
||||||
|
// Profiler.EndSample();
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 查找坐标落位的三角形,空说明在阻挡区内
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="position"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public NavTriangle GetTriangle(in LVector3 position)
|
||||||
|
{
|
||||||
|
return m_Graph.GetTriangle(position);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 查找坐标落位的三角形或是距离最近的三角形,返回最近三角形上的点
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="position"></param>
|
||||||
|
/// <param name="outNearestPosition"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public NavTriangle GetTriangleOrNearestTriangle(in LVector3 position, out LVector3 outNearestPosition)
|
||||||
|
{
|
||||||
|
return m_Graph.GetTriangleOrNeareastTriangle(position, out outNearestPosition);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 查询距离指定位置最近的三角形网格边
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="navTriangle">三角形</param>
|
||||||
|
/// <param name="position">位置</param>
|
||||||
|
/// <param name="filter">边查找过滤</param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public TriangleEdge GetNearestEdge(NavTriangle navTriangle, in LVector3 position, EnumEdgeFilter filter)
|
||||||
|
{
|
||||||
|
return filter switch
|
||||||
|
{
|
||||||
|
EnumEdgeFilter.kFilterShared => m_Graph.GetNearestSharedEdge(navTriangle, in position),
|
||||||
|
EnumEdgeFilter.kFilterIsolated => m_Graph.GetNeareastIsolatedEdge(navTriangle, in position),
|
||||||
|
EnumEdgeFilter.kFilterAll => m_Graph.GetNearestEdge(navTriangle, in position),
|
||||||
|
_ => null,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 根据索引获取三角形网格
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="index"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public NavTriangle GetTriangle(int index)
|
||||||
|
{
|
||||||
|
return m_Graph.GetNode(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取全部的导航三角形网格数据
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
public List<NavTriangle> GetNavTriangles()
|
||||||
|
{
|
||||||
|
return m_Graph.Triangles;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 0de2ec35d68a342c292a00bb7f43e327
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
@ -0,0 +1,8 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: b8bb5a4c219ae4dcbbd5a7b6ff3b6b85
|
||||||
|
folderAsset: yes
|
||||||
|
DefaultImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
@ -0,0 +1,62 @@
|
|||||||
|
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace JNGame.PathFinding
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 描述图数据结构上的一条路径
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="TEdge">路径节点描述:可以是图数据结构中邻接边或节点</typeparam>
|
||||||
|
public class DefaultGraphPath<TEdge> : IGraphPath<TEdge>
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 路径节点的集合,节点可以用图的邻接边或节点描述
|
||||||
|
/// </summary>
|
||||||
|
public List<TEdge> nodes;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Creates a {@code DefaultGraphPath} with no nodes.
|
||||||
|
/// </summary>
|
||||||
|
public DefaultGraphPath() : this(new List<TEdge>()) { }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Creates a {@code DefaultGraphPath} with the given capacity and no nodes.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="capacity"></param>
|
||||||
|
public DefaultGraphPath(int capacity) : this(new List<TEdge>(capacity)) { }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Creates a {@code DefaultGraphPath} with the given nodes.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="nodes"></param>
|
||||||
|
public DefaultGraphPath(List<TEdge> nodes)
|
||||||
|
{
|
||||||
|
this.nodes = nodes;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Clear()
|
||||||
|
{
|
||||||
|
nodes.Clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
public int GetCount()
|
||||||
|
{
|
||||||
|
return nodes.Count;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Add(TEdge node)
|
||||||
|
{
|
||||||
|
nodes.Add(node);
|
||||||
|
}
|
||||||
|
|
||||||
|
public TEdge Get(int index)
|
||||||
|
{
|
||||||
|
return nodes[index];
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Reverse()
|
||||||
|
{
|
||||||
|
nodes.Reverse();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 2c513670f2d7d435ab65402918015090
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
@ -0,0 +1,48 @@
|
|||||||
|
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using JNGame.Math;
|
||||||
|
|
||||||
|
namespace JNGame.PathFinding
|
||||||
|
{
|
||||||
|
public class EdgePoint
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Triangle which must be crossed to reach the next path point.
|
||||||
|
*/
|
||||||
|
public NavTriangle toNode;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Triangle which was crossed to reach this point.
|
||||||
|
*/
|
||||||
|
public NavTriangle fromNode;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Path edges connected to this point. Can be used for spline generation at some
|
||||||
|
* point perhaps...
|
||||||
|
*/
|
||||||
|
public List<TriangleEdge> connectingEdges = new List<TriangleEdge>(8);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The point where the path crosses an edge.
|
||||||
|
*/
|
||||||
|
public LVector3 point;
|
||||||
|
|
||||||
|
public EdgePoint()
|
||||||
|
{
|
||||||
|
point = LVector3.Zero;
|
||||||
|
toNode = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Set(in LVector3 point, NavTriangle toNode)
|
||||||
|
{
|
||||||
|
this.point = point;
|
||||||
|
this.toNode = toNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
public EdgePoint(in LVector3 point, NavTriangle toNode)
|
||||||
|
{
|
||||||
|
this.point = point;
|
||||||
|
this.toNode = toNode;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: a8be0d16ec4044fbc8b80bb7a236024b
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
@ -0,0 +1,75 @@
|
|||||||
|
using JNGame.Math;
|
||||||
|
|
||||||
|
namespace JNGame.PathFinding
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 漏斗
|
||||||
|
/// </summary>
|
||||||
|
public class Funnel
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 漏斗点,路径的起点或拐点
|
||||||
|
/// </summary>
|
||||||
|
public LVector3 pivot = LVector3.Zero;
|
||||||
|
/// <summary>
|
||||||
|
/// 漏斗的边界面A
|
||||||
|
/// </summary>
|
||||||
|
public Plane leftPlane = new Plane(); // 左平面,高度为y轴
|
||||||
|
/// <summary>
|
||||||
|
/// 漏斗的边界面B
|
||||||
|
/// </summary>
|
||||||
|
public Plane rightPlane = new Plane();
|
||||||
|
/// <summary>
|
||||||
|
/// 漏斗的边界面A与三角形平面的交点
|
||||||
|
/// </summary>
|
||||||
|
public LVector3 leftPortal = LVector3.Zero; // 路径左顶点,
|
||||||
|
/// <summary>
|
||||||
|
/// 漏斗的边界面B与三角形平面的交点
|
||||||
|
/// </summary>
|
||||||
|
public LVector3 rightPortal = LVector3.Zero; // 路径右顶点
|
||||||
|
|
||||||
|
public void SetLeftPlane(in LVector3 pivot, in LVector3 leftEdgeVertex)
|
||||||
|
{
|
||||||
|
leftPlane.Set(pivot, pivot + LVector3.Up, leftEdgeVertex);
|
||||||
|
leftPortal = leftEdgeVertex;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SetRightPlane(in LVector3 pivot, in LVector3 rightEdgeVertex)
|
||||||
|
{
|
||||||
|
rightPlane.Set(pivot, pivot + LVector3.Up, rightEdgeVertex); // 高度
|
||||||
|
rightPlane.normal = -rightPlane.normal; // 平面方向取反
|
||||||
|
rightPlane.distFromOrigin = -rightPlane.distFromOrigin;
|
||||||
|
rightPortal = rightEdgeVertex;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 设置漏斗的两个边面
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="pivot">漏斗点</param>
|
||||||
|
/// <param name="edge">三角形的共享边</param>
|
||||||
|
public void SetPlanes(in LVector3 pivot, TriangleEdge edge)
|
||||||
|
{
|
||||||
|
SetLeftPlane(pivot, edge.vertexB);
|
||||||
|
SetRightPlane(pivot, edge.vertexA);
|
||||||
|
}
|
||||||
|
|
||||||
|
public EnumPlaneSide SideLeftPlane(in LVector3 point)
|
||||||
|
{
|
||||||
|
return leftPlane.TestPoint(point);
|
||||||
|
}
|
||||||
|
|
||||||
|
public EnumPlaneSide SideRightPlane(in LVector3 point)
|
||||||
|
{
|
||||||
|
return rightPlane.TestPoint(point);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Reset()
|
||||||
|
{
|
||||||
|
pivot = LVector3.Zero;
|
||||||
|
leftPlane.Reset();
|
||||||
|
rightPlane.Reset();
|
||||||
|
leftPortal = LVector3.Zero;
|
||||||
|
rightPortal = LVector3.Zero;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 55922bc76371f4895b885c6663d8d181
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
@ -0,0 +1,44 @@
|
|||||||
|
|
||||||
|
namespace JNGame.PathFinding
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 描述一条路径的接口
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="TEdge">路径节点描述:可以是图数据结构中邻接边或节点</typeparam>
|
||||||
|
public interface IGraphPath<TEdge>
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 返回路径节点总数
|
||||||
|
/// <para> Returns the number of items of this path. </para>
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
int GetCount();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取指定索引路径节点
|
||||||
|
/// <para> Returns the item of this path at the given index. </para>
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="index"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
TEdge Get(int index);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 添加一个路径节点到列表尾部
|
||||||
|
/// <para> Adds an item at the end of this path. </para>
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="node"></param>
|
||||||
|
void Add(TEdge node);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 清理所有的路径节点
|
||||||
|
/// <para> Clears this path. </para>
|
||||||
|
/// </summary>
|
||||||
|
void Clear();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 翻转路径节点(节点A->节点B 变为 节点B->节点A)
|
||||||
|
/// <para> Reverses this path. </para>
|
||||||
|
/// </summary>
|
||||||
|
void Reverse();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 3b81b57e2d2d1466eadfe89f96171b11
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
@ -0,0 +1,25 @@
|
|||||||
|
using JNGame.Math;
|
||||||
|
|
||||||
|
namespace JNGame.PathFinding
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// <para> A {@code Heuristic} generates estimates of the cost to move from a given node to the goal. </para>
|
||||||
|
/// With a heuristic function pathfinding algorithms can choose the node that is most likely to lead to the optimal path. The
|
||||||
|
/// notion of "most likely" is controlled by a heuristic. If the heuristic is accurate, then the algorithm will be efficient. If
|
||||||
|
/// the heuristic is terrible, then it can perform even worse than other algorithms that don't use any heuristic function such as
|
||||||
|
/// Dijkstra.
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="TNode">Type of node</typeparam>
|
||||||
|
public interface IHeuristic<TNode>
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 启发式算法估价函数,计算从当前点到目标点的估价
|
||||||
|
/// <para>A*启发函数的g(n)</para>
|
||||||
|
/// <para>Calculates an estimated cost to reach the goal node from the given node.</para>
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="node">the start node</param>
|
||||||
|
/// <param name="endNode">the end node</param>
|
||||||
|
/// <returns>the estimated cost</returns>
|
||||||
|
LFloat Estimate(TNode node, TNode endNode);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 736f27d5a74ce43f8923b8bc96b225b3
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
@ -0,0 +1,30 @@
|
|||||||
|
|
||||||
|
namespace JNGame.PathFinding
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 路径搜索器的接口定义
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="TNode">图数据结构的节点</typeparam>
|
||||||
|
public interface IPathFinder<TNode>
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 搜索从startNode到endNode的一条路径
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="startNode">起始节点</param>
|
||||||
|
/// <param name="endNode">目标节点</param>
|
||||||
|
/// <param name="heuristic">启发函数</param>
|
||||||
|
/// <param name="outPath">输出结果路径:路径用图的邻接边描述</param>
|
||||||
|
/// <returns>是否成功搜索到一条路径</returns>
|
||||||
|
bool SearchPath(TNode startNode, TNode endNode, IHeuristic<TNode> heuristic, IGraphPath<IConnection<TNode>> outPath);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 搜索从startNode到endNode的一条路径
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="startNode">图中的起始节点</param>
|
||||||
|
/// <param name="endNode">图中的目标节点</param>
|
||||||
|
/// <param name="heuristic">启发函数</param>
|
||||||
|
/// <param name="outPath">输出结果路径:路径用图的节点描述</param>
|
||||||
|
/// <returns>是否成功搜索到一条路径</returns>
|
||||||
|
bool SearchNodePath(TNode startNode, TNode endNode, IHeuristic<TNode> heuristic, IGraphPath<TNode> outPath);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 09b9a4d779c64410b8720c88bd5168e5
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
@ -0,0 +1,366 @@
|
|||||||
|
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using JNGame.Math;
|
||||||
|
|
||||||
|
namespace JNGame.PathFinding
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 基于A*算法的路径搜索器
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="TNode">图的节点类型</typeparam>
|
||||||
|
public class IndexedAStarPathFinder<TNode> : IPathFinder<TNode>
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 节点搜索状态 - 未遍历
|
||||||
|
/// </summary>
|
||||||
|
public const int UNVISITED = 0;
|
||||||
|
/// <summary>
|
||||||
|
/// 节点搜索状态 - 处理OpenList中
|
||||||
|
/// </summary>
|
||||||
|
public const int OPEN = 1;
|
||||||
|
/// <summary>
|
||||||
|
/// 节点搜索状态 - 处理完成
|
||||||
|
/// </summary>
|
||||||
|
public const int CLOSED = 2;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 寻路使用的数据源
|
||||||
|
/// <para>以TNode为节点构成的图数据结构,包含TNode节点集合,以及TNode的邻接关系集合</para>
|
||||||
|
/// </summary>
|
||||||
|
private readonly IIndexedGraph<TNode> m_Graph;
|
||||||
|
/// <summary>
|
||||||
|
/// 节点的搜索记录集合,数组长度为图的节点总数
|
||||||
|
/// </summary>
|
||||||
|
private readonly NodeRecord<TNode>[] m_NodeRecords;
|
||||||
|
/// <summary>
|
||||||
|
/// OpenList,用二叉堆数据结构描述
|
||||||
|
/// </summary>
|
||||||
|
private readonly GenericBinaryHeap<NodeRecord<TNode>> m_OpenList;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 搜索ID,每次搜索自增,用于标记节点搜索记录
|
||||||
|
/// The unique ID for each search run. Used to mark nodes.
|
||||||
|
/// </summary>
|
||||||
|
private int m_SearchId = 0;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 当前搜索的节点
|
||||||
|
/// </summary>
|
||||||
|
private NodeRecord<TNode> m_Current;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 性能评估指标,与搜索过程无关,记录A*的搜索次数,以此评估性能
|
||||||
|
/// </summary>
|
||||||
|
public Metrics metrics;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 基于A*算法的路径搜索器构造
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="graph">路径搜索器使用的数据源</param>
|
||||||
|
/// <param name="calculateMetrics">是否开启性能评估,默认:false</param>
|
||||||
|
public IndexedAStarPathFinder(IIndexedGraph<TNode> graph, bool calculateMetrics = false)
|
||||||
|
{
|
||||||
|
m_Graph = graph;
|
||||||
|
m_NodeRecords = new NodeRecord<TNode>[graph.GetNodeCount()];
|
||||||
|
m_OpenList = new GenericBinaryHeap<NodeRecord<TNode>>();
|
||||||
|
if (calculateMetrics)
|
||||||
|
{
|
||||||
|
metrics = new Metrics();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool SearchPath(TNode startNode, TNode endNode, IHeuristic<TNode> heuristic, IGraphPath<IConnection<TNode>> outPath)
|
||||||
|
{
|
||||||
|
// Perform AStar
|
||||||
|
bool found = Search(startNode, endNode, heuristic);
|
||||||
|
if (found)
|
||||||
|
{
|
||||||
|
// Create a path made of connections
|
||||||
|
GeneratePath(startNode, outPath);
|
||||||
|
}
|
||||||
|
return found;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool SearchNodePath(TNode startNode, TNode endNode, IHeuristic<TNode> heuristic, IGraphPath<TNode> outPath)
|
||||||
|
{
|
||||||
|
// Perform AStar
|
||||||
|
bool found = Search(startNode, endNode, heuristic);
|
||||||
|
if (found)
|
||||||
|
{
|
||||||
|
// Create a path made of nodes
|
||||||
|
GenerateNodePath(startNode, outPath);
|
||||||
|
}
|
||||||
|
return found;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 开始执行路径搜索
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="startNode">图上的起始节点</param>
|
||||||
|
/// <param name="endNode">图上的目标节点</param>
|
||||||
|
/// <param name="heuristic">启发函数</param>
|
||||||
|
/// <returns>是否存在路径</returns>
|
||||||
|
protected bool Search(TNode startNode, TNode endNode, IHeuristic<TNode> heuristic)
|
||||||
|
{
|
||||||
|
InitSearch(startNode, endNode, heuristic);
|
||||||
|
// Iterate through processing each node
|
||||||
|
do
|
||||||
|
{
|
||||||
|
// Retrieve the node with smallest estimated total cost from the open list
|
||||||
|
m_Current = m_OpenList.Pop();
|
||||||
|
m_Current.category = CLOSED;
|
||||||
|
// Terminate if we reached the goal node
|
||||||
|
if (m_Current.node.Equals(endNode)) { return true; }
|
||||||
|
// 遍历当前节点的邻接节点,选取评估值
|
||||||
|
VisitChildren(endNode, heuristic);
|
||||||
|
}
|
||||||
|
while (m_OpenList.size > 0);
|
||||||
|
// We've run out of nodes without finding the goal, so there's no solution
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 初始化路径搜索
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="startNode">图上的起始节点</param>
|
||||||
|
/// <param name="endNode">图上的目标节点</param>
|
||||||
|
/// <param name="heuristic">启发函数</param>
|
||||||
|
protected void InitSearch(TNode startNode, TNode endNode, IHeuristic<TNode> heuristic)
|
||||||
|
{
|
||||||
|
// 清空性能指标
|
||||||
|
metrics?.Reset();
|
||||||
|
// 搜索ID自增
|
||||||
|
if (++m_SearchId < 0) { m_SearchId = 1; }
|
||||||
|
// 初始化OpenList
|
||||||
|
m_OpenList.Clear();
|
||||||
|
// Initialize the record for the start node and add it to the open list
|
||||||
|
NodeRecord<TNode> startRecord = GetNodeRecord(startNode);
|
||||||
|
startRecord.node = startNode;
|
||||||
|
startRecord.connection = null; // 起点的连接口设置为null
|
||||||
|
startRecord.costSoFar = 0.ToLFloat();
|
||||||
|
// 起始节点添加到OpenList中
|
||||||
|
AddToOpenList(startRecord, heuristic.Estimate(startNode, endNode));
|
||||||
|
m_Current = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 遍历子节点
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="endNode">路径的目标节点</param>
|
||||||
|
/// <param name="heuristic">启发函数</param>
|
||||||
|
protected void VisitChildren(TNode endNode, IHeuristic<TNode> heuristic)
|
||||||
|
{
|
||||||
|
// Get current node's outgoing connections
|
||||||
|
List<IConnection<TNode>> connections = m_Graph.GetConnections(m_Current.node);
|
||||||
|
// Loop through each connection in turn
|
||||||
|
for (int i = 0; i < connections.Count; i++)
|
||||||
|
{
|
||||||
|
if (metrics != null) { ++metrics.VisitedNodes; }
|
||||||
|
|
||||||
|
IConnection<TNode> connection = connections[i];
|
||||||
|
// Get the cost estimate for the node
|
||||||
|
TNode node = connection.GetToNode(); // 邻接边连接的目标节点
|
||||||
|
LFloat nodeCost = m_Current.costSoFar + connection.GetCost(); // 节点到起点的消耗(g(n))
|
||||||
|
LFloat nodeHeuristic;
|
||||||
|
NodeRecord<TNode> nodeRecord = GetNodeRecord(node);
|
||||||
|
if (nodeRecord.category == CLOSED)
|
||||||
|
{ // The node is closed
|
||||||
|
// If we didn't find a shorter route, skip 已经是消耗最小的目标点
|
||||||
|
if (nodeRecord.costSoFar <= nodeCost) { continue; }
|
||||||
|
// We can use the node's old cost values to calculate its heuristic
|
||||||
|
// without calling the possibly expensive heuristic function
|
||||||
|
nodeHeuristic = nodeRecord.GetEstimatedTotalCost() - nodeRecord.costSoFar;
|
||||||
|
}
|
||||||
|
else if (nodeRecord.category == OPEN)
|
||||||
|
{ // The node is open
|
||||||
|
// If our route is no better, then skip
|
||||||
|
if (nodeRecord.costSoFar <= nodeCost) { continue; }
|
||||||
|
// Remove it from the open list (it will be re-added with the new cost)
|
||||||
|
m_OpenList.Remove(nodeRecord);
|
||||||
|
// We can use the node's old cost values to calculate its heuristic
|
||||||
|
// without calling the possibly expensive heuristic function
|
||||||
|
nodeHeuristic = nodeRecord.GetEstimatedTotalCost() - nodeRecord.costSoFar;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{ // the node is unvisited
|
||||||
|
// We'll need to calculate the heuristic value using the function,
|
||||||
|
// since we don't have a node record with a previously calculated value
|
||||||
|
nodeHeuristic = heuristic.Estimate(node, endNode);
|
||||||
|
}
|
||||||
|
// Update node record's cost and connection
|
||||||
|
nodeRecord.costSoFar = nodeCost;
|
||||||
|
nodeRecord.connection = connection;
|
||||||
|
// Add it to the open list with the estimated total cost
|
||||||
|
AddToOpenList(nodeRecord, nodeCost + nodeHeuristic);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 生成用图的邻接边描述的路径
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="startNode">图起点</param>
|
||||||
|
/// <param name="outPath">输出的路径</param>
|
||||||
|
protected void GeneratePath(TNode startNode, IGraphPath<IConnection<TNode>> outPath)
|
||||||
|
{
|
||||||
|
// outPath.clear();
|
||||||
|
// Work back along the path, accumulating connections
|
||||||
|
while (!m_Current.node.Equals(startNode))
|
||||||
|
{ // 沿着变成搜索的连接口,搜索到起点
|
||||||
|
outPath.Add(m_Current.connection);
|
||||||
|
m_Current = m_NodeRecords[m_Graph.GetIndex(m_Current.connection.GetFromNode())];
|
||||||
|
}
|
||||||
|
// Reverse the path
|
||||||
|
outPath.Reverse();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 生成用图的节点描述的路径
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="startNode">图起点</param>
|
||||||
|
/// <param name="outPath">输出的路径</param>
|
||||||
|
protected void GenerateNodePath(TNode startNode, IGraphPath<TNode> outPath)
|
||||||
|
{
|
||||||
|
// outPath.clear();
|
||||||
|
// Work back along the path, accumulating nodes
|
||||||
|
while (m_Current.connection != null)
|
||||||
|
{ // 沿着变成搜索的连接口,搜索到空连接
|
||||||
|
outPath.Add(m_Current.node);
|
||||||
|
m_Current = m_NodeRecords[m_Graph.GetIndex(m_Current.connection.GetFromNode())];
|
||||||
|
}
|
||||||
|
// 额外添加起点
|
||||||
|
outPath.Add(startNode);
|
||||||
|
// Reverse the path
|
||||||
|
outPath.Reverse();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 添加节点到OpenList,节点搜索记录状态设置为Open
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="nodeRecord">节点关联的搜索记录</param>
|
||||||
|
/// <param name="estimatedTotalCost">当前节点的到路径终点的总消耗(g(n)+h(n))</param>
|
||||||
|
protected void AddToOpenList(NodeRecord<TNode> nodeRecord, LFloat estimatedTotalCost)
|
||||||
|
{
|
||||||
|
m_OpenList.Add(nodeRecord, estimatedTotalCost);
|
||||||
|
// 节点搜索状态更新为OPEN
|
||||||
|
nodeRecord.category = OPEN;
|
||||||
|
if (metrics != null)
|
||||||
|
{
|
||||||
|
// 更新性能指标
|
||||||
|
++metrics.OpenListAdditions;
|
||||||
|
if (m_OpenList.size > metrics.OpenListPeak)
|
||||||
|
{
|
||||||
|
metrics.OpenListPeak = m_OpenList.size;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取指定图节点的搜索记录
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="node">图节点</param>
|
||||||
|
/// <returns>图节点关联的搜索记录</returns>
|
||||||
|
protected NodeRecord<TNode> GetNodeRecord(TNode node)
|
||||||
|
{
|
||||||
|
int index = m_Graph.GetIndex(node);
|
||||||
|
NodeRecord<TNode> nr = m_NodeRecords[index];
|
||||||
|
if (nr != null)
|
||||||
|
{
|
||||||
|
// 不同批次的搜索,重置节点状态和关联的搜索ID
|
||||||
|
if (nr.searchId != m_SearchId)
|
||||||
|
{
|
||||||
|
nr.category = UNVISITED;
|
||||||
|
nr.searchId = m_SearchId;
|
||||||
|
}
|
||||||
|
return nr;
|
||||||
|
}
|
||||||
|
// 从未搜索过,创建新的节点搜索记录
|
||||||
|
nr = m_NodeRecords[index] = new NodeRecord<TNode>();
|
||||||
|
nr.node = node;
|
||||||
|
nr.searchId = m_SearchId;
|
||||||
|
return nr;
|
||||||
|
}
|
||||||
|
|
||||||
|
#region 二叉堆的节点数据结构定义
|
||||||
|
/// <summary>
|
||||||
|
/// 图节点搜索记录
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="TN"></typeparam>
|
||||||
|
public class NodeRecord<TN> : BinaryHeapNode
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 关联的图节点
|
||||||
|
/// <para>The reference to the node.</para>
|
||||||
|
/// </summary>
|
||||||
|
public TN node;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 本次搜索走的邻接口
|
||||||
|
/// <para>The incoming connection to the node.</para>
|
||||||
|
/// </summary>
|
||||||
|
public IConnection<TN> connection;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 当前节点到起点的实际消耗,A*启发函数的g(n)
|
||||||
|
/// <para>The actual cost from the start node.</para>
|
||||||
|
/// </summary>
|
||||||
|
public LFloat costSoFar;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 节点的状态,UNVISITED / OPEN / OPEN 三者之一
|
||||||
|
/// <para>The node category: {@link #UNVISITED}, {@link #OPEN} or {@link #OPEN}.</para>
|
||||||
|
/// </summary>
|
||||||
|
public int category;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 关联的搜索ID
|
||||||
|
/// <para>ID of the current search.</para>
|
||||||
|
/// </summary>
|
||||||
|
public int searchId;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Creates a {@code NodeRecord}.
|
||||||
|
/// </summary>
|
||||||
|
public NodeRecord() : base(LFloat.Zero) { }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取当前节点总的消耗:f(n) = g(n) + h(n)
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>Returns the estimated total cost.</returns>
|
||||||
|
public LFloat GetEstimatedTotalCost()
|
||||||
|
{
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region 寻路指标定义,与寻路过程无关
|
||||||
|
/// <summary>
|
||||||
|
/// 寻路指标,评测寻路性能使用
|
||||||
|
/// </summary>
|
||||||
|
public class Metrics
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 遍历节点的次数
|
||||||
|
/// </summary>
|
||||||
|
public int VisitedNodes;
|
||||||
|
/// <summary>
|
||||||
|
/// OpenList添加的次数
|
||||||
|
/// </summary>
|
||||||
|
public int OpenListAdditions;
|
||||||
|
/// <summary>
|
||||||
|
/// OpenList中最大的待处理节点数
|
||||||
|
/// </summary>
|
||||||
|
public int OpenListPeak;
|
||||||
|
|
||||||
|
public Metrics() { }
|
||||||
|
|
||||||
|
public void Reset()
|
||||||
|
{
|
||||||
|
VisitedNodes = 0;
|
||||||
|
OpenListAdditions = 0;
|
||||||
|
OpenListPeak = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 5243578b0e4974e358512ec1e0c2ae05
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
@ -0,0 +1,317 @@
|
|||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Text;
|
||||||
|
using JNGame.Math;
|
||||||
|
|
||||||
|
namespace JNGame.PathFinding
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 二叉堆的节点基类
|
||||||
|
/// </summary>
|
||||||
|
public class BinaryHeapNode
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 节点排序比较值
|
||||||
|
/// </summary>
|
||||||
|
public LFloat value;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 节点索引
|
||||||
|
/// </summary>
|
||||||
|
public int index;
|
||||||
|
|
||||||
|
public BinaryHeapNode(LFloat value)
|
||||||
|
{
|
||||||
|
this.value = value;
|
||||||
|
}
|
||||||
|
public override string ToString()
|
||||||
|
{
|
||||||
|
return value.ToString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 二叉堆数据结构
|
||||||
|
/// <para>常规二叉堆不从索引0开始,而是从索引1开始</para>
|
||||||
|
/// <para>索引为n的左孩子索引是2n,索引为n的右孩子索引是2n+1,索引为n的父节点索引是n/2</para>
|
||||||
|
/// <para>本实现从索引0开始</para>
|
||||||
|
/// <para>本实现索引为n的左孩子索引是2n+1,索引为n的右孩子索引是2(n+1),索引为n的父节点索引是(n-1)/2</para>
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="T">二叉堆中的数据节点</typeparam>
|
||||||
|
public class GenericBinaryHeap<T> where T : BinaryHeapNode
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 二叉堆中的有效节点总数,同时是当前的可插入位置
|
||||||
|
/// </summary>
|
||||||
|
public int size;
|
||||||
|
/// <summary>
|
||||||
|
/// 二叉堆节点集合,用数组存储
|
||||||
|
/// </summary>
|
||||||
|
private BinaryHeapNode[] m_Nodes;
|
||||||
|
/// <summary>
|
||||||
|
/// 是否是最大堆
|
||||||
|
/// <para>最大堆:任意节点权值不小于其子节点</para>
|
||||||
|
/// <para>最小堆:任意节点权值不大于于其子节点</para>
|
||||||
|
/// </summary>
|
||||||
|
private readonly bool m_IsMaxHeap;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 二叉堆构造器
|
||||||
|
/// </summary>
|
||||||
|
public GenericBinaryHeap() : this(16, false) { }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 二叉堆构造器
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="capacity">初始容量</param>
|
||||||
|
/// <param name="isMaxHeap">是否是最大堆</param>
|
||||||
|
public GenericBinaryHeap(int capacity, bool isMaxHeap)
|
||||||
|
{
|
||||||
|
m_IsMaxHeap = isMaxHeap;
|
||||||
|
m_Nodes = new BinaryHeapNode[capacity];
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 添加节点到二叉堆
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="node"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public T Add(T node)
|
||||||
|
{
|
||||||
|
// Expand if necessary.
|
||||||
|
if (size == m_Nodes.Length)
|
||||||
|
{
|
||||||
|
BinaryHeapNode[] newNodes = new BinaryHeapNode[size << 1];
|
||||||
|
Array.Copy(m_Nodes, 0, newNodes, 0, size);
|
||||||
|
m_Nodes = newNodes;
|
||||||
|
}
|
||||||
|
// Insert at end.
|
||||||
|
node.index = size;
|
||||||
|
m_Nodes[size] = node;
|
||||||
|
// bubble up
|
||||||
|
Up(size++);
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 添加节点到二叉堆,并设置节点的排序权重为value
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="node">添加到二叉堆的节点</param>
|
||||||
|
/// <param name="value">节点的排序权重</param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public T Add(T node, LFloat value)
|
||||||
|
{
|
||||||
|
node.value = value;
|
||||||
|
return Add(node);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取二叉堆顶的节点
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
/// <exception cref="Exception"></exception>
|
||||||
|
public T Peek()
|
||||||
|
{
|
||||||
|
if (size == 0)
|
||||||
|
throw new Exception("The heap is empty.");
|
||||||
|
return (T)m_Nodes[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 弹出二叉堆顶的节点
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
public T Pop()
|
||||||
|
{
|
||||||
|
return Remove(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 弹出指定的二叉堆中节点
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="node">移除的节点</param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public T Remove(T node)
|
||||||
|
{
|
||||||
|
return Remove(node.index);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 移除二叉堆指定索引位置的节点
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="index">移除位置索引</param>
|
||||||
|
/// <returns></returns>
|
||||||
|
private T Remove(int index)
|
||||||
|
{
|
||||||
|
BinaryHeapNode[] nodes = m_Nodes;
|
||||||
|
BinaryHeapNode removed = nodes[index];
|
||||||
|
// 用最后一个位置的节点填充移除的位置
|
||||||
|
nodes[index] = nodes[--size];
|
||||||
|
nodes[size] = null;
|
||||||
|
if (size > 0 && index < size)
|
||||||
|
{
|
||||||
|
Down(index);
|
||||||
|
}
|
||||||
|
return (T)removed;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 清空二叉堆
|
||||||
|
/// TODO 优化,可以不用对nodes进行清零
|
||||||
|
/// </summary>
|
||||||
|
public void Clear()
|
||||||
|
{
|
||||||
|
for (int i = 0, n = size; i < n; ++i)
|
||||||
|
{
|
||||||
|
m_Nodes[i] = null;
|
||||||
|
}
|
||||||
|
size = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 修改二叉堆中一个节点的排序权重
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="node">二叉堆中的一个节点</param>
|
||||||
|
/// <param name="value">新的排序值</param>
|
||||||
|
public void SetValue(T node, LFloat value)
|
||||||
|
{
|
||||||
|
LFloat oldValue = node.value;
|
||||||
|
node.value = value;
|
||||||
|
if ((value < oldValue) ^ m_IsMaxHeap)
|
||||||
|
{
|
||||||
|
Up(node.index);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Down(node.index);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 上浮索引位置的节点,直至满足二叉堆性质
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="index">上浮的节点索引</param>
|
||||||
|
private void Up(int index)
|
||||||
|
{
|
||||||
|
BinaryHeapNode[] nodes = this.m_Nodes;
|
||||||
|
BinaryHeapNode node = nodes[index];
|
||||||
|
LFloat value = node.value;
|
||||||
|
while (index > 0)
|
||||||
|
{
|
||||||
|
// 获取父节点
|
||||||
|
int parentIndex = (index - 1) >> 1;
|
||||||
|
BinaryHeapNode parent = nodes[parentIndex];
|
||||||
|
// 当前节点的权值与父节点比较,是否满足二叉堆性质(最大堆或最小堆)
|
||||||
|
if ((value < parent.value) ^ m_IsMaxHeap)
|
||||||
|
{ // 不满足,则将父节点的值写入到当前节点的位置,当前节点索引该为父节点索引
|
||||||
|
nodes[index] = parent;
|
||||||
|
parent.index = index;
|
||||||
|
index = parentIndex;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// 满足,退出上浮
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 当前节点写入正确位置,更新节点的索引
|
||||||
|
nodes[index] = node;
|
||||||
|
node.index = index;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 节点下沉,寻找符合二叉堆性质的
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="index"></param>
|
||||||
|
private void Down(int index)
|
||||||
|
{
|
||||||
|
BinaryHeapNode[] nodes = m_Nodes;
|
||||||
|
int size = this.size;
|
||||||
|
BinaryHeapNode node = nodes[index];
|
||||||
|
LFloat value = node.value;
|
||||||
|
// 当前节点循环下沉,寻找符合二叉堆性质的索引位置
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
// no child, finished
|
||||||
|
int leftIndex = 1 + (index << 1);
|
||||||
|
if (leftIndex >= size)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
// Always have a left child.
|
||||||
|
BinaryHeapNode leftNode = nodes[leftIndex];
|
||||||
|
LFloat leftValue = leftNode.value;
|
||||||
|
// May have a right child.
|
||||||
|
int rightIndex = leftIndex + 1;
|
||||||
|
BinaryHeapNode rightNode;
|
||||||
|
LFloat rightValue;
|
||||||
|
if (rightIndex >= size)
|
||||||
|
{
|
||||||
|
rightNode = null;
|
||||||
|
rightValue = m_IsMaxHeap ? LFloat.FLT_MIN : LFloat.FLT_MAX;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
rightNode = nodes[rightIndex];
|
||||||
|
rightValue = rightNode.value;
|
||||||
|
}
|
||||||
|
// The smallest of the three values is the parent.
|
||||||
|
if ((leftValue < rightValue) ^ m_IsMaxHeap)
|
||||||
|
{ // 最大堆,左节点为两个子节点的大值 || 最小堆,左节点为两个子节点的小值
|
||||||
|
if (leftValue == value || ((leftValue > value) ^ m_IsMaxHeap))
|
||||||
|
{ // 左节点与当前节点(父节点)权值相同,或 最大堆:左节点为权值小的 | 最小堆:左节点为权值大的。退出,下沉完成
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
// 最小堆:左节点为权值最小的 || 最大堆:左节点为权值最大的,交换当前(父)节点与左节点的位置
|
||||||
|
nodes[index] = leftNode;
|
||||||
|
leftNode.index = index;
|
||||||
|
index = leftIndex;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{ // 最大堆,右节点为两个子节点的大值 || 最小堆,右节点为两个子节点的小值
|
||||||
|
if (rightValue == value || ((rightValue > value) ^ m_IsMaxHeap))
|
||||||
|
{ // 右节点与当前节点(父节点)权值相同,或 最大堆右节点为权值小的 | 最小堆:右节点为权值大的。退出,下沉完成
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
// 最小堆:右节点为权值最小的 || 最大堆:右节点为权值最大的,交换当前(父)节点与右节点的位置
|
||||||
|
nodes[index] = rightNode;
|
||||||
|
rightNode.index = index;
|
||||||
|
index = rightIndex;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 更新当前节点到最终的索引位置
|
||||||
|
nodes[index] = node;
|
||||||
|
node.index = index;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override int GetHashCode()
|
||||||
|
{
|
||||||
|
long h = 1;
|
||||||
|
for (int i = 0, n = size; i < n; i++)
|
||||||
|
{
|
||||||
|
h = h * 31 + m_Nodes[i].value.rawValue;
|
||||||
|
}
|
||||||
|
return (int)h;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override string ToString()
|
||||||
|
{
|
||||||
|
if (size == 0)
|
||||||
|
{
|
||||||
|
return "[]";
|
||||||
|
}
|
||||||
|
BinaryHeapNode[] nodes = this.m_Nodes;
|
||||||
|
StringBuilder buffer = new StringBuilder(32);
|
||||||
|
buffer.Append('[');
|
||||||
|
buffer.Append(nodes[0].value);
|
||||||
|
for (int i = 1; i < size; i++)
|
||||||
|
{
|
||||||
|
buffer.Append(", ");
|
||||||
|
buffer.Append(nodes[i].value);
|
||||||
|
}
|
||||||
|
|
||||||
|
buffer.Append(']');
|
||||||
|
return buffer.ToString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 024aed145f1c9421faa2dcf00949e00d
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
@ -0,0 +1,38 @@
|
|||||||
|
using JNGame.Math;
|
||||||
|
|
||||||
|
namespace JNGame.PathFinding
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 描述以三角形为图元节点的图上,从起点三角形到终点三角形的一条图上的路径。
|
||||||
|
/// <para>路径描节点用图的邻接边描述</para>
|
||||||
|
/// </summary>
|
||||||
|
public class TriangleEdgeGraphPath : DefaultGraphPath<IConnection<NavTriangle>>
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 路径的起点
|
||||||
|
/// <para>The start point when generating a point path for this triangle path</para>
|
||||||
|
/// </summary>
|
||||||
|
public LVector3 startPoint;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 路径的终点
|
||||||
|
/// <para>The end point when generating a point path for this triangle path</para>
|
||||||
|
/// </summary>
|
||||||
|
public LVector3 endPoint;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 路径的起始三角形
|
||||||
|
/// </summary>
|
||||||
|
public NavTriangle startTriangle;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取路径上的最后一个三角形
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>Last triangle in the path.</returns>
|
||||||
|
public NavTriangle GetEndTriangle()
|
||||||
|
{
|
||||||
|
// If the triangle path is empty, the point path will span this triangle
|
||||||
|
return (GetCount() > 0) ? Get(GetCount() - 1).GetToNode() : startTriangle;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 274f209b145dc49a0b89a286ea968a06
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
@ -0,0 +1,97 @@
|
|||||||
|
using JNGame.Math;
|
||||||
|
|
||||||
|
namespace JNGame.PathFinding
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 三角形节点寻路启发式算法
|
||||||
|
/// </summary>
|
||||||
|
public class TriangleHeuristic : IHeuristic<NavTriangle>
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 三角形A的AB边中点
|
||||||
|
/// </summary>
|
||||||
|
private LVector3 m_MidPointAB_A = LVector3.Zero;
|
||||||
|
/// <summary>
|
||||||
|
/// 三角形A的BC边中点
|
||||||
|
/// </summary>
|
||||||
|
private LVector3 m_MidPointBC_A = LVector3.Zero;
|
||||||
|
/// <summary>
|
||||||
|
/// 三角形A的CA边中点
|
||||||
|
/// </summary>
|
||||||
|
private LVector3 m_MidPointCA_A = LVector3.Zero;
|
||||||
|
/// <summary>
|
||||||
|
/// 三角形B的AB边中点
|
||||||
|
/// </summary>
|
||||||
|
private LVector3 m_MidPointAB_B = LVector3.Zero;
|
||||||
|
/// <summary>
|
||||||
|
/// 三角形B的BC边中点
|
||||||
|
/// </summary>
|
||||||
|
private LVector3 m_MidPointBC_B = LVector3.Zero;
|
||||||
|
/// <summary>
|
||||||
|
/// 三角形B的CA边中点
|
||||||
|
/// </summary>
|
||||||
|
private LVector3 m_MidPointCA_B = LVector3.Zero;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 启发式算法估价函数:两个三角形节点三边中点的距离,获取最短的距离
|
||||||
|
/// <para>A*启发函数的g(n)</para>
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="node">当前节点</param>
|
||||||
|
/// <param name="endNode">目标节点</param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public LFloat Estimate(NavTriangle node, NavTriangle endNode)
|
||||||
|
{
|
||||||
|
LFloat minDst2 = LFloat.FLT_MAX;
|
||||||
|
// 三角形A的三边中点
|
||||||
|
m_MidPointAB_A = (node.vertexA + node.vertexB) * LFloat.Half;
|
||||||
|
m_MidPointBC_A = (node.vertexB + node.vertexC) * LFloat.Half;
|
||||||
|
m_MidPointCA_A = (node.vertexC + node.vertexA) * LFloat.Half;
|
||||||
|
// 三角形B的三边中点
|
||||||
|
m_MidPointAB_B = (endNode.vertexA + endNode.vertexB) * LFloat.Half;
|
||||||
|
m_MidPointBC_B = (endNode.vertexB + endNode.vertexC) * LFloat.Half;
|
||||||
|
m_MidPointCA_B = (endNode.vertexC + endNode.vertexA) * LFloat.Half;
|
||||||
|
LFloat dst2;
|
||||||
|
// 三角形A的边AB中点到三角形B的三边中点的距离平方
|
||||||
|
if ((dst2 = LVector3.Distance2(m_MidPointAB_A, m_MidPointAB_B)) < minDst2)
|
||||||
|
{
|
||||||
|
minDst2 = dst2;
|
||||||
|
}
|
||||||
|
if ((dst2 = LVector3.Distance2(m_MidPointAB_A, m_MidPointBC_B)) < minDst2)
|
||||||
|
{
|
||||||
|
minDst2 = dst2;
|
||||||
|
}
|
||||||
|
if ((dst2 = LVector3.Distance2(m_MidPointAB_A, m_MidPointCA_B)) < minDst2)
|
||||||
|
{
|
||||||
|
minDst2 = dst2;
|
||||||
|
}
|
||||||
|
// 三角形A的边BC中点到三角形B的三边中点的距离平方
|
||||||
|
if ((dst2 = LVector3.Distance2(m_MidPointBC_A, m_MidPointAB_B)) < minDst2)
|
||||||
|
{
|
||||||
|
minDst2 = dst2;
|
||||||
|
}
|
||||||
|
if ((dst2 = LVector3.Distance2(m_MidPointBC_A, m_MidPointBC_B)) < minDst2)
|
||||||
|
{
|
||||||
|
minDst2 = dst2;
|
||||||
|
}
|
||||||
|
if ((dst2 = LVector3.Distance2(m_MidPointBC_A, m_MidPointCA_B)) < minDst2)
|
||||||
|
{
|
||||||
|
minDst2 = dst2;
|
||||||
|
}
|
||||||
|
// 三角形A的边CA中点到三角形B的三边中点的距离平方
|
||||||
|
if ((dst2 = LVector3.Distance2(m_MidPointCA_A, m_MidPointAB_B)) < minDst2)
|
||||||
|
{
|
||||||
|
minDst2 = dst2;
|
||||||
|
}
|
||||||
|
if ((dst2 = LVector3.Distance2(m_MidPointCA_A, m_MidPointBC_B)) < minDst2)
|
||||||
|
{
|
||||||
|
minDst2 = dst2;
|
||||||
|
}
|
||||||
|
if ((dst2 = LVector3.Distance2(m_MidPointCA_A, m_MidPointCA_B)) < minDst2)
|
||||||
|
{
|
||||||
|
minDst2 = dst2;
|
||||||
|
}
|
||||||
|
// 返回最短距离
|
||||||
|
return LMath.Sqrt(minDst2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 29ee51a11a00042b6bcd827f0d2d634f
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
@ -0,0 +1,476 @@
|
|||||||
|
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using JNGame.Math;
|
||||||
|
|
||||||
|
namespace JNGame.PathFinding
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 位置平面关系枚举
|
||||||
|
/// </summary>
|
||||||
|
public enum EnumPlaneSide
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 点在平面上
|
||||||
|
/// </summary>
|
||||||
|
OnPlane,
|
||||||
|
/// <summary>
|
||||||
|
/// 点在平面背面
|
||||||
|
/// </summary>
|
||||||
|
Back,
|
||||||
|
/// <summary>
|
||||||
|
/// 点在平面正面
|
||||||
|
/// </summary>
|
||||||
|
Front
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 将图节点路径转换为一条最短路径
|
||||||
|
/// <para>漏斗算法</para>
|
||||||
|
/// </summary>
|
||||||
|
public class TrianglePointPath
|
||||||
|
{
|
||||||
|
private readonly Plane m_CrossingPlane = new Plane(); // 横跨平面
|
||||||
|
/// <summary>
|
||||||
|
/// 用图边描述的路径
|
||||||
|
/// </summary>
|
||||||
|
private List<IConnection<NavTriangle>> m_EdgePaths; // 路径连接点
|
||||||
|
/// <summary>
|
||||||
|
/// 路径起点
|
||||||
|
/// </summary>
|
||||||
|
private LVector3 m_Start; // 起点
|
||||||
|
/// <summary>
|
||||||
|
/// 路径终点
|
||||||
|
/// </summary>
|
||||||
|
private LVector3 m_End; // 终点
|
||||||
|
/// <summary>
|
||||||
|
/// 起始三角形
|
||||||
|
/// </summary>
|
||||||
|
private NavTriangle m_StartTri; // 起始三角形
|
||||||
|
/// <summary>
|
||||||
|
/// 上次添加的边点
|
||||||
|
/// </summary>
|
||||||
|
private EdgePoint m_LastPointAdded;
|
||||||
|
/// <summary>
|
||||||
|
/// 最终结果路径坐标点
|
||||||
|
/// </summary>
|
||||||
|
private readonly List<LVector3> m_Vectors = new List<LVector3>();
|
||||||
|
/// <summary>
|
||||||
|
/// 最终结果边点描述
|
||||||
|
/// </summary>
|
||||||
|
private readonly List<EdgePoint> m_PathPoints = new List<EdgePoint>();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 路径计算的中间射线对象,每次计算清理并复用
|
||||||
|
/// </summary>
|
||||||
|
private readonly Ray m_TempRay = new Ray();
|
||||||
|
/// <summary>
|
||||||
|
/// 路径计算的中间漏斗对象,每次计算清理并复用
|
||||||
|
/// </summary>
|
||||||
|
private readonly Funnel m_TempFunnel = new Funnel();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 路径计算的最后一个边,每次计算清理并复用
|
||||||
|
/// </summary>
|
||||||
|
private TriangleEdge m_TempLastEdge = new TriangleEdge();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// EdgePoint临时对象队列的初始数量
|
||||||
|
/// </summary>
|
||||||
|
private const int kDefaultEdgePointCount = 16;
|
||||||
|
/// <summary>
|
||||||
|
/// EdgePoint的临时对象缓存队列,作为对象池复用
|
||||||
|
/// </summary>
|
||||||
|
private readonly Queue<EdgePoint> m_TempEdgePointQueue = new Queue<EdgePoint>(kDefaultEdgePointCount);
|
||||||
|
|
||||||
|
public TrianglePointPath()
|
||||||
|
{
|
||||||
|
// 初始化一些EdgePoint的临时对象
|
||||||
|
for (int i = 0; i < kDefaultEdgePointCount; ++i)
|
||||||
|
{
|
||||||
|
m_TempEdgePointQueue.Enqueue(new EdgePoint());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void CalculateForGraphPath(TriangleEdgeGraphPath trianglePath)
|
||||||
|
{
|
||||||
|
Clear();
|
||||||
|
m_EdgePaths = trianglePath.nodes;
|
||||||
|
m_Start = trianglePath.startPoint;
|
||||||
|
m_End = trianglePath.endPoint;
|
||||||
|
m_StartTri = trianglePath.startTriangle;
|
||||||
|
for (int i = 0; i < m_EdgePaths.Count; ++i)
|
||||||
|
{
|
||||||
|
IConnection<NavTriangle> connection = m_EdgePaths[i];
|
||||||
|
NavTriangle to = connection.GetToNode();
|
||||||
|
m_Vectors.Add(to.center);
|
||||||
|
}
|
||||||
|
m_Vectors.Add(m_End);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 通过图元中间路径转化为点路径
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="trianglePath"></param>
|
||||||
|
/// <param name="calculateCrossPoint"></param>
|
||||||
|
public void CalculateForGraphPath(TriangleEdgeGraphPath trianglePath, bool calculateCrossPoint)
|
||||||
|
{
|
||||||
|
Clear();
|
||||||
|
m_EdgePaths = trianglePath.nodes;
|
||||||
|
m_Start = trianglePath.startPoint;
|
||||||
|
m_End = trianglePath.endPoint;
|
||||||
|
m_StartTri = trianglePath.startTriangle;
|
||||||
|
// Check that the start point is actually inside the start triangle,
|
||||||
|
// if not, project it to the closest triangle edge.
|
||||||
|
// Otherwise the funnel calculation might generate spurious path segments.
|
||||||
|
LVector3 rayOrigin = m_Start + LVector3.Up * 1000;
|
||||||
|
// Ray ray = new Ray(rayOrigin, LVector3.Down);
|
||||||
|
// 起始坐标从上向下的射线
|
||||||
|
m_TempRay.origin = rayOrigin;
|
||||||
|
m_TempRay.direction = LVector3.Down;
|
||||||
|
if (!GeometryUtil.IntersectRayTriangle(m_TempRay, m_StartTri.vertexA, m_StartTri.vertexB, m_StartTri.vertexC, out var ss))
|
||||||
|
{
|
||||||
|
LFloat minDst = LFloat.FLT_MAX;
|
||||||
|
LVector3 projection = new LVector3(); // 规划坐标
|
||||||
|
LVector3 newStart = new LVector3(); // 新坐标
|
||||||
|
LFloat dst;
|
||||||
|
// A-B
|
||||||
|
if ((dst = GeometryUtil.NearestSegmentPointSquareDistance(ref projection, m_StartTri.vertexA, m_StartTri.vertexB,
|
||||||
|
m_Start)) < minDst)
|
||||||
|
{
|
||||||
|
minDst = dst;
|
||||||
|
newStart = projection;
|
||||||
|
}
|
||||||
|
|
||||||
|
// B-C
|
||||||
|
if ((dst = GeometryUtil.NearestSegmentPointSquareDistance(ref projection, m_StartTri.vertexB, m_StartTri.vertexC,
|
||||||
|
m_Start)) < minDst)
|
||||||
|
{
|
||||||
|
minDst = dst;
|
||||||
|
newStart = projection;
|
||||||
|
}
|
||||||
|
|
||||||
|
// C-A
|
||||||
|
if ((dst = GeometryUtil.NearestSegmentPointSquareDistance(ref projection, m_StartTri.vertexC, m_StartTri.vertexA,
|
||||||
|
m_Start)) < minDst)
|
||||||
|
{
|
||||||
|
minDst = dst;
|
||||||
|
newStart = projection;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_Start = newStart;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_EdgePaths.Count == 0)
|
||||||
|
{ // 起点终点在同一三角形中
|
||||||
|
AddPoint(m_Start, m_StartTri);
|
||||||
|
AddPoint(m_End, m_StartTri);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_TempLastEdge.Set(m_EdgePaths[^1].GetToNode(), m_EdgePaths[^1].GetToNode(), m_End, m_End);
|
||||||
|
CalculateEdgePoints(calculateCrossPoint);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Clear()
|
||||||
|
{
|
||||||
|
m_TempFunnel.Reset();
|
||||||
|
m_TempRay.Reset();
|
||||||
|
m_Vectors.Clear();
|
||||||
|
// Debug.Log("RemainCount: {0}", m_TempEdgePointQueue.Count);
|
||||||
|
for (int i = m_PathPoints.Count - 1; i >= 0; --i)
|
||||||
|
{
|
||||||
|
RecycleEdgePoint(m_PathPoints[i]);
|
||||||
|
}
|
||||||
|
// Debug.Log("TotalCount: {0}", m_TempEdgePointQueue.Count);
|
||||||
|
m_PathPoints.Clear();
|
||||||
|
m_StartTri = null;
|
||||||
|
m_LastPointAdded = null;
|
||||||
|
m_TempLastEdge.Clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
private TriangleEdge GetEdge(int index)
|
||||||
|
{
|
||||||
|
return (TriangleEdge)((index == m_EdgePaths.Count) ? m_TempLastEdge : m_EdgePaths[index]);
|
||||||
|
}
|
||||||
|
|
||||||
|
private int NumEdges()
|
||||||
|
{
|
||||||
|
return m_EdgePaths.Count + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LVector3 GetVector(int index)
|
||||||
|
{
|
||||||
|
return m_Vectors[index];
|
||||||
|
}
|
||||||
|
|
||||||
|
public int GetSize()
|
||||||
|
{
|
||||||
|
return m_Vectors.Count;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** All vectors in the path */
|
||||||
|
public List<LVector3> GetVectors()
|
||||||
|
{
|
||||||
|
return m_Vectors;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** The triangle which must be crossed to reach the next path point.*/
|
||||||
|
public NavTriangle GetToTriangle(int index)
|
||||||
|
{
|
||||||
|
return m_PathPoints[index].toNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** The triangle from which must be crossed to reach this point. */
|
||||||
|
public NavTriangle GetFromTriangle(int index)
|
||||||
|
{
|
||||||
|
return m_PathPoints[index].fromNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** The navmesh edge(s) crossed at this path point. */
|
||||||
|
public List<TriangleEdge> GetCrossedEdges(int index)
|
||||||
|
{
|
||||||
|
return m_PathPoints[index].connectingEdges;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void AddPoint(in LVector3 point, NavTriangle toNode)
|
||||||
|
{
|
||||||
|
// AddPoint(new EdgePoint(point, toNode));
|
||||||
|
AddPoint(GetFreeEdgePoint(in point, toNode));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void AddPoint(EdgePoint edgePoint)
|
||||||
|
{
|
||||||
|
m_Vectors.Add(edgePoint.point);
|
||||||
|
m_PathPoints.Add(edgePoint);
|
||||||
|
m_LastPointAdded = edgePoint;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 基于漏斗算法,将图的边路径转换为最短点路径
|
||||||
|
/// <para>point path through the path triangles, using the Simple Stupid Funnel Algorithm.</para>
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="calculateCrossPoint"></param>
|
||||||
|
private void CalculateEdgePoints(bool calculateCrossPoint)
|
||||||
|
{
|
||||||
|
TriangleEdge edge = GetEdge(0);
|
||||||
|
AddPoint(m_Start, edge.fromNode);
|
||||||
|
m_LastPointAdded.fromNode = edge.fromNode;
|
||||||
|
// 初始化第一个漏斗
|
||||||
|
m_TempFunnel.pivot = m_Start;
|
||||||
|
m_TempFunnel.SetPlanes(m_TempFunnel.pivot, edge);// 路径起点为漏斗点,设置共享边的两个端点为漏斗边界平面
|
||||||
|
int leftIndex = 0; // 左顶点索引
|
||||||
|
int rightIndex = 0; // 右顶点索引
|
||||||
|
int lastRestart = 0;
|
||||||
|
for (int i = 1; i < NumEdges(); ++i)
|
||||||
|
{
|
||||||
|
edge = GetEdge(i); // 下一条边
|
||||||
|
// 边的两个端点与漏斗边平面A的位置关系
|
||||||
|
var leftPlaneLeftDP = m_TempFunnel.SideLeftPlane(edge.vertexB);
|
||||||
|
var leftPlaneRightDP = m_TempFunnel.SideLeftPlane(edge.vertexA);
|
||||||
|
// 边的两个端点与漏斗边平面B的位置关系
|
||||||
|
var rightPlaneLeftDP = m_TempFunnel.SideRightPlane(edge.vertexB);
|
||||||
|
var rightPlaneRightDP = m_TempFunnel.SideRightPlane(edge.vertexA);
|
||||||
|
|
||||||
|
// 右顶点在右平面里面
|
||||||
|
if (rightPlaneRightDP != EnumPlaneSide.Front)
|
||||||
|
{
|
||||||
|
// 右顶点在左平面里面
|
||||||
|
if (leftPlaneRightDP != EnumPlaneSide.Front)
|
||||||
|
{
|
||||||
|
// Tighten the funnel. 缩小漏斗
|
||||||
|
m_TempFunnel.SetRightPlane(m_TempFunnel.pivot, edge.vertexA);
|
||||||
|
rightIndex = i;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Right over left, insert left to path and restart scan from portal left point.
|
||||||
|
// 右顶点在左平面外面,设置左顶点为漏斗顶点和路径点,从新已该漏斗开始扫描
|
||||||
|
if (calculateCrossPoint)
|
||||||
|
{
|
||||||
|
CalculateEdgeCrossings(lastRestart, leftIndex, m_TempFunnel.pivot, m_TempFunnel.leftPortal);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_Vectors.Add(m_TempFunnel.leftPortal);
|
||||||
|
}
|
||||||
|
|
||||||
|
m_TempFunnel.pivot = m_TempFunnel.leftPortal;
|
||||||
|
i = leftIndex;
|
||||||
|
rightIndex = i;
|
||||||
|
if (i < NumEdges() - 1)
|
||||||
|
{
|
||||||
|
lastRestart = i;
|
||||||
|
m_TempFunnel.SetPlanes(m_TempFunnel.pivot, GetEdge(i + 1));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 左顶点在左平面里面
|
||||||
|
if (leftPlaneLeftDP != EnumPlaneSide.Front)
|
||||||
|
{
|
||||||
|
// 左顶点在右平面里面
|
||||||
|
if (rightPlaneLeftDP != EnumPlaneSide.Front)
|
||||||
|
{
|
||||||
|
// Tighten the funnel.
|
||||||
|
m_TempFunnel.SetLeftPlane(m_TempFunnel.pivot, edge.vertexB);
|
||||||
|
leftIndex = i;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Left over right, insert right to path and restart scan from portal right point.
|
||||||
|
if (calculateCrossPoint)
|
||||||
|
{
|
||||||
|
CalculateEdgeCrossings(lastRestart, rightIndex, m_TempFunnel.pivot, m_TempFunnel.rightPortal);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_Vectors.Add(m_TempFunnel.rightPortal);
|
||||||
|
}
|
||||||
|
|
||||||
|
m_TempFunnel.pivot = m_TempFunnel.rightPortal;
|
||||||
|
i = rightIndex;
|
||||||
|
leftIndex = i;
|
||||||
|
if (i < NumEdges() - 1)
|
||||||
|
{
|
||||||
|
lastRestart = i;
|
||||||
|
m_TempFunnel.SetPlanes(m_TempFunnel.pivot, GetEdge(i + 1));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (calculateCrossPoint)
|
||||||
|
{
|
||||||
|
CalculateEdgeCrossings(lastRestart, NumEdges() - 1, m_TempFunnel.pivot, m_End);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_Vectors.Add(m_End);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 1; i < m_PathPoints.Count; i++)
|
||||||
|
{
|
||||||
|
EdgePoint p = m_PathPoints[i];
|
||||||
|
p.fromNode = m_PathPoints[i - 1].toNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Store all edge crossing points between the start and end indices. If the path
|
||||||
|
* crosses exactly the start or end points (which is quite likely), store the
|
||||||
|
* edges in order of crossing in the EdgePoint data structure.
|
||||||
|
* <p/>
|
||||||
|
* Edge crossings are calculated as intersections with the plane from the start,
|
||||||
|
* end and up vectors.
|
||||||
|
*/
|
||||||
|
private void CalculateEdgeCrossings(int startIndex, int endIndex, LVector3 startPoint, LVector3 endPoint)
|
||||||
|
{
|
||||||
|
if (startIndex >= NumEdges() || endIndex >= NumEdges())
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_CrossingPlane.Set(startPoint, startPoint + LVector3.Up, endPoint);
|
||||||
|
|
||||||
|
EdgePoint previousLast = m_LastPointAdded;
|
||||||
|
|
||||||
|
var edge = GetEdge(endIndex);
|
||||||
|
// EdgePoint end = new EdgePoint(endPoint, edge.toNode);
|
||||||
|
EdgePoint end = GetFreeEdgePoint(in endPoint, edge.toNode);
|
||||||
|
for (int i = startIndex; i < endIndex; i++)
|
||||||
|
{
|
||||||
|
edge = GetEdge(i);
|
||||||
|
|
||||||
|
if (edge.vertexA.Equals(startPoint) || edge.vertexB.Equals(startPoint))
|
||||||
|
{
|
||||||
|
previousLast.toNode = edge.toNode;
|
||||||
|
if (!previousLast.connectingEdges.Contains(edge))
|
||||||
|
{
|
||||||
|
previousLast.connectingEdges.Add(edge);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (edge.vertexB.Equals(endPoint) || edge.vertexA.Equals(endPoint))
|
||||||
|
{
|
||||||
|
if (!end.connectingEdges.Contains(edge))
|
||||||
|
{
|
||||||
|
end.connectingEdges.Add(edge);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (IntersectSegmentPlane(edge.vertexB, edge.vertexA, m_CrossingPlane, out LVector3 intersection))
|
||||||
|
{
|
||||||
|
if (i != startIndex || i == 0)
|
||||||
|
{
|
||||||
|
m_LastPointAdded.toNode = edge.fromNode;
|
||||||
|
// EdgePoint crossing = new EdgePoint(intersection, edge.toNode);
|
||||||
|
EdgePoint crossing = GetFreeEdgePoint(in intersection, edge.toNode);
|
||||||
|
crossing.connectingEdges.Add(edge);
|
||||||
|
AddPoint(crossing);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (endIndex < NumEdges() - 1)
|
||||||
|
{
|
||||||
|
end.connectingEdges.Add(GetEdge(endIndex));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!m_LastPointAdded.Equals(end))
|
||||||
|
{
|
||||||
|
AddPoint(end);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static bool IntersectSegmentPlane(LVector3 start, LVector3 end, Plane plane, out LVector3 intersection)
|
||||||
|
{
|
||||||
|
intersection = LVector3.Zero;
|
||||||
|
LVector3 dir = end - start;
|
||||||
|
LFloat denom = LVector3.Dot(dir, plane.normal);
|
||||||
|
LFloat t = -(LVector3.Dot(start, plane.normal) + plane.distFromOrigin) / denom;
|
||||||
|
if (t < 0 || t > 1)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
intersection = start + dir * t;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 从临时队列中获取缓存的EdgePoint对象,并且初始化
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="point"></param>
|
||||||
|
/// <param name="toNode"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
private EdgePoint GetFreeEdgePoint(in LVector3 point, NavTriangle toNode)
|
||||||
|
{
|
||||||
|
if (m_TempEdgePointQueue.Count == 0)
|
||||||
|
{
|
||||||
|
return new EdgePoint(in point, toNode);
|
||||||
|
}
|
||||||
|
EdgePoint edgePoint = m_TempEdgePointQueue.Dequeue();
|
||||||
|
edgePoint.Set(in point, toNode);
|
||||||
|
return edgePoint;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 回收edgePoint临时对象,以备复用
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="edgePoint"></param>
|
||||||
|
private void RecycleEdgePoint(EdgePoint edgePoint)
|
||||||
|
{
|
||||||
|
if (edgePoint == null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
m_TempEdgePointQueue.Enqueue(edgePoint);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 8f226701410f4424d8ac316660c1ccb0
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
3
JNFrame2/Assets/JNGame/Map/DotRecast.meta
Normal file
3
JNFrame2/Assets/JNGame/Map/DotRecast.meta
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 8405f7862a7145bc96b9cbc73bf9853c
|
||||||
|
timeCreated: 1715335241
|
214
JNFrame2/Assets/JNGame/Map/DotRecast/DotRecastController.cs
Normal file
214
JNFrame2/Assets/JNGame/Map/DotRecast/DotRecastController.cs
Normal file
@ -0,0 +1,214 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
|
using DotRecast.Core.Numerics;
|
||||||
|
using DotRecast.Detour;
|
||||||
|
using DotRecast.Recast.Geom;
|
||||||
|
using DotRecast.Recast.Toolset;
|
||||||
|
using DotRecast.Recast.Toolset.Builder;
|
||||||
|
using JNGame.Map.DotRecast.Util;
|
||||||
|
using JNGame.Math;
|
||||||
|
using UnityEngine;
|
||||||
|
using UnityEngine.AI;
|
||||||
|
|
||||||
|
namespace JNGame.Map.DotRecast
|
||||||
|
{
|
||||||
|
public class DotRecastController : MonoBehaviour
|
||||||
|
{
|
||||||
|
|
||||||
|
public LayerMask layerMask;
|
||||||
|
|
||||||
|
private Mesh debugMesh;
|
||||||
|
private DtNavMesh dtNavMesh;
|
||||||
|
|
||||||
|
private List<Mesh> debugPathMeshs;
|
||||||
|
|
||||||
|
|
||||||
|
public void Save()
|
||||||
|
{
|
||||||
|
if (debugMesh is null)
|
||||||
|
{
|
||||||
|
Debug.Log("[DotRecast] 未生成地形 请生成地形.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var data = new MeshData(debugMesh);
|
||||||
|
File.WriteAllText(UnityEngine.Application.dataPath + "/Resources/map1.json", JsonUtility.ToJson(data));
|
||||||
|
Debug.Log("[DotRecast] 保存成功.");
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Load()
|
||||||
|
{
|
||||||
|
|
||||||
|
debugMesh = this.Merge();
|
||||||
|
var data = new MeshData(debugMesh);
|
||||||
|
|
||||||
|
var vertices = new LFloat[data.vertices.Length * 3];
|
||||||
|
for (int i = 0; i < data.vertices.Length; ++i)
|
||||||
|
{
|
||||||
|
vertices[i * 3 + 0] = (LFloat)data.vertices[i].x;
|
||||||
|
vertices[i * 3 + 1] = (LFloat)data.vertices[i].y;
|
||||||
|
vertices[i * 3 + 2] = (LFloat)data.vertices[i].z;
|
||||||
|
}
|
||||||
|
|
||||||
|
var bmin = RcVecUtils.Create(vertices);
|
||||||
|
var bmax = RcVecUtils.Create(vertices);
|
||||||
|
for (int i = 1; i < vertices.Length / 3; i++)
|
||||||
|
{
|
||||||
|
bmin = RcVecUtils.Min(bmin, vertices, i * 3);
|
||||||
|
bmax = RcVecUtils.Max(bmax, vertices, i * 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
var geom = new DefaultInputGeomProvider(vertices,data.triangles);
|
||||||
|
var builder = new TileNavMeshBuilder();
|
||||||
|
var settings = new RcNavMeshBuildSettings();
|
||||||
|
settings.cellSize = (LFloat)1f;
|
||||||
|
var result = builder.Build(geom, settings);
|
||||||
|
|
||||||
|
dtNavMesh = result.NavMesh;
|
||||||
|
|
||||||
|
debugPathMeshs = new List<Mesh>();
|
||||||
|
for (int i = 0; i < dtNavMesh.GetMaxTiles(); ++i)
|
||||||
|
{
|
||||||
|
DtMeshTile tile = dtNavMesh.GetTile(i);
|
||||||
|
if (tile != null && tile.data != null)
|
||||||
|
{
|
||||||
|
DrawMeshTile(tile);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Debug.Log("[DotRecast] 加载完成.");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private void DrawMeshTile(DtMeshTile tile)
|
||||||
|
{
|
||||||
|
List<Vector3> vertices = new List<Vector3>();
|
||||||
|
//Begin(DebugDrawPrimitives.TRIS);
|
||||||
|
for (int i = 0; i < tile.data.header.polyCount; ++i)
|
||||||
|
{
|
||||||
|
DtPoly p = tile.data.polys[i];
|
||||||
|
|
||||||
|
if (p.GetPolyType() == DtPolyTypes.DT_POLYTYPE_OFFMESH_CONNECTION)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (tile.data.detailMeshes != null)
|
||||||
|
{
|
||||||
|
DtPolyDetail pd = tile.data.detailMeshes[i];
|
||||||
|
for (int j = 0; j < pd.triCount; ++j)
|
||||||
|
{
|
||||||
|
int t = (pd.triBase + j) * 4;
|
||||||
|
for (int k = 0; k < 3; ++k)
|
||||||
|
{
|
||||||
|
int v = tile.data.detailTris[t + k];
|
||||||
|
if (v < p.vertCount)
|
||||||
|
{
|
||||||
|
vertices.Add(new Vector3(tile.data.verts[p.verts[v] * 3], tile.data.verts[p.verts[v] * 3 + 1] + 0.1f,
|
||||||
|
tile.data.verts[p.verts[v] * 3 + 2]));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
vertices.Add(new Vector3(tile.data.detailVerts[(pd.vertBase + v - p.vertCount) * 3],
|
||||||
|
tile.data.detailVerts[(pd.vertBase + v - p.vertCount) * 3 + 1],
|
||||||
|
tile.data.detailVerts[(pd.vertBase + v - p.vertCount) * 3 + 2]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
List<Vector3[]> vertices3 = new List<Vector3[]>();
|
||||||
|
for (int i = 0; i < vertices.Count; i += 3)
|
||||||
|
{
|
||||||
|
vertices3.Add(new []{vertices[i], vertices[i + 1], vertices[i + 2]});
|
||||||
|
}
|
||||||
|
|
||||||
|
int triCount = vertices3.Count;
|
||||||
|
|
||||||
|
Vector3[] verts = new Vector3[3 * triCount];
|
||||||
|
int[] tris = new int[3* triCount];
|
||||||
|
Color[] colors = new Color[3*triCount];
|
||||||
|
|
||||||
|
for (int i=0;i<triCount;++i){
|
||||||
|
int v = i*3;
|
||||||
|
for (int j=0;j<3;++j){
|
||||||
|
verts[v+j] = vertices3[i][j];
|
||||||
|
tris[v+j] = v+j;
|
||||||
|
colors[v+j] = Color.white;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Mesh mesh1 = new Mesh();
|
||||||
|
mesh1.vertices = verts;
|
||||||
|
mesh1.triangles = tris;
|
||||||
|
mesh1.colors = colors;
|
||||||
|
mesh1.RecalculateNormals();
|
||||||
|
|
||||||
|
debugPathMeshs.Add(mesh1);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private Mesh Merge()
|
||||||
|
{
|
||||||
|
//获取所有子物体的网格过滤器组件
|
||||||
|
MeshFilter[] meshFilters = FindObjectsOfType<MeshFilter>(true).Where(mf => ((1 << mf.gameObject.layer) & layerMask) > 0).ToArray();
|
||||||
|
|
||||||
|
//创建一个新的合并后的网格
|
||||||
|
Mesh mergedMesh = new Mesh();
|
||||||
|
|
||||||
|
//创建一个合并用的网格数组
|
||||||
|
CombineInstance[] combine = new CombineInstance[meshFilters.Length+1];
|
||||||
|
|
||||||
|
for (int i = 0; i < meshFilters.Length; i++)
|
||||||
|
{
|
||||||
|
//设置合并用的网格数组
|
||||||
|
combine[i].mesh = meshFilters[i].sharedMesh;
|
||||||
|
combine[i].transform = meshFilters[i].transform.localToWorldMatrix;
|
||||||
|
}
|
||||||
|
|
||||||
|
var triangulation = NavMesh.CalculateTriangulation();
|
||||||
|
combine[^1].mesh = new Mesh()
|
||||||
|
{
|
||||||
|
vertices = triangulation.vertices,
|
||||||
|
triangles = triangulation.indices,
|
||||||
|
};
|
||||||
|
combine[^1].transform = Matrix4x4.identity;
|
||||||
|
|
||||||
|
//合并网格
|
||||||
|
mergedMesh.CombineMeshes(combine);
|
||||||
|
mergedMesh.RecalculateNormals();
|
||||||
|
mergedMesh.RecalculateBounds();
|
||||||
|
|
||||||
|
debugPathMeshs = null;
|
||||||
|
|
||||||
|
return mergedMesh;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void OnDrawGizmos()
|
||||||
|
{
|
||||||
|
// if (debugMesh is not null)
|
||||||
|
// {
|
||||||
|
// Gizmos.color = new Color(0f, 1f, 1f, 0.5f);
|
||||||
|
// Gizmos.DrawMesh(debugMesh);
|
||||||
|
// Gizmos.color = new Color(0f, 0f, 0f, 0.3f);
|
||||||
|
// Gizmos.DrawWireMesh(debugMesh);
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// return;
|
||||||
|
|
||||||
|
if (debugPathMeshs is not null)
|
||||||
|
{
|
||||||
|
foreach (var mesh in debugPathMeshs)
|
||||||
|
{
|
||||||
|
Gizmos.color = new Color(0f, 1f, 1f, 0.5f);
|
||||||
|
Gizmos.DrawMesh(mesh);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,3 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: f83204b2c7bd45b086634b5819450152
|
||||||
|
timeCreated: 1715336022
|
190
JNFrame2/Assets/JNGame/Map/DotRecast/DotRecastRoot.cs
Normal file
190
JNFrame2/Assets/JNGame/Map/DotRecast/DotRecastRoot.cs
Normal file
@ -0,0 +1,190 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using DotRecast.Core.Numerics;
|
||||||
|
using DotRecast.Detour;
|
||||||
|
using DotRecast.Detour.Crowd;
|
||||||
|
using DotRecast.Recast.Geom;
|
||||||
|
using DotRecast.Recast.Toolset;
|
||||||
|
using DotRecast.Recast.Toolset.Builder;
|
||||||
|
using JNGame.Map.DotRecast.Util;
|
||||||
|
using JNGame.Math;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
namespace JNGame.Map.DotRecast
|
||||||
|
{
|
||||||
|
public class DotRecastRoot
|
||||||
|
{
|
||||||
|
|
||||||
|
//导航数据
|
||||||
|
public DtNavMesh NavMesh;
|
||||||
|
|
||||||
|
//导航查询
|
||||||
|
public DtNavMeshQuery Query { private set; get; }
|
||||||
|
|
||||||
|
//智能体避障
|
||||||
|
public DtCrowd Crowd { private set; get; }
|
||||||
|
private Dictionary<long, DtCrowdAgent> agents;
|
||||||
|
|
||||||
|
public DotRecastRoot(MeshData data)
|
||||||
|
{
|
||||||
|
agents = new Dictionary<long, DtCrowdAgent>();
|
||||||
|
//初始化导航数据
|
||||||
|
InitNavMesh(data);
|
||||||
|
//初始化避障数据
|
||||||
|
InitCrowd(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
//更新
|
||||||
|
public void Update(LFloat dt)
|
||||||
|
{
|
||||||
|
Crowd.Update(dt,null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public DtCrowdAgentParams GetAgentParams()
|
||||||
|
{
|
||||||
|
int updateFlags = DtCrowdAgentUpdateFlags.DT_CROWD_ANTICIPATE_TURNS |
|
||||||
|
DtCrowdAgentUpdateFlags.DT_CROWD_OPTIMIZE_VIS |
|
||||||
|
DtCrowdAgentUpdateFlags.DT_CROWD_OPTIMIZE_TOPO |
|
||||||
|
DtCrowdAgentUpdateFlags.DT_CROWD_OBSTACLE_AVOIDANCE;
|
||||||
|
DtCrowdAgentParams ap = new DtCrowdAgentParams();
|
||||||
|
ap.radius = (LFloat)0.6f;
|
||||||
|
ap.height = (LFloat)2f;
|
||||||
|
ap.maxAcceleration = (LFloat)8.0f;
|
||||||
|
ap.maxSpeed = (LFloat)6f;
|
||||||
|
ap.collisionQueryRange = ap.radius * (LFloat)12f;
|
||||||
|
ap.pathOptimizationRange = ap.radius * (LFloat)30f;
|
||||||
|
ap.updateFlags = updateFlags;
|
||||||
|
ap.obstacleAvoidanceType = 0;
|
||||||
|
ap.separationWeight = (LFloat)2f;
|
||||||
|
return ap;
|
||||||
|
}
|
||||||
|
|
||||||
|
//初始化导航
|
||||||
|
private void InitNavMesh(MeshData data)
|
||||||
|
{
|
||||||
|
var vertices = new LFloat[data.vertices.Length * 3];
|
||||||
|
for (int i = 0; i < data.vertices.Length; ++i)
|
||||||
|
{
|
||||||
|
vertices[i * 3 + 0] = data.vertices[i].x;
|
||||||
|
vertices[i * 3 + 1] = data.vertices[i].y;
|
||||||
|
vertices[i * 3 + 2] = data.vertices[i].z;
|
||||||
|
}
|
||||||
|
|
||||||
|
var bmin = RcVecUtils.Create(vertices);
|
||||||
|
var bmax = RcVecUtils.Create(vertices);
|
||||||
|
for (int i = 1; i < vertices.Length / 3; i++)
|
||||||
|
{
|
||||||
|
bmin = RcVecUtils.Min(bmin, vertices, i * 3);
|
||||||
|
bmax = RcVecUtils.Max(bmax, vertices, i * 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
var geom = new DefaultInputGeomProvider(vertices,data.triangles);
|
||||||
|
var builder = new TileNavMeshBuilder();
|
||||||
|
var settings = new RcNavMeshBuildSettings();
|
||||||
|
|
||||||
|
settings.cellSize = (LFloat)1f;
|
||||||
|
var result = builder.Build(geom, settings);
|
||||||
|
|
||||||
|
NavMesh = result.NavMesh;
|
||||||
|
Query = new DtNavMeshQuery(NavMesh);
|
||||||
|
}
|
||||||
|
|
||||||
|
//初始化避障
|
||||||
|
private void InitCrowd(MeshData data)
|
||||||
|
{
|
||||||
|
DtCrowdConfig config = new DtCrowdConfig((LFloat)0.6f);
|
||||||
|
Crowd = new DtCrowd(config, NavMesh);
|
||||||
|
DtObstacleAvoidanceParams option = new DtObstacleAvoidanceParams();
|
||||||
|
option.velBias = (LFloat)0.5f;
|
||||||
|
option.adaptiveDivs = 5;
|
||||||
|
option.adaptiveRings = 2;
|
||||||
|
option.adaptiveDepth = 1;
|
||||||
|
Crowd.SetObstacleAvoidanceParams(0, option);
|
||||||
|
}
|
||||||
|
|
||||||
|
//添加避障
|
||||||
|
public void AddAgent(long id,RcVec3f start)
|
||||||
|
{
|
||||||
|
agents.Add(id,Crowd.AddAgent(start, GetAgentParams()));
|
||||||
|
}
|
||||||
|
public void AddAgent(long id,RcVec3f start,DtCrowdAgentParams agentParams)
|
||||||
|
{
|
||||||
|
agents.Add(id,Crowd.AddAgent(start, agentParams));
|
||||||
|
}
|
||||||
|
|
||||||
|
//添加避障
|
||||||
|
public void DelAgent(long id)
|
||||||
|
{
|
||||||
|
if (agents.ContainsKey(id))
|
||||||
|
{
|
||||||
|
Crowd.RemoveAgent(agents[id]);
|
||||||
|
agents.Remove(id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//移动避障
|
||||||
|
public void MoveAgent(long id,RcVec3f move)
|
||||||
|
{
|
||||||
|
|
||||||
|
DtCrowdAgent agent = agents[id];
|
||||||
|
Query.FindNearestPoly(move, Crowd.GetQueryExtents(), Crowd.GetFilter(0), out var nearestRef, out var nearestPt, out var _);
|
||||||
|
Crowd.RequestMoveTarget(agent, nearestRef, nearestPt);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//向量移动避障
|
||||||
|
public void VectorMoveAgent(long id,RcVec3f vector)
|
||||||
|
{
|
||||||
|
DtCrowdAgent agent = agents[id];
|
||||||
|
Crowd.RequestMoveVelocity(agent,vector);
|
||||||
|
}
|
||||||
|
|
||||||
|
//获取避障
|
||||||
|
public DtCrowdAgent GetAgent(long id)
|
||||||
|
{
|
||||||
|
return agents[id];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 查询导航
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="pos"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public List<DtStraightPath> FindPath(LVector3 start,LVector3 end)
|
||||||
|
{
|
||||||
|
var start1 = new RcVec3f(start.x,start.y,start.z);
|
||||||
|
var end1 = new RcVec3f(end.x,end.y,end.z);
|
||||||
|
var half = new RcVec3f(1000, 1000, 1000);
|
||||||
|
var filter = new DtQueryDefaultFilter();
|
||||||
|
Query.FindNearestPoly(start1, half, filter, out var startRef, out var startPt, out var _);
|
||||||
|
Query.FindNearestPoly(end1, half, filter, out var endRef, out var endPt, out var _);
|
||||||
|
var path = new List<long>();
|
||||||
|
DtStatus status = Query.FindPath(startRef,endRef,startPt, endPt, filter,ref path, DtFindPathOption.AnyAngle);
|
||||||
|
var paths = new List<DtStraightPath>();
|
||||||
|
Query.FindStraightPath(startPt, endPt, path, path.Count, ref paths, 256, 0);
|
||||||
|
return paths;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 返回最近点
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="pos"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public LVector3 GetNearbyPoints(LVector3 pos)
|
||||||
|
{
|
||||||
|
DtStatus status = Query.FindNearestPoly(
|
||||||
|
new RcVec3f(pos.x, pos.y, pos.z),
|
||||||
|
new RcVec3f(1000, 1000, 1000),
|
||||||
|
new DtQueryDefaultFilter(),
|
||||||
|
out var refs,
|
||||||
|
out var nearestPt,
|
||||||
|
out var _);
|
||||||
|
return new LVector3((LFloat)nearestPt.X, (LFloat)nearestPt.Y, (LFloat)nearestPt.Z);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,3 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: dfd8873ca1a84305b83bc38ebe5eb1f0
|
||||||
|
timeCreated: 1715335565
|
3
JNFrame2/Assets/JNGame/Map/DotRecast/Editor.meta
Normal file
3
JNFrame2/Assets/JNGame/Map/DotRecast/Editor.meta
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: f5d0c5be78d74f4989de7e063e90e52b
|
||||||
|
timeCreated: 1715335958
|
@ -0,0 +1,31 @@
|
|||||||
|
using UnityEditor;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
namespace JNGame.Map.DotRecast.Editor
|
||||||
|
{
|
||||||
|
[CustomEditor(typeof(DotRecastController))]
|
||||||
|
public class DotRecastEditor : UnityEditor.Editor
|
||||||
|
{
|
||||||
|
|
||||||
|
private DotRecastController dotRecast;
|
||||||
|
|
||||||
|
private void OnEnable()
|
||||||
|
{
|
||||||
|
dotRecast = target as DotRecastController;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void OnInspectorGUI()
|
||||||
|
{
|
||||||
|
base.OnInspectorGUI();
|
||||||
|
if (GUILayout.Button("Save"))
|
||||||
|
{
|
||||||
|
dotRecast.Save();
|
||||||
|
}
|
||||||
|
if (GUILayout.Button("Load"))
|
||||||
|
{
|
||||||
|
dotRecast.Load();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,3 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: d8673655a79141d48eb9e89c85ee1a9a
|
||||||
|
timeCreated: 1715335972
|
8
JNFrame2/Assets/JNGame/Map/DotRecast/Src.meta
Normal file
8
JNFrame2/Assets/JNGame/Map/DotRecast/Src.meta
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 62ef7a1f4db447008e8974609a74ce24
|
||||||
|
folderAsset: yes
|
||||||
|
DefaultImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
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