no message

This commit is contained in:
PC-20230316NUNE\Administrator 2024-02-20 18:39:12 +08:00
parent 97b3671979
commit 2b467e56ad
1876 changed files with 440340 additions and 35266 deletions

View File

@ -41,14 +41,16 @@
<ImplicitlyExpandDesignTimeFacades>false</ImplicitlyExpandDesignTimeFacades>
</PropertyGroup>
<ItemGroup>
<Compile Include="Assets\Game\Plugins\App\Game\RVO\JNGRVOObstacle.cs" />
<Compile Include="Assets\Game\Plugins\App\Sync\JNGSyncFrameEntrust.cs" />
<Compile Include="Assets\Game\Plugins\App\Sync\JNGSyncFrame.cs" />
<Compile Include="Assets\Game\Plugins\App\JNGSyncFrame.cs" />
<Compile Include="Assets\Game\Plugins\App\Sync\JNGSyncFrameDefault.cs" />
<Compile Include="Assets\Game\Plugins\App\Game\RVO\JNGRVOManager.cs" />
<Compile Include="Assets\Game\Plugins\App\Game\RVO\JNGRVOAgent.cs" />
<Compile Include="Assets\Game\Plugins\App\App.cs" />
<Compile Include="Assets\Game\Plugins\App\Util\JNRandom.cs" />
<Compile Include="Assets\Game\Plugins\App\JNGSocket.cs" />
<Compile Include="Assets\Game\Plugins\App\Game\RVO\JNGRVOManager.cs" />
<None Include="Assets\Game\Plugins\App\App.asmdef" />
<Reference Include="UnityEngine">
<HintPath>D:\Unity\2021.3.33f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.dll</HintPath>
@ -329,12 +331,12 @@
<Reference Include="log4netPlastic">
<HintPath>D:\myproject\JisolGame\JNFrame\Library\PackageCache\com.unity.collab-proxy@2.2.0\Lib\Editor\PlasticSCM\log4netPlastic.dll</HintPath>
</Reference>
<Reference Include="Google.Protobuf">
<HintPath>D:\myproject\JisolGame\JNFrame\Assets\Packages\Google.Protobuf.3.15.8\lib\netstandard2.0\Google.Protobuf.dll</HintPath>
</Reference>
<Reference Include="Newtonsoft.Json">
<HintPath>D:\myproject\JisolGame\JNFrame\Assets\Packages\Newtonsoft.Json.13.0.3\lib\netstandard2.0\Newtonsoft.Json.dll</HintPath>
</Reference>
<Reference Include="Google.Protobuf">
<HintPath>D:\myproject\JisolGame\JNFrame\Assets\Packages\Google.Protobuf.3.15.8\lib\netstandard2.0\Google.Protobuf.dll</HintPath>
</Reference>
<Reference Include="Pathfinding.ClipperLib">
<HintPath>D:\myproject\JisolGame\JNFrame\Assets\Game\Plugins\AstarPathfindingProject\Plugins\Clipper\Pathfinding.ClipperLib.dll</HintPath>
</Reference>

View File

@ -336,12 +336,12 @@
<Reference Include="log4netPlastic">
<HintPath>D:\myproject\JisolGame\JNFrame\Library\PackageCache\com.unity.collab-proxy@2.2.0\Lib\Editor\PlasticSCM\log4netPlastic.dll</HintPath>
</Reference>
<Reference Include="Google.Protobuf">
<HintPath>D:\myproject\JisolGame\JNFrame\Assets\Packages\Google.Protobuf.3.15.8\lib\netstandard2.0\Google.Protobuf.dll</HintPath>
</Reference>
<Reference Include="Newtonsoft.Json">
<HintPath>D:\myproject\JisolGame\JNFrame\Assets\Packages\Newtonsoft.Json.13.0.3\lib\netstandard2.0\Newtonsoft.Json.dll</HintPath>
</Reference>
<Reference Include="Google.Protobuf">
<HintPath>D:\myproject\JisolGame\JNFrame\Assets\Packages\Google.Protobuf.3.15.8\lib\netstandard2.0\Google.Protobuf.dll</HintPath>
</Reference>
<Reference Include="Pathfinding.ClipperLib">
<HintPath>D:\myproject\JisolGame\JNFrame\Assets\Game\Plugins\AstarPathfindingProject\Plugins\Clipper\Pathfinding.ClipperLib.dll</HintPath>
</Reference>
@ -744,30 +744,87 @@
<Reference Include="System.Xml.XPath.XDocument">
<HintPath>D:\Unity\2021.3.33f1c1\Editor\Data\UnityReferenceAssemblies\unity-4.8-api\Facades\System.Xml.XPath.XDocument.dll</HintPath>
</Reference>
<Reference Include="UnityEngine.TestRunner">
<HintPath>D:\myproject\JisolGame\JNFrame\Library\ScriptAssemblies\UnityEngine.TestRunner.dll</HintPath>
</Reference>
<Reference Include="UnityEditor.TestRunner">
<HintPath>D:\myproject\JisolGame\JNFrame\Library\ScriptAssemblies\UnityEditor.TestRunner.dll</HintPath>
</Reference>
<Reference Include="Unity.VisualScripting.Flow.Editor">
<HintPath>D:\myproject\JisolGame\JNFrame\Library\ScriptAssemblies\Unity.VisualScripting.Flow.Editor.dll</HintPath>
<Reference Include="UnityEngine.TestRunner">
<HintPath>D:\myproject\JisolGame\JNFrame\Library\ScriptAssemblies\UnityEngine.TestRunner.dll</HintPath>
</Reference>
<Reference Include="Unity.VSCode.Editor">
<HintPath>D:\myproject\JisolGame\JNFrame\Library\ScriptAssemblies\Unity.VSCode.Editor.dll</HintPath>
</Reference>
<Reference Include="Unity.RenderPipelines.Universal.Shaders">
<HintPath>D:\myproject\JisolGame\JNFrame\Library\ScriptAssemblies\Unity.RenderPipelines.Universal.Shaders.dll</HintPath>
</Reference>
<Reference Include="Unity.TextMeshPro.Editor">
<HintPath>D:\myproject\JisolGame\JNFrame\Library\ScriptAssemblies\Unity.TextMeshPro.Editor.dll</HintPath>
</Reference>
<Reference Include="Unity.VisualStudio.Editor">
<HintPath>D:\myproject\JisolGame\JNFrame\Library\ScriptAssemblies\Unity.VisualStudio.Editor.dll</HintPath>
</Reference>
<Reference Include="Unity.Performance.Profile-Analyzer.Editor">
<HintPath>D:\myproject\JisolGame\JNFrame\Library\ScriptAssemblies\Unity.Performance.Profile-Analyzer.Editor.dll</HintPath>
</Reference>
<Reference Include="Unity.TestTools.CodeCoverage.Editor.OpenCover.Model">
<HintPath>D:\myproject\JisolGame\JNFrame\Library\ScriptAssemblies\Unity.TestTools.CodeCoverage.Editor.OpenCover.Model.dll</HintPath>
</Reference>
<Reference Include="Unity.VisualScripting.State.Editor">
<HintPath>D:\myproject\JisolGame\JNFrame\Library\ScriptAssemblies\Unity.VisualScripting.State.Editor.dll</HintPath>
</Reference>
<Reference Include="Unity.Searcher.Editor">
<HintPath>D:\myproject\JisolGame\JNFrame\Library\ScriptAssemblies\Unity.Searcher.Editor.dll</HintPath>
</Reference>
<Reference Include="Unity.VisualScripting.SettingsProvider.Editor">
<HintPath>D:\myproject\JisolGame\JNFrame\Library\ScriptAssemblies\Unity.VisualScripting.SettingsProvider.Editor.dll</HintPath>
</Reference>
<Reference Include="Unity.TestTools.CodeCoverage.Editor.OpenCover.Mono.Reflection">
<HintPath>D:\myproject\JisolGame\JNFrame\Library\ScriptAssemblies\Unity.TestTools.CodeCoverage.Editor.OpenCover.Mono.Reflection.dll</HintPath>
</Reference>
<Reference Include="UnityEditor.UI">
<HintPath>D:\myproject\JisolGame\JNFrame\Library\ScriptAssemblies\UnityEditor.UI.dll</HintPath>
</Reference>
<Reference Include="Unity.Rider.Editor">
<HintPath>D:\myproject\JisolGame\JNFrame\Library\ScriptAssemblies\Unity.Rider.Editor.dll</HintPath>
</Reference>
<Reference Include="Unity.RenderPipelines.Core.ShaderLibrary">
<HintPath>D:\myproject\JisolGame\JNFrame\Library\ScriptAssemblies\Unity.RenderPipelines.Core.ShaderLibrary.dll</HintPath>
</Reference>
<Reference Include="UnityEngine.UI">
<HintPath>D:\myproject\JisolGame\JNFrame\Library\ScriptAssemblies\UnityEngine.UI.dll</HintPath>
</Reference>
<Reference Include="Unity.EditorCoroutines.Editor">
<HintPath>D:\myproject\JisolGame\JNFrame\Library\ScriptAssemblies\Unity.EditorCoroutines.Editor.dll</HintPath>
</Reference>
<Reference Include="Unity.ShaderGraph.Editor">
<HintPath>D:\myproject\JisolGame\JNFrame\Library\ScriptAssemblies\Unity.ShaderGraph.Editor.dll</HintPath>
</Reference>
<Reference Include="Unity.Toolchain.Win-x86_64-Linux-x86_64">
<HintPath>D:\myproject\JisolGame\JNFrame\Library\ScriptAssemblies\Unity.Toolchain.Win-x86_64-Linux-x86_64.dll</HintPath>
</Reference>
<Reference Include="Unity.RenderPipeline.Universal.ShaderLibrary">
<HintPath>D:\myproject\JisolGame\JNFrame\Library\ScriptAssemblies\Unity.RenderPipeline.Universal.ShaderLibrary.dll</HintPath>
</Reference>
<Reference Include="Unity.AI.Navigation">
<HintPath>D:\myproject\JisolGame\JNFrame\Library\ScriptAssemblies\Unity.AI.Navigation.dll</HintPath>
</Reference>
<Reference Include="Unity.Mathematics.Editor">
<HintPath>D:\myproject\JisolGame\JNFrame\Library\ScriptAssemblies\Unity.Mathematics.Editor.dll</HintPath>
</Reference>
<Reference Include="Unity.AI.Navigation.Editor">
<HintPath>D:\myproject\JisolGame\JNFrame\Library\ScriptAssemblies\Unity.AI.Navigation.Editor.dll</HintPath>
</Reference>
<Reference Include="Unity.VisualScripting.Flow.Editor">
<HintPath>D:\myproject\JisolGame\JNFrame\Library\ScriptAssemblies\Unity.VisualScripting.Flow.Editor.dll</HintPath>
</Reference>
<Reference Include="Unity.RenderPipelines.Universal.Runtime">
<HintPath>D:\myproject\JisolGame\JNFrame\Library\ScriptAssemblies\Unity.RenderPipelines.Universal.Runtime.dll</HintPath>
</Reference>
<Reference Include="PPv2URPConverters">
<HintPath>D:\myproject\JisolGame\JNFrame\Library\ScriptAssemblies\PPv2URPConverters.dll</HintPath>
</Reference>
<Reference Include="Unity.VisualStudio.Editor">
<HintPath>D:\myproject\JisolGame\JNFrame\Library\ScriptAssemblies\Unity.VisualStudio.Editor.dll</HintPath>
</Reference>
<Reference Include="Unity.Sysroot.Linux_x86_64">
<HintPath>D:\myproject\JisolGame\JNFrame\Library\ScriptAssemblies\Unity.Sysroot.Linux_x86_64.dll</HintPath>
</Reference>
<Reference Include="Unity.Timeline">
<HintPath>D:\myproject\JisolGame\JNFrame\Library\ScriptAssemblies\Unity.Timeline.dll</HintPath>
</Reference>
@ -777,35 +834,29 @@
<Reference Include="Unity.TextMeshPro">
<HintPath>D:\myproject\JisolGame\JNFrame\Library\ScriptAssemblies\Unity.TextMeshPro.dll</HintPath>
</Reference>
<Reference Include="Unity.VisualScripting.State.Editor">
<HintPath>D:\myproject\JisolGame\JNFrame\Library\ScriptAssemblies\Unity.VisualScripting.State.Editor.dll</HintPath>
<Reference Include="Unity.Burst.Editor">
<HintPath>D:\myproject\JisolGame\JNFrame\Library\ScriptAssemblies\Unity.Burst.Editor.dll</HintPath>
</Reference>
<Reference Include="Unity.VisualScripting.SettingsProvider.Editor">
<HintPath>D:\myproject\JisolGame\JNFrame\Library\ScriptAssemblies\Unity.VisualScripting.SettingsProvider.Editor.dll</HintPath>
</Reference>
<Reference Include="Unity.TestTools.CodeCoverage.Editor.OpenCover.Mono.Reflection">
<HintPath>D:\myproject\JisolGame\JNFrame\Library\ScriptAssemblies\Unity.TestTools.CodeCoverage.Editor.OpenCover.Mono.Reflection.dll</HintPath>
<Reference Include="Unity.RenderPipelines.Core.Runtime">
<HintPath>D:\myproject\JisolGame\JNFrame\Library\ScriptAssemblies\Unity.RenderPipelines.Core.Runtime.dll</HintPath>
</Reference>
<Reference Include="Unity.VisualScripting.Flow">
<HintPath>D:\myproject\JisolGame\JNFrame\Library\ScriptAssemblies\Unity.VisualScripting.Flow.dll</HintPath>
</Reference>
<Reference Include="UnityEditor.UI">
<HintPath>D:\myproject\JisolGame\JNFrame\Library\ScriptAssemblies\UnityEditor.UI.dll</HintPath>
</Reference>
<Reference Include="Unity.PlasticSCM.Editor">
<HintPath>D:\myproject\JisolGame\JNFrame\Library\ScriptAssemblies\Unity.PlasticSCM.Editor.dll</HintPath>
</Reference>
<Reference Include="Unity.Rider.Editor">
<HintPath>D:\myproject\JisolGame\JNFrame\Library\ScriptAssemblies\Unity.Rider.Editor.dll</HintPath>
</Reference>
<Reference Include="UnityEngine.UI">
<HintPath>D:\myproject\JisolGame\JNFrame\Library\ScriptAssemblies\UnityEngine.UI.dll</HintPath>
</Reference>
<Reference Include="Unity.VisualScripting.Core">
<HintPath>D:\myproject\JisolGame\JNFrame\Library\ScriptAssemblies\Unity.VisualScripting.Core.dll</HintPath>
</Reference>
<Reference Include="Unity.EditorCoroutines.Editor">
<HintPath>D:\myproject\JisolGame\JNFrame\Library\ScriptAssemblies\Unity.EditorCoroutines.Editor.dll</HintPath>
<Reference Include="Unity.Mathematics">
<HintPath>D:\myproject\JisolGame\JNFrame\Library\ScriptAssemblies\Unity.Mathematics.dll</HintPath>
</Reference>
<Reference Include="Unity.Burst">
<HintPath>D:\myproject\JisolGame\JNFrame\Library\ScriptAssemblies\Unity.Burst.dll</HintPath>
</Reference>
<Reference Include="Unity.RenderPipelines.Universal.Editor">
<HintPath>D:\myproject\JisolGame\JNFrame\Library\ScriptAssemblies\Unity.RenderPipelines.Universal.Editor.dll</HintPath>
</Reference>
<Reference Include="Unity.VisualScripting.Shared.Editor">
<HintPath>D:\myproject\JisolGame\JNFrame\Library\ScriptAssemblies\Unity.VisualScripting.Shared.Editor.dll</HintPath>
@ -813,46 +864,35 @@
<Reference Include="Unity.Timeline.Editor">
<HintPath>D:\myproject\JisolGame\JNFrame\Library\ScriptAssemblies\Unity.Timeline.Editor.dll</HintPath>
</Reference>
<Reference Include="Unity.RenderPipelines.ShaderGraph.ShaderGraphLibrary">
<HintPath>D:\myproject\JisolGame\JNFrame\Library\ScriptAssemblies\Unity.RenderPipelines.ShaderGraph.ShaderGraphLibrary.dll</HintPath>
</Reference>
<Reference Include="Unity.TestTools.CodeCoverage.Editor">
<HintPath>D:\myproject\JisolGame\JNFrame\Library\ScriptAssemblies\Unity.TestTools.CodeCoverage.Editor.dll</HintPath>
</Reference>
<Reference Include="Unity.RenderPipelines.Core.Editor">
<HintPath>D:\myproject\JisolGame\JNFrame\Library\ScriptAssemblies\Unity.RenderPipelines.Core.Editor.dll</HintPath>
</Reference>
<Reference Include="Unity.VisualScripting.State">
<HintPath>D:\myproject\JisolGame\JNFrame\Library\ScriptAssemblies\Unity.VisualScripting.State.dll</HintPath>
</Reference>
<Reference Include="Unity.SysrootPackage.Editor">
<HintPath>D:\myproject\JisolGame\JNFrame\Library\ScriptAssemblies\Unity.SysrootPackage.Editor.dll</HintPath>
</Reference>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="Assembly-CSharp.csproj">
<Project>{3ca4410c-c33b-25ce-55bc-3a432b9830ed}</Project>
<Name>Assembly-CSharp</Name>
</ProjectReference>
<ProjectReference Include="BestHTTP.csproj">
<Project>{49f1e414-166b-61b7-ba11-ad89c8d920ee}</Project>
<Name>BestHTTP</Name>
</ProjectReference>
<ProjectReference Include="App.csproj">
<Project>{86f5a836-c92e-bcf7-bc96-4683fb573cb1}</Project>
<Name>App</Name>
</ProjectReference>
<ProjectReference Include="PackageToolsEditor.csproj">
<Project>{d850d0b5-3d03-e2f4-ebd4-5c75d2c94d81}</Project>
<Name>PackageToolsEditor</Name>
</ProjectReference>
<ProjectReference Include="UniTask.DOTween.csproj">
<Project>{99c4c7d2-ca96-1038-95e0-77e225df2b06}</Project>
<Name>UniTask.DOTween</Name>
</ProjectReference>
<ProjectReference Include="UniTask.Linq.csproj">
<Project>{7f60f694-1f75-f2f0-5fde-36ccb7fd82d1}</Project>
<Name>UniTask.Linq</Name>
</ProjectReference>
<ProjectReference Include="UniTask.TextMeshPro.csproj">
<Project>{4b964c85-7c9d-2d07-a2e0-8595262e4e96}</Project>
<Name>UniTask.TextMeshPro</Name>
</ProjectReference>
<ProjectReference Include="AstarPathfindingProject.csproj">
<Project>{01d387ea-c776-81ef-4b5e-bf013e2cd20f}</Project>
<Name>AstarPathfindingProject</Name>
</ProjectReference>
<ProjectReference Include="AstarPathfindingProjectEditor.csproj">
<Project>{c006c4ab-5a1d-a86c-7397-6d5ecfbfd468}</Project>
<Name>AstarPathfindingProjectEditor</Name>
@ -861,14 +901,38 @@
<Project>{6daf7f60-fa83-da88-56be-04871b5df574}</Project>
<Name>JNGame</Name>
</ProjectReference>
<ProjectReference Include="UniTask.csproj">
<Project>{39f5acb9-cdbb-9f48-497c-14159a0afd38}</Project>
<Name>UniTask</Name>
</ProjectReference>
<ProjectReference Include="UniTask.Addressables.csproj">
<Project>{6d8bd378-3e5b-6997-5e5e-288243f0f72b}</Project>
<Name>UniTask.Addressables</Name>
</ProjectReference>
<ProjectReference Include="BestHTTP.csproj">
<Project>{49f1e414-166b-61b7-ba11-ad89c8d920ee}</Project>
<Name>BestHTTP</Name>
</ProjectReference>
<ProjectReference Include="App.csproj">
<Project>{86f5a836-c92e-bcf7-bc96-4683fb573cb1}</Project>
<Name>App</Name>
</ProjectReference>
<ProjectReference Include="UniTask.DOTween.csproj">
<Project>{99c4c7d2-ca96-1038-95e0-77e225df2b06}</Project>
<Name>UniTask.DOTween</Name>
</ProjectReference>
<ProjectReference Include="UniTask.Linq.csproj">
<Project>{7f60f694-1f75-f2f0-5fde-36ccb7fd82d1}</Project>
<Name>UniTask.Linq</Name>
</ProjectReference>
<ProjectReference Include="AstarPathfindingProject.csproj">
<Project>{01d387ea-c776-81ef-4b5e-bf013e2cd20f}</Project>
<Name>AstarPathfindingProject</Name>
</ProjectReference>
<ProjectReference Include="HPJ.Presentation.csproj">
<Project>{0e7776eb-ee05-4bc9-0e83-5325dc548854}</Project>
<Name>HPJ.Presentation</Name>
</ProjectReference>
<ProjectReference Include="UniTask.csproj">
<Project>{39f5acb9-cdbb-9f48-497c-14159a0afd38}</Project>
<Name>UniTask</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.

File diff suppressed because it is too large Load Diff

View File

@ -8,7 +8,7 @@ namespace Game.Plugins.App
public static readonly JNGSocket Socket = new JNGSocket();
public static readonly JNGSyncFrame Sync = new JNGSyncFrame();
public static readonly JAPI Api = new(new JAPIConfig(){BaseURL = "http://192.168.0.116:8080"});
public static readonly JAPI Api = new(new JAPIConfig(){BaseURL = "http://192.168.0.126:8080"});
public static readonly EventDispatcher Event = EventDispatcher.Event;
public static SystemBase[] System()

View File

