From 7aa8798b8400dd111730cf0d4415f1d02160ca4b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E6=B3=A0=E6=BC=AA?=
<32807696+AngelShadow2017@users.noreply.github.com>
Date: Wed, 9 Apr 2025 05:47:46 +0800
Subject: [PATCH 1/9] collidermodifications
---
.../.idea/.gitignore | 13 +
.../.idea/encodings.xml | 4 +
.../.idea/indexLayout.xml | 8 +
.../.idea.something_jobLearning/.idea/vcs.xml | 6 +
Assets/ColliderObj.cs | 1620 +++++++++++++++++
Assets/ColliderObj.cs.meta | 2 +
Assets/ColliderStructure.cs | 378 ++++
Assets/ColliderStructure.cs.meta | 3 +
Assets/HashTypeHelpers.cs | 458 +++++
Assets/HashTypeHelpers.cs.meta | 2 +
Assets/JobsTesting.cs | 80 +-
Assets/PoolingManager.cs | 47 +
Assets/PoolingManager.cs.meta | 2 +
Assets/Scenes/SampleScene.unity | 32 +-
Assets/TrueSync/Fix64.cs | 2 +
Assets/TrueSync/Fuck.cs | 8 +
Assets/TrueSync/Fuck.cs.meta | 3 +
Assets/TrueSync/TSVector2.cs | 34 +-
Assets/math.cs | 511 ++++++
Assets/math.cs.meta | 2 +
Assets/tmpExtensions.cs | 45 +
Assets/tmpExtensions.cs.meta | 3 +
.../BurstAotSettings_StandaloneWindows.json | 18 +
ProjectSettings/CommonBurstAotSettings.json | 6 +
ProjectSettings/SceneTemplateSettings.json | 121 ++
25 files changed, 3378 insertions(+), 30 deletions(-)
create mode 100644 .idea/.idea.something_jobLearning/.idea/.gitignore
create mode 100644 .idea/.idea.something_jobLearning/.idea/encodings.xml
create mode 100644 .idea/.idea.something_jobLearning/.idea/indexLayout.xml
create mode 100644 .idea/.idea.something_jobLearning/.idea/vcs.xml
create mode 100644 Assets/ColliderObj.cs
create mode 100644 Assets/ColliderObj.cs.meta
create mode 100644 Assets/ColliderStructure.cs
create mode 100644 Assets/ColliderStructure.cs.meta
create mode 100644 Assets/HashTypeHelpers.cs
create mode 100644 Assets/HashTypeHelpers.cs.meta
create mode 100644 Assets/PoolingManager.cs
create mode 100644 Assets/PoolingManager.cs.meta
create mode 100644 Assets/TrueSync/Fuck.cs
create mode 100644 Assets/TrueSync/Fuck.cs.meta
create mode 100644 Assets/math.cs
create mode 100644 Assets/math.cs.meta
create mode 100644 Assets/tmpExtensions.cs
create mode 100644 Assets/tmpExtensions.cs.meta
create mode 100644 ProjectSettings/BurstAotSettings_StandaloneWindows.json
create mode 100644 ProjectSettings/CommonBurstAotSettings.json
create mode 100644 ProjectSettings/SceneTemplateSettings.json
diff --git a/.idea/.idea.something_jobLearning/.idea/.gitignore b/.idea/.idea.something_jobLearning/.idea/.gitignore
new file mode 100644
index 0000000..728bffe
--- /dev/null
+++ b/.idea/.idea.something_jobLearning/.idea/.gitignore
@@ -0,0 +1,13 @@
+# 默认忽略的文件
+/shelf/
+/workspace.xml
+# Rider 忽略的文件
+/modules.xml
+/contentModel.xml
+/projectSettingsUpdater.xml
+/.idea.something_jobLearning.iml
+# 基于编辑器的 HTTP 客户端请求
+/httpRequests/
+# Datasource local storage ignored files
+/dataSources/
+/dataSources.local.xml
diff --git a/.idea/.idea.something_jobLearning/.idea/encodings.xml b/.idea/.idea.something_jobLearning/.idea/encodings.xml
new file mode 100644
index 0000000..df87cf9
--- /dev/null
+++ b/.idea/.idea.something_jobLearning/.idea/encodings.xml
@@ -0,0 +1,4 @@
+
+
+
+
\ No newline at end of file
diff --git a/.idea/.idea.something_jobLearning/.idea/indexLayout.xml b/.idea/.idea.something_jobLearning/.idea/indexLayout.xml
new file mode 100644
index 0000000..7b08163
--- /dev/null
+++ b/.idea/.idea.something_jobLearning/.idea/indexLayout.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/.idea.something_jobLearning/.idea/vcs.xml b/.idea/.idea.something_jobLearning/.idea/vcs.xml
new file mode 100644
index 0000000..35eb1dd
--- /dev/null
+++ b/.idea/.idea.something_jobLearning/.idea/vcs.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Assets/ColliderObj.cs b/Assets/ColliderObj.cs
new file mode 100644
index 0000000..5dc5eb8
--- /dev/null
+++ b/Assets/ColliderObj.cs
@@ -0,0 +1,1620 @@
+using System;
+using System.Collections.Generic;
+using TrueSync;
+using UnityEngine;
+using UnityEngine.Pool;
+using ZeroAs.DOTS.Colliders;
+
+namespace Core.Algorithm
+{
+ public interface ICollideShape {
+ public ref ColliderStructure Collider { get; }
+ //获取在某个方向上的最远点
+ public TSVector2 GetFurthestPoint(in TSVector2 direction);
+ //设置该形状的旋转角
+ public void SetRotation(FP rotRad);
+ public void SetCenter(in TSVector2 center);
+ public TSVector2 GetCenter();
+ //左上点和右下点!!!
+ public TSVector4 GetBoundingBox();
+ public CollisionManager.CollisionGroup colliGroup { get; set; }
+ public bool enabled { get; set; }
+ public void DebugDisplayColliderShape(Color color);
+ }
+ public interface IMasteredCollider
+ {
+ public T Master { get; set; }
+ }
+ [Serializable]
+ public abstract class ColliderBase : ICollideShape
+ {
+ public ColliderStructure collider;
+
+ public ref ColliderStructure Collider => ref collider;
+ protected CollisionManager.CollisionGroup __colli__ = CollisionManager.CollisionGroup.Default;
+ protected bool __enabled__ = true;
+ public int tag = -1;//用来识别特定的tag
+ public CollisionManager.CollisionGroup colliGroup {
+ get
+ {
+ return __colli__;
+ }
+ set
+ {
+ __colli__ = value;
+ }
+ }
+ public bool enabled
+ {
+ get
+ {
+ return __enabled__;
+ }
+ set
+ {
+ __enabled__ = value;
+ }
+ }
+
+ static TSVector2 SupportFunc(ColliderBase shape1,ColliderBase shape2,TSVector2 direciton) {
+ //Debug.Log("direction: "+direciton+" "+ shape1.GetFurthestPoint(direciton)+" "+shape2.GetFurthestPoint(-direciton));
+ return shape1.GetFurthestPoint(direciton) - shape2.GetFurthestPoint(-direciton);
+ }
+ static TSVector2 TripleProduct2d(TSVector2 a,TSVector2 b,TSVector2 c) {
+ FP sign = (a.x * b.y - a.y * b.x);
+ return new TSVector2(-c.y, c.x) * sign;
+ }
+ public abstract TSVector4 GetBoundingBox();
+ public TSVector2 GetFurthestPoint(in TSVector2 direction)
+ {
+ GetFurthestPointExtensions.GetFurthestPoint(out var result, collider, direction);
+ return result;
+ }
+ public abstract void SetRotation(FP rotRad);
+ public abstract void SetCenter(in TSVector2 center);
+ public abstract TSVector2 GetCenter();
+ public static bool CheckCollide(ColliderBase shape1, ColliderBase shape2) {
+ /*
+ #两个形状s1,s2相交则返回True。所有的向量/点都是二维的,例如([x,y])
+ #第一步:选择一个初始方向,这个初始方向可以是随机选择的,但通常来说是两个形状中心之间的向量,即:
+
+ */
+ TSVector2 direction = (shape2.GetCenter() - shape1.GetCenter()).normalized;
+ //#第二步:找到支撑点,即第一个支撑点(即闵可夫斯基差的边上的点之一……)
+ TSVector2[] Simplex = new TSVector2[3];//单纯形数组,最多只能是3个
+ Simplex[0] = SupportFunc(shape1, shape2, direction);
+ int simplexLastInd = 1;
+ int interateTimeMax = 100;//最大迭代次数
+ //#第三步:找到第一个支撑点后,以第一个支撑点为起点指向原点O的方向为新方向d
+ direction = -Simplex[0].normalized;
+ //#第四步:开始循环,找下一个支撑点
+ while (interateTimeMax-- > 0)
+ {
+ TSVector2 A = SupportFunc(shape1,shape2,direction);
+ //因为A点是闵可夫斯基差形状在给定方向的最远点,如果那个点没有超过原点,就不想交
+ //#当新的支撑点A没有包含原点,那我们就返回False,即两个形状没有相交
+ if (TSVector2.Dot(A,direction)<0) {
+ return false;
+ }
+ Simplex[simplexLastInd++] = A;
+ //Debug.Log("input: "+A+shape1.GetType()+" "+shape2.GetType());
+ //处理为线段的情况
+ if (simplexLastInd == 2)
+ {
+ //三维的处理方式
+ /*
+ TSVector AB = Simplex[simplexLastInd-2] - Simplex[simplexLastInd - 1];
+ TSVector AO = -Simplex[simplexLastInd-1];
+ TSVector ABPrep = TSVector.Cross(TSVector.Cross(AB, AO),AB);//垂直于AB的那个点!
+ */
+ //在2d里面可以这么简化
+ TSVector2 AB = Simplex[simplexLastInd - 2] - Simplex[simplexLastInd - 1];
+ TSVector2 AO = -Simplex[simplexLastInd - 1];
+ TSVector2 ABPrep = TripleProduct2d(AB,AO,AB);
+ direction = ABPrep.normalized;
+ /*
+ * A是最新插入的点,B是第一次插入的点
+ 当我们拥有两个点时,我们怎么选择新的方向?
+ 1. 构建向量:
+ o 构建向量 𝐴𝑂(从点A到原点O),即 𝐴𝑂=𝑂−𝐴
+ o 构建向量 𝐴𝐵(从点A到点B),即 𝐴𝐵=𝐵−𝐴
+ 2. 求解垂直向量:
+ o 通过叉积 𝐴𝐵×𝐴𝑂,我们可以得到一个垂直于这两个向量的向量。这个向量垂直于 𝐴𝐵 和 𝐴𝑂 所在的平面,并且指向由右手定则决定的方向。
+ 3. 求解新的方向:
+ o 为了得到新的方向 𝑑,我们需要一个向量,这个向量既垂直于 𝐴𝐵×𝐴𝑂,又垂直于 𝐴𝐵。这可以通过三重积来实现,即:
+ 𝑑=(𝐴𝐵×𝐴𝑂)×𝐴𝐵
+ 这个三重积的结果是一个向量,它垂直于 𝐴𝐵 和 𝐴𝐵×𝐴𝑂 所在的平面。换句话说,它是垂直于 𝐴𝐵 的并且指向原点的可能性最大。
+
+ 简单来说:通过选择垂直于 𝐴𝐵 的方向,我们可以在最有可能包含原点的方向上进行搜索,从而提高搜索效率。
+ */
+ }
+ else//处理为三角形的情况
+ {
+ //C是单纯形第一次插入的元素,B是第二次插入的,A是最后插入的
+ //构建向量AB,AC与AO,并来检测原点在空间的哪个沃罗诺伊区域(通过排除法可以知道肯定在AB或AC或ABC三角形内部区域)
+ TSVector2 AC = Simplex[simplexLastInd - 3] - Simplex[simplexLastInd - 1];
+ TSVector2 AB = Simplex[simplexLastInd - 2] - Simplex[simplexLastInd - 1];
+ TSVector2 AO = -Simplex[simplexLastInd - 1];
+ //#通过三重积 分别得到垂直于AB、AC转向特定方向的的向量,检测区域Rab、Rac中是否包含原点。
+ TSVector2 ABPrep = TripleProduct2d(AC, AB, AB).normalized;
+ TSVector2 ACPrep = TripleProduct2d(AB, AC, AC).normalized;
+ //Debug.Log(ABPrep+" "+ACPrep+" "+AC+" "+AB+" "+AO);
+ //#如果原点在AB区域中,我们移除点C以寻找更加完美的simplex(C离原点最远),新的方向就是垂直于AB的向量
+ if (TSVector2.Dot(ABPrep, AO) > 0)
+ {
+ for (int i = 1; i < 3; i++)
+ {
+ Simplex[i - 1] = Simplex[i];
+ }//删除数组首个元素(C点),当前的单纯形并不包含原点,
+ simplexLastInd--;
+ direction = ABPrep;
+ } else if (TSVector2.Dot(ACPrep, AO) > 0) {
+ //#如果原点在AC区域中,我们移除点B以寻找更加完美的simplex,新的方向就是垂直于AC的向量
+ Simplex[simplexLastInd - 2] = Simplex[simplexLastInd-1];
+ simplexLastInd--;
+ direction = ACPrep;
+ }
+ else
+ {
+ //否则单纯形包含原点,碰到了
+ return true;
+ }
+ }
+ }
+ //如果超过迭代次数都没有找到点,则判定为没有碰到。
+ return false;
+ }
+ public virtual bool CheckCollide(ColliderBase shape2) {
+ return CheckCollide(this, shape2);
+ }
+ public virtual void DebugDisplayColliderShape(Color color) { }
+ }
+ [Serializable]
+ public abstract class ColliderBase : ColliderBase
+ {
+ public T Master;
+ }
+ [Serializable]
+ public class CircleCollider : ColliderBase
+ {
+ public CircleCollider(FP R,TSVector2 center,CollisionManager.CollisionGroup group = CollisionManager.CollisionGroup.Default)
+ {
+ Collider = new ColliderStructure()
+ {
+ colliderType = ColliderType.Circle,
+ radius = R,
+ center = center
+ };
+
+ colliGroup = group;
+ }
+ public override void SetRotation(FP rotRad) { }//没错,圆形没有旋转
+ public override void SetCenter(in TSVector2 center)
+ {
+ Collider.center = center;
+ }
+ public override TSVector2 GetCenter()
+ {
+ return Collider.center;
+ }
+ /*public override TSVector2 GetFurthestPoint(in TSVector2 direction)
+ {
+ GetFurthestPointExtensions.GetFurthestPoint(out var result, this.Collider, direction);
+ return result;
+ }*/
+ public override TSVector4 GetBoundingBox()
+ {
+ TSVector2 centerPos = GetCenter();
+ FP r = this.Collider.radius;
+ return new TSVector4(centerPos.x-r,centerPos.y+r,centerPos.x+r,centerPos.y-r);
+ }
+ bool CircleCollideWithCircle(CircleCollider shape2)
+ {
+ return CollideExtensions.CircleCollideWithCircle(this.Collider,shape2.Collider);
+ }
+ public override bool CheckCollide(ColliderBase shape2)
+ {
+ if(shape2 is CircleCollider sh)
+ {
+ return CircleCollideWithCircle(sh);
+ }else if(shape2 is DoubleCircleCollider d)
+ {
+
+ //Debug.Log(d.CircleCollideWithCircle(this));
+ return d.CircleCollideWithCircle(this);
+ }
+ return CheckCollide(this, shape2);
+ }
+ public override void DebugDisplayColliderShape(Color color)
+ {
+ float r = (float)collider.radius;
+ int circleCount = Mathf.FloorToInt(Mathf.Lerp(5,8,((float)r)/72f));
+ float angleDelta = 2 * Mathf.PI / circleCount;
+
+ GL.Begin(GL.TRIANGLE_STRIP);
+ GL.Color(color);
+
+ for (int i = 0; i < circleCount + 1; i++)
+ {
+ float angle = angleDelta * i;
+ float angleNext = angle + angleDelta;
+ Vector3 cent = GetCenter().ToVector();
+ Vector3 cent2 = new Vector3(Mathf.Cos(angle) * (float)r, Mathf.Sin(angle) * (float)r, 0) + cent;
+ GL.Vertex3(cent2.x,cent2.y,cent2.z);
+ GL.Vertex3(cent.x,cent.y,cent.z);
+ }
+
+ GL.End();
+ }
+ }
+ [Serializable]
+ public class CircleCollider : CircleCollider,IMasteredCollider
+ {
+ T _master_;
+ public T Master {
+ get => _master_;
+ set => _master_ = value;
+ }
+
+ public CircleCollider(T master,FP R, TSVector2 center, CollisionManager.CollisionGroup group = CollisionManager.CollisionGroup.Default) : base(R, center, group)
+ {
+ this._master_ = master;
+ }
+
+ }
+ [Serializable]
+ public class OvalCollider : ColliderBase
+ {
+ //public FP rot, b2Dividea2;//旋转,长轴方除以短轴方,因为定点数除法……真的太慢了。。。
+ //public TSVector2 Axis,SqrAxis;//半长轴和半短轴?其实应该叫水平轴和竖直轴
+ //TSVector2 centerPos;
+ public OvalCollider(TSVector2 axis, TSVector2 center,in FP rotation, CollisionManager.CollisionGroup group = CollisionManager.CollisionGroup.Default)
+ {
+ collider = new ColliderStructure()
+ {
+ colliderType = ColliderType.Oval,
+ rot = rotation,
+ center = center
+ };
+ SetAxis(axis);
+ colliGroup = group;
+ }
+ public void SetAxis(TSVector2 axis) {
+ collider.Axis = axis;
+ collider.SqrAxis = new TSVector2(TSMath.FastQuadratic(axis.x), TSMath.FastQuadratic(axis.y));
+ if (collider.SqrAxis.x == 0)
+ {
+ collider.b2Dividea2 = FP.MaxValue;
+ }
+ else
+ {
+ collider.b2Dividea2 = collider.SqrAxis.y / collider.SqrAxis.x;
+ }
+ }
+ public override void SetRotation(FP rotRad) {
+ collider.rot = rotRad;
+ }//没错,圆形没有旋转
+ public override void SetCenter(in TSVector2 center)
+ {
+ collider.center = center;
+ }
+ public override TSVector2 GetCenter()
+ {
+ return collider.center;
+ }
+ /*public override TSVector2 GetFurthestPoint(in TSVector2 direction)
+ {
+
+ //sin和cos还是很快的,因为是线性插值……有Lut
+ direction = direction.RotateRad(-rot);
+ if (direction.x == 0)
+ {
+ return (TSMath.Sign(direction.y)*Axis.y * TSVector2.up).RotateRad(rot) + centerPos;
+ }else if (direction.y == 0)
+ {
+ return (TSMath.Sign(direction.x) * Axis.x * TSVector2.right).RotateRad(rot) + centerPos;
+ }
+ FP signX = TSMath.Sign(direction.x);
+ FP k = direction.y / direction.x;//目标斜率
+ FP a2 = SqrAxis.x;
+ FP b2 = SqrAxis.y;
+ FP ratio = FP.OverflowMul(k, b2Dividea2);
+ FP denominator = FP.OverflowAdd(1, FP.OverflowMul(k, ratio));
+ if (denominator >= FP.MaxValue || denominator <= FP.MinValue)
+ {
+ //Debug.Log("denominatorOverflow "+ direction + " "+ new TSVector2(0, TSMath.Sign(direction.y) * Axis.y).RotateRad(rot));
+ return new TSVector2(0, TSMath.Sign(direction.y) * Axis.y).RotateRad(rot) + centerPos;
+ }
+ FP value = 1.0/denominator;
+
+ FP tarX = signX * (Axis.x*TSMath.Sqrt(value));
+ FP tarY = FP.OverflowMul(tarX,ratio);
+ //Debug.Log("ovalthings: "+tarX+" "+tarY+" "+k+" "+ratio);
+ if (tarY >= FP.MaxValue||tarY<=FP.MinValue)
+ {
+ return new TSVector2(0, TSMath.Sign(direction.y)*Axis.y).RotateRad(rot) + centerPos;
+ }
+ return new TSVector2(tarX,tarY).RotateRad(rot)+centerPos;
+ }*/
+ //椭圆的包围盒超级难算,懒了,就这样吧。
+ public override TSVector4 GetBoundingBox()
+ {
+ FP maxBorder = TSMath.Max(collider.Axis.x, collider.Axis.y);
+ return new TSVector4(collider.center.x - collider.Axis.x, collider.center.y + collider.Axis.x, collider.center.x + collider.Axis.x, collider.center.y - collider.Axis.x);
+ }
+ public override void DebugDisplayColliderShape(Color color)
+ {
+ int circleCount = Mathf.FloorToInt(Mathf.Lerp(16, 32, ((float)collider.Axis.x) / 72f));
+ Vector2 size = collider.Axis.ToVector();
+ Vector3 cent = collider.center.ToVector();
+ float rotRad = ((float)collider.rot);
+ GL.Begin(GL.TRIANGLE_STRIP);
+ GL.Color(color);
+ float angleDelta = 2 * Mathf.PI / circleCount;
+ for (int i = 0; i < circleCount + 1; i++)
+ {
+ float angle = angleDelta * i;
+ float angleNext = angle + angleDelta;
+ Vector2 cent2 = new Vector2(Mathf.Cos(angle) * size.x, Mathf.Sin(angle) * size.y);
+ cent2 = cent2.RotateRad(rotRad);
+ GL.Vertex3(cent2.x+cent.x, cent2.y + cent.y, cent.z);
+ GL.Vertex3(cent.x, cent.y, cent.z);
+ }
+ GL.End();
+ }
+ }
+ [Serializable]
+ public class OvalCollider : OvalCollider, IMasteredCollider
+ {
+ T _master_;
+ public T Master
+ {
+ get => _master_;
+ set => _master_ = value;
+ }
+
+ public OvalCollider(T master, TSVector2 axis, TSVector2 center, FP rotation, CollisionManager.CollisionGroup group = CollisionManager.CollisionGroup.Default) : base(axis, center,rotation, group)
+ {
+ this._master_ = master;
+ }
+
+ }
+ [Serializable]
+ public class PolygonCollider : ColliderBase
+ {
+ public FP rot;
+ public TSVector2[] vertexs,movedVertexs;
+ public TSVector2 centerPos;
+ TSVector4 _boundingBox_=TSVector4.zero;
+ public PolygonCollider() {
+
+ //throw new System.NotImplementedException("必须为顶点赋值");
+ }
+ public PolygonCollider(TSVector2[] vertex, TSVector2 center, FP rotation, CollisionManager.CollisionGroup group = CollisionManager.CollisionGroup.Default)
+ {
+ movedVertexs = new TSVector2[vertex.Length]; //边数是不能变的
+ centerPos = center;
+ SetRotation(rotation);
+ colliGroup = group;
+ }
+ public override void SetRotation(FP rotRad)
+ {
+ rot = rotRad;
+ RotateVertexs();
+ }//没错,圆形没有旋转
+ public override void SetCenter(in TSVector2 center)
+ {
+ MoveDeltaPos(center-centerPos);
+ centerPos = center;
+ }
+ public override TSVector2 GetCenter()
+ {
+ return centerPos;
+ }
+ void RotateVertexs()
+ {
+ TSVector4 tSVector4 = new TSVector4(FP.MaxValue, FP.MinValue, FP.MinValue, FP.MaxValue);
+ for (int i = movedVertexs.Length - 1; i >= 0; --i)
+ {
+ movedVertexs[i] = vertexs[i].RotateRad(rot) + centerPos;
+ if (movedVertexs[i].x > tSVector4.z)
+ {
+ tSVector4.z= movedVertexs[i].x;
+ }
+ if (movedVertexs[i].x < tSVector4.x)
+ {
+ tSVector4.x = movedVertexs[i].x;
+ }
+ if (movedVertexs[i].y > tSVector4.y)
+ {
+ tSVector4.y = movedVertexs[i].y;//最大值,代表上方点
+ }
+ if (movedVertexs[i].y < tSVector4.w)
+ {
+ tSVector4.w = movedVertexs[i].y;//最小值,代表下方点
+ }
+ }
+ _boundingBox_ = tSVector4;
+ }
+ void MoveDeltaPos(TSVector2 pos)
+ {
+ for (int i = movedVertexs.Length - 1; i >= 0; --i)
+ {
+ movedVertexs[i] += pos;
+ }
+ _boundingBox_.x += pos.x;
+ _boundingBox_.y += pos.y;
+ _boundingBox_.z += pos.x;
+ _boundingBox_.w += pos.y;
+ }
+ public override TSVector2 GetFurthestPoint(TSVector2 direction)
+ {
+ direction = direction.normalized;
+ FP maxLen = FP.MinValue,len;
+ TSVector2 pos = movedVertexs[0];
+ for(int i = movedVertexs.Length-1; i >= 0; --i)
+ {
+ if((len= TSVector2.Dot(direction, movedVertexs[i])) > maxLen)
+ {
+ maxLen = len;
+ pos = movedVertexs[i];
+ }
+ }
+ return pos;
+ }
+
+ public override TSVector4 GetBoundingBox()
+ {
+ return _boundingBox_;
+ }
+ }
+ [Serializable]
+ public class BoxCollider : PolygonCollider
+ {
+ public BoxCollider(TSVector2 widthHeight,TSVector2 center,FP rotation, CollisionManager.CollisionGroup group = CollisionManager.CollisionGroup.Default)
+ {
+ TSVector2 a = widthHeight * 0.5;//左下,左上,右上,右下
+ TSVector2 b = new TSVector2(a.x,-a.y);
+ vertexs = new TSVector2[4] {-a,-b, a, b}; //边数是不能变的
+ movedVertexs = new TSVector2[4]; //边数是不能变的
+ centerPos = center;
+ SetRotation(rotation);
+ colliGroup = group;
+
+ }
+ public override void DebugDisplayColliderShape(Color color)
+ {
+
+ GL.Begin(GL.TRIANGLE_STRIP);
+ GL.Color(color);
+ //因为原来是顺时针的,现在反过来,变成逆时针画图
+ for (int i = movedVertexs.Length-1; i >= 0; i--)
+ {
+ GL.Vertex(movedVertexs[i].ToVector());
+ }
+
+ GL.End();
+ }
+ }
+ [Serializable]
+ public class BoxCollider : BoxCollider, IMasteredCollider
+ {
+ T _master_;
+ public T Master
+ {
+ get => _master_;
+ set => _master_ = value;
+ }
+
+ public BoxCollider(T master, TSVector2 widthHeight, TSVector2 center, FP rotation, CollisionManager.CollisionGroup group = CollisionManager.CollisionGroup.Default) : base(widthHeight, center, rotation, group)
+ {
+ this._master_ = master;
+ }
+
+ }
+ [Serializable]
+ public class DiamondCollider : PolygonCollider
+ {
+ public DiamondCollider(TSVector2 widthHeight, TSVector2 center, FP rotation, CollisionManager.CollisionGroup group = CollisionManager.CollisionGroup.Default)
+ {
+ TSVector2 b = new TSVector2(widthHeight.x * 0.5, 0);
+ TSVector2 c = new TSVector2(0, widthHeight.y * 0.5);
+ vertexs = new TSVector2[4] { -b, c, b, -c }; //边数是不能变的
+ movedVertexs = new TSVector2[4]; //边数是不能变的
+ centerPos = center;
+ SetRotation(rotation);
+ colliGroup = group;
+ }
+
+ }
+ [Serializable]
+//两个相同的圆中间连线
+ public class DoubleCircleCollider : ColliderBase
+ {
+ public FP r;
+ protected TSVector2 centerPos;
+ public TSVector2 centerCircle1;
+ public TSVector2 centerCircle2;
+ public DoubleCircleCollider(FP R, TSVector2 center1,TSVector2 center2, CollisionManager.CollisionGroup group = CollisionManager.CollisionGroup.Default)
+ {
+ SetCircleCenters(center1,center2);
+ r = R;
+ colliGroup = group;
+ }
+ public override void SetRotation(FP rotRad) { }//没错,圆形没有旋转
+ public override void SetCenter(in TSVector2 center)
+ {
+ TSVector2 delta = center - centerPos;
+ centerCircle1 += delta;
+ centerCircle2 += delta;
+ centerPos = center;
+ }
+ public void SetCircleCenters(TSVector2 center1,TSVector2 center2) {
+
+ centerCircle1 = center1;
+ centerCircle2 = center2;
+ centerPos = (center1 + center2) * 0.5;
+ }
+ public void SetCircleCenter2(TSVector2 center2)
+ {
+ centerCircle2 = center2;
+ centerPos = (centerCircle1 + center2) * 0.5;
+ }
+ public void SetCircleCenter1(TSVector2 center1)
+ {
+ centerCircle1 = center1;
+ centerPos = (centerCircle2 + center1) * 0.5;
+ }
+ public override TSVector2 GetCenter()
+ {
+ return centerPos;
+ }
+ public override TSVector2 GetFurthestPoint(TSVector2 direction)
+ {
+ //d.normal*
+ if (TSVector2.Dot(direction, centerCircle1-centerPos) > 0)
+ {
+ return direction.normalized * r + centerCircle1;
+ }
+ else
+ {
+ return direction.normalized * r + centerCircle2;
+ }
+ }
+ public override TSVector4 GetBoundingBox()
+ {
+ FP minX;
+ FP minY;
+ FP maxX;
+ FP maxY;
+ if (centerCircle1.x halfLen+r+shape2.r) {
+ //Debug.Log("Type1: "+distance + " " + (this.r + shape2.r) + " " + halfLen);
+ return false;
+ }
+ if (absDis >= halfLen)
+ {
+ //Debug.Log("Type2: " + distance + " "+ centerShape + " " + this.centerCircle2+ " " + this.centerCircle1 + " " + (this.r + shape2.r) + " " + halfLen);
+ if (distance > 0)
+ {
+ return (this.centerCircle2 - centerShape).LengthSquared() <= TSMath.FastQuadratic(this.r + shape2.r);
+ }
+ else
+ {
+ return (this.centerCircle1 - centerShape).LengthSquared() <= TSMath.FastQuadratic(this.r + shape2.r);
+ }
+ }
+ else
+ {
+ //Debug.Log("Type3: " + distance + " " + deltaPos.LengthSquared() + " " + (this.r + shape2.r) + " " + halfLen);
+ //勾股定理
+ return deltaPos.LengthSquared() - TSMath.FastQuadratic(distance) <= TSMath.FastQuadratic(this.r + shape2.r);
+ }
+ }
+ public override bool CheckCollide(ColliderBase shape2)
+ {
+ if (shape2 is CircleCollider sh)
+ {
+ return CircleCollideWithCircle(sh);
+ }
+ return CheckCollide(this, shape2);
+ }
+ public override void DebugDisplayColliderShape(Color color)
+ {
+ int circleCount = Mathf.FloorToInt(Mathf.Lerp(5, 8, ((float)r) / 72f));
+ float angleDelta = 2 * Mathf.PI / circleCount;
+
+ GL.Begin(GL.TRIANGLE_STRIP);
+ GL.Color(color);
+
+ for (int i = 0; i < circleCount + 1; i++)
+ {
+ float angle = angleDelta * i;
+ float angleNext = angle + angleDelta;
+ Vector3 cent = centerCircle1.ToVector();
+ Vector3 cent2 = new Vector3(Mathf.Cos(angle) * (float)r, Mathf.Sin(angle) * (float)r, 0) + cent;
+ GL.Vertex3(cent2.x, cent2.y, cent2.z);
+ GL.Vertex3(cent.x, cent.y, cent.z);
+ }
+ for (int i = 0; i < circleCount + 1; i++)
+ {
+ float angle = angleDelta * i;
+ float angleNext = angle + angleDelta;
+ Vector3 cent = centerCircle2.ToVector();
+ Vector3 cent2 = new Vector3(Mathf.Cos(angle) * (float)r, Mathf.Sin(angle) * (float)r, 0) + cent;
+ GL.Vertex3(cent2.x, cent2.y, cent2.z);
+ GL.Vertex3(cent.x, cent.y, cent.z);
+ }
+ GL.End();
+ }
+ }
+ [Serializable]
+ public class DoubleCircleCollider : DoubleCircleCollider, IMasteredCollider
+ {
+ T _master_;
+ public T Master
+ {
+ get => _master_;
+ set => _master_ = value;
+ }
+
+ public DoubleCircleCollider(T master, FP R, TSVector2 center1,TSVector2 center2, CollisionManager.CollisionGroup group = CollisionManager.CollisionGroup.Default) : base(R, center1,center2, group)
+ {
+ this._master_ = master;
+ }
+
+ }
+ [Serializable]
+ public class CollisionController:IDisposable {
+ ///
+ /// 这个用来防止报错,在正式版的时候
+ ///
+ const bool strictMode = true;
+ static List emptyTmp = new List();
+ static HashSet hashSetTmp = new HashSet();//在非严格模式下防止回收池后报奇怪的错
+ public List Colliders = ListPool.Get();
+ public HashSet hadCollider = HashSetPool.Get();
+ public bool destroyed = false;
+ bool DestroyedChecker() {
+ if (strictMode)
+ {
+ if (destroyed)
+ {
+ Debug.LogError("Try To Use Collisions After Destoyed");
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+ }
+ else
+ {
+ return false;
+ }
+ }
+ public CollisionController(params ColliderBase[] collider)
+ {
+ SetCollidersIEnumerable(collider);
+ }
+ public CollisionController(List collider)
+ {
+ SetCollidersIEnumerable(collider);
+ }
+ public void SetCollidersIEnumerable(IEnumerable colliders)
+ {
+ if (DestroyedChecker()) return;//销毁后不允许再增加
+ foreach (var item in Colliders)
+ {
+ CollisionManager.instance.RemoveShape(item);//添加物品
+ }
+ hadCollider.Clear();
+ Colliders.Clear();
+ foreach (var item in colliders)
+ {
+ AppendCollider(item);
+ }
+ }
+ public void AppendCollider(ColliderBase item) {
+ if(DestroyedChecker()) return;//销毁后不允许再增加
+ if (hadCollider.Add(item))
+ {
+ Colliders.Add(item);
+ CollisionManager.instance.AddShape(item);//添加物品
+ }
+ }
+ public void RemoveCollider(int startIndex,int length) {
+ if (DestroyedChecker()) return;//销毁后不允许再增加
+ int endIndex = startIndex+length;
+ for (int i = startIndex;i collideEnter, Action collide, Action collideLeave, params CollisionManager.CollisionGroup[] collisionGroups)
+ {
+ if (DestroyedChecker()) return this;//销毁后不允许再增加
+ foreach (var item in Colliders)
+ {
+ CollisionManager.instance.AddListener(item, collideEnter, collide, collideLeave, collisionGroups).multiColli=multiColli;
+ }
+ return this;
+ }
+ public CollisionController AddListener(Action collideEnter, Action collide, Action collideLeave,params CollisionManager.CollisionGroup[] collisionGroups) {
+ if (DestroyedChecker()) return this;//销毁后不允许再增加
+ foreach (var item in Colliders)
+ {
+ CollisionManager.instance.AddListener(item, collideEnter, collide, collideLeave, collisionGroups);
+ }
+ return this;
+ }
+ public CollisionController AddListener(Action collide, params CollisionManager.CollisionGroup[] groups) {
+ return AddListener(null,collide,null,groups);
+ }
+ public CollisionController AddListener(Action collide, bool multiColli=false, params CollisionManager.CollisionGroup[] groups)
+ {
+ return AddListener(multiColli ,null, collide, null, groups);
+ }
+ public CollisionController MoveDeltaPos(in TSVector2 deltaPos) {
+ if (DestroyedChecker()) return this;//销毁后不允许再增加
+ foreach (var i in Colliders)
+ {
+ CollisionManager.instance.SetCenter(i.GetCenter()+deltaPos, i);
+ }
+ return this;
+ }
+ public CollisionController SetCenter(in TSVector2 center) {
+ if (DestroyedChecker()) return this;//销毁后不允许再增加
+ foreach (var i in Colliders) {
+ CollisionManager.instance.SetCenter(center, i);
+ }
+ return this;
+ }
+ public CollisionController SetEnabled(bool enabled)
+ {
+ if (DestroyedChecker()) return this;//销毁后不允许再增加
+ foreach (var item in Colliders)
+ {
+ item.enabled = enabled;
+ }
+ return this;
+ }
+ public void Destroy()
+ {
+ if (destroyed) {
+ return;
+ }
+ destroyed = true;
+ foreach (var i in Colliders)
+ {
+ CollisionManager.instance.RemoveShape(i);
+ CollisionManager.instance.RemoveListener(i);//尝试停止所有的监听器
+ CollisionManager.instance.RemoveReceiver(i);//尝试停止所有的监听器
+ }
+ HashSetPool.Release(hadCollider);
+ ListPool.Release(Colliders);
+ hadCollider = null;
+ Colliders = null;
+ if (!strictMode)
+ {
+ Colliders = emptyTmp;
+ hadCollider = hashSetTmp;
+ Colliders.Clear();
+ hadCollider.Clear();
+ }
+ }
+ public void Dispose() {
+ Destroy();
+ }
+ }
+ public class QuadTree where T : ICollideShape
+ {
+ public int cellSize = 64;//最小格子宽高
+ public FP OneDivideCellSize;
+ public int depth = 6;//载入时的深度
+ public int maxSize;
+ public int groupCnt = 1;//碰撞组的个数
+ FP maxSizeFP,OneHalfMaxSizeFP;
+ FP[] log4Numbers, log2Numbers;
+ public TreeNode root = new TreeNode();
+ public TreeNode[] treeNodeArr = new TreeNode[0];//用数组优化四叉树的读取
+ //储存每个collider所在的坐标格子位置,
+ public Dictionary colliderPositions = new Dictionary();
+ //public HashSet[] unmanagedColliders;
+
+ protected void __init__(int dp = 6, int cw = 64) {
+ cellSize = cw;
+ depth = dp;
+ maxSize = cw << (dp);
+ maxSizeFP = maxSize;
+ OneHalfMaxSizeFP = maxSizeFP * 0.5;
+ OneDivideCellSize = FP.One / (FP)cw;
+ log4Numbers = new FP[depth + 1];
+ log2Numbers = new FP[depth + 1];
+ groupCnt = Enum.GetValues(typeof(CollisionManager.CollisionGroup)).Length;
+ for (int i = 1; i <= depth; i++)
+ {
+ //0 2 4 6 8
+ log4Numbers[i] = FP.One / (FP)(i << 1);
+ log2Numbers[i] = FP.One / (FP)(i);
+ }
+ /*unmanagedColliders = new HashSet[groupCnt];
+ for (int i = 0; i < groupCnt; i++)
+ {
+ unmanagedColliders[i] = new HashSet();
+ }*/
+ BuildTree();
+ }
+ public static int FastPow(int a, int n)
+ {
+ int ans = 1; // 赋值为乘法单位元,可能要根据构造函数修改
+ while (n != 0)
+ {
+ if ((n & 1) != 0)
+ {
+ ans *= a; // 这里就最好别用自乘了,不然重载完*还要重载*=,有点麻烦。
+ }
+ n >>= 1;
+ a = a*a;
+ }
+ return ans;
+ }
+ /*public int CalcDepthCount(int dp) {
+ return (FastPow(4, dp+1)-1) / 3;
+ }*/
+ public int CalcDepthCount(int dp)
+ {
+ return ((1<<((dp+1)<<1)) - 1) / 3;//等比数列求和
+ }
+ //按照
+ /*
+ root ,
+ lt,
+ rt,
+ lb,
+ rb,
+ lt.lt, lt.rt,rt.lt,rt.rt, lt.lb, lt.rb,rt.lb,rt.rb , 4^n个
+ 初始位置:4^0+...+4^(n-1) = 1*(1-4^n)/(1-4)
+ //以屏幕为左上角,坐标向右边和下面增加
+ 坐标:floor(当前层左上坐标/当前层高度)*(最大层宽度/当前层宽度)+floor(当前左上坐标/当前层宽度)
+ */
+ public int GetPosition(int curDepth,Vector2Int scaledPosition)
+ {
+ return CalcDepthCount(curDepth-1)+scaledPosition.y * (1 << (curDepth)) + scaledPosition.x;
+ }
+ //计算子四边形的缩放过的坐标
+ ///
+ /// 把原始的四个边界从中间分成四份,然后再把坐标*2
+ ///
+ /// 原始的四个边界
+ ///
+ TSVector4[] splitRect(TSVector4 r) {
+ //originalRect *= 2;
+ /*return new TSVector4[] {
+ new TSVector4(originalRect.x,originalRect.y,(originalRect.z+originalRect.x)/2,(originalRect.w+originalRect.y)/2),
+ new TSVector4((originalRect.x+originalRect.z)/2,originalRect.y,(originalRect.x+originalRect.z)/2+(originalRect.z-originalRect.x)/2,(originalRect.w+originalRect.y)/2),
+ };*/
+ /*originalRect.x += originalRect.x;
+ originalRect.y += originalRect.y;
+ originalRect.z += originalRect.x;
+ originalRect.w += originalRect.y;*/
+ /*
+ x,y,x+(z-x)/2,y+(w-y)/2
+ x+(z-x)/2,y,z,y+(w-y)/2
+ x,y+(w-y)/2,x+(z-x)/2,w
+ x+(z-x)/2,y+(w-y)/2,z,w
+
+ */
+ /*
+ 2x,2y,x+z,y+w
+ x+z,2y,2z,y+w
+ 2x,y+w,x+z,2w
+ x+z,y+w,2z,2w
+ */
+ /*return new TSVector4[] {
+ new TSVector4(originalRect.x,originalRect.y,originalRect.z,originalRect.w),
+ new TSVector4(originalRect.z,originalRect.y,originalRect.z+originalRect.z-originalRect.x,originalRect.w),
+ new TSVector4(originalRect.x,originalRect.w,originalRect.z,originalRect.w+originalRect.w-originalRect.y),
+ new TSVector4(originalRect.z,originalRect.w,originalRect.z+originalRect.z-originalRect.x,originalRect.w+originalRect.w-originalRect.y),
+ };*/
+ FP a = r.x + r.x;
+ FP b = r.y + r.y;
+ FP c = r.x + r.z;
+ FP d = r.y + r.w;
+ FP e = r.z + r.z;
+ FP f = r.w + r.w;
+ return new TSVector4[] {
+ new TSVector4(a,b,c,d),
+ new TSVector4(c,b,e,d),
+ new TSVector4(a,d,c,f),
+ new TSVector4(c,d,e,f)
+ };
+ }
+ //应该不是,直接用大小存吧……
+ public class TreeNode {
+ public HashSet[] Values;
+ public TreeNode[] Children = new TreeNode[4];
+ public TreeNode parent = null;
+ }
+ TSVector4 TransAxis(TSVector4 vec) {
+ vec.y = OneHalfMaxSizeFP - vec.y;
+ vec.w = OneHalfMaxSizeFP - vec.w;
+ vec.x += OneHalfMaxSizeFP;
+ vec.z += OneHalfMaxSizeFP;
+ return vec;
+ }
+ int GetDepth(int width) { //如果是>=1的话也要放在上(更大的)一层比如64的大小(格子也是64)就应该放在128,不然可能会出界什么的。。。
+ int layer = 0;//1 2 4 8
+ while (width >> layer > 1)
+ {
+ layer++;
+ }
+ return depth - layer;
+ }
+ public struct positionInformation {
+ public int layer;
+ public Vector2Int mainPos;
+ public Vector2Int rightBottom;
+
+ public override bool Equals(object obj)
+ {
+ return obj is positionInformation other && Equals(other);
+ }
+
+ public bool Equals(positionInformation other)
+ {
+ return this.layer == other.layer &&
+ this.mainPos == other.mainPos &&
+ this.rightBottom == other.rightBottom;
+ }
+
+ public override int GetHashCode()
+ {
+ return HashCode.Combine(layer, mainPos, rightBottom);
+ }
+
+ public static bool operator ==(positionInformation left, positionInformation right)
+ {
+ return left.Equals(right);
+ }
+
+ public static bool operator !=(positionInformation left, positionInformation right)
+ {
+ return !(left == right);
+ }
+
+ // New method to check if the current instance contains another instance's range
+ public bool Contains(positionInformation other)
+ {
+ return this.layer == other.layer &&
+ this.mainPos.x <= other.mainPos.x &&
+ this.mainPos.y <= other.mainPos.y &&
+ this.rightBottom.x >= other.rightBottom.x &&
+ this.rightBottom.y >= other.rightBottom.y;
+ }
+ public bool TrueContains(positionInformation other)
+ {
+ return this.layer == other.layer &&
+ this.mainPos.x < other.mainPos.x &&
+ this.mainPos.y < other.mainPos.y &&
+ this.rightBottom.x > other.rightBottom.x &&
+ this.rightBottom.y > other.rightBottom.y;
+ }
+
+ // Overload >= operator to use the Contains method
+ public static bool operator >=(positionInformation left, positionInformation right)
+ {
+ return left.Contains(right);
+ }
+ public static bool operator <=(positionInformation left, positionInformation right)
+ {
+ return right.Contains(left);
+ }
+ public static bool operator >(positionInformation left, positionInformation right)
+ {
+ return left.TrueContains(right);
+ }
+ public static bool operator <(positionInformation left, positionInformation right)
+ {
+ return right.TrueContains(left);
+ }
+ }
+ //可能是一个或者四个坐标,插入一次或者四次
+ public positionInformation GetCellIndex(TSVector4 rect) {
+ rect = TransAxis(rect);//乘1/最小格子大小可以得到64-->1 128 --> 2这样
+ if (rect.x<0||rect.y<0||rect.z>maxSize||rect.w>maxSize) {
+ return new positionInformation { //出界了,这个应该放在第0层里面,不参与四叉树判断
+ mainPos = Vector2Int.zero,
+ rightBottom = Vector2Int.zero,
+ layer = 0
+ };
+ }
+ rect *= OneDivideCellSize;
+ //获取应该放在哪一层
+ int layer = GetDepth(TSMath.Ceil(TSMath.Max(rect.w - rect.y, rect.z - rect.x)).AsInt());//TSMath.Ceil(TSMath.Log2(TSMath.Max(rect.w - rect.y, rect.z - rect.x))).AsInt();//这个Log很慢,因为是定点数,自己写一个
+ if (layer < 0)
+ {
+ return new positionInformation
+ { //出界了,这个应该放在第0层里面,不参与四叉树判断
+ mainPos = Vector2Int.zero,
+ rightBottom = Vector2Int.zero,
+ layer = 0
+ };
+ }
+ int divide = depth - layer;
+ Vector2Int mainPos = new Vector2Int(rect.x.AsInt()>> divide, rect.y.AsInt()>> divide);
+ Vector2Int rightBottom = new Vector2Int((rect.z.AsInt() >> divide), (rect.w.AsInt() >> divide));
+ return new positionInformation
+ {
+ mainPos = mainPos,
+ rightBottom = rightBottom, layer = layer
+ };
+ }
+ ///
+ /// 根据坐标批量处理某个事 action传入的是 当前深度depth和坐标的参数
+ ///
+ ///
+ ///
+ public void Manufacture(Action action,positionInformation area)
+ {
+ //对应级别的坐标
+ Vector2Int nowPos = area.mainPos;
+ Vector2Int tar = area.rightBottom;
+ for(int i = nowPos.x; i <= tar.x; i++)
+ {
+ for (int j = nowPos.y;j<=tar.y;j++) {
+ Vector2Int pos = new Vector2Int(i,j);
+ action(area.layer,pos);
+ }
+ }
+ }
+ //带break的
+ public bool Manufacture(Func action, positionInformation area)
+ {
+ //对应级别的坐标
+ Vector2Int nowPos = area.mainPos;
+ Vector2Int tar = area.rightBottom;
+ for (int i = nowPos.x; i <= tar.x; i++)
+ {
+ for (int j = nowPos.y; j <= tar.y; j++)
+ {
+ Vector2Int pos = new Vector2Int(i, j);
+ if(!action(area.layer, pos)) { return false; }
+ }
+ }
+ return true;
+ }
+ public void RemoveCollider(T obj,bool insert=false) {
+ int grp = (int)obj.colliGroup;
+ if (colliderPositions.ContainsKey(obj))
+ {
+ Manufacture((layer,posInArr) => {
+ //Debug.Log(layer+ " "+posInArr);
+ var objs = treeNodeArr[GetPosition(layer, posInArr)].Values[grp];
+ objs.Remove(obj);
+ }, colliderPositions[obj]);
+ colliderPositions.Remove(obj);
+ }/*else
+ {
+ unmanagedColliders[grp].Remove(obj);
+ }*/
+ }
+ public void ClearAllCollider()
+ {
+ foreach (var obj in colliderPositions)
+ {
+ RemoveCollider(obj.Key);
+ }
+ /*foreach (var obj in unmanagedColliders) {
+ obj.Clear();
+ }*/
+ }
+ public void InsertCollider(T obj) {
+ int grp = (int)obj.colliGroup;
+ TSVector4 rect = obj.GetBoundingBox();//获取物体的包围盒
+ positionInformation positions = GetCellIndex(rect),
+ oldPosition;
+ bool hasObj = colliderPositions.ContainsKey(obj),flag=true;
+ if (hasObj) {//如果position和原position在是包含关系,这里不能替换成大于,因为 会比较图层是否相等
+ oldPosition = colliderPositions[obj];
+ if (!(oldPosition <= positions))
+ {
+ RemoveCollider(obj,true);
+ } else if (oldPosition==positions) {
+ flag = false;
+ }
+ }
+ colliderPositions[obj] = positions;
+ if (flag){
+ Manufacture((layer, posInArr) => {
+ var objs = treeNodeArr[GetPosition(layer, posInArr)].Values[grp];
+ objs.Add(obj);
+ }, positions);
+ }
+ }
+ void BuildTree() {
+ int curDepth = 0;
+ int needCnt = CalcDepthCount(depth);
+ root = new TreeNode();
+ treeNodeArr = new TreeNode[needCnt];
+ TSVector4 nowRect = new TSVector4(0,0,1,1);//四边形的边框
+ Dictionary> errorChecker = new Dictionary>();
+ void dfs(TreeNode node=null) {
+ treeNodeArr[GetPosition(curDepth,new Vector2Int(nowRect.x.AsInt(), nowRect.y.AsInt()))] = node;//存入数组
+ if(errorChecker.ContainsKey(GetPosition(curDepth, new Vector2Int(nowRect.x.AsInt(), nowRect.y.AsInt()))))
+ {
+ var conf = errorChecker[GetPosition(curDepth, new Vector2Int(nowRect.x.AsInt(), nowRect.y.AsInt()))];
+ if(curDepth!=conf.Item1||conf.Item2!= new Vector2Int(nowRect.x.AsInt(), nowRect.y.AsInt()))
+ {
+ Debug.LogError("Big Append Error" + " " + curDepth + " " + new Vector2Int(nowRect.x.AsInt(), nowRect.y.AsInt()) + " conflict with " + conf.Item1 + " " + conf.Item2);
+
+ }
+ }
+ else
+ {
+ errorChecker.Add(GetPosition(curDepth, new Vector2Int(nowRect.x.AsInt(), nowRect.y.AsInt())), new Tuple(curDepth, new Vector2Int(nowRect.x.AsInt(), nowRect.y.AsInt())));
+ }
+ /*if (curDepth == 2) {
+ Debug.Log(curDepth+" "+nowRect);
+ }*/
+ //初始化碰撞组
+ node.Values = new HashSet[groupCnt];
+ for (int j = 0; j < groupCnt; j++)
+ {
+ node.Values[j] = new HashSet();
+ }
+
+ if (curDepth>=depth)
+ {
+ return;
+ }
+ TSVector4 tmpRect = nowRect;
+ TSVector4[] splited = splitRect(tmpRect);
+ /*StringBuilder sb = new StringBuilder();
+ sb.Append(curDepth);
+ for (int i = 0;i[] groupedColliders;//这个到时候要改成LinkedHashSet之类的东西。。。
+ public HashSet colliders = new HashSet();
+ public LinkedDictionary> listeners = new LinkedDictionary>();
+ public LinkedDictionary> receivers = new LinkedDictionary>();
+
+ public HashSet tmpDrawingHasCheckedObjectsInCurFrame = new HashSet();//用来debug有哪些物体当前帧被检查碰撞
+ //readonly bool multiCollisionOptimize = false;//先关掉多碰撞优化,测试功能
+ private Material _shapeMaterial;//测试
+ public CollisionManager() {
+ groupedColliders = new LinkedHashSet[groupCnt];
+ for (int i = 0; i < groupCnt; i++) {
+ groupedColliders[i] = new LinkedHashSet();
+ }
+ }
+ public class __action_checkColli__ {
+ public ColliderBase collider;
+ public SortedSet checkGroups;
+ public Action callbackEnter, callback, callbackLeave;
+ public ColliderBase triggeringObj = null;
+ public CollisionGroup recieveGroup;
+ public bool multiColli = false;
+ }
+ public enum CollisionGroup
+ {
+ Default,
+ Hero,
+ HeroBullet,
+ Bullet,
+ Enemy,
+ EnemyCollideBullet,
+ Item
+ }
+ //方便过后删除掉
+ //添加碰撞监听器
+ //有多碰撞需求再改吧……反正就改个list现在仅支持碰一个物体
+ public __action_checkColli__ AddListener(ColliderBase collider,Action callbackEnter, Action callback, Action callbackLeave, params CollisionGroup[] checkGroups) {
+ var obj = new __action_checkColli__
+ {
+ collider = collider,
+ checkGroups = new SortedSet(checkGroups),
+ callbackEnter = callbackEnter,
+ callbackLeave = callbackLeave,
+ callback = callback
+ };
+ if (listeners.ContainsKey(collider))
+ {
+ listeners[collider].Add(obj);
+ }
+ else
+ {
+ var linkedSet = ObjectPool>.GetObject();
+ linkedSet.Add(obj);
+ listeners.Add(collider, linkedSet);
+ }
+ return obj;
+ }
+ public __action_checkColli__ AddListener(ColliderBase collider, Action callback, params CollisionGroup[] checkGroups)
+ {
+ return AddListener(collider, null, callback, null, checkGroups);
+ }
+ //移除一个碰撞监听器行为
+ public void RemoveListener(__action_checkColli__ action)
+ {
+ if (!listeners.ContainsKey(action.collider))
+ {
+ return;
+ }
+ listeners[action.collider].Remove(action);
+ if (listeners[action.collider].Count == 0)
+ {
+ RemoveListener(action.collider);
+ return;
+ }
+ }
+ //移除整个碰撞监听器
+ public void RemoveListener(ColliderBase collider) {
+ if (listeners.ContainsKey(collider)) {
+ ObjectPool>.ReturnObject(listeners[collider]);
+ }
+ listeners.Remove(collider);
+ }
+ //receiver不支持enter和leave
+ __action_checkColli__ AddReceiver(ColliderBase collider, Action callbackEnter, Action callback, Action callbackLeave, CollisionGroup recieveGroup)
+ {
+ var obj = new __action_checkColli__
+ {
+ collider = collider,
+ callbackEnter = callbackEnter,
+ callbackLeave = callbackLeave,
+ callback = callback,
+ recieveGroup = recieveGroup
+ };
+ if (receivers.ContainsKey(collider))
+ {
+ receivers[collider][recieveGroup] = obj;
+ }
+ else
+ {
+ receivers.Add(collider, new LinkedDictionary { { recieveGroup, obj } });
+ }
+ return obj;
+ }
+ public __action_checkColli__ AddReceiver(ColliderBase collider, Action callback, CollisionGroup recieveGroup)
+ {
+ return AddReceiver(collider, null, callback, null, recieveGroup);
+ }
+ //移除一个碰撞接受器行为
+ public void RemoveReceiver(__action_checkColli__ action)
+ {
+ if (!receivers.ContainsKey(action.collider))
+ {
+ return;
+ }
+ receivers[action.collider].Remove(action.recieveGroup);
+ if (receivers[action.collider].Count == 0)
+ {
+ RemoveReceiver(action.collider);
+ return;
+ }
+ }
+ //移除整个碰撞接受器
+ public void RemoveReceiver(ColliderBase collider)
+ {
+ receivers.Remove(collider);
+ }
+ public CollisionManager AddShape(ColliderBase collider) {
+ /*if (multiCollisionOptimize)
+ {
+ quadTreeOptmize.InsertCollider(collider);
+ }
+ else*/
+ {
+ int grp = (int)collider.colliGroup;
+ groupedColliders[grp].Add(collider);
+ }
+ colliders.Add(collider);
+ return this;
+ }
+ public void RemoveShape(ColliderBase collider) {
+ /*if (multiCollisionOptimize)
+ {
+ quadTreeOptmize.RemoveCollider(collider);
+ }
+ else*/
+ {
+ int grp = (int)collider.colliGroup;
+ groupedColliders[grp].Remove(collider);
+ }
+ colliders.Remove(collider);
+ }
+ public void SetCenter(in TSVector2 Pos,ColliderBase shape)
+ {
+ shape.SetCenter(Pos);
+ /*if (multiCollisionOptimize)
+ {
+ quadTreeOptmize.InsertCollider(shape);
+ }*/
+ }
+
+ /*public void SwitchMultiColli(bool swit) {
+ if (multiCollisionOptimize == swit) { return; }
+ if (swit)
+ {
+ foreach(var i in colliders)
+ {
+ quadTreeOptmize.InsertCollider(i);
+ }
+ foreach (var groupHashSet in groupedColliders) {
+ groupHashSet.Clear();
+ }
+ }
+ else
+ {
+ quadTreeOptmize.ClearAllCollider();
+ foreach(var i in colliders)
+ {
+ AddShape(i);
+ }
+ }
+ multiCollisionOptimize = swit;
+ }*/
+ public ColliderBase CheckCollision(ColliderBase obj,CollisionGroup group) {
+ if (!obj.enabled)
+ {
+ return null;
+ }
+ /*if (multiCollisionOptimize)
+ {
+ return quadTreeOptmize.CheckCollision(obj, (int)group);
+ }
+ else*/
+ {
+ int grp = (int)group;
+ foreach(var i in groupedColliders[grp])
+ {
+ if (!i.enabled) { continue; }
+ if (obj.CheckCollide(i))
+ {
+ return i;
+ }
+ }
+ return null;
+ }
+ }
+ public void CheckCollision(ColliderBase obj, CollisionGroup group, ref List colliObj, bool force = false) {
+ if (!obj.enabled&&!force)
+ {
+ return;
+ }
+ {
+ int grp = (int)group;
+ foreach (var i in groupedColliders[grp])
+ {
+ if (!i.enabled && !force) { continue; }
+ if (obj.CheckCollide(i))
+ {
+ colliObj.Add(i);
+ }
+ }
+ }
+ }
+
+ public void TraverseAllListener() {
+ {
+ tmpDrawingHasCheckedObjectsInCurFrame.Clear();
+ }
+ foreach(var kvPair in listeners)
+ {
+ var val = kvPair.Value;
+ foreach (var obj in val)
+ {
+ if (!obj.collider.enabled) { continue; }//如果自身不允许碰撞就不碰
+ foreach (var i in obj.checkGroups)
+ {
+ //多碰撞不支持接收器
+ if (obj.multiColli)
+ {
+ List collis = ListPool.Get();
+ CheckCollision(obj.collider, i, ref collis);
+ foreach(var retObj in collis)
+ {
+ callActionComponent(retObj, obj);
+ }
+ ListPool.Release(collis);
+ }else{
+ var retObj = CheckCollision(obj.collider, i);
+ callActionComponent(retObj, obj);
+ //如果对方有接收器
+ if (retObj != null && receivers.ContainsKey(retObj) && receivers[retObj].ContainsKey(obj.collider.colliGroup))
+ {
+ callActionComponent(obj.collider, receivers[retObj][obj.collider.colliGroup]);
+ }
+ }
+ }
+ }
+ }
+ }
+ void callActionComponent(ColliderBase beCollidedObj,__action_checkColli__ action) {
+ if (beCollidedObj != null)
+ {
+ if (action.triggeringObj == null)
+ {
+ action.triggeringObj = beCollidedObj;
+ if (action.callbackEnter != null)
+ {
+ action.callbackEnter(beCollidedObj);
+ }
+ }
+ action.callback(beCollidedObj);
+ }
+ else if (action.triggeringObj != null)
+ {
+ if (action.callbackLeave != null)
+ {
+ action.callbackLeave(action.triggeringObj);
+ }
+ action.triggeringObj = null;
+ }
+ }
+ public void DebugDisplayShape(Matrix4x4 matrixTransform) {
+ if (_shapeMaterial == null)
+ {
+ _shapeMaterial = new Material(Shader.Find("Hidden/Internal-Colored"));
+ }
+ _shapeMaterial.SetPass(0);
+ GL.PushMatrix();
+ GL.MultMatrix(matrixTransform);
+ /*if (!multiCollisionOptimize)
+ {
+ for (int i = 0; i < groupedColliders.Length; i++)
+ {
+ Color color = Color.Lerp(new Color(1, 0, 0, 0.2f), new Color(0, 0, 1, 0.2f), (float)i / groupCnt);
+ foreach (var collider in groupedColliders[i])
+ {
+ collider.DebugDisplayColliderShape(color);
+ }
+ }
+ }
+ else*/
+ {
+ foreach (var collider in colliders)
+ {
+ if (!collider.enabled || tmpDrawingHasCheckedObjectsInCurFrame.Contains(collider)) { continue; }
+ Color color = Color.HSVToRGB((float)collider.colliGroup / groupCnt, 1, 1);
+ color.a = 0.2f;
+ //Color color = Color.Lerp(new Color(1, 0, 0, 0.2f), new Color(0, 0, 1, 0.2f), (float)collider.colliGroup / groupCnt);
+ collider.DebugDisplayColliderShape(color);
+ }
+ foreach (var collider in tmpDrawingHasCheckedObjectsInCurFrame)
+ {
+ //Color color = Color.Lerp(new Color(1, 1, 0, 0.2f), new Color(0, 1, 1, 0.2f), (float)collider.colliGroup / groupCnt);
+ Color color = Color.HSVToRGB((float)collider.colliGroup / groupCnt, 2, 1);
+ color.a = 0.2f;
+ collider.DebugDisplayColliderShape(color);
+ }
+ }
+ GL.PopMatrix();
+ }
+ }
+/*
+ def GJK(s1,s2)
+#两个形状s1,s2相交则返回True。所有的向量/点都是三维的,例如([x,y,0])
+#第一步:选择一个初始方向,这个初始方向可以是随机选择的,但通常来说是两个形状中心之间的向量,即:
+ d= normalize(s2.center-s1.center)
+#第二步:找到支撑点,即第一个支撑点
+ simplex=[support(s1,s2,d)]
+#第三步:找到第一个支撑点后,以第一个支撑点为起点指向原点O的方向为新方向d
+ d=ORIGIN-simplex[0]
+#第四步:开始循环,找下一个支撑点
+ while True
+ A=[support(s1,s2,d)]
+#当新的支撑点A没有经过原点,那我们就返回False,即两个形状没有相交
+ if dot(A,d) <0:
+ return False
+#否则,我们就将该点A加入到simplex中
+ simplex.append(A)
+#handleSimplex负责主要逻辑部分。主要负责处理寻找新方向和更新simplex的逻辑内容,当当前simplex包含原点,则返回Ture
+ if handleSimplex(simplex,d):
+ return Ture
+
+def handleSimplex(simplex,d)
+#如果当前的simplex为直线情况,则进入lineCase(simplex,d)函数,寻找下一个方向d,并返回False,即直线情况下的simplex不包含原点
+ if len(simplex==2):
+ return lineCase(simplex,d)
+#如果当前的simplex为三角情况,则进入triangleCase(simplex,d,
+ return triangleCase(simplex,d)
+
+def lineCase(simplex,d)
+#构建向量AB与AO,并使用三重积得到下一个方向
+ B,A = simplex
+ AB,AO=B-A,ORIGIN-A
+ ABprep= tripleProd(AB,AO,AB)
+ d.set(ABprep)
+#由于一条直线的情况下,原点不能包含在simplex中,所以返回False
+ return False
+
+def triangleCase(simplex,d)
+#构建向量AB,AC与AO,并来检测原点在空间的哪个区域。
+ C,B,A = simplex
+ AB,AC,AO=B-A,C-A,ORIGIN-A
+#通过三重积分别得到垂直于AB、AC的向量,检测区域Rab、Rac中是否包含原点。
+ ABprep= tripleProd(AC,AB,AB)
+ ACprep= tripleProd(AB,AC,AC)
+#如果原点在AB区域中,我们移除点C以寻找更加完美的simplex,新的方向就是垂直于AB的向量
+ if dot(ABprep,AO)>0:
+ simplex.remove(C);d.set(ABprep)
+ return False
+#如果原点在AC区域中,我们移除点B以寻找更加完美的simplex,新的方向就是垂直于AC的向量
+ elif dot(ACprep,AO)>0:
+ simplex.remove(Ba);d.set(ACprep)
+ return False
+#如果这两种情况都不符合,那就说明当前的三角形中包含原点,两个形状相交
+ return Ture
+
+def support(s1,s2,d)
+#取第一个形状上方向d上最远点并减去第二个形状上相反反向(-d)上最远的点
+ return s1.furthestPoint(d)-s2.furthestPoint(-d)
+ */
+}
\ No newline at end of file
diff --git a/Assets/ColliderObj.cs.meta b/Assets/ColliderObj.cs.meta
new file mode 100644
index 0000000..780dbd0
--- /dev/null
+++ b/Assets/ColliderObj.cs.meta
@@ -0,0 +1,2 @@
+fileFormatVersion: 2
+guid: d3bab7401f5d98b4fafe5ba92c3e2ab6
\ No newline at end of file
diff --git a/Assets/ColliderStructure.cs b/Assets/ColliderStructure.cs
new file mode 100644
index 0000000..54c6171
--- /dev/null
+++ b/Assets/ColliderStructure.cs
@@ -0,0 +1,378 @@
+using System;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using Core.Algorithm;
+using TrueSync;
+using Unity.Burst;
+using Unity.Collections;
+
+namespace ZeroAs.DOTS.Colliders
+{
+ public enum ColliderType
+ {
+ Circle,
+ Oval,
+ Polygon,
+ DoubleCircle,
+ }
+ [StructLayout(LayoutKind.Sequential)]
+ public struct ColliderStructure
+ {
+ public ColliderType colliderType;
+ public TSVector2 center;
+ #region 圆形,和双头圆形
+ public FP radius;//圆形半径
+ #endregion
+ #region 椭圆形
+ public TSVector2 Axis, SqrAxis;
+ public FP b2Dividea2,rot;
+ #endregion
+ #region 多边形
+ public int vertexStartIndex, vertexCount;
+ #endregion
+ #region 双头圆形
+ public TSVector2 circleCenter1{
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ get => this.Axis;
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ set => this.Axis = value;
+ }
+ public TSVector2 circleCenter2{
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ get => this.SqrAxis;
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ set => this.SqrAxis = value;
+ }
+ #endregion
+ }
+ [BurstCompile(DisableDirectCall = true,OptimizeFor = OptimizeFor.Performance)]
+ public struct GetFurthestPointExtensions
+ {
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ [BurstCompile(DisableDirectCall = true,OptimizeFor = OptimizeFor.Performance)]
+ public static void RotateRad(out TSVector2 result, in TSVector2 self, in FP rad)
+ {
+ FP cos = FP.FastCos(rad);
+ FP sin = FP.FastSin(rad);
+ result.x = self.x * cos - self.y * sin;
+ result.y = self.x * sin + self.y * cos;
+ }
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ [BurstCompile(DisableDirectCall = true,OptimizeFor = OptimizeFor.Performance)]
+ public static void Negate(ref FP val)
+ {
+ val._serializedValue=val._serializedValue == MathBurstedFix.MIN_VALUE ? MathBurstedFix.MaxValue : (-val._serializedValue);
+ }
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ [BurstCompile(DisableDirectCall = true,OptimizeFor = OptimizeFor.Performance)]
+ public static void Negate(ref TSVector2 val)
+ {
+ Negate(ref val.x);
+ Negate(ref val.y);
+ }
+ static NativeArray points
+ {
+ get
+ {
+ throw new NotImplementedException();
+ }
+ }
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ [BurstCompile(DisableDirectCall = true,OptimizeFor = OptimizeFor.Performance)]
+ public static void Circle(out TSVector2 result,in TSVector2 center,in TSVector2 direction,in FP radius)
+ {
+ result = center + direction.normalized*radius;
+ }
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ [BurstCompile(DisableDirectCall = true,OptimizeFor = OptimizeFor.Performance)]
+ public static void Oval(out TSVector2 result, in TSVector2 _direction,
+ in TSVector2 centerPos,in FP rot,in TSVector2 Axis,in TSVector2 SqrAxis,in FP b2Dividea2)
+ {
+ //sin和cos还是很快的,因为是线性插值……有Lut
+ FP neg = rot;
+ Negate(ref neg);
+ RotateRad(out var direction,in _direction,in neg);
+ if (direction.x == 0)
+ {
+ RotateRad(out direction, TSMath.Sign(direction.y) * Axis.y * TSVector2.up, rot);
+ result = direction + centerPos;
+ return;
+ }else if (direction.y == 0)
+ {
+ RotateRad(out direction, (TSMath.Sign(direction.x) * Axis.x * TSVector2.right), rot);
+ result = direction + centerPos;
+ return;
+ }
+ FP signX = TSMath.Sign(direction.x);
+ FP k = direction.y / direction.x;//目标斜率
+ FP a2 = SqrAxis.x;
+ FP b2 = SqrAxis.y;
+ FP ratio = FP.OverflowMul(k, b2Dividea2);
+ FP denominator = FP.OverflowAdd(1, FP.OverflowMul(k, ratio));
+ if (denominator._serializedValue >= MathBurstedFix.MaxValue || denominator._serializedValue <= MathBurstedFix.MinValue)
+ {
+ //Debug.Log("denominatorOverflow "+ direction + " "+ new TSVector2(0, TSMath.Sign(direction.y) * Axis.y).RotateRad(rot));
+ RotateRad(out direction, new TSVector2(0, TSMath.Sign(direction.y) * Axis.y), rot);
+
+ result = direction + centerPos;
+ return;
+ }
+ FP value = 1.0/denominator;
+
+ FP tarX = signX * (Axis.x*TSMath.Sqrt(value));
+ FP tarY = FP.OverflowMul(tarX,ratio);
+ //Debug.Log("ovalthings: "+tarX+" "+tarY+" "+k+" "+ratio);
+ if (tarY._serializedValue >= MathBurstedFix.MaxValue||tarY._serializedValue<=MathBurstedFix.MinValue)
+ {
+ RotateRad(out direction, new TSVector2(0, TSMath.Sign(direction.y)*Axis.y), rot);
+
+ result = direction + centerPos;
+ return;
+ }
+ RotateRad(out direction, new TSVector2(tarX,tarY), rot);
+
+ result = direction+centerPos;
+ return;
+ }
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ [BurstCompile(DisableDirectCall = true,OptimizeFor = OptimizeFor.Performance)]
+ public static void Polygon(out TSVector2 result, in TSVector2 _direction, in NativeArray movedVertexs,int offset,int length)
+ {
+ TSVector2 direction = _direction.normalized;
+ FP maxLen,len;
+ maxLen._serializedValue = MathBurstedFix.MinValue;
+ TSVector2 pos = movedVertexs[offset];
+ int len_ = offset + length;
+ for(int i = len_-1; i >= 0; --i)
+ {
+ if((len= TSVector2.Dot(direction, movedVertexs[i])) > maxLen)
+ {
+ maxLen = len;
+ pos = movedVertexs[i];
+ }
+ }
+ result= pos;
+ }
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ [BurstCompile(DisableDirectCall = true,OptimizeFor = OptimizeFor.Performance)]
+ public static void DoubleCircle(out TSVector2 result,in TSVector2 direction,in TSVector2 centerCircle1,in TSVector2 centerCircle2,in FP r,in TSVector2 centerPos)
+ {
+ //d.normal*
+ if (TSVector2.Dot(direction, centerCircle1-centerPos) > 0)
+ {
+ result= direction.normalized * r + centerCircle1;
+ }
+ else
+ {
+ result= direction.normalized * r + centerCircle2;
+ }
+ }
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ [BurstCompile(DisableDirectCall = true,OptimizeFor = OptimizeFor.Performance)]
+ public static void GetFurthestPoint(out TSVector2 result, in ColliderStructure structure,in TSVector2 direction)
+ {
+ switch (structure.colliderType)
+ {
+ case ColliderType.Circle:
+ Circle(out result,structure.center,direction,structure.radius);
+ return;
+ case ColliderType.Oval:
+ Oval(out result,direction,structure.center,structure.rot,structure.Axis,structure.SqrAxis,structure.b2Dividea2);
+ return;
+ case ColliderType.Polygon:
+ Polygon(out result,direction,points,structure.vertexStartIndex,structure.vertexCount);
+ return;
+ case ColliderType.DoubleCircle:
+ DoubleCircle(out result,direction,structure.circleCenter1,structure.circleCenter2,structure.radius,structure.center);
+ return;
+ default:
+ throw new NotImplementedException();
+ }
+ }
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ [BurstCompile(DisableDirectCall = true,OptimizeFor = OptimizeFor.Performance)]
+ public static void SupportFunc(out TSVector2 result,in ColliderStructure structure1,in ColliderStructure structure2,in TSVector2 direciton) {
+ GetFurthestPoint(out var resTmp,structure1,direciton);
+ TSVector2 negateDirection = direciton;
+ Negate(ref negateDirection);
+ GetFurthestPoint(out var resTmp2, structure2, negateDirection);
+ //Debug.Log("direction: "+direciton+" "+ shape1.GetFurthestPoint(direciton)+" "+shape2.GetFurthestPoint(-direciton));
+ result=resTmp-resTmp2;
+ }
+ }
+ [BurstCompile(DisableDirectCall = true,OptimizeFor = OptimizeFor.Performance)]
+ public struct CollideExtensions
+ {
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ [BurstCompile(DisableDirectCall = true,OptimizeFor = OptimizeFor.Performance)]
+ public static void Abs(out FP result,in FP value) {
+ if (value._serializedValue == MathBurstedFix.MIN_VALUE) {
+ result._serializedValue= MathBurstedFix.MaxValue;
+ return;
+ }
+
+ // branchless implementation, see http://www.strchr.com/optimized_abs_function
+ var mask = value._serializedValue >> 63;
+ result._serializedValue = (value._serializedValue + mask) ^ mask;
+ }
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ [BurstCompile(DisableDirectCall = true,OptimizeFor = OptimizeFor.Performance)]
+ public static void TripleProduct2d(out TSVector2 result,in TSVector2 a,in TSVector2 b,in TSVector2 c) {
+ FP sign = (a.x * b.y - a.y * b.x);
+ FP cY = c.y;
+ GetFurthestPointExtensions.Negate(ref cY);
+ result = new TSVector2(cY, c.x) * sign;
+ }
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ [BurstCompile(DisableDirectCall = true,OptimizeFor = OptimizeFor.Performance)]
+ public static bool GJK(in ColliderStructure shape1, in ColliderStructure shape2) {
+ /*
+ #两个形状s1,s2相交则返回True。所有的向量/点都是二维的,例如([x,y])
+ #第一步:选择一个初始方向,这个初始方向可以是随机选择的,但通常来说是两个形状中心之间的向量,即:
+
+ */
+ TSVector2 tmpVec;
+ TSVector2 direction = (shape2.center - shape1.center).normalized;
+ //#第二步:找到支撑点,即第一个支撑点(即闵可夫斯基差的边上的点之一……)
+ NativeArray Simplex = new NativeArray(3,Allocator.Temp);//单纯形数组,最多只能是3个
+ GetFurthestPointExtensions.SupportFunc(out tmpVec,shape1, shape2, direction);
+ Simplex[0] = tmpVec;
+ int simplexLastInd = 1;
+ int interateTimeMax = 100;//最大迭代次数
+ //#第三步:找到第一个支撑点后,以第一个支撑点为起点指向原点O的方向为新方向d
+ direction = tmpVec;//= -Simplex[0].normalized
+ GetFurthestPointExtensions.Negate(ref direction);
+ TSVector2.Normalize(direction,out direction);
+ //#第四步:开始循环,找下一个支撑点
+ while (interateTimeMax-- > 0)
+ {
+ GetFurthestPointExtensions.SupportFunc(out var A,shape1,shape2,direction);
+ //因为A点是闵可夫斯基差形状在给定方向的最远点,如果那个点没有超过原点,就不想交
+ //#当新的支撑点A没有包含原点,那我们就返回False,即两个形状没有相交
+ if (TSVector2.Dot(A,direction)<0)
+ {
+ Simplex.Dispose();
+ return false;
+ }
+ Simplex[simplexLastInd++] = A;
+ //Debug.Log("input: "+A+shape1.GetType()+" "+shape2.GetType());
+ //处理为线段的情况
+ if (simplexLastInd == 2)
+ {
+ //三维的处理方式
+ /*
+ TSVector AB = Simplex[simplexLastInd-2] - Simplex[simplexLastInd - 1];
+ TSVector AO = -Simplex[simplexLastInd-1];
+ TSVector ABPrep = TSVector.Cross(TSVector.Cross(AB, AO),AB);//垂直于AB的那个点!
+ */
+ //在2d里面可以这么简化
+ TSVector2 AB = Simplex[simplexLastInd - 2] - Simplex[simplexLastInd - 1];
+ TSVector2 AO = Simplex[simplexLastInd - 1];
+ GetFurthestPointExtensions.Negate(ref AO);//这里记得取反
+ TripleProduct2d(out var ABPrep,AB,AO,AB);
+ direction = ABPrep.normalized;
+ /*
+ * A是最新插入的点,B是第一次插入的点
+ 当我们拥有两个点时,我们怎么选择新的方向?
+ 1. 构建向量:
+ o 构建向量 𝐴𝑂(从点A到原点O),即 𝐴𝑂=𝑂−𝐴
+ o 构建向量 𝐴𝐵(从点A到点B),即 𝐴𝐵=𝐵−𝐴
+ 2. 求解垂直向量:
+ o 通过叉积 𝐴𝐵×𝐴𝑂,我们可以得到一个垂直于这两个向量的向量。这个向量垂直于 𝐴𝐵 和 𝐴𝑂 所在的平面,并且指向由右手定则决定的方向。
+ 3. 求解新的方向:
+ o 为了得到新的方向 𝑑,我们需要一个向量,这个向量既垂直于 𝐴𝐵×𝐴𝑂,又垂直于 𝐴𝐵。这可以通过三重积来实现,即:
+ 𝑑=(𝐴𝐵×𝐴𝑂)×𝐴𝐵
+ 这个三重积的结果是一个向量,它垂直于 𝐴𝐵 和 𝐴𝐵×𝐴𝑂 所在的平面。换句话说,它是垂直于 𝐴𝐵 的并且指向原点的可能性最大。
+
+ 简单来说:通过选择垂直于 𝐴𝐵 的方向,我们可以在最有可能包含原点的方向上进行搜索,从而提高搜索效率。
+ */
+ }
+ else//处理为三角形的情况
+ {
+ //C是单纯形第一次插入的元素,B是第二次插入的,A是最后插入的
+ //构建向量AB,AC与AO,并来检测原点在空间的哪个沃罗诺伊区域(通过排除法可以知道肯定在AB或AC或ABC三角形内部区域)
+ TSVector2 AC = Simplex[simplexLastInd - 3] - Simplex[simplexLastInd - 1];
+ TSVector2 AB = Simplex[simplexLastInd - 2] - Simplex[simplexLastInd - 1];
+ TSVector2 AO = Simplex[simplexLastInd - 1];
+ GetFurthestPointExtensions.Negate(ref AO);//这里记得取反
+ //#通过三重积 分别得到垂直于AB、AC转向特定方向的的向量,检测区域Rab、Rac中是否包含原点。
+ TripleProduct2d(out var ABPrep,AC,AB,AB);
+ //TSVector2 ABPrep = TripleProduct2d(AC, AB, AB).normalized;
+ TSVector2.Normalize(ABPrep,out ABPrep);
+ TripleProduct2d(out TSVector2 ACPrep,AB, AC, AC);
+ TSVector2.Normalize(ACPrep,out ACPrep);
+ //Debug.Log(ABPrep+" "+ACPrep+" "+AC+" "+AB+" "+AO);
+ //#如果原点在AB区域中,我们移除点C以寻找更加完美的simplex(C离原点最远),新的方向就是垂直于AB的向量
+ if (TSVector2.Dot(ABPrep, AO) > 0)
+ {
+ for (int i = 1; i < 3; i++)
+ {
+ Simplex[i - 1] = Simplex[i];
+ }//删除数组首个元素(C点),当前的单纯形并不包含原点,
+ simplexLastInd--;
+ direction = ABPrep;
+ } else if (TSVector2.Dot(ACPrep, AO) > 0) {
+ //#如果原点在AC区域中,我们移除点B以寻找更加完美的simplex,新的方向就是垂直于AC的向量
+ Simplex[simplexLastInd - 2] = Simplex[simplexLastInd-1];
+ simplexLastInd--;
+ direction = ACPrep;
+ }
+ else
+ {
+ //否则单纯形包含原点,碰到了
+ Simplex.Dispose();
+ return true;
+ }
+ }
+ }
+ //如果超过迭代次数都没有找到点,则判定为没有碰到。
+ Simplex.Dispose();
+ return false;
+ }
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ [BurstCompile(DisableDirectCall = true,OptimizeFor = OptimizeFor.Performance)]
+ public static bool CircleCollideWithCircle(in ColliderStructure circle1,in ColliderStructure circle2)
+ {
+ TSVector2.DistanceSquared(in circle1.center, in circle2.center, out var dis);
+ return dis <= TSMath.FastQuadratic(circle1.radius + circle2.radius);
+ }
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ [BurstCompile(DisableDirectCall = true,OptimizeFor = OptimizeFor.Performance)]
+ public static bool CircleCollideWithDoubleCircle(in ColliderStructure doubleCircle,in ColliderStructure circle2)
+ {
+ TSVector2 centerShape = circle2.center;
+ TSVector2 deltaPos = centerShape-doubleCircle.center;
+ TSVector2 delta = (doubleCircle.circleCenter2 - doubleCircle.circleCenter1);
+ FP len = delta.magnitude;
+ FP halfLen = len * 0.5;
+ TSVector2 unit = delta/len;
+ FP distance = TSVector2.Dot(unit, deltaPos);
+ Abs(out var absDis,distance);
+ if (absDis > halfLen+doubleCircle.radius+circle2.radius) {
+ //Debug.Log("Type1: "+distance + " " + (this.r + shape2.r) + " " + halfLen);
+ return false;
+ }
+ if (absDis >= halfLen)
+ {
+ //Debug.Log("Type2: " + distance + " "+ centerShape + " " + this.centerCircle2+ " " + this.centerCircle1 + " " + (this.r + shape2.r) + " " + halfLen);
+ if (distance > 0)
+ {
+ return (doubleCircle.circleCenter2 - centerShape).LengthSquared() <= TSMath.FastQuadratic(doubleCircle.radius+circle2.radius);
+ }
+ else
+ {
+ return (doubleCircle.circleCenter1 - centerShape).LengthSquared() <= TSMath.FastQuadratic(doubleCircle.radius+circle2.radius);
+ }
+ }
+ else
+ {
+ //Debug.Log("Type3: " + distance + " " + deltaPos.LengthSquared() + " " + (this.r + shape2.r) + " " + halfLen);
+ //勾股定理
+ return deltaPos.LengthSquared() - TSMath.FastQuadratic(distance) <= TSMath.FastQuadratic(doubleCircle.radius+circle2.radius);
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/Assets/ColliderStructure.cs.meta b/Assets/ColliderStructure.cs.meta
new file mode 100644
index 0000000..df33911
--- /dev/null
+++ b/Assets/ColliderStructure.cs.meta
@@ -0,0 +1,3 @@
+fileFormatVersion: 2
+guid: 74e57101ef3e4e26b1429e4a0aef7474
+timeCreated: 1744030070
\ No newline at end of file
diff --git a/Assets/HashTypeHelpers.cs b/Assets/HashTypeHelpers.cs
new file mode 100644
index 0000000..1d07d09
--- /dev/null
+++ b/Assets/HashTypeHelpers.cs
@@ -0,0 +1,458 @@
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using MessagePack;
+
+namespace Core.Algorithm
+{
+ //给哈希类型添加上按序遍历的功能
+ [Serializable]
+ [MessagePackObject]
+ public class DictionaryWrapper : IDictionary
+ {
+ [Key(0)]
+ protected IDictionary _dictionary;
+ public DictionaryWrapper()
+ {
+ _dictionary = new Dictionary();
+ }
+
+ public DictionaryWrapper(int capacity)
+ {
+ _dictionary = new Dictionary(capacity);
+ }
+ public DictionaryWrapper(IDictionary dictionary)
+ {
+ _dictionary = dictionary;
+ }
+
+ public virtual TValue this[TKey key]
+ {
+ get => _dictionary[key];
+ set => _dictionary[key] = value;
+ }
+
+ public ICollection Keys => _dictionary.Keys;
+
+ public ICollection Values => _dictionary.Values;
+
+ public int Count => _dictionary.Count;
+
+ public bool IsReadOnly => _dictionary.IsReadOnly;
+
+ public virtual void Add(TKey key, TValue value)
+ {
+ _dictionary.Add(key, value);
+ }
+
+ public virtual void Add(KeyValuePair item)
+ {
+ _dictionary.Add(item);
+ }
+
+ public virtual void Clear()
+ {
+ _dictionary.Clear();
+ }
+
+ public bool Contains(KeyValuePair item)
+ {
+ return _dictionary.Contains(item);
+ }
+
+ public bool ContainsKey(TKey key)
+ {
+ return _dictionary.ContainsKey(key);
+ }
+
+ public virtual void CopyTo(KeyValuePair[] array, int arrayIndex)
+ {
+ _dictionary.CopyTo(array, arrayIndex);
+ }
+
+ public virtual IEnumerator> GetEnumerator()
+ {
+ return _dictionary.GetEnumerator();
+ }
+
+ public virtual bool Remove(TKey key)
+ {
+ return _dictionary.Remove(key);
+ }
+
+ public virtual bool Remove(KeyValuePair item)
+ {
+ return _dictionary.Remove(item);
+ }
+
+ public bool TryGetValue(TKey key, out TValue value)
+ {
+ return _dictionary.TryGetValue(key, out value);
+ }
+
+ IEnumerator IEnumerable.GetEnumerator()
+ {
+ return ((IEnumerable)_dictionary).GetEnumerator();
+ }
+ }
+ [Serializable]
+ [MessagePackObject(AllowPrivate = true)]
+ public class LinkedDictionary : DictionaryWrapper, IDictionary
+ {
+ [Key(0)]
+ private readonly Dictionary>> _savedNode = new Dictionary>>();
+ [Key(1)]
+ private readonly LinkedList> _insertedOrderManager = new LinkedList>();
+ public LinkedDictionary()
+ {
+ _dictionary = new Dictionary();
+ }
+
+ /*public DictionaryWrapper(int capacity)
+ {
+ _dictionary = new Dictionary(capacity);
+ }*/
+ public LinkedDictionary(IDictionary dictionary)
+ {
+ _dictionary = dictionary;
+ loadNodes();
+ }
+ private void loadNodes()
+ {
+ foreach (var i in _dictionary)
+ {
+ _insertedOrderManager.AddLast(i);
+ }
+ }
+ private void appendNode(TKey key,TValue value) {
+ var add = new LinkedListNode>(new KeyValuePair(key, value));
+ if(_savedNode.ContainsKey(key))
+ {
+ _insertedOrderManager.AddAfter(_savedNode[key],add);
+ _insertedOrderManager.Remove(_savedNode[key]);
+ _savedNode[key] = add;
+ }
+ else
+ {
+ _insertedOrderManager.AddLast(add);
+ _savedNode[key] = add;
+ }
+ }
+ private void removeNode(TKey key) {
+ if (_savedNode.ContainsKey(key))
+ {
+ _insertedOrderManager.Remove(_savedNode[key]);
+ _savedNode.Remove(key);
+ }
+ }
+ public override TValue this[TKey key]
+ {
+ get => _dictionary[key];
+ set {
+ _dictionary[key] = value;
+ appendNode(key, value);
+ }
+ }
+
+ public override void Add(TKey key, TValue value)
+ {
+ _dictionary.Add(key, value);
+ appendNode(key, value);
+ }
+
+ public override void Add(KeyValuePair item)
+ {
+ _dictionary.Add(item);
+ appendNode(item.Key, item.Value);
+ }
+
+ public override void Clear()
+ {
+ _dictionary.Clear();
+ _insertedOrderManager.Clear();
+ _savedNode.Clear();
+ }
+
+
+ public override void CopyTo(KeyValuePair[] array, int arrayIndex)
+ {
+ _insertedOrderManager.CopyTo(array, arrayIndex);
+ }
+
+ public override IEnumerator> GetEnumerator()
+ {
+ return _insertedOrderManager.GetEnumerator();
+ }
+
+ public override bool Remove(TKey key)
+ {
+ var ret = _dictionary.Remove(key);
+ removeNode(key);
+ return ret;
+ }
+
+ public override bool Remove(KeyValuePair item)
+ {
+ var ret = _dictionary.Remove(item);
+ Remove(item.Key);
+ return ret;
+ }
+
+ IEnumerator IEnumerable.GetEnumerator()
+ {
+ return ((IEnumerable)_insertedOrderManager).GetEnumerator();
+ }
+ }
+ [MessagePackObject]
+ public class HashSetWrapper : ISet
+ {
+ [Key(0)]
+ protected readonly HashSet _hashSet;
+ public HashSetWrapper()
+ {
+ _hashSet = new HashSet();
+ }
+ public HashSetWrapper(HashSet hashSet)
+ {
+ _hashSet = hashSet;
+ }
+
+ public int Count => _hashSet.Count;
+
+ public bool IsReadOnly => ((ICollection)_hashSet).IsReadOnly;
+
+ public virtual bool Add(T item)
+ {
+ return _hashSet.Add(item);
+ }
+
+ void ICollection.Add(T item)
+ {
+ _hashSet.Add(item);
+ }
+
+ public virtual void Clear()
+ {
+ _hashSet.Clear();
+ }
+
+ public bool Contains(T item)
+ {
+ return _hashSet.Contains(item);
+ }
+
+ public virtual void CopyTo(T[] array, int arrayIndex)
+ {
+ _hashSet.CopyTo(array, arrayIndex);
+ }
+
+ public virtual void ExceptWith(IEnumerable other)
+ {
+ _hashSet.ExceptWith(other);
+ }
+
+ public virtual IEnumerator GetEnumerator()
+ {
+ return _hashSet.GetEnumerator();
+ }
+
+ public virtual void IntersectWith(IEnumerable other)
+ {
+ _hashSet.IntersectWith(other);
+ }
+
+ public bool IsProperSubsetOf(IEnumerable other)
+ {
+ return _hashSet.IsProperSubsetOf(other);
+ }
+
+ public bool IsProperSupersetOf(IEnumerable other)
+ {
+ return _hashSet.IsProperSupersetOf(other);
+ }
+
+ public bool IsSubsetOf(IEnumerable other)
+ {
+ return _hashSet.IsSubsetOf(other);
+ }
+
+ public bool IsSupersetOf(IEnumerable other)
+ {
+ return _hashSet.IsSupersetOf(other);
+ }
+
+ public bool Overlaps(IEnumerable other)
+ {
+ return _hashSet.Overlaps(other);
+ }
+
+ public virtual bool Remove(T item)
+ {
+ return _hashSet.Remove(item);
+ }
+
+ public bool SetEquals(IEnumerable other)
+ {
+ return _hashSet.SetEquals(other);
+ }
+
+ public virtual void SymmetricExceptWith(IEnumerable other)
+ {
+ _hashSet.SymmetricExceptWith(other);
+ }
+
+ public virtual void UnionWith(IEnumerable other)
+ {
+ _hashSet.UnionWith(other);
+ }
+
+ IEnumerator IEnumerable.GetEnumerator()
+ {
+ return ((IEnumerable)_hashSet).GetEnumerator();
+ }
+ }
+ [Serializable]
+ [MessagePackObject(AllowPrivate = true)]
+ public class LinkedHashSet : HashSetWrapper, ISet
+ {
+ [Key(0)]
+ Dictionary> _savedNodes = new Dictionary>();
+ [Key(1)]
+ LinkedList _insertedOrderSaver = new LinkedList();
+ public override bool Add(T item)
+ {
+ if (_hashSet.Add(item))
+ {
+ _insertedOrderSaver.AddLast(item);
+ _savedNodes.Add(item,_insertedOrderSaver.Last);
+ return true;
+ }
+ return false;
+ }
+ void ICollection.Add(T item)
+ {
+ Add(item);
+ }
+ public override void Clear()
+ {
+ _hashSet.Clear();
+ _savedNodes.Clear();
+ _insertedOrderSaver.Clear();
+ }
+ public override void CopyTo(T[] array, int arrayIndex)
+ {
+ _insertedOrderSaver.CopyTo(array, arrayIndex);
+ }
+ public override void UnionWith(IEnumerable other)
+ {
+ if (other == null)
+ {
+ throw new ArgumentNullException("other");
+ }
+
+ foreach (T item in other)
+ {
+ Add(item);
+ }
+ }
+ public override void ExceptWith(IEnumerable other)
+ {
+ if (other == null)
+ {
+ throw new ArgumentNullException("other");
+ }
+
+ if (_hashSet.Count == 0)
+ {
+ return;
+ }
+
+ if (other == this)
+ {
+ Clear();
+ return;
+ }
+
+ foreach (T item in other)
+ {
+ Remove(item);
+ }
+ }
+ public override IEnumerator GetEnumerator()
+ {
+ return _insertedOrderSaver.GetEnumerator();
+ }
+
+ public override void IntersectWith(IEnumerable other)
+ {
+ _hashSet.IntersectWith(other);
+ //求交集求完之后只会删掉元素……
+ var node = _insertedOrderSaver.First;
+ LinkedListNode tmp = node;
+ while (node != null) {
+ tmp = node.Next;
+ if (node.Value==null||!_hashSet.Contains(node.Value))
+ {
+ _insertedOrderSaver.Remove(node);
+ _savedNodes.Remove(node.Value);
+ }
+ node= tmp;
+ }
+ }
+ public override bool Remove(T item)
+ {
+ if (_savedNodes.ContainsKey(item))
+ {
+ _insertedOrderSaver.Remove(_savedNodes[item]);
+ _savedNodes.Remove(item);
+ }
+ return _hashSet.Remove(item);
+ }
+ private static bool AreEqualityComparersEqual(HashSet set1, HashSet set2)
+ {
+ return set1.Comparer.Equals(set2.Comparer);
+ }
+ public override void SymmetricExceptWith(IEnumerable other)
+ {
+ if (other == null)
+ {
+ throw new ArgumentNullException("other");
+ }
+
+ if (_hashSet.Count == 0)
+ {
+ UnionWith(other);
+ }
+ else if (other == this)
+ {
+ Clear();
+ }
+ else if (other is HashSet hashSet && AreEqualityComparersEqual(_hashSet, hashSet))
+ {
+ foreach (T item in other)
+ {
+ if (!Remove(item))
+ {
+ Add(item);
+ }
+ }
+ }
+ else
+ {
+ foreach(T item in other)
+ {
+ if (!Add(item))
+ {
+ Remove(item);
+ }
+ }
+ }
+ }
+
+ }
+ [MessagePackObject]
+ public class LinkedPooledHashSet : LinkedHashSet, IPoolable
+ {
+ public void Reset() { Clear(); }
+ }
+}
\ No newline at end of file
diff --git a/Assets/HashTypeHelpers.cs.meta b/Assets/HashTypeHelpers.cs.meta
new file mode 100644
index 0000000..0a7a072
--- /dev/null
+++ b/Assets/HashTypeHelpers.cs.meta
@@ -0,0 +1,2 @@
+fileFormatVersion: 2
+guid: 0a103d9faf2bced429ffa66fa45797f7
\ No newline at end of file
diff --git a/Assets/JobsTesting.cs b/Assets/JobsTesting.cs
index 1baa818..4a6fbfa 100644
--- a/Assets/JobsTesting.cs
+++ b/Assets/JobsTesting.cs
@@ -1,17 +1,87 @@
+using System;
+using System.Collections.Generic;
+using TrueSync;
+using Unity.Burst;
+using Unity.Collections;
+using Unity.Jobs;
using Unity.Mathematics;
using UnityEngine;
+[BurstCompile(DisableDirectCall = true)]
+public struct testJob : IJobParallelFor
+{
+ public NativeArray values;
+ public void Execute(int index)
+ {
+ var tmp = values[index];
+ tmp.center += TSVector2.left;
+ values[index] = tmp;
+ }
+}
+
+public class someObjects
+{
+ public TSVector2 center;
+ public someObjectsToStruct ToStruct()
+ {
+ return new someObjectsToStruct()
+ {
+ center = center
+ };
+ }
+}
+
+public struct someObjectsToStruct
+{
+ public TSVector2 center;
+}
public class JobsTesting : MonoBehaviour
{
- // Start is called once before the first execution of Update after the MonoBehaviour is created
- void Start()
+ List objs = new List();
+
+ private void Start()
+ {
+ for (int i = 0; i < 500000; i++)
+ {
+ var o = new someObjects();
+ o.center = math.UnitVector(360*((FP)UnityEngine.Random.value))*(FP)UnityEngine.Random.value*100;
+ objs.Add(o);
+ }
+ }
+
+ void BurstUpdate()
{
-
+ int len = objs.Count;
+ var job = new testJob();
+ var values = new NativeArray(len, Allocator.TempJob);
+ for (int i = 0; i < len; i++)
+ {
+ values[i] = objs[i].ToStruct();
+ }
+ job.values = values;
+ JobHandle handle = job.Schedule(values.Length, 64);
+ // 等待作业完成
+ handle.Complete();
+ for (int i = 0; i < len; i++)
+ {
+ objs[i].center = values[i].center;
+ }
+ values.Dispose();
}
- // Update is called once per frame
+ void NormalUpdate()
+ {
+ int len = objs.Count;
+ for (int i = 0; i < len; i++)
+ {
+ objs[i].center += TSVector2.left;
+ }
+ }
+
+ // Start is called once before the first execution of Update after the MonoBehaviour is created
void Update()
{
-
+ BurstUpdate();
}
+
}
diff --git a/Assets/PoolingManager.cs b/Assets/PoolingManager.cs
new file mode 100644
index 0000000..2310e70
--- /dev/null
+++ b/Assets/PoolingManager.cs
@@ -0,0 +1,47 @@
+using System.Collections.Generic;
+
+namespace Core.Algorithm
+{
+ public interface IPoolable
+ {
+ public void Reset();
+ }
+
+ public static class ObjectPool where T : class, IPoolable, new()
+ {
+ private static readonly Stack _pool = new Stack();
+ private static readonly object _lock = new object();
+
+ // 创建并初始化对象
+ private static T CreateInstance()
+ {
+ var instance = new T();
+ instance.Reset();
+ return instance;
+ }
+
+ // 静态泛型方法获取对象
+ public static T GetObject()
+ {
+ if (_pool.Count > 0)
+ {
+ var instance = _pool.Pop();
+ instance.Reset();
+ return instance;
+ }
+
+ // 如果没有可用对象,则创建一个新的实例
+ return CreateInstance();
+ }
+
+ // 静态方法回收对象
+ public static void ReturnObject(T obj)
+ {
+ if (obj == null)
+ return;
+
+ _pool.Push(obj);
+ }
+ }
+
+}
diff --git a/Assets/PoolingManager.cs.meta b/Assets/PoolingManager.cs.meta
new file mode 100644
index 0000000..76eb66c
--- /dev/null
+++ b/Assets/PoolingManager.cs.meta
@@ -0,0 +1,2 @@
+fileFormatVersion: 2
+guid: 2cd0b71914aa8544899db2eadf8ecd45
\ No newline at end of file
diff --git a/Assets/Scenes/SampleScene.unity b/Assets/Scenes/SampleScene.unity
index 1c63aa8..a141fd2 100644
--- a/Assets/Scenes/SampleScene.unity
+++ b/Assets/Scenes/SampleScene.unity
@@ -38,12 +38,12 @@ RenderSettings:
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
+ serializedVersion: 13
+ m_BakeOnSceneLoad: 0
m_GISettings:
serializedVersion: 2
m_BounceScale: 1
@@ -131,6 +131,7 @@ GameObject:
- component: {fileID: 330585545}
- component: {fileID: 330585544}
- component: {fileID: 330585547}
+ - component: {fileID: 330585548}
m_Layer: 0
m_Name: Main Camera
m_TagString: MainCamera
@@ -250,12 +251,24 @@ MonoBehaviour:
m_RequiresColorTexture: 0
m_Version: 2
m_TaaSettings:
- quality: 3
- frameInfluence: 0.1
- jitterScale: 1
- mipBias: 0
- varianceClampScale: 0.9
- contrastAdaptiveSharpening: 0
+ m_Quality: 3
+ m_FrameInfluence: 0.1
+ m_JitterScale: 1
+ m_MipBias: 0
+ m_VarianceClampScale: 0.9
+ m_ContrastAdaptiveSharpening: 0
+--- !u!114 &330585548
+MonoBehaviour:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 330585543}
+ m_Enabled: 1
+ m_EditorHideFlags: 0
+ m_Script: {fileID: 11500000, guid: a3527897712cb704f9f4e04d329e7bba, type: 3}
+ m_Name:
+ m_EditorClassIdentifier:
--- !u!1 &410087039
GameObject:
m_ObjectHideFlags: 0
@@ -336,6 +349,9 @@ Light:
m_ForceVisible: 0
m_ShadowRadius: 0
m_ShadowAngle: 0
+ m_LightUnit: 1
+ m_LuxAtDistance: 1
+ m_EnableSpotReflector: 1
--- !u!4 &410087041
Transform:
m_ObjectHideFlags: 0
diff --git a/Assets/TrueSync/Fix64.cs b/Assets/TrueSync/Fix64.cs
index 4ddea00..eaaa6ee 100644
--- a/Assets/TrueSync/Fix64.cs
+++ b/Assets/TrueSync/Fix64.cs
@@ -3,6 +3,7 @@
using UnityEngine;
using Unity.Burst;
using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
using MessagePack;
@@ -55,6 +56,7 @@ public override void OnGUI(Rect position, SerializedProperty property, GUIConten
///
[Serializable]
[MessagePackObject]
+ [StructLayout(LayoutKind.Sequential)]
public partial struct FP : IEquatable, IComparable
{
diff --git a/Assets/TrueSync/Fuck.cs b/Assets/TrueSync/Fuck.cs
new file mode 100644
index 0000000..54bfe29
--- /dev/null
+++ b/Assets/TrueSync/Fuck.cs
@@ -0,0 +1,8 @@
+namespace TrueSync
+{
+ /*public partial struct FP
+ {
+ public static readonly long[] TanLut = { 1 };
+ public static readonly long[] AcosLut = { 1 };
+ }*/
+}
\ No newline at end of file
diff --git a/Assets/TrueSync/Fuck.cs.meta b/Assets/TrueSync/Fuck.cs.meta
new file mode 100644
index 0000000..0ad40f9
--- /dev/null
+++ b/Assets/TrueSync/Fuck.cs.meta
@@ -0,0 +1,3 @@
+fileFormatVersion: 2
+guid: 45df6d4ca1524c0f9e82eaf172ae5e9c
+timeCreated: 1744036628
\ No newline at end of file
diff --git a/Assets/TrueSync/TSVector2.cs b/Assets/TrueSync/TSVector2.cs
index 68e8704..7284619 100644
--- a/Assets/TrueSync/TSVector2.cs
+++ b/Assets/TrueSync/TSVector2.cs
@@ -42,14 +42,14 @@ public struct TSVector2 : IEquatable
{
#region Private Fields
- private static TSVector2 zeroVector = new TSVector2(0, 0);
- private static TSVector2 oneVector = new TSVector2(1, 1);
+ private static readonly TSVector2 zeroVector = new TSVector2(0, 0);
+ private static readonly TSVector2 oneVector = new TSVector2(1, 1);
- private static TSVector2 rightVector = new TSVector2(1, 0);
- private static TSVector2 leftVector = new TSVector2(-1, 0);
+ private static readonly TSVector2 rightVector = new TSVector2(1, 0);
+ private static readonly TSVector2 leftVector = new TSVector2(-1, 0);
- private static TSVector2 upVector = new TSVector2(0, 1);
- private static TSVector2 downVector = new TSVector2(0, -1);
+ private static readonly TSVector2 upVector = new TSVector2(0, 1);
+ private static readonly TSVector2 downVector = new TSVector2(0, -1);
#endregion Private Fields
@@ -230,20 +230,20 @@ public static FP Distance(TSVector2 value1, TSVector2 value2)
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static void Distance(ref TSVector2 value1, ref TSVector2 value2, out FP result)
+ public static void Distance(in TSVector2 value1, in TSVector2 value2, out FP result)
{
- DistanceSquared(ref value1, ref value2, out result);
+ DistanceSquared(in value1, in value2, out result);
result = (FP) FP.Sqrt(result);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static FP DistanceSquared(TSVector2 value1, TSVector2 value2)
{
FP result;
- DistanceSquared(ref value1, ref value2, out result);
+ DistanceSquared(in value1, in value2, out result);
return result;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static void DistanceSquared(ref TSVector2 value1, ref TSVector2 value2, out FP result)
+ public static void DistanceSquared(in TSVector2 value1, in TSVector2 value2, out FP result)
{
result._serializedValue=MathBurstedFix.DistanceSquared(
(value1.x._serializedValue - value2.x._serializedValue),
@@ -336,7 +336,7 @@ public FP magnitude {
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get {
FP result;
- DistanceSquared(ref this, ref zeroVector, out result);
+ DistanceSquared(in this, in zeroVector, out result);
return FP.Sqrt(result);
}
}
@@ -348,7 +348,7 @@ public static TSVector2 ClampMagnitude(TSVector2 vector, FP maxLength) {
public FP LengthSquared()
{
FP result;
- DistanceSquared(ref this, ref zeroVector, out result);
+ DistanceSquared(in this, in zeroVector, out result);
return result;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
@@ -455,12 +455,12 @@ public static void Negate(ref TSVector2 value, out TSVector2 result)
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void Normalize()
{
- Normalize(ref this, out this);
+ Normalize(in this, out this);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static TSVector2 Normalize(TSVector2 value)
{
- Normalize(ref value, out value);
+ Normalize(in value, out value);
return value;
}
[IgnoreMember]
@@ -468,16 +468,16 @@ public TSVector2 normalized {
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get {
TSVector2 result;
- TSVector2.Normalize(ref this, out result);
+ TSVector2.Normalize(in this, out result);
return result;
}
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static void Normalize(ref TSVector2 value, out TSVector2 result)
+ public static void Normalize(in TSVector2 value, out TSVector2 result)
{
FP factor;
- DistanceSquared(ref value, ref zeroVector, out factor);
+ DistanceSquared(in value, in zeroVector, out factor);
//UnityEngine.Debug.Log("value " + value);
factor = 1f/(FP) FP.Sqrt(factor);
result.x = value.x*factor;
diff --git a/Assets/math.cs b/Assets/math.cs
new file mode 100644
index 0000000..c258be6
--- /dev/null
+++ b/Assets/math.cs
@@ -0,0 +1,511 @@
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using UnityEngine;
+using System;
+using TrueSync;
+
+namespace RandomBenchmark
+{
+ public class XorShiftRandom
+ {
+ private const double NormalizationFactor = 1.0 / int.MaxValue;
+
+ private readonly ulong[] _state;
+ private ulong _seed;
+ private bool _takeMsb = true;
+ private ulong _currentPartialResult;
+
+ public XorShiftRandom(int seed)
+ {
+ _seed = (ulong)seed;
+ _state = new[] { SplitMix64(), SplitMix64() };
+ }
+
+ public virtual int Next()
+ {
+ var sample = InternalSample() & int.MaxValue;
+
+ return sample == int.MaxValue
+ ? --sample
+ : sample;
+ }
+
+ public virtual int Next(int minValue, int maxValue)
+ {
+ if (minValue > maxValue)
+ throw new ArgumentOutOfRangeException(nameof(minValue));
+
+ var range = (long)maxValue - minValue;
+
+ return minValue + (int)(range * NextDouble());
+ }
+
+ public virtual int Next(int maxValue)
+ {
+ if (maxValue < 0)
+ throw new ArgumentOutOfRangeException(nameof(maxValue));
+
+ return (int)(NextDouble() * maxValue);
+ }
+
+ public virtual double NextDouble()
+ {
+ var sample = Next();
+ return sample * NormalizationFactor;
+ }
+
+ public virtual void NextBytes(byte[] buffer)
+ {
+ if (buffer == null)
+ throw new ArgumentNullException(nameof(buffer));
+
+ var tmp = BitConverter.GetBytes(InternalSample());
+ short index = 0;
+ for (var i = 0; i < buffer.Length; ++i)
+ {
+ if (index == 4)
+ {
+ index = 0;
+ tmp = BitConverter.GetBytes(InternalSample());
+ }
+
+ buffer[i] = tmp[index++];
+ }
+ }
+
+ private int InternalSample()
+ {
+ int sample;
+
+ if (_takeMsb)
+ {
+ _currentPartialResult = XorShift128Plus();
+ sample = unchecked((int)(_currentPartialResult >> 32));
+ }
+ else
+ {
+ sample = unchecked((int)_currentPartialResult);
+ }
+
+ _takeMsb = !_takeMsb;
+
+ return sample;
+ }
+
+ private ulong SplitMix64()
+ {
+ var z = unchecked(_seed += 0x9E3779B97F4A7C15);
+ z = unchecked((z ^ (z >> 30)) * 0xBF58476D1CE4E5B9);
+ z = unchecked((z ^ (z >> 27)) * 0x94D049BB133111EB);
+ return z ^ (z >> 31);
+ }
+
+ private ulong XorShift128Plus()
+ {
+ var s1 = _state[0];
+ var s0 = _state[1];
+ var result = s0 + s1;
+ _state[0] = s0;
+ s1 ^= s1 << 23;
+ _state[1] = s1 ^ s0 ^ (s1 >> 18) ^ (s0 >> 5);
+ return result;
+ }
+ }
+}
+public class KalmanFilterVector3
+{
+
+ //-----------------------------------------------------------------------------------------
+ // Constants:
+ //-----------------------------------------------------------------------------------------
+
+ public const float DEFAULT_Q = 0.000001f;
+ public const float DEFAULT_R = 0.01f;
+
+ public const float DEFAULT_P = 1;
+
+ //-----------------------------------------------------------------------------------------
+ // Private Fields:
+ //-----------------------------------------------------------------------------------------
+
+ private float q;
+ private float r;
+ private float p = DEFAULT_P;
+ private Vector3 x;
+ private float k;
+
+ //-----------------------------------------------------------------------------------------
+ // Constructors:
+ //-----------------------------------------------------------------------------------------
+
+ // N.B. passing in DEFAULT_Q is necessary, even though we have the same value (as an optional parameter), because this
+ // defines a parameterless constructor, allowing us to be new()'d in generics contexts.
+ public KalmanFilterVector3() : this(DEFAULT_Q) { }
+ public KalmanFilterVector3 InitPosition(Vector3 initalPosition) {
+ x = initalPosition;
+ return this;
+ }
+
+ public KalmanFilterVector3(float aQ = DEFAULT_Q, float aR = DEFAULT_R)
+ {
+ q = aQ;
+ r = aR;
+ }
+
+ //-----------------------------------------------------------------------------------------
+ // Public Methods:
+ //-----------------------------------------------------------------------------------------
+
+ public Vector3 Update(Vector3 measurement, float? newQ = null, float? newR = null)
+ {
+
+ // update values if supplied.
+ if (newQ != null && q != newQ)
+ {
+ q = (float)newQ;
+ }
+ if (newR != null && r != newR)
+ {
+ r = (float)newR;
+ }
+
+ // update measurement.
+ {
+ k = (p + q) / (p + q + r);
+ p = r * (p + q) / (r + p + q);
+ }
+
+ // filter result back into calculation.
+ Vector3 result = x + (measurement - x) * k;
+ x = result;
+ return result;
+ }
+
+ public Vector3 Update(List measurements, bool areMeasurementsNewestFirst = false, float? newQ = null, float? newR = null)
+ {
+
+ Vector3 result = Vector3.zero;
+ int i = (areMeasurementsNewestFirst) ? measurements.Count - 1 : 0;
+
+ while (i < measurements.Count && i >= 0)
+ {
+
+ // decrement or increment the counter.
+ if (areMeasurementsNewestFirst)
+ {
+ --i;
+ }
+ else
+ {
+ ++i;
+ }
+
+ result = Update(measurements[i], newQ, newR);
+ }
+
+ return result;
+ }
+
+ public void Reset(Vector3? InitPosition=null)
+ {
+ p = 1;
+ x = InitPosition??Vector3.zero;
+ k = 0;
+ }
+}
+public static class math
+{
+ public static readonly FP sqrt2 = FP.Sqrt(2);
+ public static bool checkOut(TSVector2 border, TSVector pos, TSVector2 size)
+ {
+ FP max = TSMath.Max(size.x,size.y);
+ border *= 0.5;
+ size = TSVector2.one * (max * sqrt2 * 0.5);
+ if (pos.x - size.x > border.x || pos.x + size.x < -border.x || pos.y - size.y > border.y || pos.y + size.y < -border.y)
+ {
+ return true;
+ }
+ return false;
+ }
+ ///
+ /// 圆弧接起来的曲线
+ ///
+ /// 时间
+ /// 半径
+ /// 角速度
+ /// 每个圆弧的弧度
+ ///
+ public static Vector2 curve_joined_by_arc(float time,float r,float w,float theta) {
+ float theta2 = Mathf.PI / 2f - (2 * Mathf.PI - theta) / 2f;
+ float theta3 = Mathf.PI / 2f + (2 * Mathf.PI - theta) / 2f;
+ //目前处于的弧度
+ float currentArc = ((w * time) % theta + theta3) * Mathf.Pow((-1) , Mathf.Floor((w*time) / theta));
+ Vector2 circleCenter = new Vector2(
+ Mathf.Cos(theta2)*(2*Mathf.Floor((w*time) / theta + 1) -1)*r,
+ Mathf.Sin(theta2)*Mathf.Pow((-1) , Mathf.Floor((w*time) / theta + 1))*r
+ );
+ return new Vector2(Mathf.Cos(currentArc), Mathf.Sin(currentArc))*r+circleCenter;
+ }
+ ///
+ ///Catmull-Rom线,会通过相关的控制点
+ /// 根据起点,n个控制点,终点 计算Cspline曲线插值(首尾为必要的点,其余为控制点,所以至少有4个点)
+ ///
+ /// 起点,n-1个控制点,终点
+ /// 当前插值位置0~1 ,0为起点,1为终点
+ ///
+ public static TSVector Interp(TSVector[] pts, FP t)
+ {
+ t = TSMath.Clamp(t, 0.0, 2.0);
+ int numSections = pts.Length - 3;
+ int currPt = (int)TSMath.Min(TSMath.Floor(t * numSections), numSections - 1);
+ FP u = t * numSections - currPt;
+ TSVector a = pts[currPt];
+ TSVector b = pts[currPt + 1];
+ TSVector c = pts[currPt + 2];
+ TSVector d = pts[currPt + 3];
+
+ return 0.5 * (
+ ((TSVector.zero-a) + 3 * b - 3 * c + d) * (u * u * u)
+ + (2 * a - 5 * b + 4 * c - d) * (u * u)
+ + ((TSVector.zero - a) + c) * u
+ + 2 * b
+ );
+ }
+ ///
+ /// n阶贝塞尔曲线插值计算函数
+ /// 根据起点,n个控制点,终点 计算贝塞尔曲线插值
+ ///
+ /// 起点,n-1个控制点,终点
+ /// 当前插值位置0~1 ,0为起点,1为终点
+ ///
+ public static Vector3 bezier_interpolation_func(Vector3[] points, float t)
+ {
+ Vector3 PointF = new Vector3();
+ if (t == 1)
+ {
+ return points[points.Length - 1];
+ }
+ int count = points.Length;
+ float[] part = new float[count];
+ float sum_x = 0, sum_y = 0;
+ for (int i = 0; i < count; i++)
+ {
+ ulong tmp;
+ int n_order = count - 1; // 阶数
+ tmp = calc_combination_number(n_order, i);
+ sum_x += (float)(tmp * points[i].x * Math.Pow((1 - t), n_order - i) * Math.Pow(t, i));
+ sum_y += (float)(tmp * points[i].y * Math.Pow((1 - t), n_order - i) * Math.Pow(t, i));
+ }
+ PointF.x = sum_x;
+ PointF.y = sum_y;
+ return PointF;
+ }
+ public static TSVector2 expandVectorOnTargetAngle(in TSVector2 vec,in TSVector2 scale,FP angle=default)
+ {
+ /*
+ * (a cos^2(d) + b sin^2(d) | a sin(d) cos(d) - b sin(d) cos(d)
+ a sin(d) cos(d) - b sin(d) cos(d) | a sin^2(d) + b cos^2(d))
+ */
+ angle*=TSMath.Deg2Rad;
+ FP sin = FP.FastSin(angle);
+ FP cos = FP.FastCos(angle);
+ FP sin2 = sin * sin;
+ FP cos2 = cos * cos;
+ FP sincos = sin * cos;
+ return new TSVector2(
+ (scale.x*cos2+scale.y*sin2)*vec.x+(scale.x-scale.y)*sincos*vec.y,
+ (scale.x-scale.y)*sincos*vec.x+(scale.x*sin2+scale.y*cos2)*vec.y
+ );
+ }
+ ///
+ /// 计算组合数公式
+ ///
+ ///
+ ///
+ ///
+ private static ulong calc_combination_number(int n, int k)
+ {
+ ulong[] result = new ulong[n + 1];
+ for (int i = 1; i <= n; i++)
+ {
+ result[i] = 1;
+ for (int j = i - 1; j >= 1; j--)
+ result[j] += result[j - 1];
+ result[0] = 1;
+ }
+ return result[k];
+ }
+
+
+ public static long MoveToward(long target, long current, long maxDistanceDelta)
+ {
+ long num = target - current;
+ long power = num * num;
+ if (power == 0 || (maxDistanceDelta >= 0 && power <= maxDistanceDelta * maxDistanceDelta))
+ {
+ return target;
+ }
+ long num5 = power;
+ return current + num / num5 * maxDistanceDelta;
+ }
+ public static Vector2 UnitVector(float ang)
+ {
+ return new Vector2(Mathf.Cos(ang * Mathf.Deg2Rad), Mathf.Sin(ang * Mathf.Deg2Rad));
+ }
+ public static TSVector2 UnitVector(int ang)
+ {
+ return new TSVector2(FP.FastCos(ang * TSMath.Deg2Rad), FP.FastSin(ang * TSMath.Deg2Rad));
+ }
+ public static TSVector2 UnitVector(FP ang)
+ {
+ return new TSVector2(FP.FastCos(ang * TSMath.Deg2Rad), FP.FastSin(ang * TSMath.Deg2Rad));
+ }
+ public static Mesh CreateMesh(float radius, float innerradius, float angledegree, int segments)
+ {
+ //vertices(顶点):
+ int vertices_count = segments * 2 + 2; //因为vertices(顶点)的个数与triangles(索引三角形顶点数)必须匹配
+ Vector3[] vertices = new Vector3[vertices_count];
+ float angleRad = Mathf.Deg2Rad * angledegree;
+ float angleCur = angleRad;
+ float angledelta = angleRad / segments;
+ for (int i = 0; i < vertices_count; i += 2)
+ {
+ float cosA = Mathf.Cos(angleCur);
+ float sinA = Mathf.Sin(angleCur);
+ vertices[i] = new Vector3(radius * cosA, radius * sinA, 0);
+ vertices[i + 1] = new Vector3(innerradius * cosA, innerradius * sinA, 0);
+ angleCur -= angledelta;
+ }
+ //triangles:
+ int triangle_count = segments * 6;
+ int[] triangles = new int[triangle_count];
+ for (int i = 0, vi = 0; i < triangle_count; i += 6, vi += 2)
+ {
+ triangles[i] = vi;
+ triangles[i + 1] = vi + 3;
+ triangles[i + 2] = vi + 1;
+ triangles[i + 3] = vi + 2;
+ triangles[i + 4] = vi + 3;
+ triangles[i + 5] = vi;
+ }
+ //uv:
+ Vector2[] uvs = new Vector2[vertices_count];
+ for (int i = 0; i < vertices_count; i+=2)
+ {
+ uvs[i] = new Vector2((float)i / vertices_count, 1);
+ uvs[i+1] = new Vector2((float)i / vertices_count, 0);
+ }
+ //负载属性与mesh
+ Mesh mesh = new Mesh();
+ mesh.vertices = vertices;
+ mesh.triangles = triangles;
+ mesh.uv = uvs;
+ return mesh;
+ }
+ public static FP MapAngleTo180Range(FP angle)
+ {
+ // 使用取余运算符,首先要将负数角度转换为正数,以便正确取余
+ // 然后根据取余结果决定是否减去360度,转换回原区间并考虑正负
+ return (angle + 540) % 360 - 180;
+ }
+
+ public static bool CircleTriggerCircle(in TSVector point1, in FP r1, in TSVector point2, in FP r2, FP r1_width_height_ratio = default)
+ {
+ if (r1_width_height_ratio == 0)
+ {
+ r1_width_height_ratio = 1;
+ }
+ r1_width_height_ratio = (r1 * r1_width_height_ratio + r2) / (r1 + r2);//这个判定只适用于大椭圆与小圆判定,因为其实不是椭圆,只是近似为一个椭圆
+ return (TSMath.FastQuadratic(TSMath.Abs((point2.x - point1.x) / r1_width_height_ratio)) + TSMath.FastQuadratic(TSMath.Abs(point2.y - point1.y))) <= TSMath.FastQuadratic(r1 + r2);
+ }
+}
+namespace ZeroAs.DataStructure {
+
+ public class MaxHeap where T : IComparable
+ {
+ public List container = new List();
+ int cnt = 0;
+ public int Count { get { return cnt; } }
+ protected virtual bool cmp(T a, T b)
+ {
+ return a.CompareTo(b) > 0;
+ }
+ void swap(int a, int b)
+ {
+ T tmp = container[a]; container[a] = container[b]; container[b] = tmp;
+ }
+ void up()
+ {
+ int pos = cnt - 1;
+ while (pos > 0)
+ {
+ int father = (pos - 1) >> 1;
+ //pos>father
+ if (cmp(container[pos], container[father]))
+ {
+ swap(pos, father);
+ pos = father;
+ }
+ else
+ {
+ break;
+ }
+ }
+ }
+ void down()
+ {
+ int pos = 0, leftChild;
+ while ((leftChild = (pos << 1) + 1) < cnt)
+ {
+ int swapper = leftChild;
+ if (leftChild + 1 < cnt && cmp(container[leftChild + 1], container[leftChild]))
+ {
+ //right>left
+ swapper++;
+ }
+ //swapper > pos
+ if (cmp(container[swapper], container[pos]))
+ {
+ swap(pos, swapper);
+ pos = swapper;
+ }
+ else
+ {
+ break;
+ }
+ }
+ }
+ public void Add(T item)
+ {
+ container.Add(item);
+ cnt++;
+ up();
+ }
+ public bool IsEmpty
+ {
+ get { return cnt == 0; }
+ }
+ public T Pop()
+ {
+ if (this.IsEmpty)
+ {
+ throw new InvalidOperationException("堆为空");
+ }
+ T res = container[0];
+ --cnt;
+ container[0] = container[cnt];
+ container.RemoveAt(cnt);
+ down();
+ return res;
+ }
+ public T Peek()
+ {
+ if (this.IsEmpty)
+ {
+ throw new InvalidOperationException("堆为空");
+ }
+ return container[0];
+ }
+ }
+}
\ No newline at end of file
diff --git a/Assets/math.cs.meta b/Assets/math.cs.meta
new file mode 100644
index 0000000..f1f32e5
--- /dev/null
+++ b/Assets/math.cs.meta
@@ -0,0 +1,2 @@
+fileFormatVersion: 2
+guid: 096c4a70d4e6a474784178f5dfa52f70
\ No newline at end of file
diff --git a/Assets/tmpExtensions.cs b/Assets/tmpExtensions.cs
new file mode 100644
index 0000000..0648017
--- /dev/null
+++ b/Assets/tmpExtensions.cs
@@ -0,0 +1,45 @@
+using TrueSync;
+using UnityEngine;
+
+namespace Core.Algorithm
+{
+ public static class tmpExtensions
+ {
+ public static Vector2 RotateRad(this Vector2 self, float rad)
+ {
+ float cos = Mathf.Cos(rad), sin = Mathf.Cos(rad);
+ return new Vector2(self.x * cos - self.y * sin, self.x * sin + self.y * cos);
+ }
+ ///
+ /// 旋转一个二维向量
+ ///
+ /// 该向量
+ /// 弧度
+ ///
+ public static TSVector2 RotateRad(this TSVector2 self, FP rad, TSVector2 original = (default))
+ {
+ self -= original;
+ FP cos = FP.FastCos(rad), sin = FP.FastSin(rad);
+ return new TSVector2(self.x * cos - self.y * sin, self.x * sin + self.y * cos) + original;
+ }
+ public static TSVector RotateRad(this TSVector self, FP rad, TSVector original = (default))
+ {
+ self -= original;
+ FP cos = FP.FastCos(rad), sin = FP.FastSin(rad);
+ return new TSVector(self.x * cos - self.y * sin, self.x * sin + self.y * cos, self.z) + original;
+ }
+ ///
+ /// 旋转一个二维向量
+ ///
+ /// 该向量
+ /// 角度
+ ///
+ public static TSVector2 RotateAngle(this TSVector2 self, FP angle, TSVector2 original = (default)) {
+ return RotateRad(self, angle * TSMath.Deg2Rad, original);
+ }
+ public static TSVector RotateAngle(this TSVector self, FP angle, TSVector original = (default))
+ {
+ return RotateRad(self, angle * TSMath.Deg2Rad, original);
+ }
+ }
+}
\ No newline at end of file
diff --git a/Assets/tmpExtensions.cs.meta b/Assets/tmpExtensions.cs.meta
new file mode 100644
index 0000000..95fd7d9
--- /dev/null
+++ b/Assets/tmpExtensions.cs.meta
@@ -0,0 +1,3 @@
+fileFormatVersion: 2
+guid: dbfc0cfa7fb2449fb1e7555d8b0e0f3f
+timeCreated: 1744029491
\ No newline at end of file
diff --git a/ProjectSettings/BurstAotSettings_StandaloneWindows.json b/ProjectSettings/BurstAotSettings_StandaloneWindows.json
new file mode 100644
index 0000000..58cf25f
--- /dev/null
+++ b/ProjectSettings/BurstAotSettings_StandaloneWindows.json
@@ -0,0 +1,18 @@
+{
+ "MonoBehaviour": {
+ "Version": 4,
+ "EnableBurstCompilation": true,
+ "EnableOptimisations": true,
+ "EnableSafetyChecks": false,
+ "EnableDebugInAllBuilds": false,
+ "DebugDataKind": 1,
+ "EnableArmv9SecurityFeatures": false,
+ "CpuMinTargetX32": 0,
+ "CpuMaxTargetX32": 0,
+ "CpuMinTargetX64": 0,
+ "CpuMaxTargetX64": 0,
+ "CpuTargetsX32": 6,
+ "CpuTargetsX64": 72,
+ "OptimizeFor": 0
+ }
+}
diff --git a/ProjectSettings/CommonBurstAotSettings.json b/ProjectSettings/CommonBurstAotSettings.json
new file mode 100644
index 0000000..0293daf
--- /dev/null
+++ b/ProjectSettings/CommonBurstAotSettings.json
@@ -0,0 +1,6 @@
+{
+ "MonoBehaviour": {
+ "Version": 4,
+ "DisabledWarnings": ""
+ }
+}
diff --git a/ProjectSettings/SceneTemplateSettings.json b/ProjectSettings/SceneTemplateSettings.json
new file mode 100644
index 0000000..ede5887
--- /dev/null
+++ b/ProjectSettings/SceneTemplateSettings.json
@@ -0,0 +1,121 @@
+{
+ "templatePinStates": [],
+ "dependencyTypeInfos": [
+ {
+ "userAdded": false,
+ "type": "UnityEngine.AnimationClip",
+ "defaultInstantiationMode": 0
+ },
+ {
+ "userAdded": false,
+ "type": "UnityEditor.Animations.AnimatorController",
+ "defaultInstantiationMode": 0
+ },
+ {
+ "userAdded": false,
+ "type": "UnityEngine.AnimatorOverrideController",
+ "defaultInstantiationMode": 0
+ },
+ {
+ "userAdded": false,
+ "type": "UnityEditor.Audio.AudioMixerController",
+ "defaultInstantiationMode": 0
+ },
+ {
+ "userAdded": false,
+ "type": "UnityEngine.ComputeShader",
+ "defaultInstantiationMode": 1
+ },
+ {
+ "userAdded": false,
+ "type": "UnityEngine.Cubemap",
+ "defaultInstantiationMode": 0
+ },
+ {
+ "userAdded": false,
+ "type": "UnityEngine.GameObject",
+ "defaultInstantiationMode": 0
+ },
+ {
+ "userAdded": false,
+ "type": "UnityEditor.LightingDataAsset",
+ "defaultInstantiationMode": 0
+ },
+ {
+ "userAdded": false,
+ "type": "UnityEngine.LightingSettings",
+ "defaultInstantiationMode": 0
+ },
+ {
+ "userAdded": false,
+ "type": "UnityEngine.Material",
+ "defaultInstantiationMode": 0
+ },
+ {
+ "userAdded": false,
+ "type": "UnityEditor.MonoScript",
+ "defaultInstantiationMode": 1
+ },
+ {
+ "userAdded": false,
+ "type": "UnityEngine.PhysicsMaterial",
+ "defaultInstantiationMode": 0
+ },
+ {
+ "userAdded": false,
+ "type": "UnityEngine.PhysicsMaterial2D",
+ "defaultInstantiationMode": 0
+ },
+ {
+ "userAdded": false,
+ "type": "UnityEngine.Rendering.PostProcessing.PostProcessProfile",
+ "defaultInstantiationMode": 0
+ },
+ {
+ "userAdded": false,
+ "type": "UnityEngine.Rendering.PostProcessing.PostProcessResources",
+ "defaultInstantiationMode": 0
+ },
+ {
+ "userAdded": false,
+ "type": "UnityEngine.Rendering.VolumeProfile",
+ "defaultInstantiationMode": 0
+ },
+ {
+ "userAdded": false,
+ "type": "UnityEditor.SceneAsset",
+ "defaultInstantiationMode": 1
+ },
+ {
+ "userAdded": false,
+ "type": "UnityEngine.Shader",
+ "defaultInstantiationMode": 1
+ },
+ {
+ "userAdded": false,
+ "type": "UnityEngine.ShaderVariantCollection",
+ "defaultInstantiationMode": 1
+ },
+ {
+ "userAdded": false,
+ "type": "UnityEngine.Texture",
+ "defaultInstantiationMode": 0
+ },
+ {
+ "userAdded": false,
+ "type": "UnityEngine.Texture2D",
+ "defaultInstantiationMode": 0
+ },
+ {
+ "userAdded": false,
+ "type": "UnityEngine.Timeline.TimelineAsset",
+ "defaultInstantiationMode": 0
+ }
+ ],
+ "defaultDependencyTypeInfo": {
+ "userAdded": false,
+ "type": "",
+ "defaultInstantiationMode": 1
+ },
+ "newSceneOverride": 0
+}
\ No newline at end of file
From bad94fe9db080fefa1f443cb801bc87f479a49e6 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E6=B3=A0=E6=BC=AA?=
<32807696+AngelShadow2017@users.noreply.github.com>
Date: Sun, 13 Apr 2025 02:22:48 +0800
Subject: [PATCH 2/9] collis
---
Assets/ColliUpdate.cs | 30 +
Assets/ColliUpdate.cs.meta | 3 +
Assets/ColliderObj.cs | 612 ++++-----------
Assets/ColliderStructure.cs | 476 +++++++++++-
Assets/ColliderTester.cs | 185 +++++
Assets/ColliderTester.cs.meta | 3 +
.../NuGet/Editor/NuGetForUnity.PluginAPI.xml | 2 +-
Assets/Scenes/New Folder.meta | 8 +
Assets/Scenes/New Material.mat | 135 ++++
Assets/Scenes/New Material.mat.meta | 8 +
Assets/Scenes/New Scene.unity | 708 ++++++++++++++++++
Assets/Scenes/New Scene.unity.meta | 7 +
Assets/Scenes/SampleScene.unity | 193 ++++-
Assets/Settings/DefaultVolumeProfile.asset | 5 +-
Assets/TrueSync/TSMatrix4x4.cs | 12 +-
Assets/tmpExtensions.cs | 2 +-
Packages/manifest.json | 4 +-
Packages/packages-lock.json | 170 +++--
ProjectSettings/GraphicsSettings.asset | 9 +-
ProjectSettings/ProjectSettings.asset | 2 +-
ProjectSettings/ProjectVersion.txt | 4 +-
21 files changed, 1992 insertions(+), 586 deletions(-)
create mode 100644 Assets/ColliUpdate.cs
create mode 100644 Assets/ColliUpdate.cs.meta
create mode 100644 Assets/ColliderTester.cs
create mode 100644 Assets/ColliderTester.cs.meta
create mode 100644 Assets/Scenes/New Folder.meta
create mode 100644 Assets/Scenes/New Material.mat
create mode 100644 Assets/Scenes/New Material.mat.meta
create mode 100644 Assets/Scenes/New Scene.unity
create mode 100644 Assets/Scenes/New Scene.unity.meta
diff --git a/Assets/ColliUpdate.cs b/Assets/ColliUpdate.cs
new file mode 100644
index 0000000..f2c7fc4
--- /dev/null
+++ b/Assets/ColliUpdate.cs
@@ -0,0 +1,30 @@
+using System;
+using Core.Algorithm;
+using UnityEngine;
+
+namespace DefaultNamespace
+{
+ public class ColliUpdate:MonoBehaviour
+ {
+ void Awake()
+ {
+ this.transform.position=Vector3.zero;
+ CollisionManager.instance = new CollisionManager();
+ }
+
+ private void Update()
+ {
+ CollisionManager.instance.TraverseAllListener();
+ }
+
+ private void OnPostRender()
+ {
+ CollisionManager.instance.DebugDisplayShape(transform.localToWorldMatrix);
+ }
+
+ private void OnDestroy()
+ {
+ CollisionManager.instance.Dispose();
+ }
+ }
+}
\ No newline at end of file
diff --git a/Assets/ColliUpdate.cs.meta b/Assets/ColliUpdate.cs.meta
new file mode 100644
index 0000000..9fea738
--- /dev/null
+++ b/Assets/ColliUpdate.cs.meta
@@ -0,0 +1,3 @@
+fileFormatVersion: 2
+guid: 1ceed5607a5d49dca1e94035eaa2f698
+timeCreated: 1744470566
\ No newline at end of file
diff --git a/Assets/ColliderObj.cs b/Assets/ColliderObj.cs
index 5dc5eb8..1a29854 100644
--- a/Assets/ColliderObj.cs
+++ b/Assets/ColliderObj.cs
@@ -1,6 +1,9 @@
using System;
using System.Collections.Generic;
+using System.Runtime.CompilerServices;
+using System.Text;
using TrueSync;
+using Unity.Collections;
using UnityEngine;
using UnityEngine.Pool;
using ZeroAs.DOTS.Colliders;
@@ -20,6 +23,10 @@ public interface ICollideShape {
public CollisionManager.CollisionGroup colliGroup { get; set; }
public bool enabled { get; set; }
public void DebugDisplayColliderShape(Color color);
+
+ public void Destroy()
+ {
+ }
}
public interface IMasteredCollider
{
@@ -67,7 +74,7 @@ static TSVector2 TripleProduct2d(TSVector2 a,TSVector2 b,TSVector2 c) {
public abstract TSVector4 GetBoundingBox();
public TSVector2 GetFurthestPoint(in TSVector2 direction)
{
- GetFurthestPointExtensions.GetFurthestPoint(out var result, collider, direction);
+ GetFurthestPointExtensions.GetFurthestPoint(out var result, collider, direction,ColliderVertexBuffer.instancedBuffer);
return result;
}
public abstract void SetRotation(FP rotRad);
@@ -164,10 +171,25 @@ o 为了得到新的方向 𝑑,我们需要一个向量,这个向量既垂
//如果超过迭代次数都没有找到点,则判定为没有碰到。
return false;
}
- public virtual bool CheckCollide(ColliderBase shape2) {
+ /*public bool CheckCollide(ColliderBase shape2) {
return CheckCollide(this, shape2);
+ }*/
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public virtual ColliderStructure GetRealCollider()
+ {
+ return Collider;
}
+
+ public bool CheckCollide(ColliderBase shape2)
+ {
+ return CollideExtensions.CheckCollide(this.GetRealCollider(), shape2.GetRealCollider(),ColliderVertexBuffer.instancedBuffer);
+ }
+
public virtual void DebugDisplayColliderShape(Color color) { }
+
+ public virtual void Destroy()
+ {
+ }
}
[Serializable]
public abstract class ColliderBase : ColliderBase
@@ -179,13 +201,11 @@ public class CircleCollider : ColliderBase
{
public CircleCollider(FP R,TSVector2 center,CollisionManager.CollisionGroup group = CollisionManager.CollisionGroup.Default)
{
- Collider = new ColliderStructure()
- {
- colliderType = ColliderType.Circle,
- radius = R,
- center = center
- };
-
+ Collider = ColliderStructure.CreateInstance();
+ Collider.colliderType = ColliderType.Circle;
+ Collider.radius = R;
+ Collider.center = center;
+
colliGroup = group;
}
public override void SetRotation(FP rotRad) { }//没错,圆形没有旋转
@@ -212,7 +232,7 @@ bool CircleCollideWithCircle(CircleCollider shape2)
{
return CollideExtensions.CircleCollideWithCircle(this.Collider,shape2.Collider);
}
- public override bool CheckCollide(ColliderBase shape2)
+ /*public override bool CheckCollide(ColliderBase shape2)
{
if(shape2 is CircleCollider sh)
{
@@ -224,11 +244,11 @@ public override bool CheckCollide(ColliderBase shape2)
return d.CircleCollideWithCircle(this);
}
return CheckCollide(this, shape2);
- }
+ }*/
public override void DebugDisplayColliderShape(Color color)
{
float r = (float)collider.radius;
- int circleCount = Mathf.FloorToInt(Mathf.Lerp(5,8,((float)r)/72f));
+ int circleCount = Mathf.FloorToInt(Mathf.Lerp(5,8,((float)r)/72f)*10);
float angleDelta = 2 * Mathf.PI / circleCount;
GL.Begin(GL.TRIANGLE_STRIP);
@@ -270,12 +290,10 @@ public class OvalCollider : ColliderBase
//TSVector2 centerPos;
public OvalCollider(TSVector2 axis, TSVector2 center,in FP rotation, CollisionManager.CollisionGroup group = CollisionManager.CollisionGroup.Default)
{
- collider = new ColliderStructure()
- {
- colliderType = ColliderType.Oval,
- rot = rotation,
- center = center
- };
+ collider = ColliderStructure.CreateInstance();
+ collider.colliderType = ColliderType.Oval;
+ collider.rot = rotation;
+ collider.center = center;
SetAxis(axis);
colliGroup = group;
}
@@ -380,43 +398,61 @@ public OvalCollider(T master, TSVector2 axis, TSVector2 center, FP rotation, Col
}
[Serializable]
- public class PolygonCollider : ColliderBase
+ public class PolygonCollider : ColliderBase,IDisposable
{
- public FP rot;
- public TSVector2[] vertexs,movedVertexs;
- public TSVector2 centerPos;
+ public TSVector2[] vertexs;
+ public NativeArray movedVertexs;
TSVector4 _boundingBox_=TSVector4.zero;
public PolygonCollider() {
//throw new System.NotImplementedException("必须为顶点赋值");
}
+
+ public void Dispose()
+ {
+ if (movedVertexs.IsCreated)
+ {
+ movedVertexs.Dispose();
+ }
+ }
+
public PolygonCollider(TSVector2[] vertex, TSVector2 center, FP rotation, CollisionManager.CollisionGroup group = CollisionManager.CollisionGroup.Default)
{
- movedVertexs = new TSVector2[vertex.Length]; //边数是不能变的
- centerPos = center;
+ collider = ColliderStructure.CreateInstance();
+ collider.colliderType = ColliderType.Polygon;
+ collider.rot = rotation;
+ collider.center = center;
+ movedVertexs = new NativeArray(vertex.Length,Allocator.Persistent,NativeArrayOptions.UninitializedMemory); //边数是不能变的
+ CollisionManager.instance.BufferManager.RegisterCollider(ref collider,vertex.Length);
SetRotation(rotation);
colliGroup = group;
}
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public override ColliderStructure GetRealCollider()
+ {
+ return CollisionManager.instance.BufferManager.colliders[collider.uniqueID];
+ }
+
public override void SetRotation(FP rotRad)
{
- rot = rotRad;
+ collider.rot = rotRad;
RotateVertexs();
}//没错,圆形没有旋转
public override void SetCenter(in TSVector2 center)
{
- MoveDeltaPos(center-centerPos);
- centerPos = center;
+ MoveDeltaPos(center-collider.center);
+ collider.center = center;
}
public override TSVector2 GetCenter()
{
- return centerPos;
+ return collider.center;
}
void RotateVertexs()
{
TSVector4 tSVector4 = new TSVector4(FP.MaxValue, FP.MinValue, FP.MinValue, FP.MaxValue);
for (int i = movedVertexs.Length - 1; i >= 0; --i)
{
- movedVertexs[i] = vertexs[i].RotateRad(rot) + centerPos;
+ movedVertexs[i] = vertexs[i].RotateRad(collider.rot) + collider.center;
if (movedVertexs[i].x > tSVector4.z)
{
tSVector4.z= movedVertexs[i].x;
@@ -434,6 +470,7 @@ void RotateVertexs()
tSVector4.w = movedVertexs[i].y;//最小值,代表下方点
}
}
+ CollisionManager.instance.BufferManager.ModifyCollider(collider,movedVertexs);
_boundingBox_ = tSVector4;
}
void MoveDeltaPos(TSVector2 pos)
@@ -442,14 +479,17 @@ void MoveDeltaPos(TSVector2 pos)
{
movedVertexs[i] += pos;
}
+ //标注顶点缓冲区的移动
+ CollisionManager.instance.BufferManager.ModifyCollider(collider,movedVertexs);
_boundingBox_.x += pos.x;
_boundingBox_.y += pos.y;
_boundingBox_.z += pos.x;
_boundingBox_.w += pos.y;
}
- public override TSVector2 GetFurthestPoint(TSVector2 direction)
+ /*public override TSVector2 GetFurthestPoint(in TSVector2 _direction)
{
- direction = direction.normalized;
+ TSVector2 result = base.GetFurthestPoint(_direction);
+ var direction = _direction.normalized;
FP maxLen = FP.MinValue,len;
TSVector2 pos = movedVertexs[0];
for(int i = movedVertexs.Length-1; i >= 0; --i)
@@ -460,7 +500,19 @@ public override TSVector2 GetFurthestPoint(TSVector2 direction)
pos = movedVertexs[i];
}
}
+ if (result != pos)
+ {
+ var arr = ColliderVertexBuffer.instancedBuffer.ToArray();
+ StringBuilder sb = new StringBuilder();
+ sb.AppendJoin(", ", arr);
+ Debug.Log(result+" "+pos+" "+sb);
+ }
return pos;
+ }*/
+ public override void Destroy()
+ {
+ CollisionManager.instance.BufferManager.DeleteCollider(collider);
+ movedVertexs.Dispose();
}
public override TSVector4 GetBoundingBox()
@@ -476,11 +528,14 @@ public BoxCollider(TSVector2 widthHeight,TSVector2 center,FP rotation, Collision
TSVector2 a = widthHeight * 0.5;//左下,左上,右上,右下
TSVector2 b = new TSVector2(a.x,-a.y);
vertexs = new TSVector2[4] {-a,-b, a, b}; //边数是不能变的
- movedVertexs = new TSVector2[4]; //边数是不能变的
- centerPos = center;
+ movedVertexs = new NativeArray(4,Allocator.Persistent,NativeArrayOptions.UninitializedMemory); //边数是不能变的
+ collider = ColliderStructure.CreateInstance();
+ collider.colliderType = ColliderType.Polygon;
+ collider.rot = rotation;
+ collider.center = center;
+ CollisionManager.instance.BufferManager.RegisterCollider(ref collider,movedVertexs.Length);
SetRotation(rotation);
colliGroup = group;
-
}
public override void DebugDisplayColliderShape(Color color)
{
@@ -520,8 +575,12 @@ public DiamondCollider(TSVector2 widthHeight, TSVector2 center, FP rotation, Col
TSVector2 b = new TSVector2(widthHeight.x * 0.5, 0);
TSVector2 c = new TSVector2(0, widthHeight.y * 0.5);
vertexs = new TSVector2[4] { -b, c, b, -c }; //边数是不能变的
- movedVertexs = new TSVector2[4]; //边数是不能变的
- centerPos = center;
+ movedVertexs = new NativeArray(4,Allocator.Persistent,NativeArrayOptions.UninitializedMemory); //边数是不能变的
+ collider = ColliderStructure.CreateInstance();
+ collider.colliderType = ColliderType.Polygon;
+ collider.rot = rotation;
+ collider.center = center;
+ CollisionManager.instance.BufferManager.RegisterCollider(ref collider,movedVertexs.Length);
SetRotation(rotation);
colliGroup = group;
}
@@ -531,45 +590,43 @@ public DiamondCollider(TSVector2 widthHeight, TSVector2 center, FP rotation, Col
//两个相同的圆中间连线
public class DoubleCircleCollider : ColliderBase
{
- public FP r;
- protected TSVector2 centerPos;
- public TSVector2 centerCircle1;
- public TSVector2 centerCircle2;
public DoubleCircleCollider(FP R, TSVector2 center1,TSVector2 center2, CollisionManager.CollisionGroup group = CollisionManager.CollisionGroup.Default)
{
+ collider = ColliderStructure.CreateInstance();
+ collider.colliderType = ColliderType.DoubleCircle;
+ collider.radius = R;
SetCircleCenters(center1,center2);
- r = R;
colliGroup = group;
}
public override void SetRotation(FP rotRad) { }//没错,圆形没有旋转
public override void SetCenter(in TSVector2 center)
{
- TSVector2 delta = center - centerPos;
- centerCircle1 += delta;
- centerCircle2 += delta;
- centerPos = center;
+ TSVector2 delta = center - collider.center;
+ collider.circleCenter1 += delta;
+ collider.circleCenter2 += delta;
+ collider.center = center;
}
- public void SetCircleCenters(TSVector2 center1,TSVector2 center2) {
-
- centerCircle1 = center1;
- centerCircle2 = center2;
- centerPos = (center1 + center2) * 0.5;
+ public void SetCircleCenters(in TSVector2 center1,in TSVector2 center2)
+ {
+ collider.circleCenter1 = center1;
+ collider.circleCenter2 = center2;
+ collider.center = (center1 + center2) * 0.5;
}
- public void SetCircleCenter2(TSVector2 center2)
+ public void SetCircleCenter2(in TSVector2 center2)
{
- centerCircle2 = center2;
- centerPos = (centerCircle1 + center2) * 0.5;
+ collider.circleCenter2 = center2;
+ collider.center = (collider.circleCenter1 + center2) * 0.5;
}
- public void SetCircleCenter1(TSVector2 center1)
+ public void SetCircleCenter1(in TSVector2 center1)
{
- centerCircle1 = center1;
- centerPos = (centerCircle2 + center1) * 0.5;
+ collider.circleCenter1 = center1;
+ collider.center = (collider.circleCenter2 + center1) * 0.5;
}
public override TSVector2 GetCenter()
{
- return centerPos;
+ return collider.center;
}
- public override TSVector2 GetFurthestPoint(TSVector2 direction)
+ /*public override TSVector2 GetFurthestPoint(TSVector2 direction)
{
//d.normal*
if (TSVector2.Dot(direction, centerCircle1-centerPos) > 0)
@@ -580,39 +637,41 @@ public override TSVector2 GetFurthestPoint(TSVector2 direction)
{
return direction.normalized * r + centerCircle2;
}
- }
+ }*/
public override TSVector4 GetBoundingBox()
{
FP minX;
FP minY;
FP maxX;
FP maxY;
- if (centerCircle1.x where T : ICollideShape
- {
- public int cellSize = 64;//最小格子宽高
- public FP OneDivideCellSize;
- public int depth = 6;//载入时的深度
- public int maxSize;
- public int groupCnt = 1;//碰撞组的个数
- FP maxSizeFP,OneHalfMaxSizeFP;
- FP[] log4Numbers, log2Numbers;
- public TreeNode root = new TreeNode();
- public TreeNode[] treeNodeArr = new TreeNode[0];//用数组优化四叉树的读取
- //储存每个collider所在的坐标格子位置,
- public Dictionary colliderPositions = new Dictionary();
- //public HashSet[] unmanagedColliders;
+ public class CollisionManager:IDisposable {
+ public static void voidFunction(ColliderBase c) { }
+ private static CollisionManager _instance;
- protected void __init__(int dp = 6, int cw = 64) {
- cellSize = cw;
- depth = dp;
- maxSize = cw << (dp);
- maxSizeFP = maxSize;
- OneHalfMaxSizeFP = maxSizeFP * 0.5;
- OneDivideCellSize = FP.One / (FP)cw;
- log4Numbers = new FP[depth + 1];
- log2Numbers = new FP[depth + 1];
- groupCnt = Enum.GetValues(typeof(CollisionManager.CollisionGroup)).Length;
- for (int i = 1; i <= depth; i++)
- {
- //0 2 4 6 8
- log4Numbers[i] = FP.One / (FP)(i << 1);
- log2Numbers[i] = FP.One / (FP)(i);
- }
- /*unmanagedColliders = new HashSet[groupCnt];
- for (int i = 0; i < groupCnt; i++)
- {
- unmanagedColliders[i] = new HashSet();
- }*/
- BuildTree();
- }
- public static int FastPow(int a, int n)
+ public static CollisionManager instance
{
- int ans = 1; // 赋值为乘法单位元,可能要根据构造函数修改
- while (n != 0)
+ get => _instance;
+ set
{
- if ((n & 1) != 0)
+ if (_instance != null&&_instance!=value)
{
- ans *= a; // 这里就最好别用自乘了,不然重载完*还要重载*=,有点麻烦。
+ _instance.Dispose();
}
- n >>= 1;
- a = a*a;
+ _instance = value;
}
- return ans;
- }
- /*public int CalcDepthCount(int dp) {
- return (FastPow(4, dp+1)-1) / 3;
- }*/
- public int CalcDepthCount(int dp)
- {
- return ((1<<((dp+1)<<1)) - 1) / 3;//等比数列求和
- }
- //按照
- /*
- root ,
- lt,
- rt,
- lb,
- rb,
- lt.lt, lt.rt,rt.lt,rt.rt, lt.lb, lt.rb,rt.lb,rt.rb , 4^n个
- 初始位置:4^0+...+4^(n-1) = 1*(1-4^n)/(1-4)
- //以屏幕为左上角,坐标向右边和下面增加
- 坐标:floor(当前层左上坐标/当前层高度)*(最大层宽度/当前层宽度)+floor(当前左上坐标/当前层宽度)
- */
- public int GetPosition(int curDepth,Vector2Int scaledPosition)
- {
- return CalcDepthCount(curDepth-1)+scaledPosition.y * (1 << (curDepth)) + scaledPosition.x;
- }
- //计算子四边形的缩放过的坐标
- ///
- /// 把原始的四个边界从中间分成四份,然后再把坐标*2
- ///
- /// 原始的四个边界
- ///
- TSVector4[] splitRect(TSVector4 r) {
- //originalRect *= 2;
- /*return new TSVector4[] {
- new TSVector4(originalRect.x,originalRect.y,(originalRect.z+originalRect.x)/2,(originalRect.w+originalRect.y)/2),
- new TSVector4((originalRect.x+originalRect.z)/2,originalRect.y,(originalRect.x+originalRect.z)/2+(originalRect.z-originalRect.x)/2,(originalRect.w+originalRect.y)/2),
- };*/
- /*originalRect.x += originalRect.x;
- originalRect.y += originalRect.y;
- originalRect.z += originalRect.x;
- originalRect.w += originalRect.y;*/
- /*
- x,y,x+(z-x)/2,y+(w-y)/2
- x+(z-x)/2,y,z,y+(w-y)/2
- x,y+(w-y)/2,x+(z-x)/2,w
- x+(z-x)/2,y+(w-y)/2,z,w
-
- */
- /*
- 2x,2y,x+z,y+w
- x+z,2y,2z,y+w
- 2x,y+w,x+z,2w
- x+z,y+w,2z,2w
- */
- /*return new TSVector4[] {
- new TSVector4(originalRect.x,originalRect.y,originalRect.z,originalRect.w),
- new TSVector4(originalRect.z,originalRect.y,originalRect.z+originalRect.z-originalRect.x,originalRect.w),
- new TSVector4(originalRect.x,originalRect.w,originalRect.z,originalRect.w+originalRect.w-originalRect.y),
- new TSVector4(originalRect.z,originalRect.w,originalRect.z+originalRect.z-originalRect.x,originalRect.w+originalRect.w-originalRect.y),
- };*/
- FP a = r.x + r.x;
- FP b = r.y + r.y;
- FP c = r.x + r.z;
- FP d = r.y + r.w;
- FP e = r.z + r.z;
- FP f = r.w + r.w;
- return new TSVector4[] {
- new TSVector4(a,b,c,d),
- new TSVector4(c,b,e,d),
- new TSVector4(a,d,c,f),
- new TSVector4(c,d,e,f)
- };
- }
- //应该不是,直接用大小存吧……
- public class TreeNode {
- public HashSet[] Values;
- public TreeNode[] Children = new TreeNode[4];
- public TreeNode parent = null;
}
- TSVector4 TransAxis(TSVector4 vec) {
- vec.y = OneHalfMaxSizeFP - vec.y;
- vec.w = OneHalfMaxSizeFP - vec.w;
- vec.x += OneHalfMaxSizeFP;
- vec.z += OneHalfMaxSizeFP;
- return vec;
- }
- int GetDepth(int width) { //如果是>=1的话也要放在上(更大的)一层比如64的大小(格子也是64)就应该放在128,不然可能会出界什么的。。。
- int layer = 0;//1 2 4 8
- while (width >> layer > 1)
- {
- layer++;
- }
- return depth - layer;
- }
- public struct positionInformation {
- public int layer;
- public Vector2Int mainPos;
- public Vector2Int rightBottom;
-
- public override bool Equals(object obj)
- {
- return obj is positionInformation other && Equals(other);
- }
- public bool Equals(positionInformation other)
- {
- return this.layer == other.layer &&
- this.mainPos == other.mainPos &&
- this.rightBottom == other.rightBottom;
- }
-
- public override int GetHashCode()
- {
- return HashCode.Combine(layer, mainPos, rightBottom);
- }
-
- public static bool operator ==(positionInformation left, positionInformation right)
- {
- return left.Equals(right);
- }
-
- public static bool operator !=(positionInformation left, positionInformation right)
- {
- return !(left == right);
- }
-
- // New method to check if the current instance contains another instance's range
- public bool Contains(positionInformation other)
- {
- return this.layer == other.layer &&
- this.mainPos.x <= other.mainPos.x &&
- this.mainPos.y <= other.mainPos.y &&
- this.rightBottom.x >= other.rightBottom.x &&
- this.rightBottom.y >= other.rightBottom.y;
- }
- public bool TrueContains(positionInformation other)
- {
- return this.layer == other.layer &&
- this.mainPos.x < other.mainPos.x &&
- this.mainPos.y < other.mainPos.y &&
- this.rightBottom.x > other.rightBottom.x &&
- this.rightBottom.y > other.rightBottom.y;
- }
-
- // Overload >= operator to use the Contains method
- public static bool operator >=(positionInformation left, positionInformation right)
- {
- return left.Contains(right);
- }
- public static bool operator <=(positionInformation left, positionInformation right)
- {
- return right.Contains(left);
- }
- public static bool operator >(positionInformation left, positionInformation right)
- {
- return left.TrueContains(right);
- }
- public static bool operator <(positionInformation left, positionInformation right)
- {
- return right.TrueContains(left);
- }
- }
- //可能是一个或者四个坐标,插入一次或者四次
- public positionInformation GetCellIndex(TSVector4 rect) {
- rect = TransAxis(rect);//乘1/最小格子大小可以得到64-->1 128 --> 2这样
- if (rect.x<0||rect.y<0||rect.z>maxSize||rect.w>maxSize) {
- return new positionInformation { //出界了,这个应该放在第0层里面,不参与四叉树判断
- mainPos = Vector2Int.zero,
- rightBottom = Vector2Int.zero,
- layer = 0
- };
- }
- rect *= OneDivideCellSize;
- //获取应该放在哪一层
- int layer = GetDepth(TSMath.Ceil(TSMath.Max(rect.w - rect.y, rect.z - rect.x)).AsInt());//TSMath.Ceil(TSMath.Log2(TSMath.Max(rect.w - rect.y, rect.z - rect.x))).AsInt();//这个Log很慢,因为是定点数,自己写一个
- if (layer < 0)
- {
- return new positionInformation
- { //出界了,这个应该放在第0层里面,不参与四叉树判断
- mainPos = Vector2Int.zero,
- rightBottom = Vector2Int.zero,
- layer = 0
- };
- }
- int divide = depth - layer;
- Vector2Int mainPos = new Vector2Int(rect.x.AsInt()>> divide, rect.y.AsInt()>> divide);
- Vector2Int rightBottom = new Vector2Int((rect.z.AsInt() >> divide), (rect.w.AsInt() >> divide));
- return new positionInformation
- {
- mainPos = mainPos,
- rightBottom = rightBottom, layer = layer
- };
- }
- ///
- /// 根据坐标批量处理某个事 action传入的是 当前深度depth和坐标的参数
- ///
- ///
- ///
- public void Manufacture(Action action,positionInformation area)
- {
- //对应级别的坐标
- Vector2Int nowPos = area.mainPos;
- Vector2Int tar = area.rightBottom;
- for(int i = nowPos.x; i <= tar.x; i++)
- {
- for (int j = nowPos.y;j<=tar.y;j++) {
- Vector2Int pos = new Vector2Int(i,j);
- action(area.layer,pos);
- }
- }
- }
- //带break的
- public bool Manufacture(Func action, positionInformation area)
+ public void Dispose()
{
- //对应级别的坐标
- Vector2Int nowPos = area.mainPos;
- Vector2Int tar = area.rightBottom;
- for (int i = nowPos.x; i <= tar.x; i++)
+ foreach (var colliderBase in colliders)
{
- for (int j = nowPos.y; j <= tar.y; j++)
+ if (colliderBase is IDisposable c)
{
- Vector2Int pos = new Vector2Int(i, j);
- if(!action(area.layer, pos)) { return false; }
+ c.Dispose();
}
}
- return true;
+ BufferManager.Dispose();
}
- public void RemoveCollider(T obj,bool insert=false) {
- int grp = (int)obj.colliGroup;
- if (colliderPositions.ContainsKey(obj))
- {
- Manufacture((layer,posInArr) => {
- //Debug.Log(layer+ " "+posInArr);
- var objs = treeNodeArr[GetPosition(layer, posInArr)].Values[grp];
- objs.Remove(obj);
- }, colliderPositions[obj]);
- colliderPositions.Remove(obj);
- }/*else
- {
- unmanagedColliders[grp].Remove(obj);
- }*/
- }
- public void ClearAllCollider()
- {
- foreach (var obj in colliderPositions)
- {
- RemoveCollider(obj.Key);
- }
- /*foreach (var obj in unmanagedColliders) {
- obj.Clear();
- }*/
- }
- public void InsertCollider(T obj) {
- int grp = (int)obj.colliGroup;
- TSVector4 rect = obj.GetBoundingBox();//获取物体的包围盒
- positionInformation positions = GetCellIndex(rect),
- oldPosition;
- bool hasObj = colliderPositions.ContainsKey(obj),flag=true;
- if (hasObj) {//如果position和原position在是包含关系,这里不能替换成大于,因为 会比较图层是否相等
- oldPosition = colliderPositions[obj];
- if (!(oldPosition <= positions))
- {
- RemoveCollider(obj,true);
- } else if (oldPosition==positions) {
- flag = false;
- }
- }
- colliderPositions[obj] = positions;
- if (flag){
- Manufacture((layer, posInArr) => {
- var objs = treeNodeArr[GetPosition(layer, posInArr)].Values[grp];
- objs.Add(obj);
- }, positions);
- }
- }
- void BuildTree() {
- int curDepth = 0;
- int needCnt = CalcDepthCount(depth);
- root = new TreeNode();
- treeNodeArr = new TreeNode[needCnt];
- TSVector4 nowRect = new TSVector4(0,0,1,1);//四边形的边框
- Dictionary> errorChecker = new Dictionary>();
- void dfs(TreeNode node=null) {
- treeNodeArr[GetPosition(curDepth,new Vector2Int(nowRect.x.AsInt(), nowRect.y.AsInt()))] = node;//存入数组
- if(errorChecker.ContainsKey(GetPosition(curDepth, new Vector2Int(nowRect.x.AsInt(), nowRect.y.AsInt()))))
- {
- var conf = errorChecker[GetPosition(curDepth, new Vector2Int(nowRect.x.AsInt(), nowRect.y.AsInt()))];
- if(curDepth!=conf.Item1||conf.Item2!= new Vector2Int(nowRect.x.AsInt(), nowRect.y.AsInt()))
- {
- Debug.LogError("Big Append Error" + " " + curDepth + " " + new Vector2Int(nowRect.x.AsInt(), nowRect.y.AsInt()) + " conflict with " + conf.Item1 + " " + conf.Item2);
-
- }
- }
- else
- {
- errorChecker.Add(GetPosition(curDepth, new Vector2Int(nowRect.x.AsInt(), nowRect.y.AsInt())), new Tuple(curDepth, new Vector2Int(nowRect.x.AsInt(), nowRect.y.AsInt())));
- }
- /*if (curDepth == 2) {
- Debug.Log(curDepth+" "+nowRect);
- }*/
- //初始化碰撞组
- node.Values = new HashSet[groupCnt];
- for (int j = 0; j < groupCnt; j++)
- {
- node.Values[j] = new HashSet();
- }
-
- if (curDepth>=depth)
- {
- return;
- }
- TSVector4 tmpRect = nowRect;
- TSVector4[] splited = splitRect(tmpRect);
- /*StringBuilder sb = new StringBuilder();
- sb.Append(curDepth);
- for (int i = 0;i[] groupedColliders;//这个到时候要改成LinkedHashSet之类的东西。。。
public HashSet colliders = new HashSet();
@@ -1247,6 +950,7 @@ public static void voidFunction(ColliderBase c) { }
public HashSet tmpDrawingHasCheckedObjectsInCurFrame = new HashSet();//用来debug有哪些物体当前帧被检查碰撞
//readonly bool multiCollisionOptimize = false;//先关掉多碰撞优化,测试功能
private Material _shapeMaterial;//测试
+ public ColliderVertexBuffer BufferManager = new ColliderVertexBuffer();
public CollisionManager() {
groupedColliders = new LinkedHashSet[groupCnt];
for (int i = 0; i < groupCnt; i++) {
@@ -1387,6 +1091,8 @@ public void RemoveShape(ColliderBase collider) {
int grp = (int)collider.colliGroup;
groupedColliders[grp].Remove(collider);
}
+ //调用销毁清理函数
+ collider.Destroy();
colliders.Remove(collider);
}
public void SetCenter(in TSVector2 Pos,ColliderBase shape)
diff --git a/Assets/ColliderStructure.cs b/Assets/ColliderStructure.cs
index 54c6171..92044e2 100644
--- a/Assets/ColliderStructure.cs
+++ b/Assets/ColliderStructure.cs
@@ -1,10 +1,13 @@
using System;
+using System.Diagnostics;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using Core.Algorithm;
using TrueSync;
using Unity.Burst;
using Unity.Collections;
+using Unity.Collections.LowLevel.Unsafe;
+using UnityEngine.UIElements;
namespace ZeroAs.DOTS.Colliders
{
@@ -16,8 +19,10 @@ public enum ColliderType
DoubleCircle,
}
[StructLayout(LayoutKind.Sequential)]
- public struct ColliderStructure
+ public struct ColliderStructure:IEquatable
{
+ private static int _globalIDCounter = 0;
+
public ColliderType colliderType;
public TSVector2 center;
#region 圆形,和双头圆形
@@ -28,7 +33,15 @@ public struct ColliderStructure
public FP b2Dividea2,rot;
#endregion
#region 多边形
- public int vertexStartIndex, vertexCount;
+
+ ///
+ /// 目前进行过修改的vertexStartIndex没同步到主线程上!!!
+ ///
+ public int vertexStartIndex;
+ ///
+ /// 注意,vertexCount不可变
+ ///
+ public int vertexCount,uniqueID;//indexInArray若设置为小于0就代表会被删除
#endregion
#region 双头圆形
public TSVector2 circleCenter1{
@@ -44,12 +57,27 @@ public TSVector2 circleCenter2{
set => this.SqrAxis = value;
}
#endregion
+
+
+ public static ColliderStructure CreateInstance()
+ {
+ var t = new ColliderStructure
+ {
+ uniqueID = _globalIDCounter++
+ };
+ return t;
+ }
+
+ public bool Equals(ColliderStructure other)
+ {
+ return this.uniqueID==other.uniqueID;
+ }
}
[BurstCompile(DisableDirectCall = true,OptimizeFor = OptimizeFor.Performance)]
public struct GetFurthestPointExtensions
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- [BurstCompile(DisableDirectCall = true,OptimizeFor = OptimizeFor.Performance)]
+ [BurstCompile(DisableDirectCall = false,OptimizeFor = OptimizeFor.Performance)]
public static void RotateRad(out TSVector2 result, in TSVector2 self, in FP rad)
{
FP cos = FP.FastCos(rad);
@@ -59,35 +87,28 @@ public static void RotateRad(out TSVector2 result, in TSVector2 self, in FP rad)
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- [BurstCompile(DisableDirectCall = true,OptimizeFor = OptimizeFor.Performance)]
+ [BurstCompile(DisableDirectCall = false,OptimizeFor = OptimizeFor.Performance)]
public static void Negate(ref FP val)
{
val._serializedValue=val._serializedValue == MathBurstedFix.MIN_VALUE ? MathBurstedFix.MaxValue : (-val._serializedValue);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- [BurstCompile(DisableDirectCall = true,OptimizeFor = OptimizeFor.Performance)]
+ [BurstCompile(DisableDirectCall = false,OptimizeFor = OptimizeFor.Performance)]
public static void Negate(ref TSVector2 val)
{
Negate(ref val.x);
Negate(ref val.y);
}
- static NativeArray points
- {
- get
- {
- throw new NotImplementedException();
- }
- }
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- [BurstCompile(DisableDirectCall = true,OptimizeFor = OptimizeFor.Performance)]
+ [BurstCompile(DisableDirectCall = false,OptimizeFor = OptimizeFor.Performance)]
public static void Circle(out TSVector2 result,in TSVector2 center,in TSVector2 direction,in FP radius)
{
result = center + direction.normalized*radius;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- [BurstCompile(DisableDirectCall = true,OptimizeFor = OptimizeFor.Performance)]
+ [BurstCompile(DisableDirectCall = false,OptimizeFor = OptimizeFor.Performance)]
public static void Oval(out TSVector2 result, in TSVector2 _direction,
in TSVector2 centerPos,in FP rot,in TSVector2 Axis,in TSVector2 SqrAxis,in FP b2Dividea2)
{
@@ -138,16 +159,17 @@ public static void Oval(out TSVector2 result, in TSVector2 _direction,
return;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- [BurstCompile(DisableDirectCall = true,OptimizeFor = OptimizeFor.Performance)]
- public static void Polygon(out TSVector2 result, in TSVector2 _direction, in NativeArray movedVertexs,int offset,int length)
+ [BurstCompile(DisableDirectCall = false,OptimizeFor = OptimizeFor.Performance)]
+ public static void Polygon(out TSVector2 result, in TSVector2 _direction, in NativeArray.ReadOnly movedVertexs,int offset,int length)
{
TSVector2 direction = _direction.normalized;
FP maxLen,len;
maxLen._serializedValue = MathBurstedFix.MinValue;
TSVector2 pos = movedVertexs[offset];
- int len_ = offset + length;
- for(int i = len_-1; i >= 0; --i)
+ int len_ = length;
+ for(int ia = len_-1; ia >= 0; --ia)
{
+ int i = offset+ia;
if((len= TSVector2.Dot(direction, movedVertexs[i])) > maxLen)
{
maxLen = len;
@@ -157,7 +179,7 @@ public static void Polygon(out TSVector2 result, in TSVector2 _direction, in Nat
result= pos;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- [BurstCompile(DisableDirectCall = true,OptimizeFor = OptimizeFor.Performance)]
+ [BurstCompile(DisableDirectCall = false,OptimizeFor = OptimizeFor.Performance)]
public static void DoubleCircle(out TSVector2 result,in TSVector2 direction,in TSVector2 centerCircle1,in TSVector2 centerCircle2,in FP r,in TSVector2 centerPos)
{
//d.normal*
@@ -172,7 +194,7 @@ public static void DoubleCircle(out TSVector2 result,in TSVector2 direction,in T
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
[BurstCompile(DisableDirectCall = true,OptimizeFor = OptimizeFor.Performance)]
- public static void GetFurthestPoint(out TSVector2 result, in ColliderStructure structure,in TSVector2 direction)
+ public static void GetFurthestPoint(out TSVector2 result, in ColliderStructure structure,in TSVector2 direction,in NativeArray.ReadOnly buffer)
{
switch (structure.colliderType)
{
@@ -183,8 +205,10 @@ public static void GetFurthestPoint(out TSVector2 result, in ColliderStructure s
Oval(out result,direction,structure.center,structure.rot,structure.Axis,structure.SqrAxis,structure.b2Dividea2);
return;
case ColliderType.Polygon:
- Polygon(out result,direction,points,structure.vertexStartIndex,structure.vertexCount);
+ {
+ Polygon(out result,direction, buffer,structure.vertexStartIndex,structure.vertexCount);
return;
+ }
case ColliderType.DoubleCircle:
DoubleCircle(out result,direction,structure.circleCenter1,structure.circleCenter2,structure.radius,structure.center);
return;
@@ -193,12 +217,12 @@ public static void GetFurthestPoint(out TSVector2 result, in ColliderStructure s
}
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- [BurstCompile(DisableDirectCall = true,OptimizeFor = OptimizeFor.Performance)]
- public static void SupportFunc(out TSVector2 result,in ColliderStructure structure1,in ColliderStructure structure2,in TSVector2 direciton) {
- GetFurthestPoint(out var resTmp,structure1,direciton);
+ [BurstCompile(DisableDirectCall = false,OptimizeFor = OptimizeFor.Performance)]
+ public static void SupportFunc(out TSVector2 result,in ColliderStructure structure1,in ColliderStructure structure2,in TSVector2 direciton,in NativeArray.ReadOnly buffer) {
+ GetFurthestPoint(out var resTmp,structure1,direciton,buffer);
TSVector2 negateDirection = direciton;
Negate(ref negateDirection);
- GetFurthestPoint(out var resTmp2, structure2, negateDirection);
+ GetFurthestPoint(out var resTmp2, structure2, negateDirection,buffer);
//Debug.Log("direction: "+direciton+" "+ shape1.GetFurthestPoint(direciton)+" "+shape2.GetFurthestPoint(-direciton));
result=resTmp-resTmp2;
}
@@ -207,7 +231,7 @@ public static void SupportFunc(out TSVector2 result,in ColliderStructure structu
public struct CollideExtensions
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- [BurstCompile(DisableDirectCall = true,OptimizeFor = OptimizeFor.Performance)]
+ [BurstCompile(DisableDirectCall = false,OptimizeFor = OptimizeFor.Performance)]
public static void Abs(out FP result,in FP value) {
if (value._serializedValue == MathBurstedFix.MIN_VALUE) {
result._serializedValue= MathBurstedFix.MaxValue;
@@ -219,7 +243,7 @@ public static void Abs(out FP result,in FP value) {
result._serializedValue = (value._serializedValue + mask) ^ mask;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- [BurstCompile(DisableDirectCall = true,OptimizeFor = OptimizeFor.Performance)]
+ [BurstCompile(DisableDirectCall = false,OptimizeFor = OptimizeFor.Performance)]
public static void TripleProduct2d(out TSVector2 result,in TSVector2 a,in TSVector2 b,in TSVector2 c) {
FP sign = (a.x * b.y - a.y * b.x);
FP cY = c.y;
@@ -227,8 +251,8 @@ public static void TripleProduct2d(out TSVector2 result,in TSVector2 a,in TSVect
result = new TSVector2(cY, c.x) * sign;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- [BurstCompile(DisableDirectCall = true,OptimizeFor = OptimizeFor.Performance)]
- public static bool GJK(in ColliderStructure shape1, in ColliderStructure shape2) {
+ [BurstCompile(DisableDirectCall = false,OptimizeFor = OptimizeFor.Performance)]
+ public static bool GJK(in ColliderStructure shape1, in ColliderStructure shape2,in NativeArray.ReadOnly buffer) {
/*
#两个形状s1,s2相交则返回True。所有的向量/点都是二维的,例如([x,y])
#第一步:选择一个初始方向,这个初始方向可以是随机选择的,但通常来说是两个形状中心之间的向量,即:
@@ -238,10 +262,10 @@ public static bool GJK(in ColliderStructure shape1, in ColliderStructure shape2)
TSVector2 direction = (shape2.center - shape1.center).normalized;
//#第二步:找到支撑点,即第一个支撑点(即闵可夫斯基差的边上的点之一……)
NativeArray Simplex = new NativeArray(3,Allocator.Temp);//单纯形数组,最多只能是3个
- GetFurthestPointExtensions.SupportFunc(out tmpVec,shape1, shape2, direction);
+ GetFurthestPointExtensions.SupportFunc(out tmpVec,shape1, shape2, direction,buffer);
Simplex[0] = tmpVec;
int simplexLastInd = 1;
- int interateTimeMax = 100;//最大迭代次数
+ int interateTimeMax = 10;//最大迭代次数
//#第三步:找到第一个支撑点后,以第一个支撑点为起点指向原点O的方向为新方向d
direction = tmpVec;//= -Simplex[0].normalized
GetFurthestPointExtensions.Negate(ref direction);
@@ -249,7 +273,7 @@ public static bool GJK(in ColliderStructure shape1, in ColliderStructure shape2)
//#第四步:开始循环,找下一个支撑点
while (interateTimeMax-- > 0)
{
- GetFurthestPointExtensions.SupportFunc(out var A,shape1,shape2,direction);
+ GetFurthestPointExtensions.SupportFunc(out var A,shape1,shape2,direction,buffer);
//因为A点是闵可夫斯基差形状在给定方向的最远点,如果那个点没有超过原点,就不想交
//#当新的支撑点A没有包含原点,那我们就返回False,即两个形状没有相交
if (TSVector2.Dot(A,direction)<0)
@@ -333,14 +357,14 @@ o 为了得到新的方向 𝑑,我们需要一个向量,这个向量既垂
return false;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- [BurstCompile(DisableDirectCall = true,OptimizeFor = OptimizeFor.Performance)]
+ [BurstCompile(DisableDirectCall = false,OptimizeFor = OptimizeFor.Performance)]
public static bool CircleCollideWithCircle(in ColliderStructure circle1,in ColliderStructure circle2)
{
TSVector2.DistanceSquared(in circle1.center, in circle2.center, out var dis);
return dis <= TSMath.FastQuadratic(circle1.radius + circle2.radius);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- [BurstCompile(DisableDirectCall = true,OptimizeFor = OptimizeFor.Performance)]
+ [BurstCompile(DisableDirectCall = false,OptimizeFor = OptimizeFor.Performance)]
public static bool CircleCollideWithDoubleCircle(in ColliderStructure doubleCircle,in ColliderStructure circle2)
{
TSVector2 centerShape = circle2.center;
@@ -374,5 +398,389 @@ public static bool CircleCollideWithDoubleCircle(in ColliderStructure doubleCirc
return deltaPos.LengthSquared() - TSMath.FastQuadratic(distance) <= TSMath.FastQuadratic(doubleCircle.radius+circle2.radius);
}
}
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ [BurstCompile(DisableDirectCall = false, OptimizeFor = OptimizeFor.Performance)]
+ public static bool CheckCollide(in ColliderStructure shape1, in ColliderStructure shape2,in NativeArray.ReadOnly buffer)
+ {
+ // 圆形 vs 圆形
+ if (shape1.colliderType == ColliderType.Circle &&
+ shape2.colliderType == ColliderType.Circle)
+ {
+ return CircleCollideWithCircle(shape1, shape2);
+ }
+
+ // 双圆 vs 圆形(处理两种顺序情况)
+ if ((shape1.colliderType == ColliderType.DoubleCircle &&
+ shape2.colliderType == ColliderType.Circle) ||
+ (shape2.colliderType == ColliderType.DoubleCircle &&
+ shape1.colliderType == ColliderType.Circle))
+ {
+ var doubleCircle = shape1.colliderType == ColliderType.DoubleCircle ? shape1 : shape2;
+ var circle = shape1.colliderType == ColliderType.Circle ? shape1 : shape2;
+ return CircleCollideWithDoubleCircle(doubleCircle, circle);
+ }
+
+ // 其他所有情况使用GJK算法
+ return GJK(shape1, shape2,buffer);
+ }
+ }
+ [BurstCompile(DisableDirectCall = true,OptimizeFor = OptimizeFor.Performance)]
+ public class ColliderVertexBuffer:IDisposable{
+ public static NativeArray.ReadOnly instancedBuffer => CollisionManager.instance.BufferManager.vertices.AsReadOnly();
+ public NativeHashMap colliders = new NativeHashMap(16,Allocator.Persistent);
+ public NativeList vertices = new NativeList(Allocator.Persistent);
+
+ public int removedDelta = 0;
+ //public SegmentManager removedIndexs = new SegmentManager(Allocator.Persistent);
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ [BurstCompile(DisableDirectCall = false,OptimizeFor = OptimizeFor.Performance)]
+ static void RegisterCollider(
+ in NativeHashMap colliders,in NativeList vertices,
+ ref ColliderStructure colli,in int vertexCount
+ )
+ {
+ colli.vertexCount=vertexCount;
+ //注意目前没同步到主线程上
+ colli.vertexStartIndex = vertices.Length;
+ colliders.Add(colli.uniqueID,colli);
+
+ //不需要清理内存,因为马上就会被设置
+ vertices.Resize(colli.vertexStartIndex+vertexCount,NativeArrayOptions.UninitializedMemory);
+ }
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public void RegisterCollider(ref ColliderStructure colli,in int vertexCount)
+ {
+ RegisterCollider(colliders,vertices,ref colli,vertexCount);
+ }
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ [BurstCompile(DisableDirectCall = false,OptimizeFor = OptimizeFor.Performance)]
+ static void ModifyCollider(
+ ref NativeHashMap colliders,ref NativeList vertices,
+ in ColliderStructure colli, in NativeArray modify
+ )
+ {
+ //获取实际上的colli
+ var realColli = colliders[colli.uniqueID];
+ NativeArray.Copy(modify,0,vertices,realColli.vertexStartIndex,realColli.vertexCount);
+ }
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public void ModifyCollider(in ColliderStructure colli, in NativeArray modify)
+ {
+ ModifyCollider(ref colliders,ref vertices,in colli,modify);
+ }
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ [BurstCompile(DisableDirectCall = false,OptimizeFor = OptimizeFor.Performance)]
+ static void DeleteCollider(ref int removedDelta,ref NativeHashMap colliders,in ColliderStructure colli)
+ {
+ removedDelta += colli.vertexCount;
+ //var realColli = colliders[colli.uniqueID];
+ //removedIndexs.Add(realColli.vertexStartIndex,realColli.vertexStartIndex+realColli.vertexCount-1);
+ colliders.Remove(colli.uniqueID);
+ }
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ [BurstCompile(DisableDirectCall = false,OptimizeFor = OptimizeFor.Performance)]
+ public void DeleteCollider(in ColliderStructure colli)
+ {
+ DeleteCollider(ref removedDelta,ref colliders,colli);
+ }
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ [BurstCompile(DisableDirectCall = false,OptimizeFor = OptimizeFor.Performance)]
+ [Conditional("ENABLE_UNITY_COLLECTIONS_CHECKS"), Conditional("UNITY_DOTS_DEBUG")]
+ static void CheckIndexCount(int index, int count,int length)
+ {
+ if (count < 0)
+ {
+ throw new ArgumentOutOfRangeException($"Value for count {count} must be positive.");
+ }
+
+ if (index < 0)
+ {
+ throw new IndexOutOfRangeException($"Value for index {index} must be positive.");
+ }
+
+ if (index > length)
+ {
+ throw new IndexOutOfRangeException($"Value for index {index} is out of bounds.");
+ }
+
+ if (index + count > length)
+ {
+ throw new ArgumentOutOfRangeException($"Value for count {count} is out of bounds.");
+ }
+ }
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ [BurstCompile(DisableDirectCall = false,OptimizeFor = OptimizeFor.Performance)]
+ public static void MoveLeft(in NativeList arr,int srcStart, int count,int offset) where T : unmanaged
+ {
+ CheckIndexCount(srcStart, count,arr.Length);
+ var arrayPointer = arr.AsArray();
+ NativeArray.Copy(arrayPointer,srcStart,arrayPointer,srcStart-offset,count);
+ }
+ ///
+ /// 移除vertexbuffer的洞洞,注意这是个比较消耗性能的操作,并且要在主线程中同步所有的结构体的顶点位置?(提供同步方法,如果需要的话可以同步,貌似目前不需要,只是会throw出错而已)
+ ///
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ [BurstCompile(DisableDirectCall = false,OptimizeFor = OptimizeFor.Performance)]
+ public static unsafe void CompactVertexBuffers(
+ ref int removedDelta,ref NativeHashMap colliders,
+ ref NativeList vertices
+ )
+ {
+ if (!vertices.IsCreated)
+ {
+ throw new NullReferenceException("vertices数组未创建");
+ }
+ NativeList newList = new NativeList(vertices.Length-removedDelta,Allocator.Persistent);
+ var listArrayPointer = vertices.GetUnsafeReadOnlyPtr();
+ var _sizeof_ = UnsafeUtility.SizeOf();
+ foreach (var ele in colliders)
+ {
+ ref var val = ref ele.Value;
+ var newStartIndex = newList.Length;
+ newList.AddRangeNoResize(((byte*)listArrayPointer+(_sizeof_*val.vertexStartIndex)), val.vertexCount);
+ val.vertexStartIndex = newStartIndex;
+ }
+ vertices.Dispose();
+ vertices = newList;
+ removedDelta = 0;
+ }
+ ///
+ /// 移除vertexbuffer的洞洞,注意这是个比较消耗性能的操作,并且要在主线程中同步所有的结构体的顶点位置?(提供同步方法,如果需要的话可以同步,貌似目前不需要,只是会throw出错而已)
+ ///
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ [BurstCompile(DisableDirectCall = false,OptimizeFor = OptimizeFor.Performance)]
+ public void CompactVertexBuffers()
+ {
+ CompactVertexBuffers(ref removedDelta,ref colliders,ref vertices);
+ }
+
+ public void Dispose()
+ {
+ if(vertices.IsCreated)
+ vertices.Dispose();
+ //removedIndexs.Dispose();
+ if (colliders.IsCreated)
+ {
+ colliders.Dispose();
+ }
+
+ }
+ /*[MethodImpl(MethodImplOptions.AggressiveInlining)]
+ [BurstCompile(DisableDirectCall = true,OptimizeFor = OptimizeFor.Performance)]
+ public void ClearDeletedColliders()
+ {
+ int len = colliders.Length;
+ int thisTimeDeletionCount = 0;//这次删多少个
+ int gappedPosition = -1;
+ int gappedVertexPosition = -1;
+ int offset = 0;
+ int vertexOffset = 0;
+ int lastAvailableVertexEnd = 0;
+ for (int i =0;i=0)
+ {
+ MoveLeft(vertices,gappedVertexPosition,
+ lastAvailableVertexEnd-(gappedVertexPosition-vertexOffset),vertexOffset
+ );
+ MoveLeft(colliders,gappedPosition,i-gappedPosition,offset);
+ //colliders.CopyFrom();
+ gappedPosition = -1;
+ gappedVertexPosition = -1;
+ }
+ thisTimeDeletionCount++;
+ }
+ else if(thisTimeDeletionCount>0)
+ {
+ gappedPosition = i;
+ gappedVertexPosition = ele.vertexStartIndex;
+ offset += thisTimeDeletionCount;
+ //lastAvailableVertexEnd是虚假偏移值,是假装已经偏移过后得到的顶点结束位置
+ vertexOffset = ele.vertexStartIndex - lastAvailableVertexEnd;
+ thisTimeDeletionCount = 0;
+ }
+
+ if (ele.indexInArray >= 0)
+ {
+ ele.indexInArray -= offset;
+ ele.vertexStartIndex -= vertexOffset;
+ lastAvailableVertexEnd = ele.vertexStartIndex + ele.vertexCount;
+ }
+ }
+ //最后是有重合的
+ if (gappedPosition>=0)
+ {
+ MoveLeft(vertices,gappedVertexPosition,
+ lastAvailableVertexEnd-(gappedVertexPosition-vertexOffset),vertexOffset
+ );
+ MoveLeft(colliders,gappedPosition,colliders.Length-gappedPosition,offset);
+ //colliders.CopyFrom();
+ //gappedPosition = -1;
+ //gappedVertexPosition = -1;
+ }
+ //最后一个有效位置的起始点
+ //会变小,所以不用清除内存
+ colliders.Resize(colliders.Length-offset-thisTimeDeletionCount,NativeArrayOptions.UninitializedMemory);
+ vertices.Resize(lastAvailableVertexEnd,NativeArrayOptions.UninitializedMemory);
+ }*/
+ }
+ [BurstCompile(DisableDirectCall = true,OptimizeFor = OptimizeFor.Performance)]
+ public struct SegmentManager : IDisposable
+ {
+ [BurstCompile(DisableDirectCall = true,OptimizeFor = OptimizeFor.Performance)]
+ public struct Segment
+ {
+ public readonly int Start;
+ public readonly int End;
+
+ public Segment(int start, int end)
+ {
+ Start = start;
+ End = end;
+ }
+
+ public override string ToString()
+ {
+ return $"({Start}, {End})";
+ }
+ }
+ private NativeList segments;
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ [BurstCompile(DisableDirectCall = true,OptimizeFor = OptimizeFor.Performance)]
+ public void Add(int start, int end)
+ {
+ // 确保起点小于等于终点
+ if (start > end)
+ {
+ (start, end) = (end, start);
+ }
+
+ // 找到插入位置
+ int insertIndex = FindInsertIndex(start);
+
+ int left = insertIndex - 1;
+ int right = insertIndex;
+
+ int currentStart = start;
+ int currentEnd = end;
+
+ // 向左合并线段
+ while (left >= 0 && segments[left].End >= currentStart-1)
+ {
+ currentStart = Math.Min(segments[left].Start, currentStart);
+ currentEnd = Math.Max(segments[left].End, currentEnd);
+ left--;
+ }
+
+ int len = segments.Length;
+ // 向右合并线段
+ while (right < len && segments[right].Start <= currentEnd+1)
+ {
+ currentEnd = Math.Max(segments[right].End, currentEnd);
+ right++;
+ }
+
+
+ // 删除被合并的线段并插入新线段
+ if (left + 1 < len&&right - (left + 2)>=0)
+ {
+ segments.RemoveRange(left + 2, right - (left + 2));
+ }
+ else
+ {
+ segments.ResizeUninitialized(len+1);
+ ColliderVertexBuffer.MoveLeft(segments,left+1,len-left-1,-1);
+ }
+ segments[left + 1]=new Segment(currentStart, currentEnd);
+ }
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ [BurstCompile(DisableDirectCall = true, OptimizeFor = OptimizeFor.Performance)]
+ public void AddPoint(int point)
+ {
+ // 找到插入位置
+ int insertIndex = FindInsertIndex(point);
+
+ int left = insertIndex - 1;
+ int right = insertIndex;
+
+ int currentStart = point;
+ int currentEnd = point;
+
+ // 向左合并线段
+ if (left >= 0 && segments[left].End >= currentStart - 1)
+ {
+ currentStart = Math.Min(segments[left].Start, currentStart);
+ currentEnd = Math.Max(segments[left].End, currentEnd);
+ left--;
+ }
+
+ int len = segments.Length;
+ // 向右合并线段
+ if (right < len && segments[right].Start <= currentEnd + 1)
+ {
+ currentEnd = Math.Max(segments[right].End, currentEnd);
+ right++;
+ }
+
+ // 删除被合并的线段并插入新线段
+ if (left + 1 < len&&right - (left + 2)>=0)
+ {
+ segments.RemoveRange(left + 2, right - (left + 2));
+ }
+ else
+ {
+ segments.ResizeUninitialized(len+1);
+ ColliderVertexBuffer.MoveLeft(segments,left+1,len-left-1,-1);
+ }
+ segments[left + 1]=new Segment(currentStart, currentEnd);
+ }
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ [BurstCompile(DisableDirectCall = true,OptimizeFor = OptimizeFor.Performance)]
+ private int FindInsertIndex(int s)
+ {
+ int low = 0;
+ int high = segments.Length - 1;
+ int index = segments.Length; // 默认插入到最后
+
+ while (low <= high)
+ {
+ int mid = (low + high) / 2;
+ if (segments[mid].Start > s)
+ {
+ index = mid;
+ high = mid - 1;
+ }
+ else
+ {
+ low = mid + 1;
+ }
+ }
+
+ return index;
+ }
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ [BurstCompile(DisableDirectCall = true,OptimizeFor = OptimizeFor.Performance)]
+ public void Clear()
+ {
+ segments.Clear();
+ }
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public SegmentManager(Allocator allocator)
+ {
+ segments = new NativeList(allocator);
+ }
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ [BurstCompile(DisableDirectCall = true, OptimizeFor = OptimizeFor.Performance)]
+ public void Dispose()
+ {
+ segments.Dispose();
+ }
}
}
\ No newline at end of file
diff --git a/Assets/ColliderTester.cs b/Assets/ColliderTester.cs
new file mode 100644
index 0000000..0e2b481
--- /dev/null
+++ b/Assets/ColliderTester.cs
@@ -0,0 +1,185 @@
+using System;
+using Core.Algorithm;
+using UnityEngine;
+using ZeroAs.DOTS.Colliders;
+using UnityEngine;
+using TrueSync;
+using System.Collections.Generic;
+using BoxCollider = Core.Algorithm.BoxCollider;
+
+namespace DefaultNamespace
+{
+
+ [RequireComponent(typeof(MeshRenderer))]
+ public class ColliderTester : MonoBehaviour
+ {
+ public enum MoveMode { Keyboard, Circular, Horizontal, Custom }
+
+ [Header("Collider Settings")]
+ public ColliderType colliderType = ColliderType.Circle;
+ public FP radius = 1;
+ public TSVector2 boxSize = new TSVector2(2, 2);
+ public TSVector2 ovalAxis = new TSVector2(2, 1);
+ public TSVector2 doubleCircleOffset = new TSVector2(1, 0);
+
+ [Header("Movement Settings")]
+ public MoveMode moveMode = MoveMode.Keyboard;
+ public FP moveSpeed = 5;
+ public FP rotationSpeed = 90;
+ public FP amplitude = 3; // For horizontal/circular motion
+ public FP frequency = 1;
+
+ private CollisionController controller;
+ private MeshRenderer meshRenderer;
+ private TSVector2 startPosition;
+ private FP currentRotation;
+ private FP timeCounter;
+
+ void Start()
+ {
+ meshRenderer = GetComponent();
+ startPosition = transform.position.ToTSVector2();
+ CreateCollider();
+ }
+
+ void CreateCollider()
+ {
+ TSVector2 pos = transform.position.ToTSVector2();
+ ColliderBase collider;
+ switch (colliderType)
+ {
+ case ColliderType.Circle:
+ collider = new CircleCollider(radius, pos);
+ break;
+ case ColliderType.Oval:
+ collider = new OvalCollider(ovalAxis, pos, 0);
+ break;
+ case ColliderType.DoubleCircle:
+ collider = new DoubleCircleCollider(
+ radius,
+ pos - doubleCircleOffset,
+ pos + doubleCircleOffset
+ );
+ break;
+ case ColliderType.Polygon:
+ collider = new BoxCollider(boxSize, pos, 0);
+ break;
+ default:
+ throw new Exception("not initialized");
+ }
+ collider.enabled = true;
+ if (moveMode == MoveMode.Keyboard)
+ {
+ collider.colliGroup = CollisionManager.CollisionGroup.Default;
+ }
+ else
+ {
+ collider.colliGroup = CollisionManager.CollisionGroup.Bullet;
+ }
+ controller = new CollisionController(collider);
+ if (moveMode == MoveMode.Keyboard)
+ {
+ controller.AddListener(false, (obj) =>
+ {
+ meshRenderer.material.color=Color.red;
+ Debug.Log("collide enter");
+ },CollisionManager.voidFunction,(obj) =>
+ {
+ meshRenderer.material.color=Color.green;
+ Debug.Log("collide exit");
+ },CollisionManager.CollisionGroup.Bullet);
+ }
+ }
+
+ void Update()
+ {
+ if (Input.GetKey(KeyCode.K))
+ {
+ currentRotation+=rotationSpeed*Time.deltaTime*Mathf.Deg2Rad;
+ foreach (var controllerCollider in controller.Colliders)
+ {
+ controllerCollider.SetRotation(currentRotation);
+ }
+ }
+
+ HandleMovement(Time.deltaTime);
+ }
+
+ void HandleMovement(float deltaTime)
+ {
+ timeCounter += deltaTime * frequency;
+
+ switch (moveMode)
+ {
+ case MoveMode.Keyboard:
+ KeyboardControl(deltaTime);
+ break;
+ case MoveMode.Circular:
+ CircularMotion();
+ break;
+ case MoveMode.Horizontal:
+ HorizontalMotion();
+ break;
+ case MoveMode.Custom:
+ CustomMotion();
+ break;
+ }
+ gameObject.transform.position = startPosition.ToVector();
+ gameObject.transform.position += Vector3.forward*10;
+ }
+
+ void KeyboardControl(float deltaTime)
+ {
+ Vector2 input = new Vector2(
+ Input.GetAxisRaw("Horizontal"),
+ Input.GetAxisRaw("Vertical")
+ ).normalized;
+
+ TSVector2 movement = input.ToTSVector2() * moveSpeed * deltaTime;
+ startPosition += movement;
+ controller.SetCenter(startPosition);
+ }
+
+ void CircularMotion()
+ {
+ currentRotation += rotationSpeed * Time.deltaTime;
+ TSVector2 offset = new TSVector2(
+ TSMath.Cos(currentRotation * Mathf.Deg2Rad) * amplitude,
+ TSMath.Sin(currentRotation * Mathf.Deg2Rad) * amplitude
+ );
+ controller.SetCenter(startPosition + offset);
+ }
+
+ void HorizontalMotion()
+ {
+ FP xOffset = TSMath.Sin(timeCounter) * amplitude;
+ controller.SetCenter(startPosition + new TSVector2(xOffset, 0));
+ }
+
+ void CustomMotion()
+ {
+ // 示例:8字形运动
+ FP x = TSMath.Sin(timeCounter) * amplitude;
+ FP y = TSMath.Sin(2 * timeCounter) * amplitude / 2;
+ controller.SetCenter(startPosition + new TSVector2(x, y));
+ }
+
+
+
+ void OnDestroy()
+ {
+ if (controller != null)
+ {
+ controller.Destroy();
+ }
+ }
+
+ /*private void OnRenderObject()
+ {
+ foreach (var controllerCollider in controller.Colliders)
+ {
+ controllerCollider.DebugDisplayColliderShape(meshRenderer.material.color);
+ }
+ }*/
+ }
+}
\ No newline at end of file
diff --git a/Assets/ColliderTester.cs.meta b/Assets/ColliderTester.cs.meta
new file mode 100644
index 0000000..624a72a
--- /dev/null
+++ b/Assets/ColliderTester.cs.meta
@@ -0,0 +1,3 @@
+fileFormatVersion: 2
+guid: ea915761c8274bf983b476e4ad15da36
+timeCreated: 1744470894
\ No newline at end of file
diff --git a/Assets/NuGet/Editor/NuGetForUnity.PluginAPI.xml b/Assets/NuGet/Editor/NuGetForUnity.PluginAPI.xml
index eb40c81..c9b4dbd 100644
--- a/Assets/NuGet/Editor/NuGetForUnity.PluginAPI.xml
+++ b/Assets/NuGet/Editor/NuGetForUnity.PluginAPI.xml
@@ -80,7 +80,7 @@
NugetForUnity will call this method automatically so you can tell it what custom
functionalities your plugin is providing.
- The registry where extension points can be registered to.
+ The registry where extension vertices can be registered to.
diff --git a/Assets/Scenes/New Folder.meta b/Assets/Scenes/New Folder.meta
new file mode 100644
index 0000000..7e68f5d
--- /dev/null
+++ b/Assets/Scenes/New Folder.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: 9f62fe42e87b122428bcb90a341606a6
+folderAsset: yes
+DefaultImporter:
+ externalObjects: {}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/Scenes/New Material.mat b/Assets/Scenes/New Material.mat
new file mode 100644
index 0000000..e5c79f7
--- /dev/null
+++ b/Assets/Scenes/New Material.mat
@@ -0,0 +1,135 @@
+%YAML 1.1
+%TAG !u! tag:unity3d.com,2011:
+--- !u!21 &2100000
+Material:
+ serializedVersion: 8
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_Name: New Material
+ m_Shader: {fileID: 10755, guid: 0000000000000000f000000000000000, type: 0}
+ m_Parent: {fileID: 0}
+ m_ModifiedSerializedProperties: 0
+ m_ValidKeywords: []
+ m_InvalidKeywords: []
+ m_LightmapFlags: 4
+ m_EnableInstancingVariants: 0
+ m_DoubleSidedGI: 0
+ m_CustomRenderQueue: -1
+ stringTagMap: {}
+ disabledShaderPasses:
+ - MOTIONVECTORS
+ m_LockedProperties:
+ m_SavedProperties:
+ serializedVersion: 3
+ m_TexEnvs:
+ - _BaseMap:
+ m_Texture: {fileID: 0}
+ m_Scale: {x: 1, y: 1}
+ m_Offset: {x: 0, y: 0}
+ - _BumpMap:
+ m_Texture: {fileID: 0}
+ m_Scale: {x: 1, y: 1}
+ m_Offset: {x: 0, y: 0}
+ - _DetailAlbedoMap:
+ m_Texture: {fileID: 0}
+ m_Scale: {x: 1, y: 1}
+ m_Offset: {x: 0, y: 0}
+ - _DetailMask:
+ m_Texture: {fileID: 0}
+ m_Scale: {x: 1, y: 1}
+ m_Offset: {x: 0, y: 0}
+ - _DetailNormalMap:
+ m_Texture: {fileID: 0}
+ m_Scale: {x: 1, y: 1}
+ m_Offset: {x: 0, y: 0}
+ - _EmissionMap:
+ m_Texture: {fileID: 0}
+ m_Scale: {x: 1, y: 1}
+ m_Offset: {x: 0, y: 0}
+ - _MainTex:
+ m_Texture: {fileID: 0}
+ m_Scale: {x: 1, y: 1}
+ m_Offset: {x: 0, y: 0}
+ - _MetallicGlossMap:
+ m_Texture: {fileID: 0}
+ m_Scale: {x: 1, y: 1}
+ m_Offset: {x: 0, y: 0}
+ - _OcclusionMap:
+ m_Texture: {fileID: 0}
+ m_Scale: {x: 1, y: 1}
+ m_Offset: {x: 0, y: 0}
+ - _ParallaxMap:
+ m_Texture: {fileID: 0}
+ m_Scale: {x: 1, y: 1}
+ m_Offset: {x: 0, y: 0}
+ - _SpecGlossMap:
+ m_Texture: {fileID: 0}
+ m_Scale: {x: 1, y: 1}
+ m_Offset: {x: 0, y: 0}
+ - unity_Lightmaps:
+ m_Texture: {fileID: 0}
+ m_Scale: {x: 1, y: 1}
+ m_Offset: {x: 0, y: 0}
+ - unity_LightmapsInd:
+ m_Texture: {fileID: 0}
+ m_Scale: {x: 1, y: 1}
+ m_Offset: {x: 0, y: 0}
+ - unity_ShadowMasks:
+ m_Texture: {fileID: 0}
+ m_Scale: {x: 1, y: 1}
+ m_Offset: {x: 0, y: 0}
+ m_Ints: []
+ m_Floats:
+ - _AddPrecomputedVelocity: 0
+ - _AlphaClip: 0
+ - _AlphaToMask: 0
+ - _Blend: 0
+ - _BlendModePreserveSpecular: 1
+ - _BumpScale: 1
+ - _ClearCoatMask: 0
+ - _ClearCoatSmoothness: 0
+ - _Cull: 2
+ - _Cutoff: 0.5
+ - _DetailAlbedoMapScale: 1
+ - _DetailNormalMapScale: 1
+ - _DstBlend: 0
+ - _DstBlendAlpha: 0
+ - _EnvironmentReflections: 1
+ - _GlossMapScale: 0
+ - _Glossiness: 0
+ - _GlossyReflections: 0
+ - _Metallic: 0
+ - _OcclusionStrength: 1
+ - _Parallax: 0.005
+ - _QueueOffset: 0
+ - _ReceiveShadows: 1
+ - _Smoothness: 0.5
+ - _SmoothnessTextureChannel: 0
+ - _SpecularHighlights: 1
+ - _SrcBlend: 1
+ - _SrcBlendAlpha: 1
+ - _Surface: 0
+ - _WorkflowMode: 1
+ - _ZWrite: 1
+ m_Colors:
+ - _BaseColor: {r: 1, g: 1, b: 1, a: 1}
+ - _Color: {r: 0.4056604, g: 0.4056604, b: 0.4056604, a: 1}
+ - _EmissionColor: {r: 0, g: 0, b: 0, a: 1}
+ - _SpecColor: {r: 0.19999996, g: 0.19999996, b: 0.19999996, a: 1}
+ m_BuildTextureStacks: []
+ m_AllowLocking: 1
+--- !u!114 &166495376294266923
+MonoBehaviour:
+ m_ObjectHideFlags: 11
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 0}
+ m_Enabled: 1
+ m_EditorHideFlags: 0
+ m_Script: {fileID: 11500000, guid: d0353a89b1f911e48b9e16bdc9f2e058, type: 3}
+ m_Name:
+ m_EditorClassIdentifier:
+ version: 9
diff --git a/Assets/Scenes/New Material.mat.meta b/Assets/Scenes/New Material.mat.meta
new file mode 100644
index 0000000..2a39cdd
--- /dev/null
+++ b/Assets/Scenes/New Material.mat.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: cb388a83031c8b5449b266658342ab83
+NativeFormatImporter:
+ externalObjects: {}
+ mainObjectFileID: 2100000
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/Scenes/New Scene.unity b/Assets/Scenes/New Scene.unity
new file mode 100644
index 0000000..81960cb
--- /dev/null
+++ b/Assets/Scenes/New Scene.unity
@@ -0,0 +1,708 @@
+%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: 10
+ 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_UseRadianceAmbientProbe: 0
+--- !u!157 &3
+LightmapSettings:
+ m_ObjectHideFlags: 0
+ serializedVersion: 13
+ m_BakeOnSceneLoad: 0
+ 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_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: 1
+ m_PVRFilteringGaussRadiusAO: 1
+ m_PVRFilteringAtrousPositionSigmaDirect: 0.5
+ m_PVRFilteringAtrousPositionSigmaIndirect: 2
+ m_PVRFilteringAtrousPositionSigmaAO: 1
+ m_ExportTrainingData: 0
+ m_TrainingDataDestination: TrainingData
+ m_LightProbeSampleCountMultiplier: 4
+ m_LightingDataAsset: {fileID: 20201, guid: 0000000000000000f000000000000000, type: 0}
+ m_LightingSettings: {fileID: 0}
+--- !u!196 &4
+NavMeshSettings:
+ serializedVersion: 2
+ m_ObjectHideFlags: 0
+ m_BuildSettings:
+ serializedVersion: 3
+ 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
+ buildHeightMesh: 0
+ maxJobWorkers: 0
+ preserveTilesOutsideBounds: 0
+ debug:
+ m_Flags: 0
+ m_NavMeshData: {fileID: 0}
+--- !u!1 &596138205
+GameObject:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ serializedVersion: 6
+ m_Component:
+ - component: {fileID: 596138207}
+ - component: {fileID: 596138206}
+ - component: {fileID: 596138208}
+ 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 &596138206
+Light:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 596138205}
+ m_Enabled: 1
+ serializedVersion: 11
+ m_Type: 1
+ 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_ForceVisible: 0
+ m_ShadowRadius: 0
+ m_ShadowAngle: 0
+ m_LightUnit: 1
+ m_LuxAtDistance: 1
+ m_EnableSpotReflector: 1
+--- !u!4 &596138207
+Transform:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 596138205}
+ serializedVersion: 2
+ 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_LocalEulerAnglesHint: {x: 50, y: -30, z: 0}
+--- !u!114 &596138208
+MonoBehaviour:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 596138205}
+ m_Enabled: 1
+ m_EditorHideFlags: 0
+ m_Script: {fileID: 11500000, guid: 474bcb49853aa07438625e644c072ee6, type: 3}
+ m_Name:
+ m_EditorClassIdentifier:
+--- !u!1 &842675857
+GameObject:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ serializedVersion: 6
+ m_Component:
+ - component: {fileID: 842675860}
+ - component: {fileID: 842675859}
+ - component: {fileID: 842675858}
+ m_Layer: 0
+ m_Name: EventSystem
+ m_TagString: Untagged
+ m_Icon: {fileID: 0}
+ m_NavMeshLayer: 0
+ m_StaticEditorFlags: 0
+ m_IsActive: 1
+--- !u!114 &842675858
+MonoBehaviour:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 842675857}
+ m_Enabled: 1
+ m_EditorHideFlags: 0
+ m_Script: {fileID: 11500000, guid: 01614664b831546d2ae94a42149d80ac, type: 3}
+ m_Name:
+ m_EditorClassIdentifier:
+ m_SendPointerHoverToParent: 1
+ m_MoveRepeatDelay: 0.5
+ m_MoveRepeatRate: 0.1
+ m_XRTrackingOrigin: {fileID: 0}
+ m_ActionsAsset: {fileID: -944628639613478452, guid: ca9f5fa95ffab41fb9a615ab714db018, type: 3}
+ m_PointAction: {fileID: -1654692200621890270, guid: ca9f5fa95ffab41fb9a615ab714db018, type: 3}
+ m_MoveAction: {fileID: -8784545083839296357, guid: ca9f5fa95ffab41fb9a615ab714db018, type: 3}
+ m_SubmitAction: {fileID: 392368643174621059, guid: ca9f5fa95ffab41fb9a615ab714db018, type: 3}
+ m_CancelAction: {fileID: 7727032971491509709, guid: ca9f5fa95ffab41fb9a615ab714db018, type: 3}
+ m_LeftClickAction: {fileID: 3001919216989983466, guid: ca9f5fa95ffab41fb9a615ab714db018, type: 3}
+ m_MiddleClickAction: {fileID: -2185481485913320682, guid: ca9f5fa95ffab41fb9a615ab714db018, type: 3}
+ m_RightClickAction: {fileID: -4090225696740746782, guid: ca9f5fa95ffab41fb9a615ab714db018, type: 3}
+ m_ScrollWheelAction: {fileID: 6240969308177333660, guid: ca9f5fa95ffab41fb9a615ab714db018, type: 3}
+ m_TrackedDevicePositionAction: {fileID: 6564999863303420839, guid: ca9f5fa95ffab41fb9a615ab714db018, type: 3}
+ m_TrackedDeviceOrientationAction: {fileID: 7970375526676320489, guid: ca9f5fa95ffab41fb9a615ab714db018, type: 3}
+ m_DeselectOnBackgroundClick: 1
+ m_PointerBehavior: 0
+ m_CursorLockBehavior: 0
+ m_ScrollDeltaPerTick: 6
+--- !u!114 &842675859
+MonoBehaviour:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 842675857}
+ m_Enabled: 1
+ m_EditorHideFlags: 0
+ m_Script: {fileID: 11500000, guid: 76c392e42b5098c458856cdf6ecaaaa1, type: 3}
+ m_Name:
+ m_EditorClassIdentifier:
+ m_FirstSelected: {fileID: 0}
+ m_sendNavigationEvents: 1
+ m_DragThreshold: 10
+--- !u!4 &842675860
+Transform:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 842675857}
+ serializedVersion: 2
+ 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: []
+ m_Father: {fileID: 0}
+ m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+--- !u!1 &970346963
+GameObject:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ serializedVersion: 6
+ m_Component:
+ - component: {fileID: 970346967}
+ - component: {fileID: 970346966}
+ - component: {fileID: 970346965}
+ - component: {fileID: 970346964}
+ m_Layer: 0
+ m_Name: Cube
+ m_TagString: Untagged
+ m_Icon: {fileID: 0}
+ m_NavMeshLayer: 0
+ m_StaticEditorFlags: 0
+ m_IsActive: 1
+--- !u!114 &970346964
+MonoBehaviour:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 970346963}
+ m_Enabled: 1
+ m_EditorHideFlags: 0
+ m_Script: {fileID: 11500000, guid: ea915761c8274bf983b476e4ad15da36, type: 3}
+ m_Name:
+ m_EditorClassIdentifier:
+ colliderType: 3
+ radius:
+ _serializedValue: 4294967296
+ boxSize:
+ x:
+ _serializedValue: 8589934592
+ y:
+ _serializedValue: 8589934592
+ ovalAxis:
+ x:
+ _serializedValue: 8589934592
+ y:
+ _serializedValue: 4294967296
+ doubleCircleOffset:
+ x:
+ _serializedValue: 4294967296
+ y:
+ _serializedValue: 0
+ moveMode: 0
+ moveSpeed:
+ _serializedValue: 21474836480
+ rotationSpeed:
+ _serializedValue: -158913789952
+ amplitude:
+ _serializedValue: 12884901888
+ frequency:
+ _serializedValue: 4294967296
+--- !u!23 &970346965
+MeshRenderer:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 970346963}
+ m_Enabled: 1
+ m_CastShadows: 0
+ 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_RayTracingAccelStructBuildFlagsOverride: 0
+ m_RayTracingAccelStructBuildFlags: 1
+ m_SmallMeshCulling: 1
+ m_RenderingLayerMask: 1
+ m_RendererPriority: 0
+ m_Materials:
+ - {fileID: 2100000, guid: cb388a83031c8b5449b266658342ab83, 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!33 &970346966
+MeshFilter:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 970346963}
+ m_Mesh: {fileID: 10202, guid: 0000000000000000e000000000000000, type: 0}
+--- !u!4 &970346967
+Transform:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 970346963}
+ serializedVersion: 2
+ 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: []
+ m_Father: {fileID: 0}
+ m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+--- !u!1 &1155883975
+GameObject:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ serializedVersion: 6
+ m_Component:
+ - component: {fileID: 1155883978}
+ - component: {fileID: 1155883976}
+ - component: {fileID: 1155883979}
+ - component: {fileID: 1155883980}
+ m_Layer: 0
+ m_Name: Main Camera
+ m_TagString: MainCamera
+ m_Icon: {fileID: 0}
+ m_NavMeshLayer: 0
+ m_StaticEditorFlags: 0
+ m_IsActive: 1
+--- !u!81 &1155883976
+AudioListener:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 1155883975}
+ m_Enabled: 1
+--- !u!4 &1155883978
+Transform:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 1155883975}
+ serializedVersion: 2
+ 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: 1411761322}
+ m_Father: {fileID: 0}
+ m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+--- !u!20 &1155883979
+Camera:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 1155883975}
+ m_Enabled: 1
+ serializedVersion: 2
+ m_ClearFlags: 2
+ m_BackGroundColor: {r: 0, g: 0, b: 0, a: 0}
+ m_projectionMatrixMode: 1
+ m_GateFitMode: 2
+ m_FOVAxisMode: 0
+ m_Iso: 200
+ m_ShutterSpeed: 0.005
+ m_Aperture: 16
+ m_FocusDistance: 10
+ m_FocalLength: 50
+ m_BladeCount: 5
+ m_Curvature: {x: 2, y: 11}
+ m_BarrelClipping: 0.25
+ m_Anamorphism: 0
+ m_SensorSize: {x: 36, y: 24}
+ m_LensShift: {x: 0, y: 0}
+ m_NormalizedViewPortRect:
+ serializedVersion: 2
+ x: 0
+ y: 0
+ width: 1
+ height: 1
+ near clip plane: -10
+ far clip plane: 1000
+ field of view: 60
+ orthographic: 1
+ orthographic size: 15
+ m_Depth: 0
+ 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!114 &1155883980
+MonoBehaviour:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 1155883975}
+ m_Enabled: 1
+ m_EditorHideFlags: 0
+ m_Script: {fileID: 11500000, guid: 1ceed5607a5d49dca1e94035eaa2f698, type: 3}
+ m_Name:
+ m_EditorClassIdentifier:
+--- !u!1 &1411761320
+GameObject:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ serializedVersion: 6
+ m_Component:
+ - component: {fileID: 1411761322}
+ m_Layer: 0
+ m_Name: GameObject
+ m_TagString: Untagged
+ m_Icon: {fileID: 0}
+ m_NavMeshLayer: 0
+ m_StaticEditorFlags: 0
+ m_IsActive: 1
+--- !u!4 &1411761322
+Transform:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 1411761320}
+ serializedVersion: 2
+ 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: []
+ m_Father: {fileID: 1155883978}
+ m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+--- !u!1 &1685858033
+GameObject:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ serializedVersion: 6
+ m_Component:
+ - component: {fileID: 1685858037}
+ - component: {fileID: 1685858036}
+ - component: {fileID: 1685858035}
+ - component: {fileID: 1685858034}
+ m_Layer: 0
+ m_Name: OFF
+ m_TagString: Untagged
+ m_Icon: {fileID: 0}
+ m_NavMeshLayer: 0
+ m_StaticEditorFlags: 0
+ m_IsActive: 1
+--- !u!114 &1685858034
+MonoBehaviour:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 1685858033}
+ m_Enabled: 1
+ m_EditorHideFlags: 0
+ m_Script: {fileID: 11500000, guid: ea915761c8274bf983b476e4ad15da36, type: 3}
+ m_Name:
+ m_EditorClassIdentifier:
+ colliderType: 2
+ radius:
+ _serializedValue: 8589934592
+ boxSize:
+ x:
+ _serializedValue: 8589934592
+ y:
+ _serializedValue: 8589934592
+ ovalAxis:
+ x:
+ _serializedValue: 8589934592
+ y:
+ _serializedValue: 4294967296
+ doubleCircleOffset:
+ x:
+ _serializedValue: 4294967296
+ y:
+ _serializedValue: 0
+ moveMode: 2
+ moveSpeed:
+ _serializedValue: 0
+ rotationSpeed:
+ _serializedValue: 386547056640
+ amplitude:
+ _serializedValue: 12884901888
+ frequency:
+ _serializedValue: 4294967296
+--- !u!23 &1685858035
+MeshRenderer:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 1685858033}
+ m_Enabled: 1
+ m_CastShadows: 0
+ 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_RayTracingAccelStructBuildFlagsOverride: 0
+ m_RayTracingAccelStructBuildFlags: 1
+ m_SmallMeshCulling: 1
+ m_RenderingLayerMask: 1
+ m_RendererPriority: 0
+ m_Materials:
+ - {fileID: 2100000, guid: cb388a83031c8b5449b266658342ab83, 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!33 &1685858036
+MeshFilter:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 1685858033}
+ m_Mesh: {fileID: 10202, guid: 0000000000000000e000000000000000, type: 0}
+--- !u!4 &1685858037
+Transform:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 1685858033}
+ serializedVersion: 2
+ m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
+ m_LocalPosition: {x: 0, y: 4, z: 0}
+ m_LocalScale: {x: 1, y: 1, z: 4}
+ m_ConstrainProportionsScale: 0
+ m_Children: []
+ m_Father: {fileID: 0}
+ m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+--- !u!1660057539 &9223372036854775807
+SceneRoots:
+ m_ObjectHideFlags: 0
+ m_Roots:
+ - {fileID: 1155883978}
+ - {fileID: 596138207}
+ - {fileID: 970346967}
+ - {fileID: 1685858037}
+ - {fileID: 842675860}
diff --git a/Assets/Scenes/New Scene.unity.meta b/Assets/Scenes/New Scene.unity.meta
new file mode 100644
index 0000000..1383480
--- /dev/null
+++ b/Assets/Scenes/New Scene.unity.meta
@@ -0,0 +1,7 @@
+fileFormatVersion: 2
+guid: b1c08a7ecf0baff4dbe2dd6ea6c85de0
+DefaultImporter:
+ externalObjects: {}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/Scenes/SampleScene.unity b/Assets/Scenes/SampleScene.unity
index a141fd2..1187d56 100644
--- a/Assets/Scenes/SampleScene.unity
+++ b/Assets/Scenes/SampleScene.unity
@@ -119,6 +119,50 @@ NavMeshSettings:
debug:
m_Flags: 0
m_NavMeshData: {fileID: 0}
+--- !u!1 &112231250
+GameObject:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ serializedVersion: 6
+ m_Component:
+ - component: {fileID: 112231252}
+ - component: {fileID: 112231251}
+ m_Layer: 0
+ m_Name: GameObject
+ m_TagString: Untagged
+ m_Icon: {fileID: 0}
+ m_NavMeshLayer: 0
+ m_StaticEditorFlags: 0
+ m_IsActive: 1
+--- !u!114 &112231251
+MonoBehaviour:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 112231250}
+ m_Enabled: 1
+ m_EditorHideFlags: 0
+ m_Script: {fileID: 11500000, guid: 1ceed5607a5d49dca1e94035eaa2f698, type: 3}
+ m_Name:
+ m_EditorClassIdentifier:
+--- !u!4 &112231252
+Transform:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 112231250}
+ serializedVersion: 2
+ 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: []
+ m_Father: {fileID: 0}
+ m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!1 &330585543
GameObject:
m_ObjectHideFlags: 0
@@ -131,7 +175,6 @@ GameObject:
- component: {fileID: 330585545}
- component: {fileID: 330585544}
- component: {fileID: 330585547}
- - component: {fileID: 330585548}
m_Layer: 0
m_Name: Main Camera
m_TagString: MainCamera
@@ -178,11 +221,11 @@ Camera:
y: 0
width: 1
height: 1
- near clip plane: 0.3
+ near clip plane: -1
far clip plane: 1000
field of view: 60
- orthographic: 0
- orthographic size: 5
+ orthographic: 1
+ orthographic size: 20
m_Depth: -1
m_CullingMask:
serializedVersion: 2
@@ -257,18 +300,6 @@ MonoBehaviour:
m_MipBias: 0
m_VarianceClampScale: 0.9
m_ContrastAdaptiveSharpening: 0
---- !u!114 &330585548
-MonoBehaviour:
- m_ObjectHideFlags: 0
- m_CorrespondingSourceObject: {fileID: 0}
- m_PrefabInstance: {fileID: 0}
- m_PrefabAsset: {fileID: 0}
- m_GameObject: {fileID: 330585543}
- m_Enabled: 1
- m_EditorHideFlags: 0
- m_Script: {fileID: 11500000, guid: a3527897712cb704f9f4e04d329e7bba, type: 3}
- m_Name:
- m_EditorClassIdentifier:
--- !u!1 &410087039
GameObject:
m_ObjectHideFlags: 0
@@ -414,7 +445,7 @@ MonoBehaviour:
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 832575517}
- m_Enabled: 1
+ m_Enabled: 0
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 172515602e62fb746b5d573b38a5fe58, type: 3}
m_Name:
@@ -439,6 +470,132 @@ Transform:
m_Children: []
m_Father: {fileID: 0}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+--- !u!1 &1430430700
+GameObject:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ serializedVersion: 6
+ m_Component:
+ - component: {fileID: 1430430704}
+ - component: {fileID: 1430430703}
+ - component: {fileID: 1430430702}
+ - component: {fileID: 1430430705}
+ m_Layer: 0
+ m_Name: Cube
+ m_TagString: Untagged
+ m_Icon: {fileID: 0}
+ m_NavMeshLayer: 0
+ m_StaticEditorFlags: 0
+ m_IsActive: 1
+--- !u!23 &1430430702
+MeshRenderer:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 1430430700}
+ 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_RayTracingAccelStructBuildFlagsOverride: 0
+ m_RayTracingAccelStructBuildFlags: 1
+ m_SmallMeshCulling: 1
+ m_RenderingLayerMask: 1
+ m_RendererPriority: 0
+ m_Materials:
+ - {fileID: 2100000, guid: 31321ba15b8f8eb4c954353edc038b1d, 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!33 &1430430703
+MeshFilter:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 1430430700}
+ m_Mesh: {fileID: 10202, guid: 0000000000000000e000000000000000, type: 0}
+--- !u!4 &1430430704
+Transform:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 1430430700}
+ serializedVersion: 2
+ 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: []
+ m_Father: {fileID: 0}
+ m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+--- !u!114 &1430430705
+MonoBehaviour:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 1430430700}
+ m_Enabled: 1
+ m_EditorHideFlags: 0
+ m_Script: {fileID: 11500000, guid: ea915761c8274bf983b476e4ad15da36, type: 3}
+ m_Name:
+ m_EditorClassIdentifier:
+ colliderType: 0
+ radius:
+ _serializedValue: 4294967296
+ boxSize:
+ x:
+ _serializedValue: 8589934592
+ y:
+ _serializedValue: 8589934592
+ ovalAxis:
+ x:
+ _serializedValue: 8589934592
+ y:
+ _serializedValue: 4294967296
+ doubleCircleOffset:
+ x:
+ _serializedValue: 4294967296
+ y:
+ _serializedValue: 0
+ moveMode: 0
+ moveSpeed:
+ _serializedValue: 21474836480
+ rotationSpeed:
+ _serializedValue: 386547056640
+ amplitude:
+ _serializedValue: 12884901888
+ frequency:
+ _serializedValue: 4294967296
--- !u!1660057539 &9223372036854775807
SceneRoots:
m_ObjectHideFlags: 0
@@ -446,3 +603,5 @@ SceneRoots:
- {fileID: 330585546}
- {fileID: 410087041}
- {fileID: 832575519}
+ - {fileID: 1430430704}
+ - {fileID: 112231252}
diff --git a/Assets/Settings/DefaultVolumeProfile.asset b/Assets/Settings/DefaultVolumeProfile.asset
index 6fb1822..9e4bbfd 100644
--- a/Assets/Settings/DefaultVolumeProfile.asset
+++ b/Assets/Settings/DefaultVolumeProfile.asset
@@ -342,6 +342,9 @@ MonoBehaviour:
skyOcclusionIntensityMultiplier:
m_OverrideState: 1
m_Value: 1
+ worldOffset:
+ m_OverrideState: 1
+ m_Value: {x: 0, y: 0, z: 0}
--- !u!114 &-1216621516061285780
MonoBehaviour:
m_ObjectHideFlags: 3
@@ -462,8 +465,6 @@ MonoBehaviour:
- {fileID: -6288072647309666549}
- {fileID: 7518938298396184218}
- {fileID: -1410297666881709256}
- - {fileID: -7750755424749557576}
- - {fileID: -5139089513906902183}
--- !u!114 &853819529557874667
MonoBehaviour:
m_ObjectHideFlags: 3
diff --git a/Assets/TrueSync/TSMatrix4x4.cs b/Assets/TrueSync/TSMatrix4x4.cs
index 3cbe2ee..4d693d6 100644
--- a/Assets/TrueSync/TSMatrix4x4.cs
+++ b/Assets/TrueSync/TSMatrix4x4.cs
@@ -880,7 +880,7 @@ public static TSMatrix4x4 Scale(FP scale, TSVector centerPoint)
}
///
- /// Creates a matrix for rotating points around the X-axis.
+ /// Creates a matrix for rotating vertices around the X-axis.
///
/// The amount, in radians, by which to rotate around the X-axis.
/// The rotation matrix.
@@ -916,7 +916,7 @@ public static TSMatrix4x4 RotateX(FP radians)
}
///
- /// Creates a matrix for rotating points around the X-axis, from a center point.
+ /// Creates a matrix for rotating vertices around the X-axis, from a center point.
///
/// The amount, in radians, by which to rotate around the X-axis.
/// The center point.
@@ -956,7 +956,7 @@ public static TSMatrix4x4 RotateX(FP radians, TSVector centerPoint)
}
///
- /// Creates a matrix for rotating points around the Y-axis.
+ /// Creates a matrix for rotating vertices around the Y-axis.
///
/// The amount, in radians, by which to rotate around the Y-axis.
/// The rotation matrix.
@@ -992,7 +992,7 @@ public static TSMatrix4x4 RotateY(FP radians)
}
///
- /// Creates a matrix for rotating points around the Y-axis, from a center point.
+ /// Creates a matrix for rotating vertices around the Y-axis, from a center point.
///
/// The amount, in radians, by which to rotate around the Y-axis.
/// The center point.
@@ -1032,7 +1032,7 @@ public static TSMatrix4x4 RotateY(FP radians, TSVector centerPoint)
}
///
- /// Creates a matrix for rotating points around the Z-axis.
+ /// Creates a matrix for rotating vertices around the Z-axis.
///
/// The amount, in radians, by which to rotate around the Z-axis.
/// The rotation matrix.
@@ -1068,7 +1068,7 @@ public static TSMatrix4x4 RotateZ(FP radians)
}
///
- /// Creates a matrix for rotating points around the Z-axis, from a center point.
+ /// Creates a matrix for rotating vertices around the Z-axis, from a center point.
///
/// The amount, in radians, by which to rotate around the Z-axis.
/// The center point.
diff --git a/Assets/tmpExtensions.cs b/Assets/tmpExtensions.cs
index 0648017..1602f1f 100644
--- a/Assets/tmpExtensions.cs
+++ b/Assets/tmpExtensions.cs
@@ -7,7 +7,7 @@ public static class tmpExtensions
{
public static Vector2 RotateRad(this Vector2 self, float rad)
{
- float cos = Mathf.Cos(rad), sin = Mathf.Cos(rad);
+ float cos = Mathf.Cos(rad), sin = Mathf.Sin(rad);
return new Vector2(self.x * cos - self.y * sin, self.x * sin + self.y * cos);
}
///
diff --git a/Packages/manifest.json b/Packages/manifest.json
index 0c4acda..9444e62 100644
--- a/Packages/manifest.json
+++ b/Packages/manifest.json
@@ -2,11 +2,11 @@
"dependencies": {
"com.unity.ai.navigation": "2.0.6",
"com.unity.collab-proxy": "2.7.1",
+ "com.unity.feature.2d": "2.0.1",
"com.unity.ide.rider": "3.0.31",
"com.unity.ide.visualstudio": "2.0.22",
- "com.unity.inputsystem": "1.13.1",
+ "com.unity.inputsystem": "1.14.0",
"com.unity.multiplayer.center": "1.0.0",
- "com.unity.render-pipelines.universal": "17.0.4",
"com.unity.test-framework": "1.5.1",
"com.unity.timeline": "1.8.7",
"com.unity.ugui": "2.0.0",
diff --git a/Packages/packages-lock.json b/Packages/packages-lock.json
index e545425..c834979 100644
--- a/Packages/packages-lock.json
+++ b/Packages/packages-lock.json
@@ -1,5 +1,97 @@
{
"dependencies": {
+ "com.unity.2d.animation": {
+ "version": "10.1.4",
+ "depth": 1,
+ "source": "registry",
+ "dependencies": {
+ "com.unity.2d.common": "9.0.7",
+ "com.unity.2d.sprite": "1.0.0",
+ "com.unity.collections": "1.2.4",
+ "com.unity.modules.animation": "1.0.0",
+ "com.unity.modules.uielements": "1.0.0"
+ },
+ "url": "https://packages.unity.com"
+ },
+ "com.unity.2d.aseprite": {
+ "version": "1.1.9",
+ "depth": 1,
+ "source": "registry",
+ "dependencies": {
+ "com.unity.2d.common": "6.0.6",
+ "com.unity.2d.sprite": "1.0.0",
+ "com.unity.mathematics": "1.2.6",
+ "com.unity.modules.animation": "1.0.0"
+ },
+ "url": "https://packages.unity.com"
+ },
+ "com.unity.2d.common": {
+ "version": "9.0.7",
+ "depth": 2,
+ "source": "registry",
+ "dependencies": {
+ "com.unity.burst": "1.8.4",
+ "com.unity.2d.sprite": "1.0.0",
+ "com.unity.mathematics": "1.1.0",
+ "com.unity.modules.animation": "1.0.0",
+ "com.unity.modules.uielements": "1.0.0"
+ },
+ "url": "https://packages.unity.com"
+ },
+ "com.unity.2d.pixel-perfect": {
+ "version": "5.0.3",
+ "depth": 1,
+ "source": "registry",
+ "dependencies": {},
+ "url": "https://packages.unity.com"
+ },
+ "com.unity.2d.psdimporter": {
+ "version": "9.0.3",
+ "depth": 1,
+ "source": "registry",
+ "dependencies": {
+ "com.unity.2d.common": "9.0.4",
+ "com.unity.2d.sprite": "1.0.0"
+ },
+ "url": "https://packages.unity.com"
+ },
+ "com.unity.2d.sprite": {
+ "version": "1.0.0",
+ "depth": 1,
+ "source": "builtin",
+ "dependencies": {}
+ },
+ "com.unity.2d.spriteshape": {
+ "version": "10.0.7",
+ "depth": 1,
+ "source": "registry",
+ "dependencies": {
+ "com.unity.2d.common": "9.0.7",
+ "com.unity.mathematics": "1.1.0",
+ "com.unity.modules.physics2d": "1.0.0"
+ },
+ "url": "https://packages.unity.com"
+ },
+ "com.unity.2d.tilemap": {
+ "version": "1.0.0",
+ "depth": 1,
+ "source": "builtin",
+ "dependencies": {
+ "com.unity.modules.tilemap": "1.0.0",
+ "com.unity.modules.uielements": "1.0.0"
+ }
+ },
+ "com.unity.2d.tilemap.extras": {
+ "version": "4.1.0",
+ "depth": 1,
+ "source": "registry",
+ "dependencies": {
+ "com.unity.2d.tilemap": "1.0.0",
+ "com.unity.modules.tilemap": "1.0.0",
+ "com.unity.modules.jsonserialize": "1.0.0"
+ },
+ "url": "https://packages.unity.com"
+ },
"com.unity.ai.navigation": {
"version": "2.0.6",
"depth": 0,
@@ -11,7 +103,7 @@
},
"com.unity.burst": {
"version": "1.8.19",
- "depth": 2,
+ "depth": 3,
"source": "registry",
"dependencies": {
"com.unity.mathematics": "1.2.1",
@@ -44,6 +136,21 @@
"source": "builtin",
"dependencies": {}
},
+ "com.unity.feature.2d": {
+ "version": "2.0.1",
+ "depth": 0,
+ "source": "builtin",
+ "dependencies": {
+ "com.unity.2d.animation": "10.1.4",
+ "com.unity.2d.pixel-perfect": "5.0.3",
+ "com.unity.2d.psdimporter": "9.0.3",
+ "com.unity.2d.sprite": "1.0.0",
+ "com.unity.2d.spriteshape": "10.0.7",
+ "com.unity.2d.tilemap": "1.0.0",
+ "com.unity.2d.tilemap.extras": "4.1.0",
+ "com.unity.2d.aseprite": "1.1.9"
+ }
+ },
"com.unity.ide.rider": {
"version": "3.0.31",
"depth": 0,
@@ -63,7 +170,7 @@
"url": "https://packages.unity.com"
},
"com.unity.inputsystem": {
- "version": "1.13.1",
+ "version": "1.14.0",
"depth": 0,
"source": "registry",
"dependencies": {
@@ -93,65 +200,6 @@
"dependencies": {},
"url": "https://packages.unity.com"
},
- "com.unity.render-pipelines.core": {
- "version": "17.0.4",
- "depth": 1,
- "source": "builtin",
- "dependencies": {
- "com.unity.burst": "1.8.14",
- "com.unity.mathematics": "1.3.2",
- "com.unity.ugui": "2.0.0",
- "com.unity.collections": "2.4.3",
- "com.unity.modules.physics": "1.0.0",
- "com.unity.modules.terrain": "1.0.0",
- "com.unity.modules.jsonserialize": "1.0.0",
- "com.unity.rendering.light-transport": "1.0.1"
- }
- },
- "com.unity.render-pipelines.universal": {
- "version": "17.0.4",
- "depth": 0,
- "source": "builtin",
- "dependencies": {
- "com.unity.render-pipelines.core": "17.0.4",
- "com.unity.shadergraph": "17.0.4",
- "com.unity.render-pipelines.universal-config": "17.0.3"
- }
- },
- "com.unity.render-pipelines.universal-config": {
- "version": "17.0.3",
- "depth": 1,
- "source": "builtin",
- "dependencies": {
- "com.unity.render-pipelines.core": "17.0.3"
- }
- },
- "com.unity.rendering.light-transport": {
- "version": "1.0.1",
- "depth": 2,
- "source": "builtin",
- "dependencies": {
- "com.unity.collections": "2.2.0",
- "com.unity.mathematics": "1.2.4",
- "com.unity.modules.terrain": "1.0.0"
- }
- },
- "com.unity.searcher": {
- "version": "4.9.3",
- "depth": 2,
- "source": "registry",
- "dependencies": {},
- "url": "https://packages.unity.com"
- },
- "com.unity.shadergraph": {
- "version": "17.0.4",
- "depth": 1,
- "source": "builtin",
- "dependencies": {
- "com.unity.render-pipelines.core": "17.0.4",
- "com.unity.searcher": "4.9.3"
- }
- },
"com.unity.test-framework": {
"version": "1.5.1",
"depth": 0,
diff --git a/ProjectSettings/GraphicsSettings.asset b/ProjectSettings/GraphicsSettings.asset
index aa5a1c3..fe3b265 100644
--- a/ProjectSettings/GraphicsSettings.asset
+++ b/ProjectSettings/GraphicsSettings.asset
@@ -36,10 +36,8 @@ GraphicsSettings:
- {fileID: 10783, guid: 0000000000000000f000000000000000, type: 0}
m_PreloadedShaders: []
m_PreloadShadersBatchTimeLimit: -1
- m_SpritesDefaultMaterial: {fileID: 10754, guid: 0000000000000000f000000000000000,
- type: 0}
- m_CustomRenderPipeline: {fileID: 11400000, guid: 4b83569d67af61e458304325a23e5dfd,
- type: 2}
+ m_SpritesDefaultMaterial: {fileID: 10754, guid: 0000000000000000f000000000000000, type: 0}
+ m_CustomRenderPipeline: {fileID: 0}
m_TransparencySortMode: 0
m_TransparencySortAxis: {x: 0, y: 0, z: 1}
m_DefaultRenderingPath: 1
@@ -60,8 +58,7 @@ GraphicsSettings:
m_FogKeepExp2: 1
m_AlbedoSwatchInfos: []
m_RenderPipelineGlobalSettingsMap:
- UnityEngine.Rendering.Universal.UniversalRenderPipeline: {fileID: 11400000, guid: 18dc0cd2c080841dea60987a38ce93fa,
- type: 2}
+ UnityEngine.Rendering.Universal.UniversalRenderPipeline: {fileID: 11400000, guid: 18dc0cd2c080841dea60987a38ce93fa, type: 2}
m_LightsUseLinearIntensity: 1
m_LightsUseColorTemperature: 1
m_LogWhenShaderIsCompiled: 0
diff --git a/ProjectSettings/ProjectSettings.asset b/ProjectSettings/ProjectSettings.asset
index ac5ce5f..a09e05c 100644
--- a/ProjectSettings/ProjectSettings.asset
+++ b/ProjectSettings/ProjectSettings.asset
@@ -827,7 +827,7 @@ PlayerSettings:
managedStrippingLevel: {}
incrementalIl2cppBuild: {}
suppressCommonWarnings: 1
- allowUnsafeCode: 0
+ allowUnsafeCode: 1
useDeterministicCompilation: 1
additionalIl2CppArgs:
scriptingRuntimeVersion: 1
diff --git a/ProjectSettings/ProjectVersion.txt b/ProjectSettings/ProjectVersion.txt
index 6a73247..2795afa 100644
--- a/ProjectSettings/ProjectVersion.txt
+++ b/ProjectSettings/ProjectVersion.txt
@@ -1,2 +1,2 @@
-m_EditorVersion: 6000.0.44f1
-m_EditorVersionWithRevision: 6000.0.44f1 (101c91f3a8fb)
+m_EditorVersion: 6000.0.45f1
+m_EditorVersionWithRevision: 6000.0.45f1 (d91bd3d4e081)
From 2f91041881249a1f97448c504473a7f9638bbb4a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E6=B3=A0=E6=BC=AA?=
<32807696+AngelShadow2017@users.noreply.github.com>
Date: Sun, 13 Apr 2025 12:59:30 +0800
Subject: [PATCH 3/9] e
---
Assets/ColliUpdate.cs | 5 +
Assets/ColliderObj.cs | 5 +-
Assets/ColliderStructure.cs | 32 ++++-
Assets/Scenes/New Scene.unity | 258 +++++++++++++++++++++++++++++++++-
4 files changed, 289 insertions(+), 11 deletions(-)
diff --git a/Assets/ColliUpdate.cs b/Assets/ColliUpdate.cs
index f2c7fc4..a2d9b8a 100644
--- a/Assets/ColliUpdate.cs
+++ b/Assets/ColliUpdate.cs
@@ -17,6 +17,11 @@ private void Update()
CollisionManager.instance.TraverseAllListener();
}
+ private void LateUpdate()
+ {
+ CollisionManager.instance.BufferManager.CompactVertexBuffers();
+ }
+
private void OnPostRender()
{
CollisionManager.instance.DebugDisplayShape(transform.localToWorldMatrix);
diff --git a/Assets/ColliderObj.cs b/Assets/ColliderObj.cs
index 1a29854..242f697 100644
--- a/Assets/ColliderObj.cs
+++ b/Assets/ColliderObj.cs
@@ -512,7 +512,8 @@ void MoveDeltaPos(TSVector2 pos)
public override void Destroy()
{
CollisionManager.instance.BufferManager.DeleteCollider(collider);
- movedVertexs.Dispose();
+ if(movedVertexs.IsCreated)
+ movedVertexs.Dispose();
}
public override TSVector4 GetBoundingBox()
@@ -953,7 +954,7 @@ public void Dispose()
public ColliderVertexBuffer BufferManager = new ColliderVertexBuffer();
public CollisionManager() {
groupedColliders = new LinkedHashSet[groupCnt];
- for (int i = 0; i < groupCnt; i++) {
+ for (int i = 0; i < groupCnt; i++) {
groupedColliders[i] = new LinkedHashSet();
}
}
diff --git a/Assets/ColliderStructure.cs b/Assets/ColliderStructure.cs
index 92044e2..0fe9ffa 100644
--- a/Assets/ColliderStructure.cs
+++ b/Assets/ColliderStructure.cs
@@ -427,7 +427,14 @@ public static bool CheckCollide(in ColliderStructure shape1, in ColliderStructur
}
[BurstCompile(DisableDirectCall = true,OptimizeFor = OptimizeFor.Performance)]
public class ColliderVertexBuffer:IDisposable{
- public static NativeArray.ReadOnly instancedBuffer => CollisionManager.instance.BufferManager.vertices.AsReadOnly();
+ public static NativeArray.ReadOnly instancedBuffer
+ {
+ get
+ {
+ return CollisionManager.instance.BufferManager.vertices.AsReadOnly();
+ }
+ }
+
public NativeHashMap colliders = new NativeHashMap(16,Allocator.Persistent);
public NativeList vertices = new NativeList(Allocator.Persistent);
@@ -476,7 +483,8 @@ static void DeleteCollider(ref int removedDelta,ref NativeHashMap(in NativeList arr,int srcStart, int count,int
///
[MethodImpl(MethodImplOptions.AggressiveInlining)]
[BurstCompile(DisableDirectCall = false,OptimizeFor = OptimizeFor.Performance)]
- public static unsafe void CompactVertexBuffers(
+ public static void CompactVertexBuffers(
ref int removedDelta,ref NativeHashMap colliders,
ref NativeList vertices
)
@@ -533,14 +541,19 @@ ref NativeList vertices
throw new NullReferenceException("vertices数组未创建");
}
NativeList newList = new NativeList(vertices.Length-removedDelta,Allocator.Persistent);
- var listArrayPointer = vertices.GetUnsafeReadOnlyPtr();
- var _sizeof_ = UnsafeUtility.SizeOf();
+ newList.ResizeUninitialized(vertices.Length - removedDelta);
+ //var listArrayPointer = vertices.GetUnsafeReadOnlyPtr();
+ var listArray = vertices.AsReadOnly();
+ var newListArray = newList.AsArray();
+ int newStartIndex = 0;
+ //var _sizeof_ = UnsafeUtility.SizeOf();
foreach (var ele in colliders)
{
ref var val = ref ele.Value;
- var newStartIndex = newList.Length;
- newList.AddRangeNoResize(((byte*)listArrayPointer+(_sizeof_*val.vertexStartIndex)), val.vertexCount);
+ NativeArray.Copy(listArray,val.vertexStartIndex,newListArray,newStartIndex,val.vertexCount);
+ //newList.AddRangeNoResize(((byte*)listArrayPointer+(_sizeof_*val.vertexStartIndex)), val.vertexCount);
val.vertexStartIndex = newStartIndex;
+ newStartIndex += val.vertexCount;
}
vertices.Dispose();
vertices = newList;
@@ -783,4 +796,9 @@ public void Dispose()
segments.Dispose();
}
}
+ [BurstCompile(DisableDirectCall = true,OptimizeFor = OptimizeFor.Performance)]
+ public struct CollisionManagerBurst
+ {
+
+ }
}
\ No newline at end of file
diff --git a/Assets/Scenes/New Scene.unity b/Assets/Scenes/New Scene.unity
index 81960cb..f159803 100644
--- a/Assets/Scenes/New Scene.unity
+++ b/Assets/Scenes/New Scene.unity
@@ -339,7 +339,7 @@ MonoBehaviour:
m_Script: {fileID: 11500000, guid: ea915761c8274bf983b476e4ad15da36, type: 3}
m_Name:
m_EditorClassIdentifier:
- colliderType: 3
+ colliderType: 1
radius:
_serializedValue: 4294967296
boxSize:
@@ -571,6 +571,258 @@ Transform:
m_Children: []
m_Father: {fileID: 1155883978}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+--- !u!1 &1633608431
+GameObject:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ serializedVersion: 6
+ m_Component:
+ - component: {fileID: 1633608435}
+ - component: {fileID: 1633608434}
+ - component: {fileID: 1633608433}
+ - component: {fileID: 1633608432}
+ m_Layer: 0
+ m_Name: 1as
+ m_TagString: Untagged
+ m_Icon: {fileID: 0}
+ m_NavMeshLayer: 0
+ m_StaticEditorFlags: 0
+ m_IsActive: 1
+--- !u!114 &1633608432
+MonoBehaviour:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 1633608431}
+ m_Enabled: 1
+ m_EditorHideFlags: 0
+ m_Script: {fileID: 11500000, guid: ea915761c8274bf983b476e4ad15da36, type: 3}
+ m_Name:
+ m_EditorClassIdentifier:
+ colliderType: 2
+ radius:
+ _serializedValue: 8589934592
+ boxSize:
+ x:
+ _serializedValue: 8589934592
+ y:
+ _serializedValue: 8589934592
+ ovalAxis:
+ x:
+ _serializedValue: 8589934592
+ y:
+ _serializedValue: 4294967296
+ doubleCircleOffset:
+ x:
+ _serializedValue: 4294967296
+ y:
+ _serializedValue: 21474836480
+ moveMode: 2
+ moveSpeed:
+ _serializedValue: 0
+ rotationSpeed:
+ _serializedValue: 545460846592
+ amplitude:
+ _serializedValue: 12884901888
+ frequency:
+ _serializedValue: 4294967296
+--- !u!23 &1633608433
+MeshRenderer:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 1633608431}
+ m_Enabled: 1
+ m_CastShadows: 0
+ 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_RayTracingAccelStructBuildFlagsOverride: 0
+ m_RayTracingAccelStructBuildFlags: 1
+ m_SmallMeshCulling: 1
+ m_RenderingLayerMask: 1
+ m_RendererPriority: 0
+ m_Materials:
+ - {fileID: 2100000, guid: cb388a83031c8b5449b266658342ab83, 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!33 &1633608434
+MeshFilter:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 1633608431}
+ m_Mesh: {fileID: 10202, guid: 0000000000000000e000000000000000, type: 0}
+--- !u!4 &1633608435
+Transform:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 1633608431}
+ serializedVersion: 2
+ m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
+ m_LocalPosition: {x: -6, y: 3, z: 0}
+ m_LocalScale: {x: 1, y: 1, z: 4}
+ m_ConstrainProportionsScale: 0
+ m_Children: []
+ m_Father: {fileID: 0}
+ m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+--- !u!1 &1641945847
+GameObject:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ serializedVersion: 6
+ m_Component:
+ - component: {fileID: 1641945851}
+ - component: {fileID: 1641945850}
+ - component: {fileID: 1641945849}
+ - component: {fileID: 1641945848}
+ m_Layer: 0
+ m_Name: OFF 3
+ m_TagString: Untagged
+ m_Icon: {fileID: 0}
+ m_NavMeshLayer: 0
+ m_StaticEditorFlags: 0
+ m_IsActive: 1
+--- !u!114 &1641945848
+MonoBehaviour:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 1641945847}
+ m_Enabled: 1
+ m_EditorHideFlags: 0
+ m_Script: {fileID: 11500000, guid: ea915761c8274bf983b476e4ad15da36, type: 3}
+ m_Name:
+ m_EditorClassIdentifier:
+ colliderType: 2
+ radius:
+ _serializedValue: 8589934592
+ boxSize:
+ x:
+ _serializedValue: 21474836480
+ y:
+ _serializedValue: 21474836480
+ ovalAxis:
+ x:
+ _serializedValue: 8589934592
+ y:
+ _serializedValue: 4294967296
+ doubleCircleOffset:
+ x:
+ _serializedValue: 4294967296
+ y:
+ _serializedValue: 21474836480
+ moveMode: 2
+ moveSpeed:
+ _serializedValue: 0
+ rotationSpeed:
+ _serializedValue: 300647710720
+ amplitude:
+ _serializedValue: 12884901888
+ frequency:
+ _serializedValue: 4294967296
+--- !u!23 &1641945849
+MeshRenderer:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 1641945847}
+ m_Enabled: 1
+ m_CastShadows: 0
+ 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_RayTracingAccelStructBuildFlagsOverride: 0
+ m_RayTracingAccelStructBuildFlags: 1
+ m_SmallMeshCulling: 1
+ m_RenderingLayerMask: 1
+ m_RendererPriority: 0
+ m_Materials:
+ - {fileID: 2100000, guid: cb388a83031c8b5449b266658342ab83, 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!33 &1641945850
+MeshFilter:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 1641945847}
+ m_Mesh: {fileID: 10202, guid: 0000000000000000e000000000000000, type: 0}
+--- !u!4 &1641945851
+Transform:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 1641945847}
+ serializedVersion: 2
+ m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
+ m_LocalPosition: {x: 5, y: 4, z: 0}
+ m_LocalScale: {x: 1, y: 1, z: 4}
+ m_ConstrainProportionsScale: 0
+ m_Children: []
+ m_Father: {fileID: 0}
+ m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!1 &1685858033
GameObject:
m_ObjectHideFlags: 0
@@ -619,7 +871,7 @@ MonoBehaviour:
x:
_serializedValue: 4294967296
y:
- _serializedValue: 0
+ _serializedValue: 21474836480
moveMode: 2
moveSpeed:
_serializedValue: 0
@@ -705,4 +957,6 @@ SceneRoots:
- {fileID: 596138207}
- {fileID: 970346967}
- {fileID: 1685858037}
+ - {fileID: 1641945851}
+ - {fileID: 1633608435}
- {fileID: 842675860}
From b42f608f098bbb5eff4c54e760e012200d92a636 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E6=B3=A0=E6=BC=AA?=
<32807696+AngelShadow2017@users.noreply.github.com>
Date: Sun, 13 Apr 2025 15:19:42 +0800
Subject: [PATCH 4/9] native things
---
Assets/ColliUpdate.cs | 2 +-
Assets/ColliderObj.cs | 177 ++++++++++++++++++++++--------------
Assets/ColliderStructure.cs | 59 ++++++++++--
Assets/ColliderTester.cs | 6 +-
4 files changed, 164 insertions(+), 80 deletions(-)
diff --git a/Assets/ColliUpdate.cs b/Assets/ColliUpdate.cs
index a2d9b8a..4518c9a 100644
--- a/Assets/ColliUpdate.cs
+++ b/Assets/ColliUpdate.cs
@@ -19,7 +19,7 @@ private void Update()
private void LateUpdate()
{
- CollisionManager.instance.BufferManager.CompactVertexBuffers();
+ CollisionManager.instance.nativeCollisionManager.CompactVertexBuffers();
}
private void OnPostRender()
diff --git a/Assets/ColliderObj.cs b/Assets/ColliderObj.cs
index 242f697..dc10133 100644
--- a/Assets/ColliderObj.cs
+++ b/Assets/ColliderObj.cs
@@ -11,6 +11,7 @@
namespace Core.Algorithm
{
public interface ICollideShape {
+ public bool Registered { get; set; }
public ref ColliderStructure Collider { get; }
//获取在某个方向上的最远点
public TSVector2 GetFurthestPoint(in TSVector2 direction);
@@ -20,7 +21,7 @@ public interface ICollideShape {
public TSVector2 GetCenter();
//左上点和右下点!!!
public TSVector4 GetBoundingBox();
- public CollisionManager.CollisionGroup colliGroup { get; set; }
+ public CollisionGroup colliGroup { get; set; }
public bool enabled { get; set; }
public void DebugDisplayColliderShape(Color color);
@@ -35,21 +36,16 @@ public interface IMasteredCollider
[Serializable]
public abstract class ColliderBase : ICollideShape
{
+ public bool Registered { get; set; } = false;
public ColliderStructure collider;
public ref ColliderStructure Collider => ref collider;
- protected CollisionManager.CollisionGroup __colli__ = CollisionManager.CollisionGroup.Default;
+ //protected CollisionGroup __colli__ = CollisionGroup.Default;
protected bool __enabled__ = true;
public int tag = -1;//用来识别特定的tag
- public CollisionManager.CollisionGroup colliGroup {
- get
- {
- return __colli__;
- }
- set
- {
- __colli__ = value;
- }
+ public CollisionGroup colliGroup {
+ get => collider.collisionGroup;
+ set => collider.collisionGroup = value;//记得sync
}
public bool enabled
{
@@ -62,7 +58,7 @@ public bool enabled
__enabled__ = value;
}
}
-
+
static TSVector2 SupportFunc(ColliderBase shape1,ColliderBase shape2,TSVector2 direciton) {
//Debug.Log("direction: "+direciton+" "+ shape1.GetFurthestPoint(direciton)+" "+shape2.GetFurthestPoint(-direciton));
return shape1.GetFurthestPoint(direciton) - shape2.GetFurthestPoint(-direciton);
@@ -74,7 +70,8 @@ static TSVector2 TripleProduct2d(TSVector2 a,TSVector2 b,TSVector2 c) {
public abstract TSVector4 GetBoundingBox();
public TSVector2 GetFurthestPoint(in TSVector2 direction)
{
- GetFurthestPointExtensions.GetFurthestPoint(out var result, collider, direction,ColliderVertexBuffer.instancedBuffer);
+ CheckEssentialValues();
+ GetFurthestPointExtensions.GetFurthestPoint(out var result, collider, direction,ColliderNativeHelper.instancedBuffer);
return result;
}
public abstract void SetRotation(FP rotRad);
@@ -91,7 +88,7 @@ public static bool CheckCollide(ColliderBase shape1, ColliderBase shape2) {
TSVector2[] Simplex = new TSVector2[3];//单纯形数组,最多只能是3个
Simplex[0] = SupportFunc(shape1, shape2, direction);
int simplexLastInd = 1;
- int interateTimeMax = 100;//最大迭代次数
+ int interateTimeMax = 10;//最大迭代次数
//#第三步:找到第一个支撑点后,以第一个支撑点为起点指向原点O的方向为新方向d
direction = -Simplex[0].normalized;
//#第四步:开始循环,找下一个支撑点
@@ -179,10 +176,36 @@ public virtual ColliderStructure GetRealCollider()
{
return Collider;
}
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ protected void CheckEssentialValues()
+ {
+
+#if UNITY_EDITOR
+ if (!Registered)
+ {
+ throw new NotSupportedException("没有把当前物体注册入控制管理器中");
+ }
+ var judg = CollisionManager.instance?.nativeCollisionManager.colliders.IsCreated;
+ if (!judg.HasValue||!judg.Value)
+ {
+ throw new NotSupportedException("控制器单例不存在或buffer已被销毁");
+ }
+#endif
+ }
+
+ ///
+ /// 设置完属性后必须调用这个函数
+ ///
+ public virtual void SaveState()
+ {
+ CheckEssentialValues();
+ CollisionManager.instance.nativeCollisionManager.SyncCollider(ref collider);
+ }
public bool CheckCollide(ColliderBase shape2)
{
- return CollideExtensions.CheckCollide(this.GetRealCollider(), shape2.GetRealCollider(),ColliderVertexBuffer.instancedBuffer);
+ CheckEssentialValues();
+ return CollideExtensions.CheckCollide(this.GetRealCollider(), shape2.GetRealCollider(),ColliderNativeHelper.instancedBuffer);
}
public virtual void DebugDisplayColliderShape(Color color) { }
@@ -199,14 +222,13 @@ public abstract class ColliderBase : ColliderBase
[Serializable]
public class CircleCollider : ColliderBase
{
- public CircleCollider(FP R,TSVector2 center,CollisionManager.CollisionGroup group = CollisionManager.CollisionGroup.Default)
+ public CircleCollider(FP R,TSVector2 center,CollisionGroup group = CollisionGroup.Default)
{
- Collider = ColliderStructure.CreateInstance();
- Collider.colliderType = ColliderType.Circle;
- Collider.radius = R;
- Collider.center = center;
-
- colliGroup = group;
+ collider = ColliderStructure.CreateInstance();
+ collider.colliderType = ColliderType.Circle;
+ collider.radius = R;
+ collider.center = center;
+ collider.collisionGroup = group;
}
public override void SetRotation(FP rotRad) { }//没错,圆形没有旋转
public override void SetCenter(in TSVector2 center)
@@ -276,7 +298,7 @@ public T Master {
set => _master_ = value;
}
- public CircleCollider(T master,FP R, TSVector2 center, CollisionManager.CollisionGroup group = CollisionManager.CollisionGroup.Default) : base(R, center, group)
+ public CircleCollider(T master,FP R, TSVector2 center, CollisionGroup group = CollisionGroup.Default) : base(R, center, group)
{
this._master_ = master;
}
@@ -288,14 +310,14 @@ public class OvalCollider : ColliderBase
//public FP rot, b2Dividea2;//旋转,长轴方除以短轴方,因为定点数除法……真的太慢了。。。
//public TSVector2 Axis,SqrAxis;//半长轴和半短轴?其实应该叫水平轴和竖直轴
//TSVector2 centerPos;
- public OvalCollider(TSVector2 axis, TSVector2 center,in FP rotation, CollisionManager.CollisionGroup group = CollisionManager.CollisionGroup.Default)
+ public OvalCollider(TSVector2 axis, TSVector2 center,in FP rotation, CollisionGroup group = CollisionGroup.Default)
{
collider = ColliderStructure.CreateInstance();
collider.colliderType = ColliderType.Oval;
collider.rot = rotation;
collider.center = center;
SetAxis(axis);
- colliGroup = group;
+ collider.collisionGroup = group;
}
public void SetAxis(TSVector2 axis) {
collider.Axis = axis;
@@ -391,7 +413,7 @@ public T Master
set => _master_ = value;
}
- public OvalCollider(T master, TSVector2 axis, TSVector2 center, FP rotation, CollisionManager.CollisionGroup group = CollisionManager.CollisionGroup.Default) : base(axis, center,rotation, group)
+ public OvalCollider(T master, TSVector2 axis, TSVector2 center, FP rotation, CollisionGroup group = CollisionGroup.Default) : base(axis, center,rotation, group)
{
this._master_ = master;
}
@@ -416,21 +438,27 @@ public void Dispose()
}
}
- public PolygonCollider(TSVector2[] vertex, TSVector2 center, FP rotation, CollisionManager.CollisionGroup group = CollisionManager.CollisionGroup.Default)
+ public PolygonCollider(TSVector2[] vertex, TSVector2 center, FP rotation, CollisionGroup group = CollisionGroup.Default)
{
collider = ColliderStructure.CreateInstance();
collider.colliderType = ColliderType.Polygon;
collider.rot = rotation;
collider.center = center;
+ collider.collisionGroup = group;
+ collider.vertexCount = vertex.Length;
movedVertexs = new NativeArray(vertex.Length,Allocator.Persistent,NativeArrayOptions.UninitializedMemory); //边数是不能变的
- CollisionManager.instance.BufferManager.RegisterCollider(ref collider,vertex.Length);
- SetRotation(rotation);
- colliGroup = group;
+ RotateVertexs(false);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public override ColliderStructure GetRealCollider()
{
- return CollisionManager.instance.BufferManager.colliders[collider.uniqueID];
+ return CollisionManager.instance.nativeCollisionManager.colliders[collider.uniqueID];
+ }
+
+ public sealed override void SaveState()
+ {
+ base.SaveState();
+ CollisionManager.instance.nativeCollisionManager.ModifyCollider(collider,movedVertexs);
}
public override void SetRotation(FP rotRad)
@@ -447,7 +475,7 @@ public override TSVector2 GetCenter()
{
return collider.center;
}
- void RotateVertexs()
+ protected void RotateVertexs(bool saveState=true)
{
TSVector4 tSVector4 = new TSVector4(FP.MaxValue, FP.MinValue, FP.MinValue, FP.MaxValue);
for (int i = movedVertexs.Length - 1; i >= 0; --i)
@@ -470,8 +498,11 @@ void RotateVertexs()
tSVector4.w = movedVertexs[i].y;//最小值,代表下方点
}
}
- CollisionManager.instance.BufferManager.ModifyCollider(collider,movedVertexs);
_boundingBox_ = tSVector4;
+ if (saveState)
+ {
+ SaveState();
+ }
}
void MoveDeltaPos(TSVector2 pos)
{
@@ -480,7 +511,7 @@ void MoveDeltaPos(TSVector2 pos)
movedVertexs[i] += pos;
}
//标注顶点缓冲区的移动
- CollisionManager.instance.BufferManager.ModifyCollider(collider,movedVertexs);
+ SaveState();
_boundingBox_.x += pos.x;
_boundingBox_.y += pos.y;
_boundingBox_.z += pos.x;
@@ -502,7 +533,7 @@ void MoveDeltaPos(TSVector2 pos)
}
if (result != pos)
{
- var arr = ColliderVertexBuffer.instancedBuffer.ToArray();
+ var arr = ColliderNativeHelper.instancedBuffer.ToArray();
StringBuilder sb = new StringBuilder();
sb.AppendJoin(", ", arr);
Debug.Log(result+" "+pos+" "+sb);
@@ -511,7 +542,7 @@ void MoveDeltaPos(TSVector2 pos)
}*/
public override void Destroy()
{
- CollisionManager.instance.BufferManager.DeleteCollider(collider);
+ CollisionManager.instance.nativeCollisionManager.DeleteCollider(collider);
if(movedVertexs.IsCreated)
movedVertexs.Dispose();
}
@@ -524,7 +555,7 @@ public override TSVector4 GetBoundingBox()
[Serializable]
public class BoxCollider : PolygonCollider
{
- public BoxCollider(TSVector2 widthHeight,TSVector2 center,FP rotation, CollisionManager.CollisionGroup group = CollisionManager.CollisionGroup.Default)
+ public BoxCollider(TSVector2 widthHeight,TSVector2 center,FP rotation, CollisionGroup group = CollisionGroup.Default)
{
TSVector2 a = widthHeight * 0.5;//左下,左上,右上,右下
TSVector2 b = new TSVector2(a.x,-a.y);
@@ -534,9 +565,9 @@ public BoxCollider(TSVector2 widthHeight,TSVector2 center,FP rotation, Collision
collider.colliderType = ColliderType.Polygon;
collider.rot = rotation;
collider.center = center;
- CollisionManager.instance.BufferManager.RegisterCollider(ref collider,movedVertexs.Length);
- SetRotation(rotation);
- colliGroup = group;
+ collider.vertexCount = vertexs.Length;
+ collider.collisionGroup = group;
+ RotateVertexs(false);
}
public override void DebugDisplayColliderShape(Color color)
{
@@ -562,7 +593,7 @@ public T Master
set => _master_ = value;
}
- public BoxCollider(T master, TSVector2 widthHeight, TSVector2 center, FP rotation, CollisionManager.CollisionGroup group = CollisionManager.CollisionGroup.Default) : base(widthHeight, center, rotation, group)
+ public BoxCollider(T master, TSVector2 widthHeight, TSVector2 center, FP rotation, CollisionGroup group = CollisionGroup.Default) : base(widthHeight, center, rotation, group)
{
this._master_ = master;
}
@@ -571,7 +602,7 @@ public BoxCollider(T master, TSVector2 widthHeight, TSVector2 center, FP rotatio
[Serializable]
public class DiamondCollider : PolygonCollider
{
- public DiamondCollider(TSVector2 widthHeight, TSVector2 center, FP rotation, CollisionManager.CollisionGroup group = CollisionManager.CollisionGroup.Default)
+ public DiamondCollider(TSVector2 widthHeight, TSVector2 center, FP rotation, CollisionGroup group = CollisionGroup.Default)
{
TSVector2 b = new TSVector2(widthHeight.x * 0.5, 0);
TSVector2 c = new TSVector2(0, widthHeight.y * 0.5);
@@ -581,9 +612,9 @@ public DiamondCollider(TSVector2 widthHeight, TSVector2 center, FP rotation, Col
collider.colliderType = ColliderType.Polygon;
collider.rot = rotation;
collider.center = center;
- CollisionManager.instance.BufferManager.RegisterCollider(ref collider,movedVertexs.Length);
- SetRotation(rotation);
- colliGroup = group;
+ collider.vertexCount = vertexs.Length;
+ collider.collisionGroup = group;
+ RotateVertexs(false);
}
}
@@ -591,13 +622,13 @@ public DiamondCollider(TSVector2 widthHeight, TSVector2 center, FP rotation, Col
//两个相同的圆中间连线
public class DoubleCircleCollider : ColliderBase
{
- public DoubleCircleCollider(FP R, TSVector2 center1,TSVector2 center2, CollisionManager.CollisionGroup group = CollisionManager.CollisionGroup.Default)
+ public DoubleCircleCollider(FP R, TSVector2 center1,TSVector2 center2, CollisionGroup group = CollisionGroup.Default)
{
collider = ColliderStructure.CreateInstance();
collider.colliderType = ColliderType.DoubleCircle;
collider.radius = R;
+ collider.collisionGroup = group;
SetCircleCenters(center1,center2);
- colliGroup = group;
}
public override void SetRotation(FP rotRad) { }//没错,圆形没有旋转
public override void SetCenter(in TSVector2 center)
@@ -753,7 +784,7 @@ public T Master
set => _master_ = value;
}
- public DoubleCircleCollider(T master, FP R, TSVector2 center1,TSVector2 center2, CollisionManager.CollisionGroup group = CollisionManager.CollisionGroup.Default) : base(R, center1,center2, group)
+ public DoubleCircleCollider(T master, FP R, TSVector2 center1,TSVector2 center2, CollisionGroup group = CollisionGroup.Default) : base(R, center1,center2, group)
{
this._master_ = master;
}
@@ -838,7 +869,7 @@ public void RemoveCollider(int startIndex,int length) {
public void SetColliders(params ColliderBase[] colliders) {
SetCollidersIEnumerable(colliders);
}
- public CollisionController AddListener(bool multiColli,Action collideEnter, Action collide, Action collideLeave, params CollisionManager.CollisionGroup[] collisionGroups)
+ public CollisionController AddListener(bool multiColli,Action collideEnter, Action collide, Action collideLeave, params CollisionGroup[] collisionGroups)
{
if (DestroyedChecker()) return this;//销毁后不允许再增加
foreach (var item in Colliders)
@@ -847,7 +878,7 @@ public CollisionController AddListener(bool multiColli,Action coll
}
return this;
}
- public CollisionController AddListener(Action collideEnter, Action collide, Action collideLeave,params CollisionManager.CollisionGroup[] collisionGroups) {
+ public CollisionController AddListener(Action collideEnter, Action collide, Action collideLeave,params CollisionGroup[] collisionGroups) {
if (DestroyedChecker()) return this;//销毁后不允许再增加
foreach (var item in Colliders)
{
@@ -855,10 +886,10 @@ public CollisionController AddListener(Action collideEnter, Action
}
return this;
}
- public CollisionController AddListener(Action collide, params CollisionManager.CollisionGroup[] groups) {
+ public CollisionController AddListener(Action collide, params CollisionGroup[] groups) {
return AddListener(null,collide,null,groups);
}
- public CollisionController AddListener(Action collide, bool multiColli=false, params CollisionManager.CollisionGroup[] groups)
+ public CollisionController AddListener(Action collide, bool multiColli=false, params CollisionGroup[] groups)
{
return AddListener(multiColli ,null, collide, null, groups);
}
@@ -940,7 +971,7 @@ public void Dispose()
c.Dispose();
}
}
- BufferManager.Dispose();
+ nativeCollisionManager.Dispose();
}
public int groupCnt = Enum.GetValues(typeof(CollisionGroup)).Length;
public LinkedHashSet[] groupedColliders;//这个到时候要改成LinkedHashSet之类的东西。。。
@@ -951,7 +982,7 @@ public void Dispose()
public HashSet tmpDrawingHasCheckedObjectsInCurFrame = new HashSet