diff --git a/Assets/Unity-Bullet-Hell/Textures.meta b/Assets/Unity-Bullet-Hell/Resources/Textures.meta similarity index 100% rename from Assets/Unity-Bullet-Hell/Textures.meta rename to Assets/Unity-Bullet-Hell/Resources/Textures.meta diff --git a/Assets/Unity-Bullet-Hell/Textures/CircleGradient.png b/Assets/Unity-Bullet-Hell/Resources/Textures/CircleGradient.png similarity index 100% rename from Assets/Unity-Bullet-Hell/Textures/CircleGradient.png rename to Assets/Unity-Bullet-Hell/Resources/Textures/CircleGradient.png diff --git a/Assets/Unity-Bullet-Hell/Textures/CircleGradient.png.meta b/Assets/Unity-Bullet-Hell/Resources/Textures/CircleGradient.png.meta similarity index 84% rename from Assets/Unity-Bullet-Hell/Textures/CircleGradient.png.meta rename to Assets/Unity-Bullet-Hell/Resources/Textures/CircleGradient.png.meta index 52cf8a3..5703652 100644 --- a/Assets/Unity-Bullet-Hell/Textures/CircleGradient.png.meta +++ b/Assets/Unity-Bullet-Hell/Resources/Textures/CircleGradient.png.meta @@ -1,9 +1,9 @@ fileFormatVersion: 2 guid: 140cc34eeb6c6f349979936397bda84c TextureImporter: - fileIDToRecycleName: {} + internalIDToNameTable: [] externalObjects: {} - serializedVersion: 9 + serializedVersion: 11 mipmaps: mipMapMode: 0 enableMipMap: 0 @@ -23,6 +23,7 @@ TextureImporter: isReadable: 0 streamingMipmaps: 0 streamingMipmapsPriority: 0 + vTOnly: 0 grayScaleToAlpha: 0 generateCubemap: 6 cubemapConvolution: 0 @@ -54,11 +55,15 @@ TextureImporter: textureType: 8 textureShape: 1 singleChannelComponent: 0 + flipbookRows: 1 + flipbookColumns: 1 maxTextureSizeSet: 0 compressionQualitySet: 0 textureFormatSet: 0 + ignorePngGamma: 0 + applyGammaDecoding: 1 platformSettings: - - serializedVersion: 2 + - serializedVersion: 3 buildTarget: DefaultTexturePlatform maxTextureSize: 2048 resizeAlgorithm: 0 @@ -69,7 +74,8 @@ TextureImporter: allowsAlphaSplitting: 0 overridden: 0 androidETC2FallbackOverride: 0 - - serializedVersion: 2 + forceMaximumCompressionQuality_BC6H_BC7: 1 + - serializedVersion: 3 buildTarget: Standalone maxTextureSize: 2048 resizeAlgorithm: 0 @@ -80,7 +86,8 @@ TextureImporter: allowsAlphaSplitting: 0 overridden: 0 androidETC2FallbackOverride: 0 - - serializedVersion: 2 + forceMaximumCompressionQuality_BC6H_BC7: 1 + - serializedVersion: 3 buildTarget: Android maxTextureSize: 2048 resizeAlgorithm: 0 @@ -91,7 +98,8 @@ TextureImporter: allowsAlphaSplitting: 0 overridden: 0 androidETC2FallbackOverride: 0 - - serializedVersion: 2 + forceMaximumCompressionQuality_BC6H_BC7: 1 + - serializedVersion: 3 buildTarget: WebGL maxTextureSize: 2048 resizeAlgorithm: 0 @@ -102,6 +110,7 @@ TextureImporter: allowsAlphaSplitting: 0 overridden: 0 androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 1 spriteSheet: serializedVersion: 2 sprites: [] @@ -109,10 +118,12 @@ TextureImporter: physicsShape: [] bones: [] spriteID: 931044182c18761419b5a3ac07e4fcc2 + internalID: 0 vertices: [] indices: edges: [] weights: [] + secondaryTextures: [] spritePackingTag: pSDRemoveMatte: 0 pSDShowRemoveMatteOption: 0 diff --git a/Assets/Unity-Bullet-Hell/Textures/Square.png b/Assets/Unity-Bullet-Hell/Resources/Textures/Square.png similarity index 100% rename from Assets/Unity-Bullet-Hell/Textures/Square.png rename to Assets/Unity-Bullet-Hell/Resources/Textures/Square.png diff --git a/Assets/Unity-Bullet-Hell/Textures/Square.png.meta b/Assets/Unity-Bullet-Hell/Resources/Textures/Square.png.meta similarity index 84% rename from Assets/Unity-Bullet-Hell/Textures/Square.png.meta rename to Assets/Unity-Bullet-Hell/Resources/Textures/Square.png.meta index 9c89649..ba49f21 100644 --- a/Assets/Unity-Bullet-Hell/Textures/Square.png.meta +++ b/Assets/Unity-Bullet-Hell/Resources/Textures/Square.png.meta @@ -1,9 +1,9 @@ fileFormatVersion: 2 guid: 761d163fd0dd7e2408531cd0639e2d73 TextureImporter: - fileIDToRecycleName: {} + internalIDToNameTable: [] externalObjects: {} - serializedVersion: 7 + serializedVersion: 11 mipmaps: mipMapMode: 0 enableMipMap: 0 @@ -23,6 +23,7 @@ TextureImporter: isReadable: 0 streamingMipmaps: 0 streamingMipmapsPriority: 0 + vTOnly: 0 grayScaleToAlpha: 0 generateCubemap: 6 cubemapConvolution: 0 @@ -54,11 +55,15 @@ TextureImporter: textureType: 8 textureShape: 1 singleChannelComponent: 0 + flipbookRows: 1 + flipbookColumns: 1 maxTextureSizeSet: 0 compressionQualitySet: 0 textureFormatSet: 0 + ignorePngGamma: 0 + applyGammaDecoding: 1 platformSettings: - - serializedVersion: 2 + - serializedVersion: 3 buildTarget: DefaultTexturePlatform maxTextureSize: 2048 resizeAlgorithm: 0 @@ -69,7 +74,8 @@ TextureImporter: allowsAlphaSplitting: 0 overridden: 0 androidETC2FallbackOverride: 0 - - serializedVersion: 2 + forceMaximumCompressionQuality_BC6H_BC7: 1 + - serializedVersion: 3 buildTarget: Standalone maxTextureSize: 2048 resizeAlgorithm: 0 @@ -80,7 +86,8 @@ TextureImporter: allowsAlphaSplitting: 0 overridden: 0 androidETC2FallbackOverride: 0 - - serializedVersion: 2 + forceMaximumCompressionQuality_BC6H_BC7: 1 + - serializedVersion: 3 buildTarget: Android maxTextureSize: 2048 resizeAlgorithm: 0 @@ -91,7 +98,8 @@ TextureImporter: allowsAlphaSplitting: 0 overridden: 0 androidETC2FallbackOverride: 0 - - serializedVersion: 2 + forceMaximumCompressionQuality_BC6H_BC7: 1 + - serializedVersion: 3 buildTarget: WebGL maxTextureSize: 2048 resizeAlgorithm: 0 @@ -102,6 +110,7 @@ TextureImporter: allowsAlphaSplitting: 0 overridden: 0 androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 1 spriteSheet: serializedVersion: 2 sprites: [] @@ -109,10 +118,12 @@ TextureImporter: physicsShape: [] bones: [] spriteID: de629e9bfea367c47b17805056864241 + internalID: 0 vertices: [] indices: edges: [] weights: [] + secondaryTextures: [] spritePackingTag: pSDRemoveMatte: 0 pSDShowRemoveMatteOption: 0 diff --git a/Assets/Unity-Bullet-Hell/Textures/circlewhite.png b/Assets/Unity-Bullet-Hell/Resources/Textures/circlewhite.png similarity index 100% rename from Assets/Unity-Bullet-Hell/Textures/circlewhite.png rename to Assets/Unity-Bullet-Hell/Resources/Textures/circlewhite.png diff --git a/Assets/Unity-Bullet-Hell/Textures/circlewhite.png.meta b/Assets/Unity-Bullet-Hell/Resources/Textures/circlewhite.png.meta similarity index 84% rename from Assets/Unity-Bullet-Hell/Textures/circlewhite.png.meta rename to Assets/Unity-Bullet-Hell/Resources/Textures/circlewhite.png.meta index 4a0a0d5..5f892dc 100644 --- a/Assets/Unity-Bullet-Hell/Textures/circlewhite.png.meta +++ b/Assets/Unity-Bullet-Hell/Resources/Textures/circlewhite.png.meta @@ -1,9 +1,9 @@ fileFormatVersion: 2 guid: 8066b9c66771543409ab3e52fc14bd57 TextureImporter: - fileIDToRecycleName: {} + internalIDToNameTable: [] externalObjects: {} - serializedVersion: 7 + serializedVersion: 11 mipmaps: mipMapMode: 0 enableMipMap: 0 @@ -23,6 +23,7 @@ TextureImporter: isReadable: 0 streamingMipmaps: 0 streamingMipmapsPriority: 0 + vTOnly: 0 grayScaleToAlpha: 0 generateCubemap: 6 cubemapConvolution: 0 @@ -54,11 +55,15 @@ TextureImporter: textureType: 8 textureShape: 1 singleChannelComponent: 0 + flipbookRows: 1 + flipbookColumns: 1 maxTextureSizeSet: 0 compressionQualitySet: 0 textureFormatSet: 0 + ignorePngGamma: 0 + applyGammaDecoding: 1 platformSettings: - - serializedVersion: 2 + - serializedVersion: 3 buildTarget: DefaultTexturePlatform maxTextureSize: 2048 resizeAlgorithm: 0 @@ -69,7 +74,8 @@ TextureImporter: allowsAlphaSplitting: 0 overridden: 0 androidETC2FallbackOverride: 0 - - serializedVersion: 2 + forceMaximumCompressionQuality_BC6H_BC7: 1 + - serializedVersion: 3 buildTarget: Standalone maxTextureSize: 2048 resizeAlgorithm: 0 @@ -80,7 +86,8 @@ TextureImporter: allowsAlphaSplitting: 0 overridden: 0 androidETC2FallbackOverride: 0 - - serializedVersion: 2 + forceMaximumCompressionQuality_BC6H_BC7: 1 + - serializedVersion: 3 buildTarget: Android maxTextureSize: 2048 resizeAlgorithm: 0 @@ -91,7 +98,8 @@ TextureImporter: allowsAlphaSplitting: 0 overridden: 0 androidETC2FallbackOverride: 0 - - serializedVersion: 2 + forceMaximumCompressionQuality_BC6H_BC7: 1 + - serializedVersion: 3 buildTarget: WebGL maxTextureSize: 2048 resizeAlgorithm: 0 @@ -102,6 +110,7 @@ TextureImporter: allowsAlphaSplitting: 0 overridden: 0 androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 1 spriteSheet: serializedVersion: 2 sprites: [] @@ -109,10 +118,12 @@ TextureImporter: physicsShape: [] bones: [] spriteID: 491341f662797054fa2d65aee14bf6c9 + internalID: 0 vertices: [] indices: edges: [] weights: [] + secondaryTextures: [] spritePackingTag: pSDRemoveMatte: 0 pSDShowRemoveMatteOption: 0 diff --git a/Assets/Unity-Bullet-Hell/Scripts/Core/Pool.cs b/Assets/Unity-Bullet-Hell/Scripts/Core/Pool.cs index da935dd..5ca0e14 100644 --- a/Assets/Unity-Bullet-Hell/Scripts/Core/Pool.cs +++ b/Assets/Unity-Bullet-Hell/Scripts/Core/Pool.cs @@ -11,8 +11,8 @@ public struct Node public bool Active; } - private Node[] Nodes; - private Queue Available; + protected Node[] Nodes; + protected Queue Available; public int ActiveNodes { @@ -44,7 +44,7 @@ public Pool(int capacity) } } - public void Clear() + public virtual void Clear() { Available.Clear(); for (int i = 0; i < Nodes.Length; i++) @@ -59,14 +59,14 @@ public Node GetActive(int index) return Nodes[index]; } - public Node Get() + public virtual Node Get() { int index = Available.Dequeue(); Nodes[index].Active = true; return Nodes[index]; } - public void Return(int index) + public virtual void Return(int index) { if (Nodes[index].Active) { diff --git a/Assets/Unity-Bullet-Hell/Scripts/Core/PoolFallback.cs b/Assets/Unity-Bullet-Hell/Scripts/Core/PoolFallback.cs new file mode 100644 index 0000000..4d21b10 --- /dev/null +++ b/Assets/Unity-Bullet-Hell/Scripts/Core/PoolFallback.cs @@ -0,0 +1,91 @@ +using UnityEngine; + +namespace BulletHell +{ + public class PoolFallback : Pool where T : ProjectileData, new() + { + /// + /// `GameObject` to put fallback `GameObject`s (as children) + /// + private static GameObject manager; + public static GameObject Manager + { + get + { + manager ??= new GameObject("ProjectileManagerFallback"); + return manager; + } + } + + private static Texture2D GetTexture2DFromTexture(Texture texture) + { + Texture2D texture2D = new Texture2D(texture.width, texture.height, TextureFormat.RGBA32, false); + RenderTexture currentRT = RenderTexture.active; + RenderTexture renderTexture = new RenderTexture(texture.width, texture.height, 32); + Graphics.Blit(texture, renderTexture); + RenderTexture.active = renderTexture; + texture2D.ReadPixels(new Rect(0, 0, renderTexture.width, renderTexture.height), 0, 0); + texture2D.Apply(); + RenderTexture.active = currentRT; + return texture2D; + } + + private static Sprite GetSpriteFromTexture2D(Texture2D texture) + { + var texture2d = GetTexture2DFromTexture(texture); + return Sprite.Create(texture2d, new Rect(0, 0, texture2d.width, texture2d.height), new Vector2(0.5f, 0.5f)); + } + + /// + /// The fallback projectile prefab to display + /// + private ProjectilePrefab prefab; + + public PoolFallback(int capacity, ProjectilePrefab prefab) : base(capacity) + { + // Make sure the `GameObject` instantiated later inactive at first, and not interfere with the original prefab + var active = prefab.gameObject.activeSelf; + prefab.gameObject.SetActive(false); + this.prefab = GameObject.Instantiate(prefab, Manager.transform); + prefab.gameObject.SetActive(active); + + InitSprite(); + } + + private void InitSprite() + { + var renderer = prefab.gameObject.AddComponent(); + if (renderer) // not attached to a `SpriteRenderer` + { + renderer.sprite = prefab.Texture + ? GetSpriteFromTexture2D(GetTexture2DFromTexture(prefab.Texture)) // use specified sprite + : Resources.Load("Textures/circlewhite"); // use default sprite + } + renderer.sortingOrder = Mathf.CeilToInt(prefab.ZIndez); // `ZIndez` is floating point so it won't be the same but still try to keep consistency + } + + public override void Clear() + { + for (int i = 0; i < Nodes.Length; i++) + { + if (Nodes[i].Item.FallBackObject) GameObject.Destroy(Nodes[i].Item.FallBackObject); + } + base.Clear(); + } + + public override Node Get() + { + var node = base.Get(); + node.Item.FallBackObject = GameObject.Instantiate(prefab.gameObject, Manager.transform); + return node; + } + + public override void Return(int index) + { + var fo = Nodes[index].Item.FallBackObject; + if (fo) GameObject.Destroy(fo); + Nodes[index].Item.FallBackObject = null; + base.Return(index); + } + } +} \ No newline at end of file diff --git a/Assets/Unity-Bullet-Hell/Scripts/Core/PoolFallback.cs.meta b/Assets/Unity-Bullet-Hell/Scripts/Core/PoolFallback.cs.meta new file mode 100644 index 0000000..f2ea9c3 --- /dev/null +++ b/Assets/Unity-Bullet-Hell/Scripts/Core/PoolFallback.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: c46f66ff7237b534483a868b73747a52 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Unity-Bullet-Hell/Scripts/Core/ProjectileData.cs b/Assets/Unity-Bullet-Hell/Scripts/Core/ProjectileData.cs index bfbed11..177d472 100644 --- a/Assets/Unity-Bullet-Hell/Scripts/Core/ProjectileData.cs +++ b/Assets/Unity-Bullet-Hell/Scripts/Core/ProjectileData.cs @@ -23,5 +23,10 @@ public class ProjectileData // Stores the pooled node that is used to draw the shadow for this projectile public Pool.Node Outline; + + /// + /// GameObject to render in fallback mode + /// + public GameObject FallBackObject; } } \ No newline at end of file diff --git a/Assets/Unity-Bullet-Hell/Scripts/Emitters/ProjectileEmitterBase.cs b/Assets/Unity-Bullet-Hell/Scripts/Emitters/ProjectileEmitterBase.cs index b0832f3..c77e00b 100644 --- a/Assets/Unity-Bullet-Hell/Scripts/Emitters/ProjectileEmitterBase.cs +++ b/Assets/Unity-Bullet-Hell/Scripts/Emitters/ProjectileEmitterBase.cs @@ -88,10 +88,21 @@ public void Awake() public void Initialize(int size) { - Projectiles = new Pool(size); - if (ProjectilePrefab.Outline != null) + if (!ProjectileManager.Instance.FallbackRendering) // not fallback so as usual { - ProjectileOutlines = new Pool(size); + Projectiles = new Pool(size); + if (ProjectilePrefab.Outline != null) + { + ProjectileOutlines = new Pool(size); + } + } + else // when fallback use hooked pool to store `GameObject`s for rendering + { + Projectiles = new PoolFallback(size, ProjectilePrefab); + if (ProjectilePrefab.Outline != null) + { + ProjectileOutlines = new PoolFallback(size, ProjectilePrefab.Outline); + } } ActiveProjectileIndexes = new int[size]; diff --git a/Assets/Unity-Bullet-Hell/Scripts/ProjectileManager.cs b/Assets/Unity-Bullet-Hell/Scripts/ProjectileManager.cs index aa16b9d..0901d3c 100644 --- a/Assets/Unity-Bullet-Hell/Scripts/ProjectileManager.cs +++ b/Assets/Unity-Bullet-Hell/Scripts/ProjectileManager.cs @@ -5,6 +5,15 @@ namespace BulletHell { public class ProjectileManager : MonoBehaviour { + /// + /// `true` to disable custom shaders for rendering. Mainly because projectiles won't show on WebGL build. + /// +#if UNITY_WEBGL + public readonly bool FallbackRendering = true; +#else + public readonly bool FallbackRendering = false; +#endif + private bool Initialized = false; // Lists out all the projectile types found in Assets @@ -236,14 +245,30 @@ public ProjectilePrefab GetProjectilePrefab(int index) public void UpdateBufferData(ProjectilePrefab projectileType, ProjectileData data) { - if (projectileType.Index != LastAccessedProjectileTypeIndex) + if (!data.FallBackObject) // not fallback so use custom shaders { - LastAccessedProjectileTypeIndex = projectileType.Index; - LastAccessedRenderer = IndirectRenderers[LastAccessedProjectileTypeIndex]; + if (projectileType.Index != LastAccessedProjectileTypeIndex) + { + LastAccessedProjectileTypeIndex = projectileType.Index; + LastAccessedRenderer = IndirectRenderers[LastAccessedProjectileTypeIndex]; + } + + LastAccessedRenderer.UpdateBufferData(projectileType.BufferIndex, data); + projectileType.IncrementBufferIndex(); } + else // when fallback use normal `GameObject` + { + var transform = data.FallBackObject.transform; + transform.position = data.Position; + transform.localScale = new Vector3(data.Scale, data.Scale); + transform.localEulerAngles = Vector3.forward * data.Rotation; + data.FallBackObject.SetActive(true); - LastAccessedRenderer.UpdateBufferData(projectileType.BufferIndex, data); - projectileType.IncrementBufferIndex(); + if (!projectileType.IsStaticColor) + { + data.FallBackObject.GetComponent().color = data.Color; + } + } } public void Update() @@ -303,6 +328,8 @@ public void UpdateEmitters() public void DrawEmitters() { + if (FallbackRendering) return; // don't draw when using fallback rendering + // We draw all emitters at the same time based on their Projectile Type. 1 draw call per projectile type. for (int n = 0; n < ProjectilePrefabs.Count; n++) { @@ -346,4 +373,4 @@ public class ProjectileTypeCounters public int TotalProjectilesAssigned; public int TotalGroups; } -} \ No newline at end of file +}