@ -0,0 +1,57 @@
using System.Threading.Tasks;
using Game.Plugins.App.Sync;
using Game.Plugins.JNGame.Sync.Frame.AstarPath.RVO;
using UnityEngine;
namespace Game.Plugins.App.Game.RVO
{
public class JNGRVOAgent : JNGSyncFrameDefault
{
private JNRVOSimulator Simulator => GetComponentInParent<JNGRVOManager>().Simulator;
private JNIAgent _agent;
public float maxSpeed = 5;
public float radius = 0.5f;
private Vector2 target;
public override void OnSyncLoad()
{
base.OnSyncLoad();
var position = this.transform.position;
_agent = Simulator.AddAgent(new JNRVOAgent(
new Vector2(position.x, position.z), 0
));
SetTarget(position);
_agent.Radius = radius;
}
//设置目标点
public void SetTarget(Vector2 targetPoint)
{
this.target = targetPoint;
}
public void SetTarget(Vector3 targetPoint)
{
this.target = new Vector2(targetPoint.x,targetPoint.z);
}
public override void OnSyncUpdate(int dt, JNFrameInfo frame, Object input)
{
base.OnSyncUpdate(dt, frame, input);
var pos = _agent.Position;
var deltaPosition = Vector2.ClampMagnitude(_agent.CalculatedTargetPoint - pos,
_agent.CalculatedSpeed * GetSync().Time.deltaTime);
pos += deltaPosition;
_agent.Position = pos;
var dist = (target - pos).magnitude;
_agent.SetTarget(target, Mathf.Min(dist, maxSpeed), maxSpeed * 1.1f);
this.transform.position = new Vector3(_agent.Position.x, _agent.ElevationCoordinate, _agent.Position.y);
}
}
}

View File

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: a53ee56903f64f8c845d8eb0274f6b07
timeCreated: 1708324888

View File

@ -1,4 +1,5 @@
using Game.Plugins.App.Sync;
using System.Threading.Tasks;
using Game.Plugins.App.Sync;
using Game.Plugins.JNGame.Sync.Frame.AstarPath.RVO;
using UnityEngine;
@ -8,21 +9,37 @@ namespace Game.Plugins.App.Game.RVO
public class JNGRVOManager : JNGSyncFrameDefault
{
private JNRVOSimulator _simulator = new JNRVOSimulator(MovementPlane.XY);
private JNRVOSimulator _simulator = new JNRVOSimulator(MovementPlane.XZ);
public JNRVOSimulator Simulator => _simulator;
public override void OnSyncLoad()
{
base.OnSyncLoad();
}
public override void OnSyncUpdate(int dt, JNFrameInfo frame, Object input)
{
base.OnSyncUpdate(dt, frame, input);
Simulator.DesiredDeltaTime = 1.0f / (1000f / dt);
Simulator.symmetryBreakingBias = 0.1f;
//更新寻路
Simulator.Update();
// Simulator.DesiredDeltaTime = 1.0f / 30;
// Simulator.symmetryBreakingBias = 0.1f;
// //更新避障
// Simulator.Update();
if (frame.Index > 0)
{
Simulator.DesiredDeltaTime = 1.0f / 15;
Simulator.symmetryBreakingBias = 0.1f;
//更新避障
Simulator.Update();
}
}
// public override Task OnSyncUpdateThread(int dt, JNFrameInfo frame)
// {
// return Task.Run(() =>
// {
// if (frame.Index > 0)
// {
// Simulator.DesiredDeltaTime = 1.0f / 15;
// Simulator.symmetryBreakingBias = 0.1f;
// //更新避障
// Simulator.Update();
// }
// });
// }
}
}

View File

@ -0,0 +1,94 @@
using System;
using Game.Plugins.App.Sync;
using Game.Plugins.JNGame.Sync.Frame.AstarPath.RVO;
using UnityEngine;
namespace Game.Plugins.App.Game.RVO
{
public class JNGRVOObstacle : JNGSyncFrameDefault
{
private JNRVOSimulator Simulator => GetComponentInParent<JNGRVOManager>().Simulator;
public override void OnSyncLoad()
{
base.OnSyncLoad();
CreateObstacles();
}
public void CreateObstacles()
{
var boxCollider = this.GetComponent<BoxCollider>();
Vector3 center = transform.position;
Vector3 size = boxCollider.size;
//
// var verts = new [] { new Vector3(1, 0, -1), new Vector3(1, 0, 1), new Vector3(-1, 0, 1), new Vector3(-1, 0, -1) };
// for (int i = 0; i < verts.Length; i++) {
// verts[i].Scale(new Vector3(size.x * 0.5f, 0, size.y * 0.5f));
// verts[i] += new Vector3(center.x, 0, center.y);
// }
//
var verts = new Vector3[4];
verts[0] = (new Vector3(size.x, -size.y, size.z) * 0.5f);
verts[1] = (new Vector3(-size.x, -size.y, size.z) * 0.5f);
verts[2] = (new Vector3(-size.x, -size.y, -size.z) * 0.5f);
verts[3] = (new Vector3(size.x, -size.y, -size.z) * 0.5f);
verts[0].y = 0;
verts[1].y = 0;
verts[2].y = 0;
verts[3].y = 0;
Simulator.AddObstacle(verts, 1, transform.localToWorldMatrix);
}
// private void OnDrawGizmos()
// {
//
// Gizmos.color = new Color(0.615f, 1, 0.06f, false ? 1.0f : 0.7f);
// var movementPlane = MovementPlane.XY;
// var up = Vector3.up;
//
// if (gizmoVerts == null || AreGizmosDirty() || _obstacleMode != obstacleMode) {
// _obstacleMode = obstacleMode;
//
// if (gizmoVerts == null) gizmoVerts = new List<Vector3[]>();
// else gizmoVerts.Clear();
//
// CreateObstacles();
// }
//
// Matrix4x4 m = GetMatrix();
//
// for (int i = 0; i < gizmoVerts.Count; i++) {
// Vector3[] verts = gizmoVerts[i];
// for (int j = 0, q = verts.Length-1; j < verts.Length; q = j++) {
// Gizmos.DrawLine(m.MultiplyPoint3x4(verts[j]), m.MultiplyPoint3x4(verts[q]));
// }
//
// if (selected) {
// for (int j = 0, q = verts.Length-1; j < verts.Length; q = j++) {
// Vector3 a = m.MultiplyPoint3x4(verts[q]);
// Vector3 b = m.MultiplyPoint3x4(verts[j]);
//
// if (movementPlane != MovementPlane.XY) {
// Gizmos.DrawLine(a + up*Height, b + up*Height);
// Gizmos.DrawLine(a, a + up*Height);
// }
//
// Vector3 avg = (a + b) * 0.5f;
// Vector3 tang = (b - a).normalized;
// if (tang == Vector3.zero) continue;
//
// Vector3 normal = Vector3.Cross(up, tang);
//
// Gizmos.DrawLine(avg, avg+normal);
// Gizmos.DrawLine(avg+normal, avg+normal*0.5f+tang*0.5f);
// Gizmos.DrawLine(avg+normal, avg+normal*0.5f-tang*0.5f);
// }
// }
// }
//
// gizmoDrawing = false;
// }
}
}

View File

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 3a7e67272f48415bb20f684dfd242240
timeCreated: 1708324868

View File

@ -8,7 +8,7 @@ namespace Game.Plugins.App
protected override async UniTask<string> GetUrl()
{
await UniTask.NextFrame();
return "ws://192.168.0.116:8080/websocket";
return "ws://192.168.0.126:8080/websocket";
}
}
}

View File

