From 7a9a3b377f893d398b948f0d42236d27d9ece14f Mon Sep 17 00:00:00 2001 From: james7132 Date: Sat, 24 Feb 2018 23:50:59 -0800 Subject: [PATCH] Fix Collisions --- Assets/DanmakU/Runtime/Bounds2D.cs | 6 +- .../Default.mat.meta => Colliders.meta} | 6 +- .../Colliders/DestroyDanmakuCollider.cs | 46 ++++++++++ .../Colliders/DestroyDanmakuCollider.cs.meta | 11 +++ Assets/DanmakU/Runtime/Core/Collisions.meta | 8 ++ .../Core/{ => Collisions}/DanmakuCollider.cs | 66 ++++++++++++++- .../{ => Collisions}/DanmakuCollider.cs.meta | 0 .../Core/Collisions/DanmakuCollision.cs | 12 +++ .../Core/Collisions/DanmakuCollision.cs.meta | 11 +++ .../Core/Collisions/DanmakuCollisionList.cs | 60 +++++++++++++ .../Collisions/DanmakuCollisionList.cs.meta | 11 +++ .../Collisions/MutableDanmakuCollisionList.cs | 56 +++++++++++++ .../MutableDanmakuCollisionList.cs.meta | 11 +++ Assets/DanmakU/Runtime/Core/Danmaku.cs | 15 ++++ Assets/DanmakU/Runtime/Core/DanmakuManager.cs | 14 +--- Assets/DanmakU/Runtime/Core/DanmakuPool.cs | 8 +- .../Runtime/Core/Jobs/CollideDanamku.cs | 14 ++-- .../Runtime/Core/Jobs/DestroyDanmaku.cs | 19 +++-- Assets/DanmakU/Runtime/DanmakuBehaviour.cs | 1 + Assets/DanmakU/Runtime/MultiMap.cs | 36 ++++++++ Assets/DanmakU/Runtime/MultiMap.cs.meta | 11 +++ .../Shaders/Default Ranged Sprite Danmaku.mat | 2 +- .../Shaders/Default Sprite Danmaku.mat | 2 +- Assets/DanmakU/Runtime/Shaders/Default.mat | 84 ------------------- 24 files changed, 385 insertions(+), 125 deletions(-) rename Assets/DanmakU/Runtime/{Shaders/Default.mat.meta => Colliders.meta} (52%) create mode 100644 Assets/DanmakU/Runtime/Colliders/DestroyDanmakuCollider.cs create mode 100644 Assets/DanmakU/Runtime/Colliders/DestroyDanmakuCollider.cs.meta create mode 100644 Assets/DanmakU/Runtime/Core/Collisions.meta rename Assets/DanmakU/Runtime/Core/{ => Collisions}/DanmakuCollider.cs (58%) rename Assets/DanmakU/Runtime/Core/{ => Collisions}/DanmakuCollider.cs.meta (100%) create mode 100644 Assets/DanmakU/Runtime/Core/Collisions/DanmakuCollision.cs create mode 100644 Assets/DanmakU/Runtime/Core/Collisions/DanmakuCollision.cs.meta create mode 100644 Assets/DanmakU/Runtime/Core/Collisions/DanmakuCollisionList.cs create mode 100644 Assets/DanmakU/Runtime/Core/Collisions/DanmakuCollisionList.cs.meta create mode 100644 Assets/DanmakU/Runtime/Core/Collisions/MutableDanmakuCollisionList.cs create mode 100644 Assets/DanmakU/Runtime/Core/Collisions/MutableDanmakuCollisionList.cs.meta create mode 100644 Assets/DanmakU/Runtime/MultiMap.cs create mode 100644 Assets/DanmakU/Runtime/MultiMap.cs.meta delete mode 100644 Assets/DanmakU/Runtime/Shaders/Default.mat diff --git a/Assets/DanmakU/Runtime/Bounds2D.cs b/Assets/DanmakU/Runtime/Bounds2D.cs index 74be3e52..ac380ca4 100644 --- a/Assets/DanmakU/Runtime/Bounds2D.cs +++ b/Assets/DanmakU/Runtime/Bounds2D.cs @@ -113,8 +113,8 @@ public void Expand(Vector2 amount) { /// true if there is an intersection between bounds, false otherwise. [MethodImpl(MethodImplOptions.AggressiveInlining)] public bool Intersects(Bounds2D bounds) { - return (Math.Abs(Center.x - bounds.Center.x) * 2 < Extents.x + bounds.Extents.x) && - (Math.Abs(Center.y - bounds.Center.y) * 2 < Extents.y + bounds.Extents.y); + return (Math.Abs(Center.x - bounds.Center.x) < Extents.x + bounds.Size.x) && + (Math.Abs(Center.y - bounds.Center.y) < Extents.y + bounds.Extents.y); } /// @@ -129,7 +129,7 @@ public bool Contains(Vector2 point) { } public static implicit operator Bounds2D(Bounds bounds) { - return new Bounds2D(bounds.center, bounds.extents); + return new Bounds2D(bounds.center, bounds.size); } public static implicit operator Bounds(Bounds2D bounds) { diff --git a/Assets/DanmakU/Runtime/Shaders/Default.mat.meta b/Assets/DanmakU/Runtime/Colliders.meta similarity index 52% rename from Assets/DanmakU/Runtime/Shaders/Default.mat.meta rename to Assets/DanmakU/Runtime/Colliders.meta index 5c25dda1..8454a230 100644 --- a/Assets/DanmakU/Runtime/Shaders/Default.mat.meta +++ b/Assets/DanmakU/Runtime/Colliders.meta @@ -1,8 +1,8 @@ fileFormatVersion: 2 -guid: d8488d41296b83b46955a16919179879 -NativeFormatImporter: +guid: fc201c59b2e553f41ba131d04017d6ae +folderAsset: yes +DefaultImporter: externalObjects: {} - mainObjectFileID: 2100000 userData: assetBundleName: assetBundleVariant: diff --git a/Assets/DanmakU/Runtime/Colliders/DestroyDanmakuCollider.cs b/Assets/DanmakU/Runtime/Colliders/DestroyDanmakuCollider.cs new file mode 100644 index 00000000..2a23148a --- /dev/null +++ b/Assets/DanmakU/Runtime/Colliders/DestroyDanmakuCollider.cs @@ -0,0 +1,46 @@ +using System.Collections; +using System.Collections.Generic; +using UnityEngine; + +namespace DanmakU { + +public class DestroyDanmakuCollider : MonoBehaviour { + + public DanmakuCollider Collider; + + /// + /// This function is called when the object becomes enabled and active. + /// + void OnEnable() { + if (Collider != null) { + Debug.Log("Subscribed"); + Collider.OnDanmakuCollision += OnDanmakuCollision; + } + } + + /// + /// This function is called when the behaviour becomes disabled or inactive. + /// + void OnDisable() { + if (Collider != null) { + Collider.OnDanmakuCollision -= OnDanmakuCollision; + } + } + + void OnDanmakuCollision(DanmakuCollisionList collisions) { + foreach (var collision in collisions) { + collision.Danmaku.Destroy(); + } + } + + /// + /// Reset is called when the user hits the Reset button in the Inspector's + /// context menu or when adding the component the first time. + /// + void Reset() { + Collider = GetComponent(); + } + +} + +} \ No newline at end of file diff --git a/Assets/DanmakU/Runtime/Colliders/DestroyDanmakuCollider.cs.meta b/Assets/DanmakU/Runtime/Colliders/DestroyDanmakuCollider.cs.meta new file mode 100644 index 00000000..f1f08875 --- /dev/null +++ b/Assets/DanmakU/Runtime/Colliders/DestroyDanmakuCollider.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 221a147fe33b14d41a8aa34e8483ac3b +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/DanmakU/Runtime/Core/Collisions.meta b/Assets/DanmakU/Runtime/Core/Collisions.meta new file mode 100644 index 00000000..e05329b0 --- /dev/null +++ b/Assets/DanmakU/Runtime/Core/Collisions.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: a3a80331756292740afffee7c35b6855 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/DanmakU/Runtime/Core/DanmakuCollider.cs b/Assets/DanmakU/Runtime/Core/Collisions/DanmakuCollider.cs similarity index 58% rename from Assets/DanmakU/Runtime/Core/DanmakuCollider.cs rename to Assets/DanmakU/Runtime/Core/Collisions/DanmakuCollider.cs index b3e408b3..a815007d 100644 --- a/Assets/DanmakU/Runtime/Core/DanmakuCollider.cs +++ b/Assets/DanmakU/Runtime/Core/Collisions/DanmakuCollider.cs @@ -1,7 +1,7 @@ -using System.Collections; +using System; using System.Collections.Generic; using UnityEngine; -using UnityEngine.Assertions; +using Unity.Collections.LowLevel.Unsafe; namespace DanmakU { @@ -15,7 +15,9 @@ struct ColliderData { public int LayerMask; } + static RaycastHit2D[] raycastCache = new RaycastHit2D[256]; static readonly List Colliders; + static readonly MultiMap ColliderMap; static readonly List[] Data; static Bounds2D GlobalBounds; static int GlobalLayerMask; @@ -23,6 +25,7 @@ struct ColliderData { static DanmakuCollider() { Colliders = new List(); + ColliderMap = new MultiMap(); Data = new List[sizeof(int) * 8]; for (var i = 0; i < Data.Length; i++) { Data[i] = new List(); @@ -54,15 +57,31 @@ internal static void RebuildSpatialHashes() { } } + MutableDanmakuCollisionList collidedDanmaku; Collider2D[] colliders; ColliderData data; + public event Action OnDanmakuCollision; + /// /// Awake is called when the script instance is being loaded. /// void Awake() { colliders = GetComponents(); data = BuildData(); + collidedDanmaku = new MutableDanmakuCollisionList(); + foreach (var collider in colliders) { + ColliderMap.Add(collider, this); + } + } + + /// + /// This function is called when the MonoBehaviour will be destroyed. + /// + void OnDestroy() { + foreach (var collider in colliders) { + ColliderMap.RemoveElement(collider, this); + } } /// @@ -82,6 +101,49 @@ void FixedUpdate() { data = BuildData(); } + internal static unsafe void TestPoolCollisions(DanmakuPool pool) { + var layersPtr = (int*)(pool.CollisionMasks.GetUnsafePtr()); + var count = pool.ActiveCount; + for (var i = 0; i < count; i++) { + if (*layersPtr++ == 0) continue; + var layerMask = pool.CollisionMasks[i]; + var oldPosition = pool.OldPositions[i]; + var direction = pool.Positions[i] - oldPosition; + var distance = direction.magnitude; + var hits = Physics2D.CircleCastNonAlloc(oldPosition, pool.ColliderRadius, direction, raycastCache, distance, layerMask); + if (hits <= 0) continue; + var danmaku = new Danmaku(pool, i); + for (var j = 0; j < hits; j++) { + var collider = raycastCache[j].collider; + List danmakuColliders; + if (!ColliderMap.TryGetValue(collider, out danmakuColliders)) continue; + var collision = new DanmakuCollision { + Danmaku = danmaku, + RaycastHit = raycastCache[j] + }; + foreach (var dCollider in danmakuColliders) { + if (dCollider != null && dCollider.isActiveAndEnabled) { + dCollider.AddDanmaku(collision); + } + } + } + } + } + + internal static void FlushAll() { + foreach (var collider in Colliders) { + collider.Flush(); + } + } + + internal void AddDanmaku(DanmakuCollision danmaku) => collidedDanmaku.Add(danmaku); + internal void Flush() { + if (collidedDanmaku.Count > 0 && OnDanmakuCollision != null) { + OnDanmakuCollision(collidedDanmaku.AsReadOnly()); + } + collidedDanmaku.Clear(); + } + internal static int TestCollisions(Bounds2D bounds) { if (!GlobalBounds.Intersects(bounds)) return 0; int collisions = 0; diff --git a/Assets/DanmakU/Runtime/Core/DanmakuCollider.cs.meta b/Assets/DanmakU/Runtime/Core/Collisions/DanmakuCollider.cs.meta similarity index 100% rename from Assets/DanmakU/Runtime/Core/DanmakuCollider.cs.meta rename to Assets/DanmakU/Runtime/Core/Collisions/DanmakuCollider.cs.meta diff --git a/Assets/DanmakU/Runtime/Core/Collisions/DanmakuCollision.cs b/Assets/DanmakU/Runtime/Core/Collisions/DanmakuCollision.cs new file mode 100644 index 00000000..cece0194 --- /dev/null +++ b/Assets/DanmakU/Runtime/Core/Collisions/DanmakuCollision.cs @@ -0,0 +1,12 @@ +using System.Collections; +using System.Collections.Generic; +using UnityEngine; + +namespace DanmakU { + +public struct DanmakuCollision { + public Danmaku Danmaku; + public RaycastHit2D RaycastHit; +} + +} \ No newline at end of file diff --git a/Assets/DanmakU/Runtime/Core/Collisions/DanmakuCollision.cs.meta b/Assets/DanmakU/Runtime/Core/Collisions/DanmakuCollision.cs.meta new file mode 100644 index 00000000..dd3147e5 --- /dev/null +++ b/Assets/DanmakU/Runtime/Core/Collisions/DanmakuCollision.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 11827e1f86a96f843bb71ada7add6f2d +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/DanmakU/Runtime/Core/Collisions/DanmakuCollisionList.cs b/Assets/DanmakU/Runtime/Core/Collisions/DanmakuCollisionList.cs new file mode 100644 index 00000000..e424b078 --- /dev/null +++ b/Assets/DanmakU/Runtime/Core/Collisions/DanmakuCollisionList.cs @@ -0,0 +1,60 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using UnityEngine; +using Unity.Collections.LowLevel.Unsafe; + +namespace DanmakU { + +/// +/// A read-only list of Danmaku. +/// +public struct DanmakuCollisionList : IReadOnlyList { + + readonly DanmakuCollision[] Array; + public int Count { get; } + + internal DanmakuCollisionList(DanmakuCollision[] array, int count) { + Array = array; + Count = count; + } + + public DanmakuCollision this[int index] { + get { + if (index < 0 && index >= Count) { + throw new IndexOutOfRangeException(nameof(index)); + } + return Array[index]; + } + } + + public Enumerator GetEnumerator() => new Enumerator(this); + IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); + IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); + + public struct Enumerator : IEnumerator { + + readonly DanmakuCollisionList list; + int currentIndex; + public DanmakuCollision Current => list[currentIndex]; + object IEnumerator.Current => Current; + + internal Enumerator(DanmakuCollisionList list) { + this.list = list; + currentIndex = -1; + } + + public bool MoveNext() { + currentIndex++; + return currentIndex < list.Count; + } + + public void Reset() => currentIndex = -1; + + public void Dispose() {} + + } + +} + +} diff --git a/Assets/DanmakU/Runtime/Core/Collisions/DanmakuCollisionList.cs.meta b/Assets/DanmakU/Runtime/Core/Collisions/DanmakuCollisionList.cs.meta new file mode 100644 index 00000000..3ee19458 --- /dev/null +++ b/Assets/DanmakU/Runtime/Core/Collisions/DanmakuCollisionList.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 45c41470094c1d7468a74e2638005d71 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/DanmakU/Runtime/Core/Collisions/MutableDanmakuCollisionList.cs b/Assets/DanmakU/Runtime/Core/Collisions/MutableDanmakuCollisionList.cs new file mode 100644 index 00000000..7a6cdc91 --- /dev/null +++ b/Assets/DanmakU/Runtime/Core/Collisions/MutableDanmakuCollisionList.cs @@ -0,0 +1,56 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using UnityEngine; +using Unity.Collections.LowLevel.Unsafe; + +namespace DanmakU { + +internal class MutableDanmakuCollisionList { + + const int kDefaultCapacity = 16; + const int kGrowthFactor = 2; + + DanmakuCollision[] Array; + public int Capacity => Array?.Length ?? kDefaultCapacity; + public int Count { get; private set; } + + public DanmakuCollisionList AsReadOnly() => new DanmakuCollisionList(Array, Count); + + public MutableDanmakuCollisionList() { + Array = new DanmakuCollision[kDefaultCapacity]; + } + + public void Add(DanmakuCollision obj) { + if (Contains(obj)) return; + CheckCapacity(1); + Array[Count++] = obj; + } + + public bool Contains(DanmakuCollision obj) { + if (Count <= 1024) { + bool contained = false; + for (var i = 0; i < Count; i++) { + contained |= Array[i].Danmaku == obj.Danmaku; + } + return contained; + } else { + for (var i = 0; i < Count; i++) { + if (Array[i].Danmaku== obj.Danmaku) return true; + } + return false; + } + } + + public void Clear() => Count = 0; + + void CheckCapacity(int count) { + if (Count + count <= Capacity) return; + var newArray = new DanmakuCollision[Capacity * kGrowthFactor]; + System.Array.Copy(Array, 0, newArray, 0, Count); + Array = newArray; + } + +} + +} diff --git a/Assets/DanmakU/Runtime/Core/Collisions/MutableDanmakuCollisionList.cs.meta b/Assets/DanmakU/Runtime/Core/Collisions/MutableDanmakuCollisionList.cs.meta new file mode 100644 index 00000000..90d75cea --- /dev/null +++ b/Assets/DanmakU/Runtime/Core/Collisions/MutableDanmakuCollisionList.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 28d5419162957c44485b9981f7fa1ff3 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/DanmakU/Runtime/Core/Danmaku.cs b/Assets/DanmakU/Runtime/Core/Danmaku.cs index a4cc52dc..add2662b 100644 --- a/Assets/DanmakU/Runtime/Core/Danmaku.cs +++ b/Assets/DanmakU/Runtime/Core/Danmaku.cs @@ -154,6 +154,21 @@ public void ApplyState(DanmakuState state) { Color = state.Color; } + public static bool operator ==(Danmaku lhs, Danmaku rhs) { + return lhs.Id == rhs.Id && lhs.Pool == rhs.Pool; + } + + public static bool operator !=(Danmaku lhs, Danmaku rhs) { + return lhs.Id != rhs.Id || lhs.Pool != rhs.Pool; + } + + public override bool Equals(object obj) { + if (!(obj is Danmaku)) return false; + return ((Danmaku)obj) == this; + } + + public override int GetHashCode() => 31 * Pool.GetHashCode() + Id; + } } \ No newline at end of file diff --git a/Assets/DanmakU/Runtime/Core/DanmakuManager.cs b/Assets/DanmakU/Runtime/Core/DanmakuManager.cs index afb84be6..c82ccc6e 100644 --- a/Assets/DanmakU/Runtime/Core/DanmakuManager.cs +++ b/Assets/DanmakU/Runtime/Core/DanmakuManager.cs @@ -20,7 +20,6 @@ namespace DanmakU { [AddComponentMenu("DanmakU/Danmaku Manager")] public class DanmakuManager : MonoBehaviour { - static RaycastHit2D[] raycastCache = new RaycastHit2D[256]; /// /// Gets the singleton instance of the manager. Null if there is no active @@ -65,19 +64,10 @@ void Update() { if (DanmakuCollider.ColliderCount <= 0) return; foreach (var group in RendererGroups.Values) { foreach (var set in group.Sets) { - var pool = set.Pool; - foreach (var danmaku in pool) { - var layerMask = pool.CollisionMasks[danmaku.Id]; - if (layerMask == 0) continue; - var oldPosition = pool.OldPositions[danmaku.Id]; - var direction = oldPosition - danmaku.Position; - var distance = direction.magnitude; - var hits = Physics2D.CircleCastNonAlloc(oldPosition, pool.ColliderRadius, direction, raycastCache, distance, layerMask); - if (hits <= 0) continue; - danmaku.Destroy(); - } + DanmakuCollider.TestPoolCollisions(set.Pool); } } + DanmakuCollider.FlushAll(); } /// diff --git a/Assets/DanmakU/Runtime/Core/DanmakuPool.cs b/Assets/DanmakU/Runtime/Core/DanmakuPool.cs index c8e82d0d..8392a23b 100644 --- a/Assets/DanmakU/Runtime/Core/DanmakuPool.cs +++ b/Assets/DanmakU/Runtime/Core/DanmakuPool.cs @@ -83,7 +83,7 @@ public class DanmakuPool : IEnumerable, IDisposable { /// The recommended batch size for processing Danmaku in parallelizable jobs. /// /// - public const int kBatchSize = 1; + public const int kBatchSize = 1024; const int kGrowthFactor = 2; /// @@ -161,11 +161,11 @@ internal DanmakuPool(int poolSize) { new NativeSlice(OldPositions, 0, count).CopyFrom(new NativeSlice(Positions, 0, count)); var move = new MoveDanmaku(this).Schedule(count, kBatchSize, dependency); dependency = new BoundsCheckDanmaku(this).Schedule(count, kBatchSize, move); + dependency = new DestroyDanmaku(this).Schedule(dependency); if (DanmakuCollider.ColliderCount > 0) { - var collide = new CollideDanamku(this).Schedule(count, kBatchSize, move); - dependency = JobHandle.CombineDependencies(dependency, collide); + dependency = new CollideDanamku(this).Schedule(count, kBatchSize, dependency); } - return new DestroyDanmaku(this).Schedule(dependency); + return dependency; } /// diff --git a/Assets/DanmakU/Runtime/Core/Jobs/CollideDanamku.cs b/Assets/DanmakU/Runtime/Core/Jobs/CollideDanamku.cs index 3edbf936..60fe2363 100644 --- a/Assets/DanmakU/Runtime/Core/Jobs/CollideDanamku.cs +++ b/Assets/DanmakU/Runtime/Core/Jobs/CollideDanamku.cs @@ -8,20 +8,20 @@ namespace DanmakU { internal struct CollideDanamku : IJobParallelFor { - public float Radius; - - [ReadOnly] public NativeArray Positions; - [WriteOnly] public NativeArray Collisions; + Bounds2D Bounds; + [ReadOnly] NativeArray Positions; + [WriteOnly] NativeArray Collisions; public CollideDanamku(DanmakuPool pool) { - Radius = pool.ColliderRadius; + var radius = pool.ColliderRadius; + Bounds = new Bounds2D(Vector2.zero, new Vector2(radius, radius)); Positions = pool.Positions; Collisions = pool.CollisionMasks; } public void Execute(int index) { - var danmakuBounds = new Bounds2D(Positions[index], new Vector2(Radius, Radius)); - Collisions[index] = DanmakuCollider.TestCollisions(danmakuBounds); + Bounds.Center = Positions[index]; + Collisions[index] = DanmakuCollider.TestCollisions(Bounds); } } diff --git a/Assets/DanmakU/Runtime/Core/Jobs/DestroyDanmaku.cs b/Assets/DanmakU/Runtime/Core/Jobs/DestroyDanmaku.cs index aacde38b..4e0ce751 100644 --- a/Assets/DanmakU/Runtime/Core/Jobs/DestroyDanmaku.cs +++ b/Assets/DanmakU/Runtime/Core/Jobs/DestroyDanmaku.cs @@ -9,20 +9,22 @@ namespace DanmakU { internal struct DestroyDanmaku : IJob { - public NativeArray ActiveCountArray; - public NativeArray Times; - public NativeArray InitialStates; - public NativeArray Positions; - public NativeArray Rotations; - public NativeArray Speeds; - public NativeArray AngularSpeeds; - public NativeArray Colors; + NativeArray ActiveCountArray; + NativeArray Times; + NativeArray InitialStates; + NativeArray Positions; + NativeArray OldPositions; + NativeArray Rotations; + NativeArray Speeds; + NativeArray AngularSpeeds; + NativeArray Colors; public DestroyDanmaku(DanmakuPool pool) { ActiveCountArray = pool.activeCountArray; Times = pool.Times; InitialStates = pool.InitialStates; Positions = pool.Positions; + OldPositions = pool.OldPositions; Rotations = pool.Rotations; Times = pool.Times; Speeds = pool.Speeds; @@ -39,6 +41,7 @@ public unsafe void Execute() { InitialStates[i] = InitialStates[activeCount]; Times[i] = Times[activeCount]; Positions[i] = Positions[activeCount]; + OldPositions[i] = OldPositions[activeCount]; Rotations[i] = Rotations[activeCount]; Speeds[i] = Speeds[activeCount]; AngularSpeeds[i] = AngularSpeeds[activeCount]; diff --git a/Assets/DanmakU/Runtime/DanmakuBehaviour.cs b/Assets/DanmakU/Runtime/DanmakuBehaviour.cs index e7c9fe4e..76bfe4a0 100644 --- a/Assets/DanmakU/Runtime/DanmakuBehaviour.cs +++ b/Assets/DanmakU/Runtime/DanmakuBehaviour.cs @@ -23,6 +23,7 @@ public abstract class DanmakuBehaviour : MonoBehaviour { /// the created DanmakuSet. protected DanmakuSet CreateSet(DanmakuPrefab prefab) { var pool = new DanmakuPool(prefab.DefaultPoolSize); + pool.ColliderRadius = prefab.ColliderRadius; var set = DanmakuManager.Instance.CreateDanmakuSet(prefab.GetRendererConfig(), pool); (OwnedDanmakuSets ?? (OwnedDanmakuSets = new List())).Add(set); set.AddModifiers(prefab.GetModifiers()); diff --git a/Assets/DanmakU/Runtime/MultiMap.cs b/Assets/DanmakU/Runtime/MultiMap.cs new file mode 100644 index 00000000..cbc0532f --- /dev/null +++ b/Assets/DanmakU/Runtime/MultiMap.cs @@ -0,0 +1,36 @@ +using System.Collections; +using System.Collections.Generic; +using UnityEngine; + +namespace DanmakU { + +internal class MultiMap : Dictionary> { + + public void Add(TKey key, TValue value) { + List subset; + if (!TryGetValue(key, out subset)) { + subset = new List(); + Add(key, subset); + } + subset.Add(value); + } + + public void ClearSet(TKey key) { + List subset; + if (TryGetValue(key, out subset)) { + subset.Clear(); + } + } + + public void RemoveElement(TKey key, TValue value) { + List subset; + if (!TryGetValue(key, out subset)) return; + subset.Remove(value); + if (subset.Count <= 0) { + Remove(key); + } + } + +} + +} diff --git a/Assets/DanmakU/Runtime/MultiMap.cs.meta b/Assets/DanmakU/Runtime/MultiMap.cs.meta new file mode 100644 index 00000000..1bff7271 --- /dev/null +++ b/Assets/DanmakU/Runtime/MultiMap.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: f6305969bc957474f8ec1b45afb427e7 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/DanmakU/Runtime/Shaders/Default Ranged Sprite Danmaku.mat b/Assets/DanmakU/Runtime/Shaders/Default Ranged Sprite Danmaku.mat index bd20e787..fde79909 100644 --- a/Assets/DanmakU/Runtime/Shaders/Default Ranged Sprite Danmaku.mat +++ b/Assets/DanmakU/Runtime/Shaders/Default Ranged Sprite Danmaku.mat @@ -43,7 +43,7 @@ Material: m_Scale: {x: 1, y: 1} m_Offset: {x: 0, y: 0} - _MainTex: - m_Texture: {fileID: 2800000, guid: 4cddd60e11667c848a99d851ee8b4e89, type: 3} + m_Texture: {fileID: 0} m_Scale: {x: 1, y: 1} m_Offset: {x: 0, y: 0} - _MetallicGlossMap: diff --git a/Assets/DanmakU/Runtime/Shaders/Default Sprite Danmaku.mat b/Assets/DanmakU/Runtime/Shaders/Default Sprite Danmaku.mat index d57a4561..caea45bb 100644 --- a/Assets/DanmakU/Runtime/Shaders/Default Sprite Danmaku.mat +++ b/Assets/DanmakU/Runtime/Shaders/Default Sprite Danmaku.mat @@ -43,7 +43,7 @@ Material: m_Scale: {x: 1, y: 1} m_Offset: {x: 0, y: 0} - _MainTex: - m_Texture: {fileID: 2800000, guid: 4cddd60e11667c848a99d851ee8b4e89, type: 3} + m_Texture: {fileID: 0} m_Scale: {x: 1, y: 1} m_Offset: {x: 0, y: 0} - _MetallicGlossMap: diff --git a/Assets/DanmakU/Runtime/Shaders/Default.mat b/Assets/DanmakU/Runtime/Shaders/Default.mat deleted file mode 100644 index 353edc1d..00000000 --- a/Assets/DanmakU/Runtime/Shaders/Default.mat +++ /dev/null @@ -1,84 +0,0 @@ -%YAML 1.1 -%TAG !u! tag:unity3d.com,2011: ---- !u!21 &2100000 -Material: - serializedVersion: 6 - m_ObjectHideFlags: 0 - m_PrefabParentObject: {fileID: 0} - m_PrefabInternal: {fileID: 0} - m_Name: Default - m_Shader: {fileID: 46, guid: 0000000000000000f000000000000000, type: 0} - m_ShaderKeywords: - m_LightmapFlags: 4 - m_EnableInstancingVariants: 1 - m_DoubleSidedGI: 0 - m_CustomRenderQueue: -1 - stringTagMap: {} - disabledShaderPasses: [] - m_SavedProperties: - serializedVersion: 3 - m_TexEnvs: - - _AlphaTex: - 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} - m_Floats: - - PixelSnap: 0 - - _BumpScale: 1 - - _Cutoff: 0.5 - - _DetailNormalMapScale: 1 - - _DstBlend: 0 - - _EnableExternalAlpha: 0 - - _GlossMapScale: 1 - - _Glossiness: 0.5 - - _GlossyReflections: 1 - - _Metallic: 0 - - _Mode: 0 - - _OcclusionStrength: 1 - - _Parallax: 0.02 - - _SmoothnessTextureChannel: 0 - - _SpecularHighlights: 1 - - _SrcBlend: 1 - - _UVSec: 0 - - _ZWrite: 1 - m_Colors: - - _Color: {r: 1, g: 1, b: 1, a: 1} - - _EmissionColor: {r: 0, g: 0, b: 0, a: 1} - - _Flip: {r: 1, g: 1, b: 1, a: 1} - - _RendererColor: {r: 1, g: 1, b: 1, a: 1}