@ -184,8 +184,8 @@ namespace Pathfinding {
if (coll == null && coll2D == null) return;
// Required to ensure we get the most up to date bounding box from the physics engine
UnityEngine.Physics.SyncTransforms();
UnityEngine.Physics2D.SyncTransforms();
// UnityEngine.Physics.SyncTransforms();
// UnityEngine.Physics2D.SyncTransforms();
if (!colliderEnabled) {
// If the collider is not enabled, then col.bounds will empty

View File

@ -1,6 +1,12 @@
namespace Plugins.JNGame.Sync.Frame.AStar.Entity
using System;
using System.Collections.Generic;
using Game.Plugins.JNGame.Sync.Frame.AStar.Entity.Graph;
using UnityEngine;
namespace Plugins.JNGame.Sync.Frame.AStar.Entity
{
public class AStarData
public class AStarData : MonoBehaviour
{
/// <summary>
@ -9,13 +15,45 @@
/// 如果图形已被移除,则可能包含空条目。
/// </summary>
// 这通常用于防止某些字段被序列化,因为它们可能包含不需要或不能序列化的数据。
public NavGraph[] graphs = new NavGraph[0]; // 声明一个 NavGraph 类型的数组,初始化为长度为 0 的数组。
public List<NavGraph> graphs = new(); // 声明一个 NavGraph 类型的数组,初始化为长度为 0 的数组。
/// <summary>
/// 所有图表和设置的序列化数据。
/// 以Base64编码的字符串形式存储因为否则Unity的Undo系统有时会损坏字节数据因为它只存储增量
///
/// 可以通过<see cref="data"/>属性以字节数组的形式访问此数据。
/// </summary>
[SerializeField]
[HideInInspector]
string dataString;
/// <summary>
/// 所有图表和设置的序列化数据
/// </summary>
private byte[] data {
// 获取data的值
get {
// 如果dataString不为null则将dataString从Base64字符串转换为字节数组并返回
return dataString != null ? Convert.FromBase64String(dataString) : null;
}
// 设置data的值
set {
// 如果value不为null则将value从字节数组转换为Base64字符串并赋值给dataString
dataString = value != null ? Convert.ToBase64String(value) : null;
}
}
/// <summary>
/// 所有支持的图形类型。
/// 通过反射搜索填充
/// </summary>
public Type[] graphTypes { get; private set; }
//数据初始化
public void Init()
{
graphs = new NavGraph[0];
graphs = new();
AddGraph(new RecastGraph(this));
DeserializeGraphs();
}
@ -27,7 +65,7 @@
/// </remarks>
public void DeserializeGraphs () {
if (data != null) {
DeserializeGraphs(data);
// DeserializeGraphs(data);
}
}
@ -40,15 +78,112 @@
/// 并调用<see cref="UpdateShortcuts"/>方法来更新任何相关的快捷方式或缓存。
/// </remarks>
void ClearGraphs () {
if (graphs == null) return;
for (int i = 0; i < graphs.Length; i++) {
if (graphs[i] != null) {
((IGraphInternals)graphs[i]).OnDestroy();
graphs[i].active = null;
}
// if (graphs == null) return;
// for (int i = 0; i < graphs.Length; i++) {
// if (graphs[i] != null) {
// ((IGraphInternals)graphs[i]).OnDestroy();
// graphs[i].active = null;
// }
// }
// graphs = new NavGraph[0];
// UpdateShortcuts();
}
// /// <summary>
// /// 从内存中加载图表,如果存在缓存的图表,则加载缓存的图表
// /// </summary>
// public void Awake() {
//
// // 初始化一个空的NavGraph数组用于存储图表
// graphs = new NavGraph[0];
//
// // // 检查是否设置了在启动时加载缓存,并且存在缓存的启动文件
// // if (cacheStartup && file_cachedStartup != null) {
// // // 如果满足条件,则从缓存中加载图表
// // LoadFromCache();
// // } else {
// // // 如果不满足条件,则反序列化图表(可能是从文件或其他数据源加载)
// // DeserializeGraphs();
// // }
//
// }
/// 将指定的图形添加到 <see cref="graphs"/> 数组中
public void AddGraph (NavGraph graph) {
//
// // Make sure to not interfere with pathfinding
// var graphLock = AssertSafe(true);
// // Try to fill in an empty position
// bool foundEmpty = false;
graphs.Add(graph);
for (int i = 0; i < graphs.Count; i++) {
if (graphs[i] == null) {
graphs[i] = graph;
graph.graphIndex = (uint)i;
// foundEmpty = true;
break;
}
}
// if (!foundEmpty) {
// if (graphs != null && graphs.Length >= GraphNode.MaxGraphIndex) {
// throw new Exception("Graph Count Limit Reached. You cannot have more than " + GraphNode.MaxGraphIndex + " graphs.");
// }
//
// // Add a new entry to the list
// var graphList = new List<NavGraph>(graphs ?? new NavGraph[0]);
// graphList.Add(graph);
// graphs = graphList.ToArray();
// graph.graphIndex = (uint)(graphs.Length-1);
//
// }
//
// UpdateShortcuts();
// // graph.active = active;
// graphLock.Release();
}
/// <summary>
/// 创建一个新的类型为type的图形实例
/// 参见:<see cref="CreateGraph(string)"/>
/// </summary>
internal NavGraph CreateGraph (Type type) {
// 使用type类型的构造函数创建一个新的实例并将其转型为NavGraph类型
var graph = Activator.CreateInstance(type) as NavGraph;
// // 将新创建的图形的active属性设置为当前对象的active属性的值
// graph.active = active;
// 返回新创建的图形实例
return graph;
}
/// <summary>
/// 获取 NavGraph 在 <see cref="graphs"/> 数组中的索引
/// </summary>
/// <param name="graph">要查找索引的 NavGraph 对象</param>
/// <returns>NavGraph 在数组中的索引,如果未找到则返回 -1</returns>
public int GetGraphIndex(NavGraph graph) {
// 如果传入的 graph 参数为空,则抛出空引用异常
if (graph == null) throw new ArgumentNullException("graph");
// 初始化索引值为 -1表示默认情况下未找到 NavGraph
var index = -1;
// 如果 graphs 数组不为空
if (graphs != null) {
// 使用 Array.IndexOf 方法查找 graph 在 graphs 数组中的索引
index = Array.IndexOf(graphs.ToArray(), graph);
// 如果索引值为 -1则表示 graphs 数组中不存在该 graph打印错误日志
if (index == -1) Debug.LogError("Graph doesn't exist");
}
graphs = new NavGraph[0];
UpdateShortcuts();
// 返回找到的索引值,或者返回 -1表示未找到
return index;
}
}

View File

@ -1,4 +1,10 @@
namespace Plugins.JNGame.Sync.Frame.AStar.Entity
using System;
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;
using NotImplementedException = System.NotImplementedException;
namespace Plugins.JNGame.Sync.Frame.AStar.Entity
{
/// <summary>
@ -10,12 +16,12 @@
//
// // 当对象被销毁时调用此方法。
// void OnDestroy();
// 销毁所有节点。
void DestroyAllNodes();
//
// // 销毁所有节点。
// void DestroyAllNodes();
//
// // 扫描图形并返回进度的集合。
// IEnumerable<Progress> ScanInternal();
// 扫描图形并返回进度的集合。
void ScanInternal();
//
// // 序列化额外的信息到图形序列化上下文中。
// void SerializeExtraInfo(GraphSerializationContext ctx);
@ -32,6 +38,47 @@
public abstract class NavGraph : IGraphInternals {
/// <summary>图形的索引,用于识别目的</summary>
public uint graphIndex;
protected AStarData data;
protected NavGraph(AStarData data)
{
this.data = data;
}
//渲染GUI
public abstract void DrawGUI();
/// <summary>
/// 使用图形中的所有节点调用一个委托。
/// 这是遍历图形中所有节点的主要方式。
///
/// 不要在委托内部改变图形的结构。
/// // 这里是一个节点
/// Debug.Log("I found a node at position " + (Vector3)node.position);
/// });active.data.gridGraph;
///
/// List<GraphNode> nodes = new List<GraphNode>();
///
/// gg.GetNodes((System.Action<GraphNode>)nodes.Add);
/// </code>
///
/// 参见:<see cref="Pathfinding.AstarData.GetNodes"/>
/// </summary>
public abstract void GetNodes(Action<GraphNode> action);
/// <summary>
/// 销毁图形中的所有节点。
/// 警告:这是一个内部方法。除非你有非常充分的理由,否则你最好不要调用它。
/// </summary>
public virtual void DestroyAllNodes () {
// 调用 GetNodes 方法,对每个节点执行 Destroy 操作
GetNodes(node => node.Destroy());
}
public abstract void ScanInternal();
}
}

View File

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 754d4e70f7d14bbe9960fedad7bf8f85
timeCreated: 1708236741

View File

@ -0,0 +1,192 @@
using Game.Plugins.JNGame.Sync.Frame.AStar.Navmesh;
using Game.Plugins.JNGame.Sync.Frame.AStar.Util;
using Plugins.JNGame.Sync.Frame.AStar;
using Plugins.JNGame.Sync.Frame.AStar.Entity;
using Plugins.JNGame.Sync.Frame.AStar.Entity.Tile;
using UnityEditor;
using UnityEngine;
using UnityEngine.Pool;
namespace Game.Plugins.JNGame.Sync.Frame.AStar.Entity.Graph
{
public abstract class NavmeshBase : NavGraph, INavmesh, INavmeshHolder, ITransformedGraph
{
public const int VertexIndexMask = 0xFFF;
public const int TileIndexMask = 0x7FFFF;
public const int TileIndexOffset = 12;
/// <summary>
/// 边界框的大小。
/// </summary>
public Vector3 forcedBoundsSize = new Vector3(100, 40, 100);
/// <summary>
/// 瓦片在X轴方向上的世界单位大小
/// </summary>
public abstract float TileWorldSizeX { get; }
/// <summary>
/// 瓦片在Z轴方向上的世界单位大小
/// </summary>
public abstract float TileWorldSizeZ { get; }
/// <summary>
/// 沿X轴方向的瓦片数量
/// </summary>
public int tileXCount;
/// <summary>
/// 沿Z轴方向的瓦片数量
/// </summary>
public int tileZCount;
/// <summary>
/// All tiles.
///
/// See: <see cref="GetTile"/>
/// </summary>
protected NavmeshTile[] tiles;
/// <summary>
/// 返回一个将图空间转换为世界空间的新变换。
/// 不更新<see cref="transform"/>字段。
/// 请参阅:<see cref="RelocateNodes(GraphTransform)"/>
/// </summary>
public abstract GraphTransform CalculateTransform();
protected NavmeshBase(AStarData data) : base(data)
{
}
public override void GetNodes (System.Action<GraphNode> action) {
if (tiles == null) return;
for (int i = 0; i < tiles.Length; i++) {
if (tiles[i] == null || tiles[i].x+tiles[i].z*tileXCount != i) continue;
TriangleMeshNode[] nodes = tiles[i].nodes;
if (nodes == null) continue;
for (int j = 0; j < nodes.Length; j++) action(nodes[j]);
}
}
public override void DrawGUI()
{
}
// /// <summary>
// /// 确定如何将图形空间转换为世界空间。
// /// 请参阅:<see cref="CalculateTransform"/>
// /// </summary>
// public GraphTransform transform = new GraphTransform(Matrix4x4.identity);
public GraphTransform transform { get; }
/// <summary>
/// 获取指定顶点索引的顶点坐标。
///
/// 异常:如果顶点索引无效,将抛出 IndexOutOfRangeException。
/// 异常:如果顶点所在的瓦片尚未计算,将抛出 NullReferenceException。
///
/// 参见NavmeshTile.GetVertex
/// </summary>
public Int3 GetVertex(int index) {
// 通过位运算提取顶点索引中的瓦片索引部分
int tileIndex = (index >> TileIndexOffset) & TileIndexMask;
// 调用对应瓦片的 GetVertex 方法来获取顶点坐标
return tiles[tileIndex].GetVertex(index);
}
/// <summary>
/// 获取指定顶点索引在图空间中的顶点坐标
/// </summary>
public Int3 GetVertexInGraphSpace(int index) {
// 通过位运算从顶点索引中提取瓦片索引
int tileIndex = (index >> TileIndexOffset) & TileIndexMask;
// 返回指定瓦片中的顶点在图空间中的坐标
return tiles[tileIndex].GetVertexInGraphSpace(index);
}
public int GetVertexArrayIndex (int index) {
return index & VertexIndexMask;
}
/// <summary>
/// 从瓦片索引获取瓦片坐标
/// </summary>
public void GetTileCoordinates(int tileIndex, out int x, out int z) {
// 原本的代码使用了 System.Math.DivRem 方法来同时获取商和余数,但这里为了简化直接使用了除法和减法。
//z = System.Math.DivRem(tileIndex, tileXCount, out x);
z = tileIndex / tileXCount; // 计算商即瓦片在Z轴上的坐标
x = tileIndex - z * tileXCount; // 计算余数即瓦片在X轴上的坐标
}
/// <summary>
/// 返回包含指定位置的瓦片坐标。
/// 这个瓦片坐标不一定是有效的(即它可能超出边界)。
/// </summary>
public Int2 GetTileCoordinates(Vector3 position) {
// 将给定的世界空间位置转换为本地空间位置
position = transform.InverseTransform(position);
// 根据瓦片的世界大小将位置坐标转换为瓦片坐标
position.x /= TileWorldSizeX;
position.z /= TileWorldSizeZ;
// 返回计算出的瓦片坐标
return new Int2((int)position.x, (int)position.z);
}
/// <summary>
/// 使用NewEmptyTile创建的tile填充图形
/// </summary>
protected void FillWithEmptyTiles() {
// 对于每一个z层通常是深度或高度方向
for (int z = 0; z < tileZCount; z++) {
// 对于每一个x层通常是宽度或长度方向
for (int x = 0; x < tileXCount; x++) {
// 调用NewEmptyTile方法来创建一个新的空tile并将其放置在二维数组tiles的对应位置
tiles[z * tileXCount + x] = NewEmptyTile(x, z);
}
}
}
/// <summary>
/// 创建一个新的空tile
/// </summary>
/// <param name="x">tile的x坐标</param>
/// <param name="z">tile的z坐标</param>
/// <returns>返回一个新的NavmeshTile实例</returns>
protected NavmeshTile NewEmptyTile(int x, int z) {
return new NavmeshTile {
// 设置tile的x坐标
x = x,
// 设置tile的z坐标
z = z,
// 设置tile的宽度为1
w = 1,
// 设置tile的高度为1
d = 1,
// 初始化一个空的顶点数组
verts = new Int3[0],
// 初始化一个空的图形空间顶点数组
vertsInGraphSpace = new Int3[0],
// 初始化一个空的三角形数组
tris = new int[0],
// 初始化一个空的TriangleMeshNode数组
nodes = new TriangleMeshNode[0],
// 从BBTree对象池中取出一个BBTree实例
bbTree = new BBTree(),
// 将当前对象可能是NavmeshGraph或其他包含此方法的类赋值给tile的graph属性
graph = this,
};
}
}
}

View File

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 672f1ca8ed43420b9be5f44fea1ccc65
timeCreated: 1708236768

View File

@ -0,0 +1,284 @@
using System;
using System.Collections.Generic;
using Game.Plugins.JNGame.Sync.Frame.AStar.Navmesh;
using Game.Plugins.JNGame.Sync.Frame.AStar.Util;
using Plugins.JNGame.Sync.Frame.AStar.Entity;
using Plugins.JNGame.Sync.Frame.AStar.Entity.Tile;
using UnityEditor;
using UnityEngine;
using UnityEngine.Pool;
namespace Game.Plugins.JNGame.Sync.Frame.AStar.Entity.Graph
{
public class RecastGraph : NavmeshBase
{
/// <summary>
/// 边界框的中心点。
/// 扫描将仅在边界框内部进行。
/// </summary>
public Vector3 forcedBoundsCenter;
/// <summary>
/// 图形的旋转角度(以度为单位)
/// </summary>
public Vector3 rotation;
/// <summary>
/// 如果为true扫描图形将生成一个完全空的图形。
/// 例如,如果你想用自定义的导航网格替换图形,这将非常有用。
/// </summary>
public bool scanEmptyGraph;
/// <summary>
/// 体素样本大小xz
/// 当生成重铸图形时,会将世界体素化。
/// 可以将其视为使用许多盒子构建的世界的近似值。
/// 如果您玩过《我的世界》,那么它看起来非常相似(但盒子更小)。
/// [打开在线文档以查看图像]
/// 单元格大小是这些盒子的宽度和深度。盒子的高度通常要小得多,并且是自动计算的。请参阅<see cref="CellHeight"/>。
///
/// 较低的值将产生更高质量的导航网格,但扫描图形将更慢。
///
/// [打开在线文档以查看图像]
/// </summary>
public float cellSize = 0.5F;
/// <summary>
/// 如果为true则将图形分割成tile否则使用单个tile覆盖整个图形。
///
/// 使用tile具有多种用途但也存在一些缺点。
/// - 使用tile允许您一次只更新图形的一部分。在重铸图形上进行图形更新时它将始终重新计算整个tile或如果没有tile则重新计算整个图形
/// <see cref="NavmeshCut"/>组件也按tile进行处理。
/// - 使用tile允许您使用<see cref="NavmeshPrefab"/>s。
/// - 使用tile可以分解非常大的三角形这在某些情况下可以提高路径质量并使导航网格更紧密地跟随地面的y坐标。
/// - 使用tile可以大大加快生成导航网格的速度因为每个tile都可以并行计算。
/// 但是如果tile制作得太小则许多tile的开销可能会使其比拥有较少的tile更慢。
/// - 使用小tile在某些情况下可能会使路径质量变差但是将<see cref="FunnelModifier"/>s的质量设置设置为高或使用<see cref="RichAI.funnelSimplification"/>)将大多数情况下会缓解这个问题。
///
/// 请参阅:<see cref="editorTileSize"/>
///
/// 自4.1版本起默认值为true。
/// </summary>
public bool useTiles = true;
/// <summary>
/// 沿X轴的一个tile在体素中的大小。
/// \copydetails editorTileSize
///
/// 警告:不要修改,它会在扫描时从<see cref="editorTileSize"/>设置
///
/// 请参阅:<see cref="tileSizeZ"/>
/// </summary>
public int tileSizeX = 128;
/// <summary>
/// 沿Z轴的一个tile在体素中的大小。
/// \copydetails editorTileSize
///
/// 警告:不要修改,它会在扫描时从<see cref="editorTileSize"/>设置
///
/// 请参阅:<see cref="tileSizeX"/>
/// </summary>
public int tileSizeZ = 128;
/// <summary>
/// 单个tile在体素中的大小。
/// 这是tile的宽度。
///
/// [打开在线文档以查看图像]
///
/// 较大的tile大小在初始扫描
/// 时可能更快但如果在大世界中使用过大的tile大小请小心内存溢出问题
/// 较小的tile大小在更新时快得多
///
/// 不同的tile大小会影响路径的质量。通常最好将巨大的开放区域拆分为多个tile以获得更好的路径质量
/// 但过小的tile也可能导致看起来像无形障碍物的效果。
/// 要了解更多关于此的信息请参阅navmeshnotes在在线文档中查看工作链接
/// 通常最好进行实验,看看哪种方法最适合您的游戏。
///
/// 当扫描重铸图形时可以并行计算单个tile这可以大大加快扫描大型世界的速度。
/// 当您要重新计算重铸图形的一部分时这只能按tile逐个进行这意味着如果您经常尝试更新重铸图形中远小于tile大小的区域
/// 则将进行大量不必要的计算。然而另一方面如果您更新比tile大小大得多的重铸图形区域则可能会比必要的速度慢因为使用大量的tile会有一些开销
/// 而不是几个较大的tile尽管不是很多
///
/// 推荐的值介于64和256之间但这些是非常软的限制。可以使用较大和较小的值。
/// </summary>
public int editorTileSize = 128;
public RecastGraph(AStarData data) : base(data)
{
}
public override void DrawGUI()
{
}
public override void GetNodes(Action<GraphNode> action)
{
throw new NotImplementedException();
}
public override void ScanInternal()
{
TriangleMeshNode.SetNavmeshHolder(this.data.GetGraphIndex(this), this);
// RelevantGraphSurface.UpdateAllPositions();
// ScanAllTiles();
}
public override float TileWorldSizeX { get; }
public override float TileWorldSizeZ { get; }
/// <summary>
/// 计算图变换。
/// </summary>
/// <returns>返回表示图变换的 GraphTransform 对象。</returns>
public override GraphTransform CalculateTransform() {
// 创建一个新的 GraphTransform 对象,该对象基于给定的矩阵变换。
// 矩阵变换首先应用 forcedBoundsSize*0.5f 的负值作为平移,然后应用旋转和缩放。
return new GraphTransform(
Matrix4x4.TRS(
forcedBoundsCenter, // 平移中心
Quaternion.Euler(rotation), // 旋转值,通过欧拉角表示
Vector3.one // 缩放因子所有维度都缩放为1
) * // 矩阵乘法
Matrix4x4.TRS(
-forcedBoundsSize * 0.5f, // 平移量,是 forcedBoundsSize 的一半的负值
Quaternion.identity, // 不旋转
Vector3.one // 缩放因子所有维度都缩放为1
)
);
}
void InitializeTileInfo () {
// 计算体素网格的尺寸
// Voxel grid size
int totalVoxelWidth = (int)(forcedBoundsSize.x / cellSize + 0.5f); // 总体素宽度
int totalVoxelDepth = (int)(forcedBoundsSize.z / cellSize + 0.5f); // 总体素深度
// 根据是否使用tiles来设置tile的尺寸
if (!useTiles) {
// 如果不使用tiles则tile的尺寸等于总体素的尺寸
tileSizeX = totalVoxelWidth;
tileSizeZ = totalVoxelDepth;
} else {
// 如果使用tiles则tile的尺寸等于编辑器设置的尺寸
tileSizeX = editorTileSize;
tileSizeZ = editorTileSize;
}
// 计算tiles的数量
// Number of tiles
tileXCount = (totalVoxelWidth + tileSizeX - 1) / tileSizeX; // X轴上的tile数量
tileZCount = (totalVoxelDepth + tileSizeZ - 1) / tileSizeZ; // Z轴上的tile数量
// 检查tiles的数量是否超过了最大限制
if (tileXCount * tileZCount > TileIndexMask + 1) {
// 如果超过了最大限制,则抛出异常
throw new System.Exception("Tiles数量过多 (" + (tileXCount * tileZCount) + "),最大限制是 " + (TileIndexMask + 1) +
"\n尝试在A*检查器的'Optimizations'选项卡下禁用ASTAR_RECAST_LARGER_TILES选项。");
}
// 初始化tiles数组
tiles = new NavmeshTile[tileXCount * tileZCount];
}
// protected void ScanAllTiles () {
//
// transform = CalculateTransform();
// InitializeTileInfo();
//
// // If this is true, just fill the graph with empty tiles
// if (scanEmptyGraph) {
// FillWithEmptyTiles();
// yield break;
// }
//
// // A walkableClimb higher than walkableHeight can cause issues when generating the navmesh since then it can in some cases
// // Both be valid for a character to walk under an obstacle and climb up on top of it (and that cannot be handled with navmesh without links)
// // The editor scripts also enforce this but we enforce it here too just to be sure
// walkableClimb = Mathf.Min(walkableClimb, walkableHeight);
//
// yield return new Progress(0, "Finding Meshes");
// var bounds = transform.Transform(new Bounds(forcedBoundsSize*0.5f, forcedBoundsSize));
// var meshes = CollectMeshes(bounds);
// var buckets = PutMeshesIntoTileBuckets(meshes);
//
// Queue<Int2> tileQueue = new Queue<Int2>();
//
// // Put all tiles in the queue
// for (int z = 0; z < tileZCount; z++) {
// for (int x = 0; x < tileXCount; x++) {
// tileQueue.Enqueue(new Int2(x, z));
// }
// }
//
// var workQueue = new ParallelWorkQueue<Int2>(tileQueue);
// // Create the voxelizers and set all settings (one for each thread)
// var voxelizers = new Voxelize[workQueue.threadCount];
// for (int i = 0; i < voxelizers.Length; i++) voxelizers[i] = new Voxelize(CellHeight, cellSize, walkableClimb, walkableHeight, maxSlope, maxEdgeLength);
// workQueue.action = (tile, threadIndex) => {
// voxelizers[threadIndex].inputMeshes = buckets[tile.x + tile.y*tileXCount];
// tiles[tile.x + tile.y*tileXCount] = BuildTileMesh(voxelizers[threadIndex], tile.x, tile.y, threadIndex);
// };
//
// // Prioritize responsiveness while playing
// // but when not playing prioritize throughput
// // (the Unity progress bar is also pretty slow to update)
// int timeoutMillis = Application.isPlaying ? 1 : 200;
//
// // Scan all tiles in parallel
// foreach (var done in workQueue.Run(timeoutMillis)) {
// yield return new Progress(Mathf.Lerp(0.1f, 0.9f, done / (float)tiles.Length), "Calculated Tiles: " + done + "/" + tiles.Length);
// }
//
// yield return new Progress(0.9f, "Assigning Graph Indices");
//
// // Assign graph index to nodes
// uint graphIndex = (uint)AstarPath.active.data.GetGraphIndex(this);
//
// GetNodes(node => node.GraphIndex = graphIndex);
//
// // First connect all tiles with an EVEN coordinate sum
// // This would be the white squares on a chess board.
// // Then connect all tiles with an ODD coordinate sum (which would be all black squares on a chess board).
// // This will prevent the different threads that do all
// // this in parallel from conflicting with each other.
// // The directions are also done separately
// // first they are connected along the X direction and then along the Z direction.
// // Looping over 0 and then 1
// for (int coordinateSum = 0; coordinateSum <= 1; coordinateSum++) {
// for (int direction = 0; direction <= 1; direction++) {
// for (int i = 0; i < tiles.Length; i++) {
// if ((tiles[i].x + tiles[i].z) % 2 == coordinateSum) {
// tileQueue.Enqueue(new Int2(tiles[i].x, tiles[i].z));
// }
// }
//
// workQueue = new ParallelWorkQueue<Int2>(tileQueue);
// workQueue.action = (tile, threadIndex) => {
// // Connect with tile at (x+1,z) and (x,z+1)
// if (direction == 0 && tile.x < tileXCount - 1)
// ConnectTiles(tiles[tile.x + tile.y * tileXCount], tiles[tile.x + 1 + tile.y * tileXCount]);
// if (direction == 1 && tile.y < tileZCount - 1)
// ConnectTiles(tiles[tile.x + tile.y * tileXCount], tiles[tile.x + (tile.y + 1) * tileXCount]);
// };
//
// var numTilesInQueue = tileQueue.Count;
// // Connect all tiles in parallel
// foreach (var done in workQueue.Run(timeoutMillis)) {
// yield return new Progress(0.95f, "Connected Tiles " + (numTilesInQueue - done) + "/" + numTilesInQueue + " (Phase " + (direction + 1 + 2*coordinateSum) + " of 4)");
// }
// }
// }
//
// for (int i = 0; i < meshes.Count; i++) meshes[i].Pool();
// ListPool<RasterizationMesh>.Release(ref meshes);
//
// // Signal that tiles have been recalculated to the navmesh cutting system.
// navmeshUpdateData.OnRecalculatedTiles(tiles);
// if (OnRecalculatedTiles != null) OnRecalculatedTiles(tiles.Clone() as NavmeshTile[]);
// }
}
}

View File

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: ad9082d87a694dc7bac28df204c9e562
timeCreated: 1708236704

View File

@ -1,10 +1,97 @@
using Game.Plugins.JNGame.Sync.Frame.AStar.Util;
using System;
using Game.Plugins.JNGame.Sync.Frame.AStar.Util;
using UnityEngine;
using Object = UnityEngine.Object;
namespace Plugins.JNGame.Sync.Frame.AStar.Entity
{
/// <summary>
/// 表示与其他节点的连接
/// </summary>
public struct Connection {
/// <summary>
/// 该连接所指向的节点
/// </summary>
public GraphNode node;
/// <summary>
/// 沿此连接移动的成本。
/// 成本为1000大约对应于移动一个世界单位的成本。
/// </summary>
public uint cost;
/// <summary>
/// 该连接所使用的节点形状的边。
/// 用于网格节点。
/// 值为0表示使用节点上的顶点0和顶点1的边。1表示顶点1和2的边以此类推。
/// 如果值为<see cref="NoSharedEdge"/>,则表示此连接不使用任何边(这主要用于网格外的链接)。
///
/// 注意:由于对齐,<see cref="node"/>和<see cref="cost"/>字段使用12个字节当在数组中使用时即使移除此字段也会填充到16个字节。
/// 因此,此字段不会增加内存使用量。
///
/// 请参阅TriangleMeshNode
/// 请参阅TriangleMeshNode.AddConnection
/// </summary>
public byte shapeEdge;
/// <summary>
/// 表示连接不使用任何边的常量值
/// </summary>
public const byte NoSharedEdge = 0xFF;
/// <summary>
/// Connection结构体的构造函数
/// </summary>
/// <param name="node">连接的节点</param>
/// <param name="cost">连接的成本</param>
/// <param name="shapeEdge">节点形状的边默认为NoSharedEdge</param>
public Connection(GraphNode node, uint cost, byte shapeEdge = NoSharedEdge) {
this.node = node;
this.cost = cost;
this.shapeEdge = shapeEdge;
}
/// <summary>
/// 重写GetHashCode方法以基于node和cost生成此连接的唯一哈希码
/// </summary>
/// <returns>此连接的哈希码</returns>
public override int GetHashCode() {
return node.GetHashCode() ^ (int)cost;
}
/// <summary>
/// 重写Equals方法以基于node、cost和shapeEdge比较此连接与另一个对象是否相等
/// </summary>
/// <param name="obj">要比较的另一个对象</param>
/// <returns>如果相等则返回true否则返回false</returns>
public override bool Equals(object obj) {
if (obj == null) return false;
var conn = (Connection)obj;
return conn.node == node && conn.cost == cost && conn.shapeEdge == shapeEdge;
}
}
public abstract class GraphNode
{
private JNAStarPath astar;
/// <summary>图形索引位的开始位置。参见:<see cref="GraphIndex"/></summary>
const int FlagsGraphOffset = 24;
/// <summary>图形索引位的掩码。参见:<see cref="GraphIndex"/></summary>
const uint FlagsGraphMask = (256u-1) << FlagsGraphOffset;
/// <summary>最大图形数量减一</summary>
public const uint MaxGraphIndex = FlagsGraphMask >> FlagsGraphOffset;
/// <summary>Start of <see cref="IsHierarchicalNodeDirty"/> bits. See: <see cref="IsHierarchicalNodeDirty"/></summary>
const int HierarchicalDirtyOffset = 18;
/// <summary>
/// <see cref="IsHierarchicalNodeDirty"/>位的掩码。
/// 参见:<see cref="IsHierarchicalNodeDirty"/>
/// </summary>
const uint HierarchicalDirtyMask = 1 << HierarchicalDirtyOffset;
/// <summary>
/// 内部唯一索引。同时存储一些位打包的值,如<see cref="TemporaryFlag1"/>和<see cref="TemporaryFlag2"/>。
@ -51,6 +138,32 @@ namespace Plugins.JNGame.Sync.Frame.AStar.Entity
// 如果结果是非零值那么TemporaryFlag2就被设置了否则它未被设置
const int TemporaryFlag2Mask = 0x20000000;
public bool Destroyed {
get {
return NodeIndex == DestroyedNodeIndex;
}
}
/// <summary>
/// 内部簿记。用于标记层次化节点是否已更改。
/// </summary>
internal bool IsHierarchicalNodeDirty {
// 获取IsHierarchicalNodeDirty属性的值
get {
// 使用位运算检查flags变量中是否设置了HierarchicalDirtyMask位掩码
// 如果设置了该位掩码则IsHierarchicalNodeDirty为true否则为false
return (flags & HierarchicalDirtyMask) != 0;
}
// 设置IsHierarchicalNodeDirty属性的值
set {
// 如果value为true则将flags变量的HierarchicalDirtyOffset位置为1
// 如果value为false则将flags变量的HierarchicalDirtyOffset位置为0
// 使用位运算实现上述操作
flags = flags & ~HierarchicalDirtyMask | (value ? 1U : 0U) << HierarchicalDirtyOffset;
}
}
/// <summary>
/// 内部唯一索引。
/// 每个节点都会获得一个唯一索引。
@ -62,13 +175,92 @@ namespace Plugins.JNGame.Sync.Frame.AStar.Entity
private set { nodeIndex = (nodeIndex & ~NodeIndexMask) | value; }
}
/// <summary>
/// 图形节点的构造函数。
/// </summary>
/// <param name="astar">AstarPath实例提供路径寻找功能。</param>
protected GraphNode(JNAStarPath astar)
{
this.astar = astar;
// 检查传入的AstarPath对象是否为null
if (!Object.ReferenceEquals(astar, null)) {
// 如果不是null则获取一个新的节点索引并将其赋值给当前节点的nodeIndex属性
this.nodeIndex = astar.GetNewNodeIndex();
// 使用AstarPath对象初始化当前节点
astar.InitializeNode(this);
} else {
// 如果AstarPath对象是null则抛出异常说明没有可绑定的活动AstarPath对象
throw new Exception("No active AstarPath object to bind to");
}
}
/// <summary>
/// 这个节点表面上距离点p最近的点
/// </summary>
/// <param name="p">给定的点</param>
/// <returns>返回节点表面上距离点p最近的点的坐标</returns>
public abstract Vector3 ClosestPointOnNode(Vector3 p);
/// <summary>
/// 从此节点移除所有连接。
/// </summary>
/// <param name="alsoReverse">
/// 如果为true将请求邻居节点也移除到此节点的连接。
/// </param>
public abstract void ClearConnections(bool alsoReverse);
/// <summary>
/// 销毁节点。
/// 清理用于此节点的任何临时路径查找数据。
/// 当节点被销毁时,图形应负责调用此方法,包括当整个图形被销毁时。
/// 否则可能会出现内存泄漏。
///
/// 一旦调用,<see cref="Destroyed"/> 属性将返回 true后续对此方法的调用将不执行任何操作。
///
/// 注意:假设当前活动的 AstarPath 实例是创建此节点的同一个实例。
///
/// 警告:只有图形类应该在其自己的节点上调用此方法
/// </summary>
public void Destroy () {
// 如果节点已经被销毁,则直接返回,不执行后续操作
if (Destroyed) return;
// 清除节点的所有连接
ClearConnections(true);
// 如果存在活动的 AstarPath 实例,则调用其 DestroyNode 方法销毁此节点
// if (AstarPath.active != null) {
// AstarPath.active.DestroyNode(this);
// }
// 将节点的索引设置为已销毁节点的索引,可能用于内部跟踪或管理
NodeIndex = DestroyedNodeIndex;
}
}
/// <summary>
/// 表示网格节点的抽象类继承自GraphNode类。
/// </summary>
public abstract class MeshNode : GraphNode {
/// <summary>
/// MeshNode类的受保护构造函数调用基类GraphNode的构造函数。
/// </summary>
/// <param name="astar">AstarPath实例提供路径寻找功能。</param>
protected MeshNode(JNAStarPath astar) : base(astar) {
}
/// <summary>
/// 从此节点出发的所有连接。
/// 请参阅:<see cref="AddConnection"/>(添加连接)
/// 请参阅:<see cref="RemoveConnection"/>(移除连接)
///
/// 注意:如果你修改此数组或其内容,你必须调用<see cref="SetConnectivityDirty"/>(设置连接性为脏)。
///
/// 如果节点没有连接则可能为null。
/// </summary>
public Connection[] connections;
}
}

View File

@ -1,4 +1,5 @@
using Game.Plugins.JNGame.Sync.Frame.AStar.Util;
using System;
using Game.Plugins.JNGame.Sync.Frame.AStar.Util;
namespace Plugins.JNGame.Sync.Frame.AStar.Entity
{
@ -161,5 +162,44 @@ namespace Plugins.JNGame.Sync.Frame.AStar.Entity
return nodes[node.NodeIndex];
}
/// <summary>
/// 内部方法,用于初始化节点数据
/// </summary>
public void InitializeNode(GraphNode node)
{
// 获取节点的索引
//Get the index of the node
int ind = node.NodeIndex;
// 如果索引大于或等于当前nodes数组的长度
if (ind >= nodes.Length)
{
// 则扩大数组的长度扩大倍数为2
// Grow by a factor of 2
PathNode[] newNodes = new PathNode[Math.Max(128, nodes.Length * 2)];
// 将旧的nodes数组中的数据复制到新的newNodes数组中
nodes.CopyTo(newNodes, 0);
// 初始化newNodes数组中新增的部分
// 这样做很重要我们不应该留下NULL的入口然后延迟初始化它们
// 通过一次性分配所有PathNode实例我们更有可能将它们分配在内存中的相邻位置
// 大多数系统使用某种形式的bump-allocator这可以提高缓存局部性并减少错误的共享
// 如果我们将不同线程的PathNodes分配在相邻位置就会发生这种情况
// 据分析这样做可以提高大约4%的总体路径查找性能
// Initialize all PathNode instances at once
for (int i = nodes.Length; i < newNodes.Length; i++)
{
newNodes[i] = new PathNode();
}
// 更新nodes数组引用使其指向新的newNodes数组
nodes = newNodes;
}
// 将传入的node赋值给nodes数组中对应索引位置的node属性
nodes[ind].node = node;
}
}
}

View File

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 3eda45f5495f42788c698c76f2b8331e
timeCreated: 1708245174

View File

@ -0,0 +1,33 @@
using Game.Plugins.JNGame.Sync.Frame.AStar.Navmesh;
using Game.Plugins.JNGame.Sync.Frame.AStar.Util;
namespace Plugins.JNGame.Sync.Frame.AStar.Entity.Tile
{
/// <summary>
/// 基于三角形的导航网格的接口
/// </summary>
public interface INavmeshHolder : ITransformedGraph, INavmesh {
/// <summary>
/// 顶点i在世界坐标系中的位置
/// </summary>
Int3 GetVertex(int i);
/// <summary>
/// 顶点i在图坐标系中的位置。
/// 对于这些坐标,向上的方向始终是+Y轴。
/// </summary>
Int3 GetVertexInGraphSpace(int i);
/// <summary>
/// 获取顶点数组的索引
/// </summary>
int GetVertexArrayIndex(int index);
/// <summary>
/// 将坐标从图空间转换为世界空间
/// </summary>
void GetTileCoordinates(int tileIndex, out int x, out int z);
}
}

View File

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 6fcd692c2ea04216b9096a49a7647a12
timeCreated: 1708245186

View File

@ -0,0 +1,100 @@
using System;
using Game.Plugins.JNGame.Sync.Frame.AStar.Entity.Graph;
using Game.Plugins.JNGame.Sync.Frame.AStar.Navmesh;
using Game.Plugins.JNGame.Sync.Frame.AStar.Util;
using NotImplementedException = System.NotImplementedException;
namespace Plugins.JNGame.Sync.Frame.AStar.Entity.Tile
{
public class NavmeshTile : INavmeshHolder
{
/// <summary>瓦片三角形</summary>
/// 这是一个包含瓦片所有三角形的数组
public int[] tris;
/// <summary>瓦片顶点</summary>
/// 这是一个包含瓦片所有顶点的数组
public Int3[] verts;
/// <summary>图空间中的瓦片顶点</summary>
/// 这是一个包含在图空间中定义的瓦片顶点的数组
public Int3[] vertsInGraphSpace;
/// <summary>瓦片X坐标</summary>
/// 这表示瓦片在X轴上的位置
public int x;
/// <summary>瓦片Z坐标</summary>
/// 这表示瓦片在Z轴上的位置
public int z;
/// <summary>
/// 瓦片坐标中的宽度。
/// 警告除了1以外的宽度不受支持。这主要是为了未来可能的功能。
/// </summary>
/// 这表示瓦片在X轴上的宽度但请注意目前只支持宽度为1的瓦片
public int w;
/// <summary>
/// 瓦片坐标中的深度。
/// 警告除了1以外的深度不受支持。这主要是为了未来可能的功能。
/// </summary>
/// 这表示瓦片在Z轴上的深度但请注意目前只支持深度为1的瓦片
public int d;
/// <summary>瓦片中的所有节点</summary>
/// 这是一个包含瓦片中所有节点的数组
public TriangleMeshNode[] nodes;
/// <summary>用于节点查找的边界框树</summary>
/// 这是一个边界框树BBTree用于高效地查找和定位瓦片中的节点
public BBTree bbTree;
/// <summary>用于批处理的临时标志</summary>
/// 这是一个布尔值,可能用于在批处理过程中标记或跟踪某些状态
public bool flag;
// 这是一个指向NavmeshBase对象的引用可能表示瓦片所属的导航网格
public NavmeshBase graph;
// 获取瓦片Tile的坐标
public void GetTileCoordinates(int tileIndex, out int x, out int z) {
x = this.x; // 返回当前对象的x坐标
z = this.z; // 返回当前对象的z坐标
}
// 获取顶点数组的索引
public int GetVertexArrayIndex(int index) {
return index & NavmeshBase.VertexIndexMask; // 返回index与NavmeshBase.VertexIndexMask的按位与结果
}
/// <summary>获取瓦片中的特定顶点</summary>
// 获取特定索引的顶点
public Int3 GetVertex(int index) {
int idx = index & NavmeshBase.VertexIndexMask; // 计算索引的按位与结果
return verts[idx]; // 返回顶点数组在idx位置的元素
}
// 获取图空间中的顶点
public Int3 GetVertexInGraphSpace(int index) {
return vertsInGraphSpace[index & NavmeshBase.VertexIndexMask]; // 返回图空间顶点数组在指定索引位置的元素
}
/// <summary>将坐标从图空间转换为世界空间</summary>
// 获取图到世界的转换
public GraphTransform transform {
get {
return graph.transform; // 返回图的转换对象
}
}
// 获取所有的节点,并对每个节点执行给定的动作
public void GetNodes(Action<GraphNode> action)
{
if (nodes == null) return; // 如果节点为空,则直接返回
for (int i = 0; i < nodes.Length; i++) action(nodes[i]); // 遍历节点数组,对每个节点执行给定的动作
}
}
}

View File

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: a30c721add504a2abcee3b8b8ff19889
timeCreated: 1708245174

View File

@ -1,11 +1,55 @@
using System;
using System.Collections.Generic;
using Game.Plugins.JNGame.Sync.Frame.AStar.Util;
using Plugins.JNGame.Sync.Frame.AStar.Entity;
using UnityEngine;
using Object = System.Object;
namespace Plugins.JNGame.Sync.Frame.AStar
{
public delegate void OnPathDelegate(JNPath p);
// public delegate void OnGraphDelegate(NavGraph graph);
// public delegate void OnScanDelegate(AstarPath script);
public delegate void OnScanDelegate(JNAStarPath script);
/// <summary>
/// 具有从图空间到世界空间明确定义的变换的图
/// </summary>
public interface ITransformedGraph {
/// <summary>
/// 获取图的变换信息
/// </summary>
GraphTransform transform { get; }
}
// /// <summary>Graph which supports the Linecast method</summary>
// public interface IRaycastableGraph {
// /// <summary>
// /// Checks if the straight line of sight between the two points on the graph is obstructed.
// ///
// /// Returns: True if an obstacle was hit, and false otherwise.
// /// </summary>
// /// <param name="start">The start point of the raycast.</param>
// /// <param name="end">The end point of the raycast.</param>
// bool Linecast(Vector3 start, Vector3 end);
// /// <summary>Deprecated:</summary>
// bool Linecast(Vector3 start, Vector3 end, GraphNode hint);
// /// <summary>Deprecated:</summary>
// bool Linecast(Vector3 start, Vector3 end, GraphNode hint, out GraphHitInfo hit);
// /// <summary>Deprecated:</summary>
// bool Linecast(Vector3 start, Vector3 end, GraphNode hint, out GraphHitInfo hit, List<GraphNode> trace);
// /// <summary>
// /// Checks if the straight line of sight between the two points on the graph is obstructed.
// ///
// /// Returns: True if an obstacle was hit, and false otherwise.
// /// </summary>
// /// <param name="start">The start point of the raycast.</param>
// /// <param name="end">The end point of the raycast.</param>
// /// <param name="hit">Additional information about what was hit.</param>
// /// <param name="trace">If you supply a list, it will be filled with all nodes that the linecast traversed. You may pass null if you don't care about this.</param>
// /// <param name="filter">You may supply a callback to indicate which nodes should be considered unwalkable. Note that already unwalkable nodes cannot be made walkable in this way.</param>
// bool Linecast(Vector3 start, Vector3 end, out GraphHitInfo hit, List<GraphNode> trace = null, System.Func<GraphNode, bool> filter = null);
// }
/// <summary>
/// 持有图形的位掩码。
@ -178,15 +222,15 @@ namespace Plugins.JNGame.Sync.Frame.AStar
/// </summary>
public class PathNNConstraint : NNConstraint {
// 定义了一个静态的默认PathNNConstraint实例该实例在创建时默认将constrainArea设置为true
public static new PathNNConstraint Default {
get {
return new PathNNConstraint {
constrainArea = true
};
}
}
// // 定义了一个静态的默认PathNNConstraint实例该实例在创建时默认将constrainArea设置为true
// public static new PathNNConstraint Default {
// get {
// return new PathNNConstraint {
// constrainArea = true
// };
// }
// }
//
// /// <summary>在找到起始节点后被调用。这用于在路径中的起始节点和结束节点使用不同的搜索逻辑</summary>
// /// <param name="node">找到的起始节点</param>
// public virtual void SetStart (GraphNode node) {
@ -229,6 +273,155 @@ namespace Plugins.JNGame.Sync.Frame.AStar
Partial = 3,
}
/// <summary>
/// Integer Rectangle.
/// Uses an inclusive coordinate range.
///
/// Works almost like UnityEngine.Rect but with integer coordinates
/// </summary>
[Serializable]
public struct IntRect {
public int xmin, ymin, xmax, ymax;
public IntRect (int xmin, int ymin, int xmax, int ymax) {
this.xmin = xmin;
this.xmax = xmax;
this.ymin = ymin;
this.ymax = ymax;
}
public bool Contains (int x, int y) {
return !(x < xmin || y < ymin || x > xmax || y > ymax);
}
public Int2 Min {
get {
return new Int2(xmin, ymin);
}
}
public Int2 Max {
get {
return new Int2(xmax, ymax);
}
}
public int Width {
get {
return xmax-xmin+1;
}
}
public int Height {
get {
return ymax-ymin+1;
}
}
public int Area {
get {
return Width * Height;
}
}
/// <summary>
/// Returns if this rectangle is valid.
/// An invalid rect could have e.g xmin > xmax.
/// Rectamgles with a zero area area invalid.
/// </summary>
public bool IsValid () {
return xmin <= xmax && ymin <= ymax;
}
public static bool operator == (IntRect a, IntRect b) {
return a.xmin == b.xmin && a.xmax == b.xmax && a.ymin == b.ymin && a.ymax == b.ymax;
}
public static bool operator != (IntRect a, IntRect b) {
return a.xmin != b.xmin || a.xmax != b.xmax || a.ymin != b.ymin || a.ymax != b.ymax;
}
public override bool Equals (Object obj) {
var rect = (IntRect)obj;
return xmin == rect.xmin && xmax == rect.xmax && ymin == rect.ymin && ymax == rect.ymax;
}
public override int GetHashCode () {
return xmin*131071 ^ xmax*3571 ^ ymin*3109 ^ ymax*7;
}
/// <summary>
/// Returns the intersection rect between the two rects.
/// The intersection rect is the area which is inside both rects.
/// If the rects do not have an intersection, an invalid rect is returned.
/// See: IsValid
/// </summary>
public static IntRect Intersection (IntRect a, IntRect b) {
return new IntRect(
Math.Max(a.xmin, b.xmin),
Math.Max(a.ymin, b.ymin),
Math.Min(a.xmax, b.xmax),
Math.Min(a.ymax, b.ymax)
);
}
/// <summary>Returns if the two rectangles intersect each other</summary>
public static bool Intersects (IntRect a, IntRect b) {
return !(a.xmin > b.xmax || a.ymin > b.ymax || a.xmax < b.xmin || a.ymax < b.ymin);
}
/// <summary>
/// Returns a new rect which contains both input rects.
/// This rectangle may contain areas outside both input rects as well in some cases.
/// </summary>
public static IntRect Union (IntRect a, IntRect b) {
return new IntRect(
Math.Min(a.xmin, b.xmin),
Math.Min(a.ymin, b.ymin),
Math.Max(a.xmax, b.xmax),
Math.Max(a.ymax, b.ymax)
);
}
/// <summary>Returns a new IntRect which is expanded to contain the point</summary>
public IntRect ExpandToContain (int x, int y) {
return new IntRect(
Math.Min(xmin, x),
Math.Min(ymin, y),
Math.Max(xmax, x),
Math.Max(ymax, y)
);
}
/// <summary>Returns a new rect which is expanded by range in all directions.</summary>
/// <param name="range">How far to expand. Negative values are permitted.</param>
public IntRect Expand (int range) {
return new IntRect(xmin-range,
ymin-range,
xmax+range,
ymax+range
);
}
public override string ToString () {
return "[x: "+xmin+"..."+xmax+", y: " + ymin +"..."+ymax+"]";
}
/// <summary>Draws some debug lines representing the rect</summary>
public void DebugDraw (GraphTransform transform, Color color) {
Vector3 p1 = transform.Transform(new Vector3(xmin, 0, ymin));
Vector3 p2 = transform.Transform(new Vector3(xmin, 0, ymax));
Vector3 p3 = transform.Transform(new Vector3(xmax, 0, ymax));
Vector3 p4 = transform.Transform(new Vector3(xmax, 0, ymin));
Debug.DrawLine(p1, p2, color);
Debug.DrawLine(p2, p3, color);
Debug.DrawLine(p3, p4, color);
Debug.DrawLine(p4, p1, color);
}
}
/// <summary>
/// 路径在管道中的内部状态
/// </summary>

View File

@ -1,5 +1,6 @@
using System;
using Game.Plugins.JNGame.Sync.Frame.AStar.Navmesh;
using Game.Plugins.JNGame.Sync.Frame.AStar.Util.Graph;
using Plugins.JNGame.Sync.Frame.AStar.Entity;
using Plugins.JNGame.Sync.Frame.AStar.Processor;
using UnityEngine;
@ -18,10 +19,10 @@ namespace Plugins.JNGame.Sync.Frame.AStar
/// <summary>
/// 导航数据
/// </summary>
public AStarData data = new AStarData();
public AStarData data;
/// 网格数据
public NavGraph[] graphs => data.graphs;
public NavGraph[] graphs => data.graphs.ToArray();
/// <summary>保存所有已完成的路径,等待返回至请求它们的地方</summary>
internal readonly PathReturnQueue pathReturnQueue;
@ -44,16 +45,45 @@ namespace Plugins.JNGame.Sync.Frame.AStar
/// 在搜索每个路径之后调用。当使用多线程时要小心,因为这将从不同的线程调用。
/// </summary>
public static OnPathDelegate OnPathPostSearch;
/// <summary>
/// 在开始扫描之前调用
/// </summary>
///
public OnScanDelegate OnPreScan;
/// <summary>
/// 扫描后调用。这会在应用链接、洪水填充图形和其他后期处理之前被调用。
/// </summary>
public static OnScanDelegate OnPostScan;
/// <summary>
/// 存储一个层次化图以加速某些查询,例如判断两个节点之间是否存在路径
/// </summary>
internal readonly HierarchicalGraph hierarchicalGraph = new HierarchicalGraph();
/// <summary>
/// 返回一个新的全局节点索引。
/// 警告此方法不应直接调用。它仅由GraphNode构造函数使用。
/// </summary>
internal int GetNewNodeIndex() {
// 调用pathProcessor对象的GetNewNodeIndex方法获取一个新的全局节点索引
return pathProcessor.GetNewNodeIndex();
}
public JNAStarPath()
public JNAStarPath(AStarData data)
{
//寻路数据
this.data = data;
pathReturnQueue = new PathReturnQueue(this);;
navmeshUpdates = new NavmeshUpdates(this);
graphUpdates = new GraphUpdateProcessor(this);
//初始化
Init();
}
/// <summary>
@ -76,9 +106,6 @@ namespace Plugins.JNGame.Sync.Frame.AStar
// // 返回计算出的路径
// pathReturnQueue.ReturnPaths(true);
//初始化
Init();
}
/// <summary>
@ -103,19 +130,101 @@ namespace Plugins.JNGame.Sync.Frame.AStar
// 初始化A*数据
InitializeAstarData();
// 刷新工作项这些工作项可能在InitializeAstarData中用于加载图形数据
FlushWorkItems();
// 标记euclideanEmbedding为需要更新
euclideanEmbedding.dirty = true;
// // 刷新工作项这些工作项可能在InitializeAstarData中用于加载图形数据
// FlushWorkItems();
//
// // 标记euclideanEmbedding为需要更新
// euclideanEmbedding.dirty = true;
//
// 启用导航网格更新
navmeshUpdates.OnEnable();
// 如果在启动时扫描且缓存未启用或缓存文件为空,则执行扫描
if (scanOnStartup && (!data.cacheStartup || data.file_cachedStartup == null)) {
Scan();
}
// 如果在启动时扫描且缓存未启用或缓存文件为空,则执行扫描(因为没有缓存所以直接扫描)
Scan();
}
/// <summary>
/// 扫描所有指定的图。
///
/// 调用此方法将重新计算所有指定的图或者如果graphsToScan参数为null则重新计算所有图。
/// 此方法的速度相对较慢(当然取决于图的类型和复杂性),因此建议在可能的情况下使用更小的图更新。 var graphToScan = AstarPath.active.data.gridGraph;
/// AstarPath.active.Scan(graphToScan);
///
/// // 仅重新计算第一个和第三个图
/// var graphsToScan = new [] { AstarPath.active.data.graphs[0], AstarPath.active.data.graphs[2] };
/// AstarPath.active.Scan(graphsToScan);
/// </code>
///
/// 请参阅graph-updates请在线文档中查看工作链接
/// 请参阅ScanAsync
/// </summary>
/// <param name="graphsToScan">要扫描的图。如果此参数为null则将扫描所有图</param>
public void Scan (NavGraph[] graphsToScan = null) {
Debug.Log("初始化导航图");
if (graphsToScan == null) graphsToScan = graphs;
if (graphsToScan == null || graphsToScan.Length <= 0)
{
Debug.LogError("初始化失败 没有导航图");
return;
}
//开始扫描
if (OnPreScan != null) {
OnPreScan(this);
}
Physics2D.SyncTransforms();
// 销毁之前的节点
for (int i = 0; i < graphsToScan.Length; i++) {
// 遍历graphsToScan数组中的每一个元素
if (graphsToScan[i] != null) {
// 如果当前元素不为null即存在图形对象
((IGraphInternals)graphsToScan[i]).DestroyAllNodes();
// 将当前图形对象强制转换为IGraphInternals接口并调用其DestroyAllNodes方法销毁所有节点
}
}
// 遍历所有的图并逐个进行扫描
for (int i = 0; i < graphsToScan.Length; i++) {
// 跳过为null的图
if (graphsToScan[i] == null) continue;
NavGraph graph = graphsToScan[i];
//直接扫描图形
((IGraphInternals)graph).ScanInternal();
// foreach (var p in ((IGraphInternals)graph).ScanInternal()) {
// yield return p.MapTo(0, 0.95f);
// }
// // 仅用于进度信息
// // 这个图将从minp推进到maxp的进度条
// float minp = Mathf.Lerp(0.1F, 0.8F, (float)(i)/(graphsToScan.Length));
// float maxp = Mathf.Lerp(0.1F, 0.8F, (float)(i+0.95F)/(graphsToScan.Length));
// 进度描述的前缀
// var progressDescriptionPrefix = "Scanning graph " + (i+1) + " of " + graphsToScan.Length + " - ";
// // 类似于foreach循环但由于异常处理在try-except块中不能使用yield所以稍微复杂一些
// var coroutine = ScanGraph(graphsToScan[i]).GetEnumerator();
//
// while (true) {
// try {
// if (!coroutine.MoveNext()) break;
// } catch {
// // 如果在扫描过程中发生异常,则停止扫描,解锁图结构,并释放图更新的锁
// isScanning = false;
// data.UnlockGraphStructure();
// graphUpdateLock.Release();
// throw; // 重新抛出捕获的异常
// }
// // 返回当前扫描的进度和描述
// yield return coroutine.Current.MapTo(minp, maxp, progressDescriptionPrefix);
// }
}
}
/// <summary>
@ -124,15 +233,16 @@ namespace Plugins.JNGame.Sync.Frame.AStar
///
/// 请参阅AstarData.FindGraphTypes
/// </summary>
void InitializeAstarData () {
// // 调用AstarData类的FindGraphTypes方法该方法负责搜索并识别可用的图类型。
// data.FindGraphTypes();
// 调用AstarData类的Awake方法该方法可能用于唤醒或初始化类的内部状态或资源。
data.Awake();
// 调用AstarData类的UpdateShortcuts方法该方法可能用于更新或创建图的快捷方式或优化路径。
data.UpdateShortcuts();
void InitializeAstarData () {
// // // 调用AstarData类的FindGraphTypes方法该方法负责搜索并识别可用的图类型。
// // data.FindGraphTypes();
//
// // 调用AstarData类的Awake方法该方法可能用于唤醒或初始化类的内部状态或资源。
// data.Awake();
//
// // 调用AstarData类的UpdateShortcuts方法该方法可能用于更新或创建图的快捷方式或优化路径。
// data.UpdateShortcuts();
}
/// <summary>
@ -252,5 +362,16 @@ namespace Plugins.JNGame.Sync.Frame.AStar
// }
}
/// <summary>
/// 初始化节点的临时路径数据。
/// 警告此方法不应直接调用。它仅由GraphNode构造函数使用。
/// </summary>
/// <param name="node">要初始化路径数据的节点</param>
internal void InitializeNode(GraphNode node) {
// 调用pathProcessor的InitializeNode方法将node作为参数传递
// 以初始化节点的临时路径数据
pathProcessor.InitializeNode(node);
}
}
}

View File

@ -7,7 +7,7 @@ namespace Game.Plugins.JNGame.Sync.Frame.AStar.Navmesh
private JNAStarPath AStar;
public event System.Action OnGraphsUpdated;
// public event System.Action OnGraphsUpdated;
public GraphUpdateProcessor(JNAStarPath aStar)
{

View File

@ -0,0 +1,9 @@
using System;
using Plugins.JNGame.Sync.Frame.AStar.Entity;
namespace Game.Plugins.JNGame.Sync.Frame.AStar.Navmesh
{
public interface INavmesh {
void GetNodes(Action<GraphNode> del);
}
}

View File

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 901fdfb7cace4dd0a55c7d4e3f5ff844
timeCreated: 1708246486

View File

@ -0,0 +1,22 @@
namespace Game.Plugins.JNGame.Sync.Frame.AStar.Navmesh
{
/// <summary>
/// NavmeshCut 和 NavmeshAdd 组件的基类
/// NavmeshCut 和 NavmeshAdd 组件可能是用于处理导航网格Navmesh的切割和添加操作的自定义组件。导航网格是Unity中用于AI寻路系统的一个关键组件
/// 它定义了角色可以在场景中移动的区域。通过切割和添加导航网格,开发者可以动态地改变这些区域,以适应游戏逻辑的需要。
/// </summary>
public class NavmeshClipper
{
/// <summary>
/// 每次启用NavmeshCut/NavmeshAdd组件时都会调用。
/// </summary>
static System.Action<NavmeshClipper> OnEnableCallback;
/// <summary>
/// 每次禁用NavmeshCut/NavmeshAdd组件时都会调用。
/// </summary>
static System.Action<NavmeshClipper> OnDisableCallback;
}
}

View File

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: f5f05d3c79f1457a9c7314989e300a7c
timeCreated: 1708242797

View File

@ -13,6 +13,11 @@ namespace Game.Plugins.JNGame.Sync.Frame.AStar.Navmesh
AStar = aStar;
}
internal void OnEnable () {
}
internal void OnDisable () {
}
}
}

View File

@ -0,0 +1,162 @@
using BepuUtilities;
using Plugins.JNGame.Sync.Frame.AStar;
using Plugins.JNGame.Sync.Frame.AStar.Entity;
using Plugins.JNGame.Sync.Frame.AStar.Entity.Tile;
using UnityEngine;
namespace Game.Plugins.JNGame.Sync.Frame.AStar.Navmesh
{
/// <summary>由三角形表示的节点</summary>
public class TriangleMeshNode : GraphNode
{
// /// <summary>使用AstarPath对象初始化TriangleMeshNode实例</summary>
// /// <param name="astar">AstarPath对象</param>
// public TriangleMeshNode(AstarPath astar) : base(astar) { }
/// <summary>第一个顶点的内部顶点索引</summary>
public int v0;
/// <summary>第二个顶点的内部顶点索引</summary>
public int v1;
/// <summary>第三个顶点的内部顶点索引</summary>
public int v2;
// /// <summary>
// /// 保存所有图索引的INavmeshHolder引用以便以高性能的方式访问它们
// /// </summary>
// protected static INavmeshHolder[] _navmeshHolders = new INavmeshHolder[0];
/// <summary>存储所有图形索引的INavmeshHolder引用以便以高性能的方式访问它们</summary>
/// <remarks>
/// 这个静态数组用于存储INavmeshHolder的引用其中每个索引对应一个图形。
/// 数组的大小可以动态调整以适应更多的图形索引。
/// </remarks>
protected static INavmeshHolder[] _navmeshHolders = new INavmeshHolder[0];
//
// /// <summary>用于同步访问<see cref="_navmeshHolders"/>数组的锁对象</summary>
// /// <remarks>
// /// 当多个线程尝试访问或修改_navmeshHolders数组时lockObject确保这些操作是线程安全的。
// /// </remarks>
// protected static readonly System.Object lockObject = new System.Object();
//
// /// <summary>
// /// 根据给定的图形索引获取内部的INavmeshHolder。
// /// </summary>
// /// <param name="graphIndex">图形索引</param>
// /// <returns>对应索引的INavmeshHolder对象</returns>
// public static INavmeshHolder GetNavmeshHolder(uint graphIndex)
// {
// return _navmeshHolders[(int)graphIndex];
// }
/// <summary>
/// 为给定的图形索引设置内部的INavmeshHolder。
/// 警告:这是一个内部方法。
/// </summary>
/// <param name="graphIndex">图形索引</param>
/// <param name="graph">INavmeshHolder对象</param>
/// <remarks>
/// 这个方法用于设置特定图形索引的INavmeshHolder。
/// 由于可能涉及数组大小的调整因此需要使用lockObject确保线程安全。
/// </remarks>
public static void SetNavmeshHolder(int graphIndex, INavmeshHolder graph)
{
if (graphIndex >= _navmeshHolders.Length)
{
// 如果graphIndex超出了当前数组的长度则扩展数组
var gg = new INavmeshHolder[graphIndex + 1];
_navmeshHolders.CopyTo(gg, 0);
_navmeshHolders = gg;
}
// 设置指定索引位置的INavmeshHolder
_navmeshHolders[graphIndex] = graph;
}
public static INavmeshHolder GetNavmeshHolder (uint graphIndex) {
return _navmeshHolders[(int)graphIndex];
}
// /// <summary>
// /// 返回此节点在世界空间中的所有3个顶点
// /// </summary>
// public void GetVertices (out Int3 v0, out Int3 v1, out Int3 v2) {
// // 获取保存此节点顶点数据的对象
// // 这通常是一个图或一个重新生成的图块
// var holder = GetNavmeshHolder(GraphIndex);
//
// v0 = holder.GetVertex(this.v0);
// v1 = holder.GetVertex(this.v1);
// v2 = holder.GetVertex(this.v2);
// }
// public override Vector3 ClosestPointOnNode(Vector3 p)
// {
// Int3 a, b, c;
//
// GetVertices(out a, out b, out c);
// return Pathfinding.Polygon.ClosestPointOnTriangle((Vector3)a, (Vector3)b, (Vector3)c, p);
// }
// /// <summary>
// /// 在图空间中,找到给定点在节点三角形上的最近点。
// /// </summary>
// /// <param name="p">给定的点。</param>
// /// <returns>在节点三角形上的最近点。</returns>
// internal Int3 ClosestPointOnNodeXZInGraphSpace(Vector3 p) {
// // 获取构成三角形的顶点
// Int3 a, b, c;
// GetVerticesInGraphSpace(out a, out b, out c);
//
// // 将点p转换为图空间
// p = GetNavmeshHolder(GraphIndex).transform.InverseTransform(p);
//
// // 从上方查看三角形时找到三角形上离点p最近的点
// var closest = Pathfinding.Polygon.ClosestPointOnTriangleXZ((Vector3)a, (Vector3)b, (Vector3)c, p);
//
// // 确保点实际上在节点内部
// var i3closest = (Int3)closest;
// if (ContainsPointInGraphSpace(i3closest)) {
// // 常规情况,最近点已经在节点内部
// return i3closest;
// } else {
// // 讨厌的情况...
// // 当从浮点坐标转换为整数坐标时,最近的点实际上不在节点内部。
// // 对于某些方法例如Linecast来说这个点需要在节点内部才能正常工作。
//
// // 尝试最近点周围的8个整数坐标
// // 并检查它们中的任何一个是否完全在节点内部。
// // 由于它应该非常接近,因此这很可能成功。
// for (int dx = -1; dx <= 1; dx++) {
// for (int dz = -1; dz <= 1; dz++) {
// if ((dx != 0 || dz != 0)) {
// var candidate = new Int3(i3closest.x + dx, i3closest.y, i3closest.z + dz);
// if (ContainsPointInGraphSpace(candidate)) return candidate;
// }
// }
// }
//
// // 很少发生的情况。
// // 选择三角形的最近顶点。
// // 顶点保证在三角形内部。
// var da = (a - i3closest).sqrMagnitudeLong;
// var db = (b - i3closest).sqrMagnitudeLong;
// var dc = (c - i3closest).sqrMagnitudeLong;
// return da < db ? (da < dc ? a : c) : (db < dc ? b : c);
// }
// }
public TriangleMeshNode(JNAStarPath astar) : base(astar)
{
}
public override Vector3 ClosestPointOnNode(Vector3 p)
{
throw new System.NotImplementedException();
}
public override void ClearConnections(bool alsoReverse)
{
throw new System.NotImplementedException();
}
}
}

View File

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 70948cd2a41546a1ba5e7e1661f88d3d
timeCreated: 1708246882

View File

@ -17,6 +17,8 @@ namespace Plugins.JNGame.Sync.Frame.AStar.Processor
public JNAStarPath AStar;
readonly PathReturnQueue returnQueue;
readonly PathHandler[] pathHandlers;
/// <summary>
/// (帧同步无法使用原始的多线程 IEnumerator 可以 所以去除了多线程代码)
@ -28,11 +30,53 @@ namespace Plugins.JNGame.Sync.Frame.AStar.Processor
/// 参见CalculatePathsHandler
/// </summary>
IEnumerator threadCoroutine;
/// <summary>
/// 保存下一个尚未被任何节点使用的节点索引。
/// 请参阅nodeIndexPool
/// </summary>
int nextNodeIndex = 1;
/// <summary>
/// 存储已被销毁的节点的索引。
/// 当节点频繁地被删除和创建时,为了避免破坏大量的内存结构,节点索引会被重新使用。
/// </summary>
readonly Stack<int> nodeIndexPool = new Stack<int>();
/// <summary>
/// 返回一个新的全局节点索引。
/// 警告此方法不应直接调用。它仅由GraphNode构造函数使用。
/// </summary>
public int GetNewNodeIndex() {
// 检查节点索引池nodeIndexPool中是否有可用的索引
// 如果有,则从池中弹出一个索引并返回
// 如果没有则增加下一个节点索引nextNodeIndex的值并返回
return nodeIndexPool.Count > 0 ? nodeIndexPool.Pop() : nextNodeIndex++;
}
/// <summary>
/// 初始化节点的临时路径数据。
/// 警告此方法不应直接调用。它仅由GraphNode构造函数使用。
/// </summary>
/// <param name="node">要初始化路径数据的节点</param>
public void InitializeNode(GraphNode node) {
// 遍历pathHandlers数组
for (int i = 0; i < pathHandlers.Length; i++) {
// 调用每个pathHandler的InitializeNode方法传入要初始化的节点
pathHandlers[i].InitializeNode(node);
}
// 调用hierarchicalGraph的OnCreatedNode方法通知它一个新的节点已被创建
AStar.hierarchicalGraph.OnCreatedNode(node);
}
public PathProcessor(JNAStarPath AStar, PathReturnQueue returnQueue)
{
this.AStar = this.AStar;
this.AStar = AStar;
threadCoroutine = CalculatePaths(new PathHandler());
}
@ -46,7 +90,7 @@ namespace Plugins.JNGame.Sync.Frame.AStar.Processor
IEnumerator CalculatePaths(PathHandler pathHandler)
{
// 允许的最大片数量
long maxTicks = 10;
// long maxTicks = 10;
while (true)
{
@ -69,8 +113,7 @@ namespace Plugins.JNGame.Sync.Frame.AStar.Processor
// 如果队列为空则设置blockedBefore为true
blockedBefore |= p == null;
}
catch (Exception e)
{
catch{
// 如果队列被终止,则退出循环
yield break;
}

View File

@ -332,7 +332,7 @@ namespace Game.Plugins.JNGame.Sync.Frame.AstarPath.RVO
{
return; // 直接返回,不进行速度计算
}
if (locked) // 如果代理被锁定
{
calculatedSpeed = 0; // 速度设置为0

View File

@ -301,20 +301,21 @@ namespace Game.Plugins.JNGame.Sync.Frame.AstarPath.RVO
private WorkerContext context = new WorkerContext();
/// <summary>
/// Inverse desired simulation fps.
/// See: DesiredDeltaTime
/// </summary>
private float desiredDeltaTime = 0.03f;
/// <summary>
/// Time in seconds between each simulation step.
/// This is the desired delta time, the simulation will never run at a higher fps than
/// the rate at which the Update function is called.
/// </summary>
public float DesiredDeltaTime { get { return desiredDeltaTime; } set { desiredDeltaTime = Math.Max(value, 0.0f); } }
/// <summary>
/// 所需的模拟帧率的倒数。
/// 请参见DesiredDeltaTime
/// </summary>
private float desiredDeltaTime = 0.03f;
/// <summary>
/// 每次模拟步骤之间的时间(以秒为单位)。
/// 这是期望的Delta时间模拟的帧率永远不会高于Update函数被调用的速率。
/// </summary>
public float DesiredDeltaTime
{
get { return desiredDeltaTime; }
set { desiredDeltaTime = Math.Max(value, 0.0f); }
}
/// <summary>
/// 使代理在彼此之间通过右侧。
@ -414,6 +415,172 @@ namespace Game.Plugins.JNGame.Sync.Frame.AstarPath.RVO
return agent; // 返回添加的代理对象
}
/// <summary>
/// 将之前移除的障碍物重新添加到模拟中。
/// 此方法不会检查障碍物是否已经被添加到模拟中,因此请确保不要多次添加同一个障碍物。
/// 假设这是一个有效的障碍物。
/// </summary>
/// <param name="v">要添加的障碍物顶点。</param>
/// <returns>返回添加的障碍物顶点。</returns>
/// <exception cref="System.ArgumentNullException">如果传入的障碍物顶点为 null则抛出此异常。</exception>
public JNObstacleVertex AddObstacle(JNObstacleVertex v)
{
// 如果传入的障碍物顶点为 null则抛出一个 ArgumentNullException 异常,
// 异常消息指出障碍物不能为空。
if (v == null) throw new System.ArgumentNullException("Obstacle must not be null");
// 将障碍物顶点添加到 obstacles 集合中。
obstacles.Add(v);
UpdateObstacles();
// 返回添加的障碍物顶点。
return v;
}
/// <summary>
/// 根据顶点数组添加障碍物。
///
/// 请注意,此方法与 RemoveObstacle 方法相关,用于在模拟中添加和移除障碍物。
/// </summary>
/// <param name="vertices">描述障碍物的顶点数组。</param>
/// <param name="height">障碍物的高度。</param>
/// <param name="matrix">用于转换顶点坐标的4x4矩阵。</param>
/// <param name="layer">障碍物所在的RVO层默认为DefaultObstacle层。</param>
/// <param name="cycle">是否将障碍物的顶点连接成循环链表默认为true。</param>
/// <returns>返回添加的障碍物的第一个顶点。</returns>
/// <exception cref="System.ArgumentNullException">如果传入的顶点数组为null则抛出此异常。</exception>
/// <exception cref="System.ArgumentException">如果顶点数组中的顶点数量少于2个则抛出此异常。</exception>
///
public JNObstacleVertex AddObstacle(Vector3[] vertices, float height, Matrix4x4 matrix, JNRVOLayer layer = JNRVOLayer.DefaultObstacle, bool cycle = true)
{
// 如果传入的顶点数组为null则抛出ArgumentNullException异常。
if (vertices == null) throw new System.ArgumentNullException("Vertices must not be null");
// 如果顶点数组中的顶点数量少于2个则抛出ArgumentException异常。
if (vertices.Length < 2) throw new System.ArgumentException("Less than 2 vertices in an obstacle");
JNObstacleVertex first = null; // 障碍物的第一个顶点
JNObstacleVertex prev = null; // 前一个顶点,用于构建顶点链表
// 遍历顶点数组为每个顶点创建一个ObstacleVertex对象并构建顶点之间的链表关系。
for (int i = 0; i < vertices.Length; i++)
{
var v = new JNObstacleVertex
{
prev = prev, // 前一个顶点
layer = layer, // 障碍物所在的层
height = height // 障碍物的高度
};
if (first == null) first = v; // 如果是第一个顶点则将其设置为first
else prev.next = v; // 否则将前一个顶点的next指向当前顶点
prev = v; // 更新prev为当前顶点用于下一个循环迭代
}
// 如果cycle为true则将障碍物的顶点连接成循环链表。
if (cycle)
{
prev.next = first; // 最后一个顶点的next指向第一个顶点
first.prev = prev; // 第一个顶点的prev指向最后一个顶点
}
// 更新障碍物的信息,可能是根据顶点数组和转换矩阵来设置障碍物的最终位置和形状。
UpdateObstacle(first, vertices, matrix);
// 将障碍物的第一个顶点添加到obstacles集合中。
obstacles.Add(first);
// 返回添加的障碍物的第一个顶点。
return first;
}
/// <summary>
/// 更新障碍物的顶点。
///
/// 障碍物中的顶点数量不能改变,只能移动现有的顶点。
/// </summary>
/// <param name="obstacle">要更新的障碍物</param>
/// <param name="vertices">障碍物的新顶点数组,必须至少包含原始障碍物中的顶点数量</param>
/// <param name="matrix">在更新障碍物之前用于乘以顶点的矩阵</param>
public void UpdateObstacle(JNObstacleVertex obstacle, Vector3[] vertices, Matrix4x4 matrix)
{
// 如果传入的顶点数组为空,则抛出异常,表示顶点不能为空
if (vertices == null) throw new System.ArgumentNullException("Vertices must not be null");
// 如果传入的障碍物对象为空,则抛出异常,表示障碍物不能为空
if (obstacle == null) throw new System.ArgumentNullException("Obstacle must not be null");
// 如果顶点数组中的顶点数量少于2个则抛出异常因为障碍物至少需要2个顶点
if (vertices.Length < 2) throw new System.ArgumentException("Less than 2 vertices in an obstacle");
// 检查矩阵是否是单位矩阵,单位矩阵乘以任何点都不会改变点的位置
bool identity = matrix == Matrix4x4.identity;
int count = 0;
// 障碍物使用链表表示
var vertex = obstacle;
do
{
// 如果已经处理的顶点数量超过传入的新顶点数组长度,则抛出异常
if (count >= vertices.Length)
{
// 使用红色线条在调试时绘制连接上一个顶点和当前顶点的线段
Debug.DrawLine(vertex.prev.position, vertex.position, Color.red);
throw new System.ArgumentException("Obstacle has more vertices than supplied for updating (" + vertices.Length + " supplied)");
}
// 如果矩阵是单位矩阵,则直接赋值;否则使用矩阵乘以顶点得到新的位置
// 这里的优化可能不是必要的因为即使matrix不是单位矩阵MultiplyPoint3x4也是一个很高效的操作
vertex.position = identity ? vertices[count] : matrix.MultiplyPoint3x4(vertices[count]);
// 移动到下一个顶点
vertex = vertex.next;
count++;
}
while (vertex != obstacle && vertex != null); // 循环直到回到障碍物的第一个顶点或链表结束
// 重新计算每个顶点的方向向量
vertex = obstacle;
do
{
if (vertex.next == null)
{
// 如果是链表的最后一个顶点,则方向向量为零向量
vertex.dir = Vector2.zero;
}
else
{
// 计算当前顶点到下一个顶点的方向向量,并标准化
Vector3 dir = vertex.next.position - vertex.position;
vertex.dir = new Vector2(dir.x, dir.z).normalized;
}
// 移动到下一个顶点
vertex = vertex.next;
}
while (vertex != obstacle && vertex != null); // 循环直到回到障碍物的第一个顶点或链表结束
// 安排清理障碍物(可能是移除不再需要的障碍物)
ScheduleCleanObstacles();
// 更新所有障碍物(可能是重新计算位置、碰撞等)
UpdateObstacles();
}
/// <summary>
/// 在下一个模拟帧中重建障碍物树。
/// 添加和移除障碍物的函数会自动调用此函数。
/// </summary>
public void UpdateObstacles () {
// 在下一帧更新障碍物
doUpdateObstacles = true;
}
private void ScheduleCleanObstacles () {
doCleanObstacles = true;
}
/// <summary>
/// 每帧调用一次
/// </summary>

View File

@ -0,0 +1,18 @@
//#define ASTARDEBUG //"BBTree Debug" If enables, some queries to the tree will show debug lines. Turn off multithreading when using this since DrawLine calls cannot be called from a different thread
using System;
using System.Buffers;
using Game.Plugins.JNGame.Sync.Frame.AStar.Navmesh;
using Pathfinding.ClipperLib;
using Plugins.JNGame.Sync.Frame.AStar;
using UnityEngine;
using IntRect = Plugins.JNGame.Sync.Frame.AStar.IntRect;
namespace Game.Plugins.JNGame.Sync.Frame.AStar.Util {
/// <summary>
/// Axis Aligned Bounding Box Tree.
/// Holds a bounding box tree of triangles.
/// </summary>
public class BBTree {
}
}

View File

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 67d69e724b1645a2a58e2a4707b8c0a0
timeCreated: 1708253060

View File

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: c97677627ec34518b52e79e26b5234aa
timeCreated: 1708249424

View File

@ -0,0 +1,131 @@
using Plugins.JNGame.Sync.Frame.AStar.Entity;
namespace Game.Plugins.JNGame.Sync.Frame.AStar.Util.Graph
{
/// <summary>
///保存层次图以加快某些寻路查询的速度。
///
///一种需要非常快速的常见查询类型是“此节点可从其他节点到达吗”这种形式。
///例如,在选取路径的结束节点时使用。该结束节点被确定为离该结束点最近的节点
///可以从开始节点访问的。
///
///此数据结构的主要目的是跟踪每个节点包含在哪个连接的组件中,以便快速进行此类查询。
///
///参见:https://en . Wikipedia . org/wiki/Connected _ component _graph _ theory
///
///连通分量是一组节点,其中每对节点之间都有一条有效路径。
///因此,上面的查询可以简单地通过检查它们是否在同一个连接的组件中来回答。
///连接的组件在节点上作为《see cref=“寻路。graph node . Area“/》属性并使用《see cref =“get Area“/》方法对该类进行初始化。
///
///在下图显示200x200网格图每个连接的组件都使用不同的颜色进行着色。
///然而,实际的颜色并没有什么特别的意义,只是它们有所不同。
///【打开在线文档查看图像】
///
///在4.2版之前,连接的组件只是存储在每个节点上的一个数字,当图形更新时
///已完全重新计算连接的组件。这可以使用淹没填充相对有效地完成
///算法参见https://en.wikipedia.org/wiki/Flood_fill但是它仍然需要通过每个节点
///这对于较大的图形来说代价很高。
///
///相反,该类构建了一个小得多的图,但仍保持与原始图相同的连通性。
///此分层图中的每个节点代表大量的实际节点,这些节点是一个单一的连通组件。
///请看下图中的示例。在图像中,每种颜色都是一个单独的层次节点,黑色连接位于每个层次节点的中心之间。
///
///【打开在线文档查看图像】
///
///使用分层图,可以通过对分层图进行洪水填充来计算连通分量,而不是真实图。
///然后当我们需要知道一个节点属于哪个连通分量时,我们会查找该节点所属的层次节点的连通分量。
///
///好处不会立即显现。以上只是完成同一件事的更复杂的方法。然而,真正的好处出现在更新图表时。
///当图形被更新时,包含受更新影响的任何节点的所有分层节点被完全移除,然后一旦所有节点都被移除,新的分层节点在其位置被重新计算。
///一旦完成此操作,整个图的连接组件可以通过仅整体填充分层图来更新。由于层次图比真实图小得多,因此速度明显更快。
///
///【打开在线文档查看视频】
///
///最后,使用所有这些,可以在图形更新时非常快速地重新计算图形的连接组件。
///图形越大这种影响越大图形更新越小。通过这些优化对1000x1000网格图进行小规模更新的速度大约快40倍。
///扫描图形或同时更新整个图形时,速度不会提高。事实上,由于额外的复杂性,它有点慢,但是在分析后,与扫描图形的其余成本相比,额外的时间似乎是微不足道的。
///
///【打开在线文档查看视频】
///
///请参见:《see cref=“寻路。path utilities . ispath possible“/》
///请参见:《see cref=“寻路。nn constraint“/》
///请参见:《see cref=“寻路。graph node . Area“/》
/// </summary >
public class HierarchicalGraph
{
GraphNode[] dirtyNodes = new GraphNode[128];
/// <summary>
/// 当创建新的图节点时调用此方法。
/// </summary>
/// <param name="node">新创建的图节点。</param>
internal void OnCreatedNode(GraphNode node) {
// 检查新节点的索引是否超过了dirtyNodes数组的长度
if (node.NodeIndex >= dirtyNodes.Length) {
// 如果是则创建一个新的数组newDirty其长度是新节点索引加1与dirtyNodes数组长度两倍的较大值
// 这确保了新节点索引在newDirty数组的有效范围内并且数组有足够的空间来容纳未来的节点
var newDirty = new GraphNode[System.Math.Max(node.NodeIndex + 1, dirtyNodes.Length * 2)];
// 将旧的dirtyNodes数组中的元素复制到新的newDirty数组中
dirtyNodes.CopyTo(newDirty, 0);
// 将dirtyNodes引用指向新的newDirty数组以便后续添加新节点
dirtyNodes = newDirty;
}
// 将新节点添加到dirtyNodes数组中
// AddDirtyNode(node);
}
// /// <summary>
// /// 将此节点标记为“脏”,因为其连接性或可通行性已发生变化。
// /// 在对节点进行任何连接性或可通行性更改后,节点类必须调用此方法。
// ///
// /// 请参见:<see cref="GraphNode.SetConnectivityDirty"/>
// /// </summary>
// /// <param name="node">要标记为“脏”的节点。</param>
// public void AddDirtyNode(GraphNode node) {
// // 如果节点尚未被标记为层次化节点“脏”
// if (!node.IsHierarchicalNodeDirty) {
// // 将节点标记为层次化节点“脏”
// node.IsHierarchicalNodeDirty = true;
//
// // 当dirtyNodes数组保证足够大以容纳图中所有节点时
// // 数组可能也包含许多已销毁的节点。在极少数情况下,这可能导致数组越界。
// // 在那种情况下,我们需要遍历数组并过滤掉任何已销毁的节点,同时确保将其对应的层次化节点标记为“脏”。
// if (numDirtyNodes < dirtyNodes.Length) {
// // 如果dirtyNodes数组还有空余空间则直接将新节点添加到数组中
// dirtyNodes[numDirtyNodes] = node;
// // 增加脏节点计数
// numDirtyNodes++;
// } else {
// // 如果数组已满,则需要压缩数组以移除已销毁的节点
// int maxIndex = 0;
// for (int i = numDirtyNodes - 1; i >= 0; i--) {
// // 检查节点是否已销毁
// if (dirtyNodes[i].Destroyed) {
// // 如果是,则减少脏节点计数
// numDirtyNodes--;
// // 标记对应的层次化节点为“脏”
// dirty[dirtyNodes[i].HierarchicalNodeIndex] = 1;
// // 将最后一个有效节点移到当前位置
// dirtyNodes[i] = dirtyNodes[numDirtyNodes];
// // 将当前位置设置为null表示该位置不再包含有效节点
// dirtyNodes[numDirtyNodes] = null;
// } else {
// // 如果节点未销毁则更新maxIndex为当前节点索引和maxIndex中的较大值
// maxIndex = System.Math.Max(maxIndex, dirtyNodes[i].NodeIndex);
// }
// }
// // 检查是否成功压缩了数组。如果numDirtyNodes仍然大于等于dirtyNodes.Length则抛出异常
// if (numDirtyNodes >= dirtyNodes.Length)
// throw new System.Exception("Failed to compactify dirty nodes array. This should not happen. " + maxIndex + " " + numDirtyNodes + " " + dirtyNodes.Length);
// // 再次尝试添加新节点,此时数组应该有足够的空间
// AddDirtyNode(node);
// }
// }
// }
}
}

View File

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: f06db991bf79449f9045161837498431
timeCreated: 1708249427

View File

@ -0,0 +1,265 @@
using UnityEngine;
namespace Game.Plugins.JNGame.Sync.Frame.AStar.Util
{
/// <summary>
/// 在世界空间和二维移动平面之间进行转换。
/// 保证转换只包含旋转
/// 因此不使用缩放或偏移。此接口主要用于
/// 方便编写能够处理XZ平面和XY平面上的移动的脚本。
///
/// 参见:<see cref="Pathfinding.Util.GraphTransform"/>
/// </summary>
public interface IMovementPlane {
/// <summary>
/// 将三维向量转换到二维平面上。
/// </summary>
/// <param name="p">要转换的三维向量。</param>
/// <returns>转换后的二维向量。</returns>
Vector2 ToPlane(Vector3 p);
/// <summary>
/// 将三维向量转换到二维平面上,并返回其高度信息。
/// </summary>
/// <param name="p">要转换的三维向量。</param>
/// <param name="elevation">转换后的二维向量的高度信息。</param>
/// <returns>转换后的二维向量。</returns>
Vector2 ToPlane(Vector3 p, out float elevation);
/// <summary>
/// 将二维向量和高度信息转换回三维世界空间。
/// </summary>
/// <param name="p">要转换的二维向量。</param>
/// <param name="elevation">二维向量的高度信息。</param>
/// <param name="elevation">默认值为0。</param>
/// <returns>转换后的三维向量。</returns>
Vector3 ToWorld(Vector2 p, float elevation = 0);
}
/// <summary>
/// 通用的三维坐标变换
/// </summary>
public interface ITransform {
// 将一个三维坐标位置进行变换
Vector3 Transform(Vector3 position);
// 对一个已经变换过的三维坐标位置进行逆变换,恢复到原始坐标空间
Vector3 InverseTransform(Vector3 position);
}
/// <summary>
/// 定义从图空间到世界空间的变换。
/// 这本质上只是一个矩阵的简单封装,但它提供了几个有用的实用程序。
/// </summary>
public class GraphTransform : IMovementPlane, ITransform {
/// <summary>
/// 如果这个变换是恒等变换(即它不执行任何操作),则为真
/// </summary>
public readonly bool identity;
/// <summary>
/// 如果这个变换是一个纯平移变换,没有任何缩放或旋转,则为真
/// </summary>
public readonly bool onlyTranslational;
// 只读布尔值表示变换是否仅涉及X和Y轴
readonly bool isXY;
// 只读布尔值表示变换是否仅涉及X和Z轴
readonly bool isXZ;
// 4x4变换矩阵用于从图空间到世界空间的变换
readonly Matrix4x4 matrix;
// 变换矩阵的逆矩阵,用于从世界空间到图空间的变换
readonly Matrix4x4 inverseMatrix;
// 表示变换后的“上”方向的向量,通常与旋转部分相关
readonly Vector3 up;
// 变换的平移部分表示在X、Y、Z轴上的移动量
readonly Vector3 translation;
// 变换的平移部分,表示为整数类型,可能用于某些优化或特定的计算场景
readonly Int3 i3translation;
// 变换的旋转部分,使用四元数表示
readonly Quaternion rotation;
// 旋转部分的逆四元数,用于反向旋转
readonly Quaternion inverseRotation;
// 恒等变换的实例,即不改变任何点位置的变换
public static readonly GraphTransform identityTransform = new GraphTransform(Matrix4x4.identity);
/// <summary>
/// GraphTransform 类的构造函数,用于通过提供的 4x4 矩阵初始化变换。
/// </summary>
/// <param name="matrix">用于初始化变换的 4x4 矩阵。</param>
public GraphTransform(Matrix4x4 matrix) {
// 将传入的矩阵赋值给类的成员变量 matrix
this.matrix = matrix;
// 计算并赋值逆矩阵
inverseMatrix = matrix.inverse;
// 判断矩阵是否为恒等矩阵,并赋值给成员变量 identity
identity = matrix.isIdentity;
// 判断矩阵是否仅包含平移变换,并赋值给成员变量 onlyTranslational
onlyTranslational = MatrixIsTranslational(matrix);
// 计算变换后的“上”方向向量,并对其进行单位化
up = matrix.MultiplyVector(Vector3.up).normalized;
// 计算平移部分,通过矩阵乘以一个原点向量得到
translation = matrix.MultiplyPoint3x4(Vector3.zero);
// 将平移部分转换为整数类型并赋值给成员变量 i3translation
i3translation = (Int3)translation;
// 从矩阵中提取旋转部分。这只有在矩阵没有倾斜时才正确,但我们只想在移动平面上使用它,
// 只要 Up 轴与 Forward 轴垂直,一切就应该没问题。在项目中,只有当使用六边形或等距网格图时,
// 三个轴才不全部垂直,但在这两种情况下,只有 X 轴和 Z 轴不垂直。
// 使用 LookRotation 方法从两个向量Forward 和 Up中计算四元数表示的旋转
rotation = Quaternion.LookRotation(TransformVector(Vector3.forward), TransformVector(Vector3.up));
// 计算旋转部分的逆四元数
inverseRotation = Quaternion.Inverse(rotation);
// 一些用于移动平面计算的短路代码
// 检查旋转是否等于绕 Y 轴旋转 -90 度的四元数,如果是,则 isXY 为真
isXY = rotation == Quaternion.Euler(-90, 0, 0);
// 检查旋转是否等于恒等四元数,如果是,则 isXZ 为真
isXZ = rotation == Quaternion.Euler(0, 0, 0);
}
/// <summary>
/// 一个辅助方法,用于判断一个矩阵是否仅包含平移变换。
/// </summary>
/// <param name="matrix">要检查的 4x4 矩阵。</param>
/// <returns>如果矩阵仅包含平移变换,则返回 true否则返回 false。</returns>
static bool MatrixIsTranslational (Matrix4x4 matrix) {
return matrix.GetColumn(0) == new Vector4(1, 0, 0, 0) && matrix.GetColumn(1) == new Vector4(0, 1, 0, 0) && matrix.GetColumn(2) == new Vector4(0, 0, 1, 0) && matrix.m33 == 1;
}
/// <summary>
/// 一个辅助方法,用于应用矩阵变换到一个向量上。
/// </summary>
/// <param name="vector">要变换的向量。</param>
/// <returns>变换后的向量。</returns>
private Vector3 TransformVector(Vector3 point) {
if (onlyTranslational) return point;
return matrix.MultiplyVector(point);
}
/// <summary>
/// 将从世界空间转换到图形的'地面'平面上。
/// 转换仅是一个旋转,不使用缩放或偏移。
///
/// 对于使用(-90, 0, 0)旋转的图形,这将把坐标(x,y,z)转换为(x,y)。
/// 对于使用(0,0,0)旋转的图形,这将把坐标(x,y,z)转换为(x,z)。
/// 更一般地说对于使用四元数旋转R的图形这将把向量V转换为R * V即使用旋转R旋转向量V
/// </summary>
Vector2 IMovementPlane.ToPlane(Vector3 point) {
// 这些特殊情况涵盖了实践中使用的大多数图形方向。
// 将它们放在这里可以在不影响通用情况的情况下提高这些情况下的性能2.5倍。
if (isXY) return new Vector2(point.x, point.y);
// 如果不是isXZ则使用逆旋转将点进行旋转
if (!isXZ) point = inverseRotation * point;
// 返回旋转后的点的x和z分量
return new Vector2(point.x, point.z);
}
/// <summary>
/// 将从世界空间中的点转换到图形的'地面'平面上,并输出该点的海拔高度。
/// 转换仅是一个旋转,不使用缩放或偏移。
/// </summary>
/// <param name="point">世界空间中的点</param>
/// <param name="elevation">输出参数,表示点的海拔高度</param>
/// <returns>返回转换后的二维坐标</returns>
Vector2 IMovementPlane.ToPlane(Vector3 point, out float elevation) {
// 如果不是isXZ则应用逆旋转来转换点
if (!isXZ) point = inverseRotation * point;
// 获取转换后的点的y分量作为海拔高度
elevation = point.y;
// 返回转换后的点的x和z分量作为二维向量
return new Vector2(point.x, point.z);
}
/// <summary>
/// 将图形'地面'平面上的点转换回世界空间中的三维坐标。
/// 转换仅是一个旋转,不使用缩放或偏移。
/// </summary>
/// <param name="point">图形'地面'平面上的二维点</param>
/// <param name="elevation">点的海拔高度</param>
/// <returns>返回转换后的世界空间中的三维坐标</returns>
Vector3 IMovementPlane.ToWorld(Vector2 point, float elevation) {
// 使用旋转矩阵或四元数将二维点和海拔高度转换为世界空间中的三维坐标
return rotation * new Vector3(point.x, elevation, point.y);
}
// 对Int3数组进行变换
public void Transform(Int3[] arr) {
// 如果只进行平移变换
if (onlyTranslational) {
// 从数组的最后一个元素开始向前遍历
for (int i = arr.Length - 1; i >= 0; i--) {
// 将当前元素与平移向量i3translation相加并将结果存回原位置
arr[i] += i3translation;
}
} else {
// 否则,使用矩阵对数组中的每个元素进行变换
for (int i = arr.Length - 1; i >= 0; i--) {
// 将数组中的当前元素转换为Vector3使用矩阵进行变换然后再将结果转换回Int3并存回原位置
arr[i] = (Int3)matrix.MultiplyPoint3x4((Vector3)arr[i]);
}
}
}
// 对Vector3数组进行变换
public void Transform(Vector3[] arr) {
// 如果只进行平移变换
if (onlyTranslational) {
// 从数组的最后一个元素开始向前遍历
for (int i = arr.Length - 1; i >= 0; i--) {
// 将当前元素与平移向量translation相加并将结果存回原位置
arr[i] += translation;
}
} else {
// 否则,使用矩阵对数组中的每个元素进行变换
for (int i = arr.Length - 1; i >= 0; i--) {
// 使用矩阵对当前元素进行变换,并将结果存回原位置
arr[i] = matrix.MultiplyPoint3x4(arr[i]);
}
}
}
// 对一个Vector3点进行逆变换
public Vector3 Transform (Vector3 point) {
if (onlyTranslational) return point + translation;
return matrix.MultiplyPoint3x4(point);
}
public Vector3 InverseTransform(Vector3 point) {
// 如果只进行平移变换
if (onlyTranslational) {
// 从点中减去平移向量translation得到逆变换后的结果
return point - translation;
} else {
// 否则,使用逆矩阵对点进行逆变换
return inverseMatrix.MultiplyPoint3x4(point);
}
}
// 对一个Vector3方向向量进行逆变换
public Vector3 InverseTransformVector(Vector3 dir) {
// 如果只进行平移变换,方向向量不受影响,直接返回原向量
if (onlyTranslational) {
return dir;
} else {
// 否则,使用逆矩阵对方向向量进行逆变换
return inverseMatrix.MultiplyVector(dir);
}
}
}
}

View File

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 8dc57bd81a84414cb40327a31212efc9
timeCreated: 1708245376

View File

@ -1,4 +1,5 @@
using System;
using System.Threading.Tasks;
using UnityEngine;
namespace Plugins.JNGame.Sync.Frame.game
@ -27,5 +28,7 @@ namespace Plugins.JNGame.Sync.Frame.game
public abstract byte[] Encoder();
public abstract Task OnSyncUpdateThread(int dt, JNFrameInfo frame);
}
}

View File

@ -1,5 +1,6 @@
using System;
using System.Text;
using System.Threading.Tasks;
using Newtonsoft.Json;
using UnityEngine;
@ -70,8 +71,10 @@ namespace Plugins.JNGame.Sync.Frame.game
//帧同步
public abstract void OnLateSyncUpdate(int dt,JNFrameInfo frame,T input);
public abstract void OnSyncUpdate(int dt,JNFrameInfo frame,T input);
public override Task OnSyncUpdateThread(int dt, JNFrameInfo frame)
{
return null;
}
}
}

View File

@ -0,0 +1,26 @@
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using Cysharp.Threading.Tasks;
using Plugins.JNGame.Sync.Frame.game;
namespace Game.Plugins.JNGame.Sync.Frame
{
public class JNFrameUtil
{
//多线程并行
public static async Task Parallel(List<IJNSyncFrameComponent> actions,int dt, JNFrameInfo frame)
{
List<Task> tasks = new();
actions.ForEach(action =>
{
Task task;
if ((task = action.OnSyncUpdateThread(dt, frame)) != null)
{
tasks.Add(task);
}
});
await Task.WhenAll(tasks);
}
}
}

View File

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: b70e8ba0044041899b8a6d37aefba41f
timeCreated: 1708422060

View File

@ -2,8 +2,10 @@
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Threading;
using System.Threading.Tasks;
using Cysharp.Threading.Tasks;
using Game.Plugins.JNGame.Sync.Frame;
using Google.Protobuf;
using Plugins.JNGame.Sync.Frame.Entity;
using Plugins.JNGame.Sync.Frame.game;
@ -32,7 +34,7 @@ namespace Plugins.JNGame.Sync.Frame
//大于多少帧进行追帧
private int _nMaxFrameBan = 4;
//大于多少帧进行快速追帧
private int _nMaxFrameLoopBan = 18;
private int _nMaxFrameLoopBan = 20;
//将服务器帧数进行平分
private int _nDivideFrame = 2;
@ -61,6 +63,8 @@ namespace Plugins.JNGame.Sync.Frame
//需要同步的Actor
private List<IJNSyncFrameComponent> _nSyncActors = new();
//需要被删除的Action
private List<IJNSyncFrameComponent> _nDelSyncActors = new();
//ID 每添加 JNSyncFrameComponent + 1
public Func<int> nSyncID = RandomUtil.Next(0);
@ -92,7 +96,13 @@ namespace Plugins.JNGame.Sync.Frame
public bool IsLoop => _isLoop;
public JNTime Time => (new JNTime(this));
//执行时间
public long frameTime = 0;
//是否正在执行
private Boolean isRun = false;
public override Task OnInit()
{
Physics.autoSimulation = false;
@ -102,8 +112,19 @@ namespace Plugins.JNGame.Sync.Frame
}
//开始
public void OnStart(){
public void OnStart()
{
this._isStart = true;
// thread = new Thread(() =>
// {
// this._isStart = true;
// while (true)
// {
// this.Update(33);
// Thread.Sleep(33);
// }
// });
// thread.Start();
}
//重置数据
@ -118,6 +139,7 @@ namespace Plugins.JNGame.Sync.Frame
this.nRandomFloat = RandomUtil.SyncRandomFloat();
this.nRandomInt = RandomUtil.SyncRandomInt();
this._nSyncActors = new();
this._nDelSyncActors = new();
this._nFrameQueue = new();
this._nFrameTempQueue = new();
this._nLocalFrame = 0;
@ -127,7 +149,7 @@ namespace Plugins.JNGame.Sync.Frame
this.dtInputTotal = 0;
this._isRequestServerData = false;
Physics.SyncTransforms();
// Physics.SyncTransforms();
//清除定时器
SingletonUtil<JNFrameTime>.Clean();
@ -141,36 +163,55 @@ namespace Plugins.JNGame.Sync.Frame
{
if(!_isStart) return;
dtTotal += dt;
dtInputTotal += dt;
// if (isRun)
// {
// return;
// }
// isRun = true;
int nSyncTime = this.DyTime();
try
{
int nSyncTime = this.DyTime();
this._isLoop = this._nFrameQueue.Count > 20;
if(nSyncTime > 0){
while(nSyncTime != 0 && this.dtTotal > nSyncTime){
this.OnUpdate();
this.dtTotal -= nSyncTime;
nSyncTime = this.DyTime();
}
}else{
//追帧运行 保持前端 15 帧 刷新
long endTime = (new DateTimeOffset(DateTime.UtcNow).ToUnixTimeMilliseconds()) + 66;
while(this.DyTime() == 0 && (new DateTimeOffset(DateTime.UtcNow).ToUnixTimeMilliseconds()) < endTime)
if (nSyncTime > 0)
{
this.OnUpdate();
this._isLoop = false;
while (nSyncTime != 0 && this.dtTotal > nSyncTime && _nFrameQueue.Count > 0)
{
this.OnUpdate();
this.dtTotal -= nSyncTime;
nSyncTime = this.DyTime();
}
}
else
{
this._isLoop = true;
//追帧运行 保持前端 15 帧 刷新
long endTime = (new DateTimeOffset(DateTime.UtcNow)).ToUnixTimeMilliseconds() + 100;
// && ((new DateTimeOffset(DateTime.UtcNow)).ToUnixTimeMilliseconds()) < endTime
while (this.DyTime() == 0 && ((new DateTimeOffset(DateTime.UtcNow)).ToUnixTimeMilliseconds()) < endTime)
{
this.OnUpdate();
}
dtTotal = 0;
}
//更新输入
if (this.dtInputTotal > (this._nSyncTime / this._nDivideFrame))
{
this.dtInputTotal = 0;
this.OnInput();
}
dtTotal = 0;
}
//更新输入
if(this.dtInputTotal > (this._nSyncTime / this._nDivideFrame)){
this.dtInputTotal = 0;
this.OnInput();
catch (Exception e)
{
Debug.LogError(e.Message);
}
// isRun = false;
}
@ -209,6 +250,8 @@ namespace Plugins.JNGame.Sync.Frame
private void OnUpdate()
{
if(!(_nFrameQueue.TryDequeue(out var frame))) return;
var second = (new DateTimeOffset(DateTime.UtcNow)).ToUnixTimeMilliseconds();
if(frame.Index != 0)
this._nLocalRunFrame = frame.Index;
@ -226,7 +269,7 @@ namespace Plugins.JNGame.Sync.Frame
// Debug.Log(inputs.Count);
//运行生命周期
this._nSyncActors.ToList().ForEach(child =>
this._nSyncActors.ForEach(child =>
{
if (!child.IsRunStart)
{
@ -236,7 +279,7 @@ namespace Plugins.JNGame.Sync.Frame
});
//运行之前帧
this._nSyncActors.ToList().ForEach(child =>
this._nSyncActors.ForEach(child =>
{
MethodInfo OnSyncUpdate = child.GetType().GetMethod("OnLateSyncUpdate");
MethodInfo Decoder = child.GetType().GetMethod("Decoder");
@ -251,7 +294,7 @@ namespace Plugins.JNGame.Sync.Frame
});
//更新帧
this._nSyncActors.ToList().ForEach(child =>
this._nSyncActors.ForEach(child =>
{
MethodInfo OnSyncUpdate = child.GetType().GetMethod("OnSyncUpdate");
MethodInfo Decoder = child.GetType().GetMethod("Decoder");
@ -269,7 +312,19 @@ namespace Plugins.JNGame.Sync.Frame
SingletonUtil<JNFrameTime>.Instance.Update(dt);
//执行下一帧物理
// Physics.Simulate((float)dt / 1000);
Physics.SyncTransforms();
// Physics.SyncTransforms();
//并发
// await JNFrameUtil.Parallel(this._nSyncActors,dt,frame);
//删除Action
this._nDelSyncActors.ForEach(child =>
{
this._nSyncActors.Remove(child);
});
this._nDelSyncActors.Clear();
this.frameTime = (new DateTimeOffset(DateTime.UtcNow)).ToUnixTimeMilliseconds() - second;
}
@ -388,7 +443,9 @@ namespace Plugins.JNGame.Sync.Frame
//销毁同步组件
public void DelSyncActor(IJNSyncFrameComponent sync){
this._nSyncActors.Remove(sync);
if(!this._nSyncActors.Contains(sync)){
this._nDelSyncActors.Add(sync);
}
}
//发送帧数据

View File

@ -0,0 +1,19 @@
using System;
namespace Game.Plugins.JNGame.Util
{
public class UseUtil
{
public static bool ContainsType(object[] array, Type typeToFind)
{
foreach (var item in array)
{
if (item.GetType() == typeToFind)
{
return true;
}
}
return false;
}
}
}

View File

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 500748b025884f42ade05338e47bff56
timeCreated: 1708237347

View File

@ -408,7 +408,7 @@ MonoBehaviour:
_nId: 0
IsRunStart: 0
isSyncInitSuccess: 0
agentCount: 150
agentCount: 100
exampleScale: 100
renderingOffset: {x: 0, y: 0.1, z: 0}
agentTimeHorizon: 10

View File

@ -455,6 +455,7 @@ GameObject:
m_Component:
- component: {fileID: 1799725643}
- component: {fileID: 1799725642}
- component: {fileID: 1799725644}
m_Layer: 0
m_Name: GMode
m_TagString: Untagged
@ -477,6 +478,7 @@ MonoBehaviour:
_nId: 0
IsRunStart: 0
isSyncInitSuccess: 0
aStarData: {fileID: 1799725644}
--- !u!4 &1799725643
Transform:
m_ObjectHideFlags: 0
@ -494,3 +496,16 @@ Transform:
m_Father: {fileID: 0}
m_RootOrder: 2
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!114 &1799725644
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1799725641}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: a5994a8804fe405bb692cda49728167c, type: 3}
m_Name:
m_EditorClassIdentifier:
dataString:

View File

@ -245,7 +245,7 @@ MonoBehaviour:
m_Script: {fileID: 11500000, guid: 1764de1de43cc4d19af52679d3eaae06, type: 3}
m_Name:
m_EditorClassIdentifier:
_nId: 3
_nId: 8
IsRunStart: 0
isSyncInitSuccess: 0
version: 1
@ -477,7 +477,7 @@ Transform:
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 924212660}
m_LocalRotation: {x: 0.7071068, y: 0, z: 0, w: 0.7071068}
m_LocalPosition: {x: 0, y: 151.15788, z: 0.000018019422}
m_LocalPosition: {x: 0, y: 227, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children: []

View File

@ -6954,6 +6954,7 @@ MonoBehaviour:
m_Name:
m_EditorClassIdentifier:
_nId: 0
IsRunStart: 0
isSyncInitSuccess: 0
allow:
- {fileID: 425}
@ -8047,6 +8048,7 @@ MonoBehaviour:
m_Name:
m_EditorClassIdentifier:
_nId: 0
IsRunStart: 0
isSyncInitSuccess: 0
allow:
- {fileID: 520}
@ -8062,7 +8064,8 @@ MonoBehaviour:
m_Script: {fileID: 11500000, guid: 78396926cbbfc4ac3b48fc5fc34a87d1, type: 3}
m_Name:
m_EditorClassIdentifier:
_nId: 5
_nId: 0
IsRunStart: 0
isSyncInitSuccess: 0
version: 1
data:
@ -8137,7 +8140,7 @@ MonoBehaviour:
seed: 0
pivotPointRoot: {fileID: 0}
spreadOutCount: 10
showGraphs: 0
showGraphs: 1
--- !u!114 &534
MonoBehaviour:
m_ObjectHideFlags: 0
@ -8151,6 +8154,7 @@ MonoBehaviour:
m_Name:
m_EditorClassIdentifier:
_nId: 0
IsRunStart: 0
isSyncInitSuccess: 0
allow: []
--- !u!196 &536
@ -8406,5 +8410,6 @@ MonoBehaviour:
m_Name:
m_EditorClassIdentifier:
_nId: 0
IsRunStart: 0
isSyncInitSuccess: 0
player: {fileID: 505715710780844734, guid: 4fed39050c35daa41b1aed0f9723e748, type: 3}

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: a34f388655db2604588caacbfcbb116f
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 32e752cec59c5244fb65b1a0778b624e
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,595 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!29 &1
OcclusionCullingSettings:
m_ObjectHideFlags: 0
serializedVersion: 2
m_OcclusionBakeSettings:
smallestOccluder: 5
smallestHole: 0.25
backfaceThreshold: 100
m_SceneGUID: 00000000000000000000000000000000
m_OcclusionCullingData: {fileID: 0}
--- !u!104 &2
RenderSettings:
m_ObjectHideFlags: 0
serializedVersion: 9
m_Fog: 0
m_FogColor: {r: 0.5, g: 0.5, b: 0.5, a: 1}
m_FogMode: 3
m_FogDensity: 0.01
m_LinearFogStart: 0
m_LinearFogEnd: 300
m_AmbientSkyColor: {r: 0.212, g: 0.227, b: 0.259, a: 1}
m_AmbientEquatorColor: {r: 0.114, g: 0.125, b: 0.133, a: 1}
m_AmbientGroundColor: {r: 0.047, g: 0.043, b: 0.035, a: 1}
m_AmbientIntensity: 1
m_AmbientMode: 0
m_SubtractiveShadowColor: {r: 0.42, g: 0.478, b: 0.627, a: 1}
m_SkyboxMaterial: {fileID: 10304, guid: 0000000000000000f000000000000000, type: 0}
m_HaloStrength: 0.5
m_FlareStrength: 1
m_FlareFadeSpeed: 3
m_HaloTexture: {fileID: 0}
m_SpotCookie: {fileID: 10001, guid: 0000000000000000e000000000000000, type: 0}
m_DefaultReflectionMode: 0
m_DefaultReflectionResolution: 128
m_ReflectionBounces: 1
m_ReflectionIntensity: 1
m_CustomReflection: {fileID: 0}
m_Sun: {fileID: 0}
m_IndirectSpecularColor: {r: 0.18028378, g: 0.22571412, b: 0.30692285, a: 1}
m_UseRadianceAmbientProbe: 0
--- !u!157 &3
LightmapSettings:
m_ObjectHideFlags: 0
serializedVersion: 12
m_GIWorkflowMode: 1
m_GISettings:
serializedVersion: 2
m_BounceScale: 1
m_IndirectOutputScale: 1
m_AlbedoBoost: 1
m_EnvironmentLightingMode: 0
m_EnableBakedLightmaps: 1
m_EnableRealtimeLightmaps: 0
m_LightmapEditorSettings:
serializedVersion: 12
m_Resolution: 2
m_BakeResolution: 40
m_AtlasSize: 1024
m_AO: 0
m_AOMaxDistance: 1
m_CompAOExponent: 1
m_CompAOExponentDirect: 0
m_ExtractAmbientOcclusion: 0
m_Padding: 2
m_LightmapParameters: {fileID: 0}
m_LightmapsBakeMode: 1
m_TextureCompression: 1
m_FinalGather: 0
m_FinalGatherFiltering: 1
m_FinalGatherRayCount: 256
m_ReflectionCompression: 2
m_MixedBakeMode: 2
m_BakeBackend: 1
m_PVRSampling: 1
m_PVRDirectSampleCount: 32
m_PVRSampleCount: 512
m_PVRBounces: 2
m_PVREnvironmentSampleCount: 256
m_PVREnvironmentReferencePointCount: 2048
m_PVRFilteringMode: 1
m_PVRDenoiserTypeDirect: 1
m_PVRDenoiserTypeIndirect: 1
m_PVRDenoiserTypeAO: 1
m_PVRFilterTypeDirect: 0
m_PVRFilterTypeIndirect: 0
m_PVRFilterTypeAO: 0
m_PVREnvironmentMIS: 1
m_PVRCulling: 1
m_PVRFilteringGaussRadiusDirect: 1
m_PVRFilteringGaussRadiusIndirect: 5
m_PVRFilteringGaussRadiusAO: 2
m_PVRFilteringAtrousPositionSigmaDirect: 0.5
m_PVRFilteringAtrousPositionSigmaIndirect: 2
m_PVRFilteringAtrousPositionSigmaAO: 1
m_ExportTrainingData: 0
m_TrainingDataDestination: TrainingData
m_LightProbeSampleCountMultiplier: 4
m_LightingDataAsset: {fileID: 0}
m_LightingSettings: {fileID: 0}
--- !u!196 &4
NavMeshSettings:
serializedVersion: 2
m_ObjectHideFlags: 0
m_BuildSettings:
serializedVersion: 2
agentTypeID: 0
agentRadius: 0.5
agentHeight: 2
agentSlope: 45
agentClimb: 0.4
ledgeDropHeight: 0
maxJumpAcrossDistance: 0
minRegionArea: 2
manualCellSize: 0
cellSize: 0.16666667
manualTileSize: 0
tileSize: 256
accuratePlacement: 0
maxJobWorkers: 0
preserveTilesOutsideBounds: 0
debug:
m_Flags: 0
m_NavMeshData: {fileID: 0}
--- !u!1 &38334037
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 38334038}
- component: {fileID: 38334040}
- component: {fileID: 38334039}
- component: {fileID: 38334042}
- component: {fileID: 38334041}
- component: {fileID: 38334043}
m_Layer: 0
m_Name: Capsule
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!4 &38334038
Transform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 38334037}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 1, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 513358594}
m_RootOrder: 1
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!23 &38334039
MeshRenderer:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 38334037}
m_Enabled: 1
m_CastShadows: 1
m_ReceiveShadows: 1
m_DynamicOccludee: 1
m_StaticShadowCaster: 0
m_MotionVectors: 1
m_LightProbeUsage: 1
m_ReflectionProbeUsage: 1
m_RayTracingMode: 2
m_RayTraceProcedural: 0
m_RenderingLayerMask: 1
m_RendererPriority: 0
m_Materials:
- {fileID: 10303, guid: 0000000000000000f000000000000000, type: 0}
m_StaticBatchInfo:
firstSubMesh: 0
subMeshCount: 0
m_StaticBatchRoot: {fileID: 0}
m_ProbeAnchor: {fileID: 0}
m_LightProbeVolumeOverride: {fileID: 0}
m_ScaleInLightmap: 1
m_ReceiveGI: 1
m_PreserveUVs: 0
m_IgnoreNormalsForChartDetection: 0
m_ImportantGI: 0
m_StitchLightmapSeams: 1
m_SelectedEditorRenderState: 3
m_MinimumChartSize: 4
m_AutoUVMaxDistance: 0.5
m_AutoUVMaxAngle: 89
m_LightmapParameters: {fileID: 0}
m_SortingLayerID: 0
m_SortingLayer: 0
m_SortingOrder: 0
m_AdditionalVertexStreams: {fileID: 0}
--- !u!33 &38334040
MeshFilter:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 38334037}
m_Mesh: {fileID: 10208, guid: 0000000000000000e000000000000000, type: 0}
--- !u!195 &38334041
NavMeshAgent:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 38334037}
m_Enabled: 1
m_AgentTypeID: 0
m_Radius: 0.5
m_Speed: 3.5
m_Acceleration: 8
avoidancePriority: 50
m_AngularSpeed: 120
m_StoppingDistance: 0
m_AutoTraverseOffMeshLink: 1
m_AutoBraking: 1
m_AutoRepath: 1
m_Height: 2
m_BaseOffset: 1
m_WalkableMask: 4294967295
m_ObstacleAvoidanceType: 4
--- !u!114 &38334042
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 38334037}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 48594c1dc3fb5aa49a018db20d994801, type: 3}
m_Name:
m_EditorClassIdentifier:
_nId: 0
IsRunStart: 0
isSyncInitSuccess: 0
--- !u!114 &38334043
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 38334037}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 48594c1dc3fb5aa49a018db20d994801, type: 3}
m_Name:
m_EditorClassIdentifier:
_nId: 0
IsRunStart: 0
isSyncInitSuccess: 0
--- !u!1 &513358592
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 513358594}
- component: {fileID: 513358596}
- component: {fileID: 513358593}
m_Layer: 0
m_Name: Root
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!114 &513358593
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 513358592}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 7a5ac11cc976e418e8d13136b07e1f52, type: 3}
m_Name:
m_EditorClassIdentifier:
m_AgentTypeID: 0
m_CollectObjects: 0
m_Size: {x: 10, y: 10, z: 10}
m_Center: {x: 0, y: 2, z: 0}
m_LayerMask:
serializedVersion: 2
m_Bits: 4294967295
m_UseGeometry: 0
m_DefaultArea: 0
m_IgnoreNavMeshAgent: 1
m_IgnoreNavMeshObstacle: 1
m_OverrideTileSize: 0
m_TileSize: 256
m_OverrideVoxelSize: 0
m_VoxelSize: 0.16666667
m_MinRegionArea: 2
m_NavMeshData: {fileID: 23800000, guid: 84e050c280baab14bbe3b453ccc9be71, type: 2}
m_BuildHeightMesh: 0
--- !u!4 &513358594
Transform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 513358592}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children:
- {fileID: 614379360}
- {fileID: 38334038}
m_Father: {fileID: 0}
m_RootOrder: 2
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!114 &513358596
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 513358592}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: c8ab58234d87b0b49a69949613d0f31e, type: 3}
m_Name:
m_EditorClassIdentifier:
_nId: 0
IsRunStart: 0
isSyncInitSuccess: 0
--- !u!1 &614379359
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 614379360}
- component: {fileID: 614379362}
- component: {fileID: 614379361}
m_Layer: 0
m_Name: Plane
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!4 &614379360
Transform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 614379359}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 5, y: 1, z: 5}
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 513358594}
m_RootOrder: 0
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!23 &614379361
MeshRenderer:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 614379359}
m_Enabled: 1
m_CastShadows: 1
m_ReceiveShadows: 1
m_DynamicOccludee: 1
m_StaticShadowCaster: 0
m_MotionVectors: 1
m_LightProbeUsage: 1
m_ReflectionProbeUsage: 1
m_RayTracingMode: 2
m_RayTraceProcedural: 0
m_RenderingLayerMask: 1
m_RendererPriority: 0
m_Materials:
- {fileID: 10303, guid: 0000000000000000f000000000000000, type: 0}
m_StaticBatchInfo:
firstSubMesh: 0
subMeshCount: 0
m_StaticBatchRoot: {fileID: 0}
m_ProbeAnchor: {fileID: 0}
m_LightProbeVolumeOverride: {fileID: 0}
m_ScaleInLightmap: 1
m_ReceiveGI: 1
m_PreserveUVs: 0
m_IgnoreNormalsForChartDetection: 0
m_ImportantGI: 0
m_StitchLightmapSeams: 1
m_SelectedEditorRenderState: 3
m_MinimumChartSize: 4
m_AutoUVMaxDistance: 0.5
m_AutoUVMaxAngle: 89
m_LightmapParameters: {fileID: 0}
m_SortingLayerID: 0
m_SortingLayer: 0
m_SortingOrder: 0
m_AdditionalVertexStreams: {fileID: 0}
--- !u!33 &614379362
MeshFilter:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 614379359}
m_Mesh: {fileID: 10209, guid: 0000000000000000e000000000000000, type: 0}
--- !u!1 &930938399
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 930938402}
- component: {fileID: 930938401}
m_Layer: 0
m_Name: Main Camera
m_TagString: MainCamera
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!20 &930938401
Camera:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 930938399}
m_Enabled: 1
serializedVersion: 2
m_ClearFlags: 1
m_BackGroundColor: {r: 0.19215687, g: 0.3019608, b: 0.4745098, a: 0}
m_projectionMatrixMode: 1
m_GateFitMode: 2
m_FOVAxisMode: 0
m_SensorSize: {x: 36, y: 24}
m_LensShift: {x: 0, y: 0}
m_FocalLength: 50
m_NormalizedViewPortRect:
serializedVersion: 2
x: 0
y: 0
width: 1
height: 1
near clip plane: 0.3
far clip plane: 1000
field of view: 60
orthographic: 0
orthographic size: 5
m_Depth: -1
m_CullingMask:
serializedVersion: 2
m_Bits: 4294967295
m_RenderingPath: -1
m_TargetTexture: {fileID: 0}
m_TargetDisplay: 0
m_TargetEye: 3
m_HDR: 1
m_AllowMSAA: 1
m_AllowDynamicResolution: 0
m_ForceIntoRT: 0
m_OcclusionCulling: 1
m_StereoConvergence: 10
m_StereoSeparation: 0.022
--- !u!4 &930938402
Transform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 930938399}
m_LocalRotation: {x: 0.40781513, y: 0.5717275, z: -0.39053324, w: 0.5952296}
m_LocalPosition: {x: -58.925278, y: 240.21237, z: 32.426117}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 0}
m_RootOrder: 0
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!1 &1048576009
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 1048576011}
- component: {fileID: 1048576010}
m_Layer: 0
m_Name: Directional Light
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!108 &1048576010
Light:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1048576009}
m_Enabled: 1
serializedVersion: 10
m_Type: 1
m_Shape: 0
m_Color: {r: 1, g: 0.95686275, b: 0.8392157, a: 1}
m_Intensity: 1
m_Range: 10
m_SpotAngle: 30
m_InnerSpotAngle: 21.80208
m_CookieSize: 10
m_Shadows:
m_Type: 2
m_Resolution: -1
m_CustomResolution: -1
m_Strength: 1
m_Bias: 0.05
m_NormalBias: 0.4
m_NearPlane: 0.2
m_CullingMatrixOverride:
e00: 1
e01: 0
e02: 0
e03: 0
e10: 0
e11: 1
e12: 0
e13: 0
e20: 0
e21: 0
e22: 1
e23: 0
e30: 0
e31: 0
e32: 0
e33: 1
m_UseCullingMatrixOverride: 0
m_Cookie: {fileID: 0}
m_DrawHalo: 0
m_Flare: {fileID: 0}
m_RenderMode: 0
m_CullingMask:
serializedVersion: 2
m_Bits: 4294967295
m_RenderingLayerMask: 1
m_Lightmapping: 4
m_LightShadowCasterMode: 0
m_AreaSize: {x: 1, y: 1}
m_BounceIntensity: 1
m_ColorTemperature: 6570
m_UseColorTemperature: 0
m_BoundingSphereOverride: {x: 0, y: 0, z: 0, w: 0}
m_UseBoundingSphereOverride: 0
m_UseViewFrustumForShadowCasterCull: 1
m_ShadowRadius: 0
m_ShadowAngle: 0
--- !u!4 &1048576011
Transform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1048576009}
m_LocalRotation: {x: 0.40821788, y: -0.23456968, z: 0.10938163, w: 0.8754261}
m_LocalPosition: {x: 0, y: 3, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 0}
m_RootOrder: 1
m_LocalEulerAnglesHint: {x: 50, y: -30, z: 0}

View File

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 60c3109dddb001d4e98de05e7b75c9d0
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 84e050c280baab14bbe3b453ccc9be71
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 23800000
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 6c24bee7c9cc721478771b258bde21c8
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 23800000
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 00f95e44473b1c944addee61552ea559
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 981ee349220c683439f641749b4a1ba5
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -1,4 +1,5 @@
using System;
using Cysharp.Threading.Tasks;
using Game.Plugins.App;
using Google.Protobuf;
using Plugins.JNGame;
@ -21,6 +22,8 @@ namespace Script
async void Start()
{
Application.targetFrameRate = 120;
//创建UI
SceneManager.LoadScene("UIScene", LoadSceneMode.Additive);
@ -51,7 +54,6 @@ namespace Script
public void OnNSyncFrameBack(JNFrameInfo info)
{
Debug.Log(info.Index);
App.Sync.AddInput(info);
}

View File

@ -10,21 +10,10 @@ namespace Script
public class UIMain : MonoBehaviour
{
public Text frameLabel;
float f = 1.23456789f;
private void Awake()
{
DontDestroyOnLoad(this.gameObject);
}
//重置
public void OnClickReset()
{
GBattleModeManager.Instance.Open(GBattleMode.Default).Forget();
}
private void Update()
{
float f = 1.23456789f;
for (int i = 1000 - 1; i >= 0; i--)
{
// 进行一些基本的浮点数运算
@ -38,7 +27,18 @@ namespace Script
f = (float)Math.Log10(f);
f = (float)Math.Exp(f);
}
this.frameLabel.text = $"浮点数计算: {f} 服务器帧数: {App.Sync.NServerFrame} 本地运行帧 {App.Sync.NLocalFrame} 本地已执行帧 {App.Sync.NLocalRunFrame} 是否正在请求{App.Sync.IsRequestServerData} FPS:{1f/Time.deltaTime} this.DyTime():{App.Sync.DyTime()}";
DontDestroyOnLoad(this.gameObject);
}
//重置
public void OnClickReset()
{
GBattleModeManager.Instance.Open(GBattleMode.Default).Forget();
}
private void Update()
{
this.frameLabel.text = $"{Application.identifier} 浮点数计算: {f} 服务器帧数: {App.Sync.NServerFrame} 本地运行帧 {App.Sync.NLocalFrame} 本地已执行帧 {App.Sync.NLocalRunFrame} 是否正在请求{App.Sync.IsRequestServerData} \nFPS:{1f/Time.deltaTime} \nthis.DyTime():{App.Sync.DyTime()} \n一帧执行时间:{App.Sync.frameTime} \n是否追帧:{App.Sync.IsLoop}";
}
}
}

View File

@ -26,7 +26,7 @@ namespace Script.battle
public class GBattleModeManager : SingletonScene<GBattleModeManager>
{
private static readonly string[] Worlds = { "GRVO02World", };
private static readonly string[] Worlds = { "RVODemoMode", };
//当前模式
private GBattleMode _current = GBattleMode.Not;

View File

@ -24,7 +24,7 @@ namespace Game.Script.battle.mode.Example11_RVO
{
/// <summary>Number of agents created at start</summary>
public int agentCount = 100;
public int agentCount = 500;
/// <summary>All agents handled by this script</summary>
List<JNIAgent> agents;
/// <summary>Goals for each agent</summary>

View File

@ -2,6 +2,7 @@ using System.Collections;
using System.Collections.Generic;
using Game.Plugins.JNGame.Sync.Frame.AstarPath.RVO;
using Plugins.JNGame.Sync.Frame.AStar;
using Plugins.JNGame.Sync.Frame.AStar.Entity;
using Script.battle;
using UnityEngine;
@ -14,8 +15,16 @@ public class GRVO02WorldMode : GBaseMode<Object>
//初始化寻路
[HideInInspector]
public JNAStarPath AStar = new();
public JNAStarPath AStar;
//寻路数据
public AStarData aStarData;
public override void OnSyncLoad()
{
base.OnSyncLoad();
//初始化寻路
AStar = new(aStarData);
}
}

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 3003c5de0741eb5469be576d175235d4
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,11 @@
using System.Collections;
using System.Collections.Generic;
using Script.battle;
using UnityEngine;
public class NavDemo1Mode : GBaseMode<Object>
{
}

View File

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

View File

@ -0,0 +1,17 @@
using System.Collections;
using System.Collections.Generic;
using Game.Plugins.App.Sync;
using UnityEngine;
using UnityEngine.AI;
public class PlayerController : JNGSyncFrameDefault
{
public override void OnSyncLoad()
{
this.GetComponent<NavMeshAgent>().SetDestination(new Vector3(10, 0, 10));
}
public override void OnSyncUpdate(int dt, JNFrameInfo frame, Object input)
{
}
}

View File

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

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 3dba20acb72e94d43b26da3e8fdd4938
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,37 @@
using System.Collections;
using System.Collections.Generic;
using Game.Plugins.App.Game.RVO;
using Game.Plugins.JNGame.Sync.Frame.AstarPath.RVO;
using Script.battle;
using UnityEngine;
public class RVODemoMode : GBaseMode<Object>
{
//初始化避障
public JNRVOSimulator Simulator => GetComponent<JNGRVOManager>().Simulator;
//随机间隔
private int time = 0;
public override void OnSyncUpdate(int dt, JNFrameInfo frame, Object input)
{
base.OnSyncUpdate(dt, frame, input);
//随机目标点
time -= dt;
if (time <= 0)
{
time = 5000;
//随机
foreach (var child in this.GetComponentsInChildren<JNGRVOAgent>())
{
child.SetTarget(new Vector2(GetSync().nRandomFloat(-30,30),GetSync().nRandomFloat(-30,30)));
}
}
}
}

View File

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

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 31fa92abbc7f91d4e8ae419622b147a3
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 01a0f35a110673144bb55c6e354ec5c7
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 9031ae192067e544fbeee3a0259a52a4
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: ace6490bddd98dc4db2593c96cbdfbfb
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: f2c39abe66e24534292134621f4093c8
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 7730f92ca2b591949b126a64e5c3c57c
PrefabImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,390 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!1 &1775098162037991150
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 6878923127267220545}
- component: {fileID: 6197011580469307211}
m_Layer: 0
m_Name: Follow
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!4 &6878923127267220545
Transform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1775098162037991150}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children:
- {fileID: 435942663296321473}
m_Father: {fileID: 831249045711970444}
m_RootOrder: 0
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!114 &6197011580469307211
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1775098162037991150}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 497eadcd7a52d844fa7c95e8ebf69c6d, type: 3}
m_Name:
m_EditorClassIdentifier:
target: {fileID: 831249045711970444}
speed: 10
acceleration: 3
--- !u!1 &2386211960287522279
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 435942663296321473}
- component: {fileID: 3017034559823589115}
- component: {fileID: 2129083654873879346}
- component: {fileID: 2133768080196629757}
m_Layer: 0
m_Name: Sphere
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!4 &435942663296321473
Transform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 2386211960287522279}
m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
m_LocalPosition: {x: 0, y: 1, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children:
- {fileID: 655149030458067793}
- {fileID: 96954893901549327}
m_Father: {fileID: 6878923127267220545}
m_RootOrder: 0
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!33 &3017034559823589115
MeshFilter:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 2386211960287522279}
m_Mesh: {fileID: 10207, guid: 0000000000000000e000000000000000, type: 0}
--- !u!23 &2129083654873879346
MeshRenderer:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 2386211960287522279}
m_Enabled: 1
m_CastShadows: 1
m_ReceiveShadows: 1
m_DynamicOccludee: 1
m_StaticShadowCaster: 0
m_MotionVectors: 1
m_LightProbeUsage: 1
m_ReflectionProbeUsage: 1
m_RayTracingMode: 2
m_RayTraceProcedural: 0
m_RenderingLayerMask: 1
m_RendererPriority: 0
m_Materials:
- {fileID: 2100000, guid: 89c9a2320098bea428ef79090d18cf3e, type: 2}
m_StaticBatchInfo:
firstSubMesh: 0
subMeshCount: 0
m_StaticBatchRoot: {fileID: 0}
m_ProbeAnchor: {fileID: 0}
m_LightProbeVolumeOverride: {fileID: 0}
m_ScaleInLightmap: 1
m_ReceiveGI: 1
m_PreserveUVs: 0
m_IgnoreNormalsForChartDetection: 0
m_ImportantGI: 0
m_StitchLightmapSeams: 1
m_SelectedEditorRenderState: 3
m_MinimumChartSize: 4
m_AutoUVMaxDistance: 0.5
m_AutoUVMaxAngle: 89
m_LightmapParameters: {fileID: 0}
m_SortingLayerID: 0
m_SortingLayer: 0
m_SortingOrder: 0
m_AdditionalVertexStreams: {fileID: 0}
--- !u!135 &2133768080196629757
SphereCollider:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 2386211960287522279}
m_Material: {fileID: 0}
m_IsTrigger: 0
m_Enabled: 0
serializedVersion: 2
m_Radius: 0.5
m_Center: {x: 0, y: 0, z: 0}
--- !u!1 &6296402949535503056
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 6296402949535503058}
- component: {fileID: 837635383573187513}
m_Layer: 0
m_Name: Sim Agent (Sphere) Swarming
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!4 &6296402949535503058
Transform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 6296402949535503056}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children:
- {fileID: 831249045711970444}
m_Father: {fileID: 0}
m_RootOrder: 0
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!114 &837635383573187513
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 6296402949535503056}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 53cb4b6f50173b44dbb35bd1007d19d0, type: 3}
m_Name:
m_EditorClassIdentifier:
_settings:
AutomaticUpdate: 1
GroundCheck: 0
RotateTowardsMovingDirection: 1
RotateSpeed: 7
_movementSpeed: 15
_autoValidateCurrentPath: 1
_autoValidateTime: 0
_localAvoidanceRange: 1
_validateCurrentTile: 1
_keepAttemptingOnFail: 1
_onFailAttemptToNearestPoint: 1
_keepTryingToReadjustToWantedPosition: 1
_keepAttemptingTime: 0
_navigationType: 2
_traversableTiles: 0002
_prefferedTiles:
_rotateTransform: {fileID: 435942663296321473}
OnPathfindingSucceed:
m_PersistentCalls:
m_Calls: []
OnPathfindingFailed:
m_PersistentCalls:
m_Calls: []
OnMovingComplete:
m_PersistentCalls:
m_Calls: []
GizmosSettings:
ShowGizmos: 0
ShowPath: 0
ShowStartAndEnd: 0
ShowTraverableRange: 0
TraversableRange: 10
ShowValidTilesInRange: 0
ValidTileRange: 10
ShowClosestValidTileToWantedPosition: 1
--- !u!1 &6981759796174483828
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 831249045711970444}
m_Layer: 0
m_Name: Graphics
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!4 &831249045711970444
Transform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 6981759796174483828}
m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children:
- {fileID: 6878923127267220545}
m_Father: {fileID: 6296402949535503058}
m_RootOrder: 0
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!1 &7688531501311199483
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 96954893901549327}
- component: {fileID: 2974966843095431318}
- component: {fileID: 3405179864363915099}
- component: {fileID: 8337354972999760580}
m_Layer: 0
m_Name: Nose
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!4 &96954893901549327
Transform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 7688531501311199483}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0.449}
m_LocalScale: {x: 0.2, y: 0.2, z: 0.4}
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 435942663296321473}
m_RootOrder: 1
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!33 &2974966843095431318
MeshFilter:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 7688531501311199483}
m_Mesh: {fileID: 10202, guid: 0000000000000000e000000000000000, type: 0}
--- !u!23 &3405179864363915099
MeshRenderer:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 7688531501311199483}
m_Enabled: 1
m_CastShadows: 1
m_ReceiveShadows: 1
m_DynamicOccludee: 1
m_StaticShadowCaster: 0
m_MotionVectors: 1
m_LightProbeUsage: 1
m_ReflectionProbeUsage: 1
m_RayTracingMode: 2
m_RayTraceProcedural: 0
m_RenderingLayerMask: 1
m_RendererPriority: 0
m_Materials:
- {fileID: 2100000, guid: 8f09f022487ca214db3170d698836721, type: 2}
m_StaticBatchInfo:
firstSubMesh: 0
subMeshCount: 0
m_StaticBatchRoot: {fileID: 0}
m_ProbeAnchor: {fileID: 0}
m_LightProbeVolumeOverride: {fileID: 0}
m_ScaleInLightmap: 1
m_ReceiveGI: 1
m_PreserveUVs: 0
m_IgnoreNormalsForChartDetection: 0
m_ImportantGI: 0
m_StitchLightmapSeams: 1
m_SelectedEditorRenderState: 3
m_MinimumChartSize: 4
m_AutoUVMaxDistance: 0.5
m_AutoUVMaxAngle: 89
m_LightmapParameters: {fileID: 0}
m_SortingLayerID: 0
m_SortingLayer: 0
m_SortingOrder: 0
m_AdditionalVertexStreams: {fileID: 0}
--- !u!65 &8337354972999760580
BoxCollider:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 7688531501311199483}
m_Material: {fileID: 0}
m_IsTrigger: 0
m_Enabled: 1
serializedVersion: 2
m_Size: {x: 1, y: 1, z: 1}
m_Center: {x: 0, y: 0, z: 0}
--- !u!1 &8677368286820038855
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 655149030458067793}
m_Layer: 0
m_Name: Ground Check
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!4 &655149030458067793
Transform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 8677368286820038855}
m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
m_LocalPosition: {x: 0, y: -0.503, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 435942663296321473}
m_RootOrder: 0
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}

View File

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 15079c202370ea144abbba8088a435d6
PrefabImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,335 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!1 &2047879137188322637
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 2047879137188322638}
m_Layer: 0
m_Name: Ground Check
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!4 &2047879137188322638
Transform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 2047879137188322637}
m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
m_LocalPosition: {x: 0, y: -0.503, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 2047879137512849049}
m_RootOrder: 0
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!1 &2047879137315987393
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 2047879137315987395}
- component: {fileID: 2047879137315987452}
- component: {fileID: 4653686088517519016}
m_Layer: 0
m_Name: Sim Agent (Sphere)
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!4 &2047879137315987395
Transform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 2047879137315987393}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children:
- {fileID: 404205591593115796}
m_Father: {fileID: 0}
m_RootOrder: 0
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!114 &2047879137315987452
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 2047879137315987393}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: e31c7a1c22f26de4698459dd6ccada5b, type: 3}
m_Name:
m_EditorClassIdentifier:
_groundLayers:
serializedVersion: 2
m_Bits: 64
_raycastSpot: {fileID: 2047879137188322638}
_rayCastDistance: 100
_rayCastElevatedDistance: 100
_rayCastEveryXFrames: 3
_effectTransform: {fileID: 404205591593115796}
_floatAmount: 0.01
_raycastDirection: {x: 0, y: -1, z: 0}
AttemptTeleportUpOnFail: 0
--- !u!114 &4653686088517519016
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 2047879137315987393}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 53cb4b6f50173b44dbb35bd1007d19d0, type: 3}
m_Name:
m_EditorClassIdentifier:
_settings:
AutomaticUpdate: 1
GroundCheck: 0
RotateTowardsMovingDirection: 1
RotateSpeed: 5
_movementSpeed: 6
_autoValidateCurrentPath: 1
_autoValidateTime: 0
_localAvoidanceRange: 15
_validateCurrentTile: 1
_keepAttemptingOnFail: 1
_keepAttemptingTime: 0
_navigationType: 2
_traversableTiles: 0002
_prefferedTiles:
_rotateTransform: {fileID: 2047879137512849049}
OnPathfindingSucceed:
m_PersistentCalls:
m_Calls: []
OnPathfindingFailed:
m_PersistentCalls:
m_Calls: []
OnMovingComplete:
m_PersistentCalls:
m_Calls: []
GizmosSettings:
ShowGizmos: 0
ShowPath: 0
ShowStartAndEnd: 0
ShowTraverableRange: 0
TraversableRange: 10
ShowValidTilesInRange: 0
ValidTileRange: 10
--- !u!1 &2047879137512849048
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 2047879137512849049}
- component: {fileID: 2047879137512849044}
- component: {fileID: 2047879137512849051}
m_Layer: 0
m_Name: Sphere
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!4 &2047879137512849049
Transform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 2047879137512849048}
m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
m_LocalPosition: {x: 0, y: 1, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children:
- {fileID: 2047879137188322638}
- {fileID: 9132513750465556029}
m_Father: {fileID: 404205591593115796}
m_RootOrder: 0
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!33 &2047879137512849044
MeshFilter:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 2047879137512849048}
m_Mesh: {fileID: 10207, guid: 0000000000000000e000000000000000, type: 0}
--- !u!23 &2047879137512849051
MeshRenderer:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 2047879137512849048}
m_Enabled: 1
m_CastShadows: 1
m_ReceiveShadows: 1
m_DynamicOccludee: 1
m_StaticShadowCaster: 0
m_MotionVectors: 1
m_LightProbeUsage: 1
m_ReflectionProbeUsage: 1
m_RayTracingMode: 2
m_RayTraceProcedural: 0
m_RenderingLayerMask: 1
m_RendererPriority: 0
m_Materials:
- {fileID: 2100000, guid: 89c9a2320098bea428ef79090d18cf3e, type: 2}
m_StaticBatchInfo:
firstSubMesh: 0
subMeshCount: 0
m_StaticBatchRoot: {fileID: 0}
m_ProbeAnchor: {fileID: 0}
m_LightProbeVolumeOverride: {fileID: 0}
m_ScaleInLightmap: 1
m_ReceiveGI: 1
m_PreserveUVs: 0
m_IgnoreNormalsForChartDetection: 0
m_ImportantGI: 0
m_StitchLightmapSeams: 1
m_SelectedEditorRenderState: 3
m_MinimumChartSize: 4
m_AutoUVMaxDistance: 0.5
m_AutoUVMaxAngle: 89
m_LightmapParameters: {fileID: 0}
m_SortingLayerID: 0
m_SortingLayer: 0
m_SortingOrder: 0
m_AdditionalVertexStreams: {fileID: 0}
--- !u!1 &4781814520866498324
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 404205591593115796}
m_Layer: 0
m_Name: Graphics
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!4 &404205591593115796
Transform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 4781814520866498324}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children:
- {fileID: 2047879137512849049}
m_Father: {fileID: 2047879137315987395}
m_RootOrder: 0
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!1 &7171135500416411219
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 9132513750465556029}
- component: {fileID: 7239096232326157073}
- component: {fileID: 4297059256315128118}
m_Layer: 0
m_Name: Nose
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!4 &9132513750465556029
Transform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 7171135500416411219}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0.449}
m_LocalScale: {x: 0.2, y: 0.2, z: 0.4}
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 2047879137512849049}
m_RootOrder: 1
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!33 &7239096232326157073
MeshFilter:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 7171135500416411219}
m_Mesh: {fileID: 10202, guid: 0000000000000000e000000000000000, type: 0}
--- !u!23 &4297059256315128118
MeshRenderer:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 7171135500416411219}
m_Enabled: 1
m_CastShadows: 1
m_ReceiveShadows: 1
m_DynamicOccludee: 1
m_StaticShadowCaster: 0
m_MotionVectors: 1
m_LightProbeUsage: 1
m_ReflectionProbeUsage: 1
m_RayTracingMode: 2
m_RayTraceProcedural: 0
m_RenderingLayerMask: 1
m_RendererPriority: 0
m_Materials:
- {fileID: 2100000, guid: 8f09f022487ca214db3170d698836721, type: 2}
m_StaticBatchInfo:
firstSubMesh: 0
subMeshCount: 0
m_StaticBatchRoot: {fileID: 0}
m_ProbeAnchor: {fileID: 0}
m_LightProbeVolumeOverride: {fileID: 0}
m_ScaleInLightmap: 1
m_ReceiveGI: 1
m_PreserveUVs: 0
m_IgnoreNormalsForChartDetection: 0
m_ImportantGI: 0
m_StitchLightmapSeams: 1
m_SelectedEditorRenderState: 3
m_MinimumChartSize: 4
m_AutoUVMaxDistance: 0.5
m_AutoUVMaxAngle: 89
m_LightmapParameters: {fileID: 0}
m_SortingLayerID: 0
m_SortingLayer: 0
m_SortingOrder: 0
m_AdditionalVertexStreams: {fileID: 0}

View File

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: a8473a725de512d49be6662ebe419f2c
PrefabImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,230 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!1 &7937144498105071957
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 7937144498105071958}
m_Layer: 0
m_Name: Ground Check
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!4 &7937144498105071958
Transform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 7937144498105071957}
m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
m_LocalPosition: {x: 0, y: -0.503, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 7937144498316270209}
m_RootOrder: 0
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!1 &7937144498261572569
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 7937144498261572571}
- component: {fileID: 7937144498261572570}
- component: {fileID: 7937144498261572580}
m_Layer: 0
m_Name: Test Agent (Sphere) - Ground Check
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!4 &7937144498261572571
Transform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 7937144498261572569}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 137.7, y: 8.14, z: -5.8}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children:
- {fileID: 7937144498316270209}
m_Father: {fileID: 0}
m_RootOrder: 0
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!114 &7937144498261572570
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 7937144498261572569}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: c4d0b4f704fd2524b9c526c68324c99c, type: 3}
m_Name:
m_EditorClassIdentifier:
_settings:
AutomaticUpdate: 1
GroundCheck: 0
_movementSpeed: 6
_autoValidateCurrentPath: 0
_autoValidateTime: 1.5
_localAvoidanceRange: -1
_validateCurrentTile: 1
_keepAttemptingOnFail: 1
_keepAttemptingTime: 1.5
_navigationType: 2
_traversableTiles: 0002
_prefferedTiles:
OnPathfindingSucceed:
m_PersistentCalls:
m_Calls: []
OnPathfindingFailed:
m_PersistentCalls:
m_Calls: []
OnMovingComplete:
m_PersistentCalls:
m_Calls: []
GizmosSettings:
ShowGizmos: 0
ShowPath: 0
ShowStartAndEnd: 0
ShowTraverableRange: 0
TraversableRange: 10
ShowValidTilesInRange: 0
ValidTileRange: 10
--- !u!114 &7937144498261572580
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 7937144498261572569}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: e31c7a1c22f26de4698459dd6ccada5b, type: 3}
m_Name:
m_EditorClassIdentifier:
_groundLayers:
serializedVersion: 2
m_Bits: 64
_raycastSpot: {fileID: 7937144498105071958}
_rayCastDistance: 100
_rayCastElevatedDistance: 100
_rayCastEveryXFrames: 3
_effectTransform: {fileID: 7937144498316270209}
_floatAmount: 1
_raycastDirection: {x: 0, y: -1, z: 0}
AttemptTeleportUpOnFail: 0
--- !u!1 &7937144498316270208
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 7937144498316270209}
- component: {fileID: 7937144498316270220}
- component: {fileID: 7937144498316270211}
- component: {fileID: 7937144498316270210}
m_Layer: 0
m_Name: Sphere
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!4 &7937144498316270209
Transform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 7937144498316270208}
m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
m_LocalPosition: {x: 0, y: 0.5, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children:
- {fileID: 7937144498105071958}
m_Father: {fileID: 7937144498261572571}
m_RootOrder: 0
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!33 &7937144498316270220
MeshFilter:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 7937144498316270208}
m_Mesh: {fileID: 10207, guid: 0000000000000000e000000000000000, type: 0}
--- !u!23 &7937144498316270211
MeshRenderer:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 7937144498316270208}
m_Enabled: 1
m_CastShadows: 1
m_ReceiveShadows: 1
m_DynamicOccludee: 1
m_StaticShadowCaster: 0
m_MotionVectors: 1
m_LightProbeUsage: 1
m_ReflectionProbeUsage: 1
m_RayTracingMode: 2
m_RayTraceProcedural: 0
m_RenderingLayerMask: 1
m_RendererPriority: 0
m_Materials:
- {fileID: 2100000, guid: 89c9a2320098bea428ef79090d18cf3e, type: 2}
m_StaticBatchInfo:
firstSubMesh: 0
subMeshCount: 0
m_StaticBatchRoot: {fileID: 0}
m_ProbeAnchor: {fileID: 0}
m_LightProbeVolumeOverride: {fileID: 0}
m_ScaleInLightmap: 1
m_ReceiveGI: 1
m_PreserveUVs: 0
m_IgnoreNormalsForChartDetection: 0
m_ImportantGI: 0
m_StitchLightmapSeams: 1
m_SelectedEditorRenderState: 3
m_MinimumChartSize: 4
m_AutoUVMaxDistance: 0.5
m_AutoUVMaxAngle: 89
m_LightmapParameters: {fileID: 0}
m_SortingLayerID: 0
m_SortingLayer: 0
m_SortingOrder: 0
m_AdditionalVertexStreams: {fileID: 0}
--- !u!135 &7937144498316270210
SphereCollider:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 7937144498316270208}
m_Material: {fileID: 0}
m_IsTrigger: 0
m_Enabled: 0
serializedVersion: 2
m_Radius: 0.5
m_Center: {x: 0, y: 0, z: 0}

View File

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 2b30a5ad4e8df2d4ab07c3b0631653e6
PrefabImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 28c562fe0ac977547a1aa075439ce2c2
PrefabImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

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