Working single-purpose object pooling solution
This commit is contained in:
@@ -15,7 +15,7 @@ MonoBehaviour:
|
|||||||
m_DefaultGroup: 6f3207429a65b3e4b83935ac19791077
|
m_DefaultGroup: 6f3207429a65b3e4b83935ac19791077
|
||||||
m_currentHash:
|
m_currentHash:
|
||||||
serializedVersion: 2
|
serializedVersion: 2
|
||||||
Hash: c0cf00979528ae95d3583c572e4eb343
|
Hash: 00000000000000000000000000000000
|
||||||
m_OptimizeCatalogSize: 0
|
m_OptimizeCatalogSize: 0
|
||||||
m_BuildRemoteCatalog: 0
|
m_BuildRemoteCatalog: 0
|
||||||
m_CatalogRequestsTimeout: 0
|
m_CatalogRequestsTimeout: 0
|
||||||
|
|||||||
3
Assets/Editor/Utilities.meta
Normal file
3
Assets/Editor/Utilities.meta
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 8b28cee1553b4a15aa1c3be950983fee
|
||||||
|
timeCreated: 1758016486
|
||||||
244
Assets/Editor/Utilities/PoolMonitorWindow.cs
Normal file
244
Assets/Editor/Utilities/PoolMonitorWindow.cs
Normal file
@@ -0,0 +1,244 @@
|
|||||||
|
using UnityEngine;
|
||||||
|
using UnityEditor;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using Minigames.DivingForPictures;
|
||||||
|
|
||||||
|
namespace Editor.Utilities
|
||||||
|
{
|
||||||
|
public class PoolMonitorWindow : EditorWindow
|
||||||
|
{
|
||||||
|
private Vector2 scrollPosition;
|
||||||
|
private bool autoRefresh = true;
|
||||||
|
private float refreshInterval = 1.0f;
|
||||||
|
private float lastRefreshTime;
|
||||||
|
private bool showTrenchTiles = true;
|
||||||
|
private bool showBubbles = true;
|
||||||
|
|
||||||
|
[MenuItem("Tools/Pool Monitor")]
|
||||||
|
public static void ShowWindow()
|
||||||
|
{
|
||||||
|
GetWindow<PoolMonitorWindow>("Pool Monitor");
|
||||||
|
}
|
||||||
|
|
||||||
|
void OnGUI()
|
||||||
|
{
|
||||||
|
EditorGUILayout.BeginVertical();
|
||||||
|
|
||||||
|
EditorGUILayout.LabelField("Object Pool Monitor", EditorStyles.boldLabel);
|
||||||
|
|
||||||
|
EditorGUILayout.BeginHorizontal();
|
||||||
|
autoRefresh = EditorGUILayout.Toggle("Auto Refresh", autoRefresh);
|
||||||
|
if (autoRefresh)
|
||||||
|
{
|
||||||
|
refreshInterval = EditorGUILayout.Slider("Refresh Interval", refreshInterval, 0.1f, 5f);
|
||||||
|
}
|
||||||
|
if (GUILayout.Button("Refresh Now"))
|
||||||
|
{
|
||||||
|
RefreshPoolInfo();
|
||||||
|
}
|
||||||
|
EditorGUILayout.EndHorizontal();
|
||||||
|
|
||||||
|
EditorGUILayout.Space();
|
||||||
|
|
||||||
|
// Display toggles for showing different pool types
|
||||||
|
EditorGUILayout.BeginHorizontal();
|
||||||
|
showTrenchTiles = EditorGUILayout.ToggleLeft("Show Trench Tile Pools", showTrenchTiles, GUILayout.Width(200));
|
||||||
|
showBubbles = EditorGUILayout.ToggleLeft("Show Bubble Pools", showBubbles, GUILayout.Width(200));
|
||||||
|
EditorGUILayout.EndHorizontal();
|
||||||
|
|
||||||
|
EditorGUILayout.Space();
|
||||||
|
|
||||||
|
scrollPosition = EditorGUILayout.BeginScrollView(scrollPosition);
|
||||||
|
|
||||||
|
if (Application.isPlaying)
|
||||||
|
{
|
||||||
|
DisplayPoolInfo();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
EditorGUILayout.HelpBox("Enter play mode to see pool statistics.", MessageType.Info);
|
||||||
|
}
|
||||||
|
|
||||||
|
EditorGUILayout.EndScrollView();
|
||||||
|
EditorGUILayout.EndVertical();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Update()
|
||||||
|
{
|
||||||
|
if (autoRefresh && Application.isPlaying)
|
||||||
|
{
|
||||||
|
float currentTime = (float)EditorApplication.timeSinceStartup;
|
||||||
|
if (currentTime - lastRefreshTime > refreshInterval)
|
||||||
|
{
|
||||||
|
lastRefreshTime = currentTime;
|
||||||
|
RefreshPoolInfo();
|
||||||
|
Repaint();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void RefreshPoolInfo()
|
||||||
|
{
|
||||||
|
if (!Application.isPlaying) return;
|
||||||
|
|
||||||
|
// Call LogPoolStats on all pool instances to update their stats in the console
|
||||||
|
if (showTrenchTiles)
|
||||||
|
{
|
||||||
|
TrenchTilePool[] tilePools = Object.FindObjectsByType<TrenchTilePool>(FindObjectsSortMode.None);
|
||||||
|
foreach (var pool in tilePools)
|
||||||
|
{
|
||||||
|
pool.LogPoolStats();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (showBubbles)
|
||||||
|
{
|
||||||
|
BubblePool[] bubblePools = Object.FindObjectsByType<BubblePool>(FindObjectsSortMode.None);
|
||||||
|
foreach (var pool in bubblePools)
|
||||||
|
{
|
||||||
|
if (pool != null && pool.gameObject.activeInHierarchy)
|
||||||
|
{
|
||||||
|
// If BubblePool has a LogPoolStats method, call it
|
||||||
|
var logMethod = typeof(BubblePool).GetMethod("LogPoolStats");
|
||||||
|
if (logMethod != null)
|
||||||
|
{
|
||||||
|
logMethod.Invoke(pool, null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void DisplayPoolInfo()
|
||||||
|
{
|
||||||
|
EditorGUILayout.LabelField("Scene Statistics:", EditorStyles.boldLabel);
|
||||||
|
EditorGUILayout.LabelField($"Total GameObjects: {Object.FindObjectsByType<GameObject>(FindObjectsSortMode.None).Length}");
|
||||||
|
|
||||||
|
EditorGUILayout.Space();
|
||||||
|
|
||||||
|
if (showTrenchTiles)
|
||||||
|
{
|
||||||
|
DisplayTrenchTilePoolInfo();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (showBubbles)
|
||||||
|
{
|
||||||
|
DisplayBubblePoolInfo();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void DisplayTrenchTilePoolInfo()
|
||||||
|
{
|
||||||
|
TrenchTilePool[] pools = Object.FindObjectsByType<TrenchTilePool>(FindObjectsSortMode.None);
|
||||||
|
if (pools.Length == 0)
|
||||||
|
{
|
||||||
|
EditorGUILayout.HelpBox("No trench tile pools found in the scene.", MessageType.Info);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
EditorGUILayout.LabelField("Trench Tile Pools", EditorStyles.boldLabel);
|
||||||
|
foreach (var pool in pools)
|
||||||
|
{
|
||||||
|
EditorGUILayout.LabelField($"Pool: {pool.name}", EditorStyles.boldLabel);
|
||||||
|
EditorGUI.indentLevel++;
|
||||||
|
|
||||||
|
// Get private field values using reflection
|
||||||
|
System.Reflection.FieldInfo totalCountField = typeof(TrenchTilePool).GetField("totalPooledCount",
|
||||||
|
System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
|
||||||
|
|
||||||
|
System.Reflection.FieldInfo pooledTilesField = typeof(TrenchTilePool).GetField("pooledTiles",
|
||||||
|
System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
|
||||||
|
|
||||||
|
System.Reflection.FieldInfo prefabUsageField = typeof(TrenchTilePool).GetField("prefabUsageCount",
|
||||||
|
System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
|
||||||
|
|
||||||
|
if (totalCountField != null)
|
||||||
|
{
|
||||||
|
int totalCount = (int)totalCountField.GetValue(pool);
|
||||||
|
EditorGUILayout.LabelField($"Total Pooled Objects: {totalCount}/{pool.totalMaxPoolSize}");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pooledTilesField != null && prefabUsageField != null)
|
||||||
|
{
|
||||||
|
var pooledTiles = pooledTilesField.GetValue(pool) as Dictionary<int, Stack<GameObject>>;
|
||||||
|
var usageCounts = prefabUsageField.GetValue(pool) as Dictionary<int, int>;
|
||||||
|
|
||||||
|
if (pooledTiles != null)
|
||||||
|
{
|
||||||
|
EditorGUILayout.LabelField("Prefab Details:", EditorStyles.boldLabel);
|
||||||
|
EditorGUI.indentLevel++;
|
||||||
|
|
||||||
|
foreach (var entry in pooledTiles)
|
||||||
|
{
|
||||||
|
int prefabIndex = entry.Key;
|
||||||
|
Stack<GameObject> stack = entry.Value;
|
||||||
|
int count = stack != null ? stack.Count : 0;
|
||||||
|
|
||||||
|
int usageCount = 0;
|
||||||
|
if (usageCounts != null && usageCounts.TryGetValue(prefabIndex, out int usage))
|
||||||
|
{
|
||||||
|
usageCount = usage;
|
||||||
|
}
|
||||||
|
|
||||||
|
EditorGUILayout.LabelField($"Prefab {prefabIndex}: {count} pooled, {usageCount} usages");
|
||||||
|
}
|
||||||
|
|
||||||
|
EditorGUI.indentLevel--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
EditorGUI.indentLevel--;
|
||||||
|
EditorGUILayout.Space();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void DisplayBubblePoolInfo()
|
||||||
|
{
|
||||||
|
BubblePool[] pools = Object.FindObjectsByType<BubblePool>(FindObjectsSortMode.None);
|
||||||
|
if (pools.Length == 0)
|
||||||
|
{
|
||||||
|
EditorGUILayout.HelpBox("No bubble pools found in the scene.", MessageType.Info);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
EditorGUILayout.LabelField("Bubble Pools", EditorStyles.boldLabel);
|
||||||
|
foreach (var pool in pools)
|
||||||
|
{
|
||||||
|
EditorGUILayout.LabelField($"Pool: {pool.name}", EditorStyles.boldLabel);
|
||||||
|
EditorGUI.indentLevel++;
|
||||||
|
|
||||||
|
// Get private field values using reflection
|
||||||
|
System.Reflection.FieldInfo pooledBubblesField = typeof(BubblePool).GetField("pooledBubbles",
|
||||||
|
System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
|
||||||
|
|
||||||
|
if (pooledBubblesField != null)
|
||||||
|
{
|
||||||
|
var pooledBubbles = pooledBubblesField.GetValue(pool) as Stack<Bubble>;
|
||||||
|
int count = pooledBubbles != null ? pooledBubbles.Count : 0;
|
||||||
|
|
||||||
|
EditorGUILayout.LabelField($"Pooled Bubbles: {count}/{pool.maxPoolSize}");
|
||||||
|
EditorGUILayout.LabelField($"Initial Pool Size: {pool.initialPoolSize}");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Try to find active bubbles in the scene
|
||||||
|
Bubble[] activeBubbles = Object.FindObjectsByType<Bubble>(FindObjectsSortMode.None);
|
||||||
|
int activeBubbleCount = 0;
|
||||||
|
|
||||||
|
foreach (var bubble in activeBubbles)
|
||||||
|
{
|
||||||
|
if (bubble.gameObject.activeInHierarchy)
|
||||||
|
{
|
||||||
|
activeBubbleCount++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
EditorGUILayout.LabelField($"Active Bubbles: {activeBubbleCount}");
|
||||||
|
|
||||||
|
EditorGUI.indentLevel--;
|
||||||
|
EditorGUILayout.Space();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
3
Assets/Editor/Utilities/PoolMonitorWindow.cs.meta
Normal file
3
Assets/Editor/Utilities/PoolMonitorWindow.cs.meta
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 17d6e42e7ca549b8b209f0714c8d106b
|
||||||
|
timeCreated: 1758016486
|
||||||
@@ -73,8 +73,8 @@ SpriteRenderer:
|
|||||||
m_AutoUVMaxDistance: 0.5
|
m_AutoUVMaxDistance: 0.5
|
||||||
m_AutoUVMaxAngle: 89
|
m_AutoUVMaxAngle: 89
|
||||||
m_LightmapParameters: {fileID: 0}
|
m_LightmapParameters: {fileID: 0}
|
||||||
m_SortingLayerID: 0
|
m_SortingLayerID: 622133659
|
||||||
m_SortingLayer: 0
|
m_SortingLayer: -1
|
||||||
m_SortingOrder: 0
|
m_SortingOrder: 0
|
||||||
m_Sprite: {fileID: 8944853044452083345, guid: 4ad95f797558b28478685ca60bd90ff4, type: 3}
|
m_Sprite: {fileID: 8944853044452083345, guid: 4ad95f797558b28478685ca60bd90ff4, type: 3}
|
||||||
m_Color: {r: 1, g: 1, b: 1, a: 1}
|
m_Color: {r: 1, g: 1, b: 1, a: 1}
|
||||||
@@ -134,4 +134,3 @@ MonoBehaviour:
|
|||||||
m_EditorClassIdentifier:
|
m_EditorClassIdentifier:
|
||||||
speed: 1
|
speed: 1
|
||||||
wobbleSpeed: 1
|
wobbleSpeed: 1
|
||||||
wobbleAmount: 0.1
|
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ Transform:
|
|||||||
m_GameObject: {fileID: 864595161669782950}
|
m_GameObject: {fileID: 864595161669782950}
|
||||||
serializedVersion: 2
|
serializedVersion: 2
|
||||||
m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
|
m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
|
||||||
m_LocalPosition: {x: -2.77, y: 0, z: 0}
|
m_LocalPosition: {x: -3.1, y: 0, z: 0}
|
||||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||||
m_ConstrainProportionsScale: 0
|
m_ConstrainProportionsScale: 0
|
||||||
m_Children: []
|
m_Children: []
|
||||||
@@ -73,8 +73,8 @@ SpriteRenderer:
|
|||||||
m_AutoUVMaxDistance: 0.5
|
m_AutoUVMaxDistance: 0.5
|
||||||
m_AutoUVMaxAngle: 89
|
m_AutoUVMaxAngle: 89
|
||||||
m_LightmapParameters: {fileID: 0}
|
m_LightmapParameters: {fileID: 0}
|
||||||
m_SortingLayerID: 0
|
m_SortingLayerID: -1132846201
|
||||||
m_SortingLayer: 0
|
m_SortingLayer: 1
|
||||||
m_SortingOrder: 0
|
m_SortingOrder: 0
|
||||||
m_Sprite: {fileID: 7559449286846427561, guid: e3d18475ab86b1246912f497417465f8, type: 3}
|
m_Sprite: {fileID: 7559449286846427561, guid: e3d18475ab86b1246912f497417465f8, type: 3}
|
||||||
m_Color: {r: 1, g: 1, b: 1, a: 1}
|
m_Color: {r: 1, g: 1, b: 1, a: 1}
|
||||||
@@ -113,7 +113,7 @@ Transform:
|
|||||||
m_GameObject: {fileID: 2171518497100337372}
|
m_GameObject: {fileID: 2171518497100337372}
|
||||||
serializedVersion: 2
|
serializedVersion: 2
|
||||||
m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
|
m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
|
||||||
m_LocalPosition: {x: 2.95, y: 0, z: 0}
|
m_LocalPosition: {x: 3.1, y: 0, z: 0}
|
||||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||||
m_ConstrainProportionsScale: 0
|
m_ConstrainProportionsScale: 0
|
||||||
m_Children: []
|
m_Children: []
|
||||||
@@ -160,8 +160,8 @@ SpriteRenderer:
|
|||||||
m_AutoUVMaxDistance: 0.5
|
m_AutoUVMaxDistance: 0.5
|
||||||
m_AutoUVMaxAngle: 89
|
m_AutoUVMaxAngle: 89
|
||||||
m_LightmapParameters: {fileID: 0}
|
m_LightmapParameters: {fileID: 0}
|
||||||
m_SortingLayerID: 0
|
m_SortingLayerID: -1132846201
|
||||||
m_SortingLayer: 0
|
m_SortingLayer: 1
|
||||||
m_SortingOrder: 0
|
m_SortingOrder: 0
|
||||||
m_Sprite: {fileID: 3241551651087908563, guid: 8e7c95ebe5325df4395d97ea2ace65d7, type: 3}
|
m_Sprite: {fileID: 3241551651087908563, guid: 8e7c95ebe5325df4395d97ea2ace65d7, type: 3}
|
||||||
m_Color: {r: 1, g: 1, b: 1, a: 1}
|
m_Color: {r: 1, g: 1, b: 1, a: 1}
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ Transform:
|
|||||||
m_GameObject: {fileID: 864595161669782950}
|
m_GameObject: {fileID: 864595161669782950}
|
||||||
serializedVersion: 2
|
serializedVersion: 2
|
||||||
m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
|
m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
|
||||||
m_LocalPosition: {x: -3.093, y: 0, z: 0}
|
m_LocalPosition: {x: -3.1, y: 0, z: 0}
|
||||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||||
m_ConstrainProportionsScale: 0
|
m_ConstrainProportionsScale: 0
|
||||||
m_Children: []
|
m_Children: []
|
||||||
@@ -73,8 +73,8 @@ SpriteRenderer:
|
|||||||
m_AutoUVMaxDistance: 0.5
|
m_AutoUVMaxDistance: 0.5
|
||||||
m_AutoUVMaxAngle: 89
|
m_AutoUVMaxAngle: 89
|
||||||
m_LightmapParameters: {fileID: 0}
|
m_LightmapParameters: {fileID: 0}
|
||||||
m_SortingLayerID: 0
|
m_SortingLayerID: -1132846201
|
||||||
m_SortingLayer: 0
|
m_SortingLayer: 1
|
||||||
m_SortingOrder: 0
|
m_SortingOrder: 0
|
||||||
m_Sprite: {fileID: 7559449286846427561, guid: e3d18475ab86b1246912f497417465f8, type: 3}
|
m_Sprite: {fileID: 7559449286846427561, guid: e3d18475ab86b1246912f497417465f8, type: 3}
|
||||||
m_Color: {r: 1, g: 1, b: 1, a: 1}
|
m_Color: {r: 1, g: 1, b: 1, a: 1}
|
||||||
@@ -113,7 +113,7 @@ Transform:
|
|||||||
m_GameObject: {fileID: 2171518497100337372}
|
m_GameObject: {fileID: 2171518497100337372}
|
||||||
serializedVersion: 2
|
serializedVersion: 2
|
||||||
m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
|
m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
|
||||||
m_LocalPosition: {x: 2.627, y: 0, z: 0}
|
m_LocalPosition: {x: 3.1, y: 0, z: 0}
|
||||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||||
m_ConstrainProportionsScale: 0
|
m_ConstrainProportionsScale: 0
|
||||||
m_Children: []
|
m_Children: []
|
||||||
@@ -160,8 +160,8 @@ SpriteRenderer:
|
|||||||
m_AutoUVMaxDistance: 0.5
|
m_AutoUVMaxDistance: 0.5
|
||||||
m_AutoUVMaxAngle: 89
|
m_AutoUVMaxAngle: 89
|
||||||
m_LightmapParameters: {fileID: 0}
|
m_LightmapParameters: {fileID: 0}
|
||||||
m_SortingLayerID: 0
|
m_SortingLayerID: -1132846201
|
||||||
m_SortingLayer: 0
|
m_SortingLayer: 1
|
||||||
m_SortingOrder: 0
|
m_SortingOrder: 0
|
||||||
m_Sprite: {fileID: 3241551651087908563, guid: 8e7c95ebe5325df4395d97ea2ace65d7, type: 3}
|
m_Sprite: {fileID: 3241551651087908563, guid: 8e7c95ebe5325df4395d97ea2ace65d7, type: 3}
|
||||||
m_Color: {r: 1, g: 1, b: 1, a: 1}
|
m_Color: {r: 1, g: 1, b: 1, a: 1}
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ Transform:
|
|||||||
m_GameObject: {fileID: 864595161669782950}
|
m_GameObject: {fileID: 864595161669782950}
|
||||||
serializedVersion: 2
|
serializedVersion: 2
|
||||||
m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
|
m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
|
||||||
m_LocalPosition: {x: -2.64, y: 0, z: 0}
|
m_LocalPosition: {x: -3.1, y: 0, z: 0}
|
||||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||||
m_ConstrainProportionsScale: 0
|
m_ConstrainProportionsScale: 0
|
||||||
m_Children: []
|
m_Children: []
|
||||||
@@ -73,8 +73,8 @@ SpriteRenderer:
|
|||||||
m_AutoUVMaxDistance: 0.5
|
m_AutoUVMaxDistance: 0.5
|
||||||
m_AutoUVMaxAngle: 89
|
m_AutoUVMaxAngle: 89
|
||||||
m_LightmapParameters: {fileID: 0}
|
m_LightmapParameters: {fileID: 0}
|
||||||
m_SortingLayerID: 0
|
m_SortingLayerID: -1132846201
|
||||||
m_SortingLayer: 0
|
m_SortingLayer: 1
|
||||||
m_SortingOrder: 0
|
m_SortingOrder: 0
|
||||||
m_Sprite: {fileID: 2249565037559538771, guid: 836c1ae2997af4045b714ceaff665a6e, type: 3}
|
m_Sprite: {fileID: 2249565037559538771, guid: 836c1ae2997af4045b714ceaff665a6e, type: 3}
|
||||||
m_Color: {r: 1, g: 1, b: 1, a: 1}
|
m_Color: {r: 1, g: 1, b: 1, a: 1}
|
||||||
@@ -113,7 +113,7 @@ Transform:
|
|||||||
m_GameObject: {fileID: 2171518497100337372}
|
m_GameObject: {fileID: 2171518497100337372}
|
||||||
serializedVersion: 2
|
serializedVersion: 2
|
||||||
m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
|
m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
|
||||||
m_LocalPosition: {x: 3.08, y: 0, z: 0}
|
m_LocalPosition: {x: 3.1, y: 0, z: 0}
|
||||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||||
m_ConstrainProportionsScale: 0
|
m_ConstrainProportionsScale: 0
|
||||||
m_Children: []
|
m_Children: []
|
||||||
@@ -160,8 +160,8 @@ SpriteRenderer:
|
|||||||
m_AutoUVMaxDistance: 0.5
|
m_AutoUVMaxDistance: 0.5
|
||||||
m_AutoUVMaxAngle: 89
|
m_AutoUVMaxAngle: 89
|
||||||
m_LightmapParameters: {fileID: 0}
|
m_LightmapParameters: {fileID: 0}
|
||||||
m_SortingLayerID: 0
|
m_SortingLayerID: -1132846201
|
||||||
m_SortingLayer: 0
|
m_SortingLayer: 1
|
||||||
m_SortingOrder: 0
|
m_SortingOrder: 0
|
||||||
m_Sprite: {fileID: 2764166773722941650, guid: f7ec8080b46b20f459d02e73b12f1694, type: 3}
|
m_Sprite: {fileID: 2764166773722941650, guid: f7ec8080b46b20f459d02e73b12f1694, type: 3}
|
||||||
m_Color: {r: 1, g: 1, b: 1, a: 1}
|
m_Color: {r: 1, g: 1, b: 1, a: 1}
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ Transform:
|
|||||||
m_GameObject: {fileID: 864595161669782950}
|
m_GameObject: {fileID: 864595161669782950}
|
||||||
serializedVersion: 2
|
serializedVersion: 2
|
||||||
m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
|
m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
|
||||||
m_LocalPosition: {x: -2.95, y: 0, z: 0}
|
m_LocalPosition: {x: -3.1, y: 0, z: 0}
|
||||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||||
m_ConstrainProportionsScale: 0
|
m_ConstrainProportionsScale: 0
|
||||||
m_Children: []
|
m_Children: []
|
||||||
@@ -73,8 +73,8 @@ SpriteRenderer:
|
|||||||
m_AutoUVMaxDistance: 0.5
|
m_AutoUVMaxDistance: 0.5
|
||||||
m_AutoUVMaxAngle: 89
|
m_AutoUVMaxAngle: 89
|
||||||
m_LightmapParameters: {fileID: 0}
|
m_LightmapParameters: {fileID: 0}
|
||||||
m_SortingLayerID: 0
|
m_SortingLayerID: -1132846201
|
||||||
m_SortingLayer: 0
|
m_SortingLayer: 1
|
||||||
m_SortingOrder: 0
|
m_SortingOrder: 0
|
||||||
m_Sprite: {fileID: 2249565037559538771, guid: 836c1ae2997af4045b714ceaff665a6e, type: 3}
|
m_Sprite: {fileID: 2249565037559538771, guid: 836c1ae2997af4045b714ceaff665a6e, type: 3}
|
||||||
m_Color: {r: 1, g: 1, b: 1, a: 1}
|
m_Color: {r: 1, g: 1, b: 1, a: 1}
|
||||||
@@ -113,7 +113,7 @@ Transform:
|
|||||||
m_GameObject: {fileID: 2171518497100337372}
|
m_GameObject: {fileID: 2171518497100337372}
|
||||||
serializedVersion: 2
|
serializedVersion: 2
|
||||||
m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
|
m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
|
||||||
m_LocalPosition: {x: 2.77, y: 0, z: 0}
|
m_LocalPosition: {x: 3.1, y: 0, z: 0}
|
||||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||||
m_ConstrainProportionsScale: 0
|
m_ConstrainProportionsScale: 0
|
||||||
m_Children: []
|
m_Children: []
|
||||||
@@ -160,8 +160,8 @@ SpriteRenderer:
|
|||||||
m_AutoUVMaxDistance: 0.5
|
m_AutoUVMaxDistance: 0.5
|
||||||
m_AutoUVMaxAngle: 89
|
m_AutoUVMaxAngle: 89
|
||||||
m_LightmapParameters: {fileID: 0}
|
m_LightmapParameters: {fileID: 0}
|
||||||
m_SortingLayerID: 0
|
m_SortingLayerID: -1132846201
|
||||||
m_SortingLayer: 0
|
m_SortingLayer: 1
|
||||||
m_SortingOrder: 0
|
m_SortingOrder: 0
|
||||||
m_Sprite: {fileID: 2764166773722941650, guid: f7ec8080b46b20f459d02e73b12f1694, type: 3}
|
m_Sprite: {fileID: 2764166773722941650, guid: f7ec8080b46b20f459d02e73b12f1694, type: 3}
|
||||||
m_Color: {r: 1, g: 1, b: 1, a: 1}
|
m_Color: {r: 1, g: 1, b: 1, a: 1}
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ Transform:
|
|||||||
m_GameObject: {fileID: 864595161669782950}
|
m_GameObject: {fileID: 864595161669782950}
|
||||||
serializedVersion: 2
|
serializedVersion: 2
|
||||||
m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
|
m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
|
||||||
m_LocalPosition: {x: -2.62, y: 0, z: 0}
|
m_LocalPosition: {x: -3.1, y: 0, z: 0}
|
||||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||||
m_ConstrainProportionsScale: 0
|
m_ConstrainProportionsScale: 0
|
||||||
m_Children: []
|
m_Children: []
|
||||||
@@ -73,8 +73,8 @@ SpriteRenderer:
|
|||||||
m_AutoUVMaxDistance: 0.5
|
m_AutoUVMaxDistance: 0.5
|
||||||
m_AutoUVMaxAngle: 89
|
m_AutoUVMaxAngle: 89
|
||||||
m_LightmapParameters: {fileID: 0}
|
m_LightmapParameters: {fileID: 0}
|
||||||
m_SortingLayerID: 0
|
m_SortingLayerID: -1132846201
|
||||||
m_SortingLayer: 0
|
m_SortingLayer: 1
|
||||||
m_SortingOrder: 0
|
m_SortingOrder: 0
|
||||||
m_Sprite: {fileID: 2249565037559538771, guid: 836c1ae2997af4045b714ceaff665a6e, type: 3}
|
m_Sprite: {fileID: 2249565037559538771, guid: 836c1ae2997af4045b714ceaff665a6e, type: 3}
|
||||||
m_Color: {r: 1, g: 1, b: 1, a: 1}
|
m_Color: {r: 1, g: 1, b: 1, a: 1}
|
||||||
@@ -113,7 +113,7 @@ Transform:
|
|||||||
m_GameObject: {fileID: 2171518497100337372}
|
m_GameObject: {fileID: 2171518497100337372}
|
||||||
serializedVersion: 2
|
serializedVersion: 2
|
||||||
m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
|
m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
|
||||||
m_LocalPosition: {x: 2.95, y: 0, z: 0}
|
m_LocalPosition: {x: 3.1, y: 0, z: 0}
|
||||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||||
m_ConstrainProportionsScale: 0
|
m_ConstrainProportionsScale: 0
|
||||||
m_Children: []
|
m_Children: []
|
||||||
@@ -160,8 +160,8 @@ SpriteRenderer:
|
|||||||
m_AutoUVMaxDistance: 0.5
|
m_AutoUVMaxDistance: 0.5
|
||||||
m_AutoUVMaxAngle: 89
|
m_AutoUVMaxAngle: 89
|
||||||
m_LightmapParameters: {fileID: 0}
|
m_LightmapParameters: {fileID: 0}
|
||||||
m_SortingLayerID: 0
|
m_SortingLayerID: -1132846201
|
||||||
m_SortingLayer: 0
|
m_SortingLayer: 1
|
||||||
m_SortingOrder: 0
|
m_SortingOrder: 0
|
||||||
m_Sprite: {fileID: 3241551651087908563, guid: 8e7c95ebe5325df4395d97ea2ace65d7, type: 3}
|
m_Sprite: {fileID: 3241551651087908563, guid: 8e7c95ebe5325df4395d97ea2ace65d7, type: 3}
|
||||||
m_Color: {r: 1, g: 1, b: 1, a: 1}
|
m_Color: {r: 1, g: 1, b: 1, a: 1}
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ Transform:
|
|||||||
m_GameObject: {fileID: 864595161669782950}
|
m_GameObject: {fileID: 864595161669782950}
|
||||||
serializedVersion: 2
|
serializedVersion: 2
|
||||||
m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
|
m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
|
||||||
m_LocalPosition: {x: -2.95, y: 0, z: 0}
|
m_LocalPosition: {x: -3.1, y: 0, z: 0}
|
||||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||||
m_ConstrainProportionsScale: 0
|
m_ConstrainProportionsScale: 0
|
||||||
m_Children: []
|
m_Children: []
|
||||||
@@ -73,8 +73,8 @@ SpriteRenderer:
|
|||||||
m_AutoUVMaxDistance: 0.5
|
m_AutoUVMaxDistance: 0.5
|
||||||
m_AutoUVMaxAngle: 89
|
m_AutoUVMaxAngle: 89
|
||||||
m_LightmapParameters: {fileID: 0}
|
m_LightmapParameters: {fileID: 0}
|
||||||
m_SortingLayerID: 0
|
m_SortingLayerID: -1132846201
|
||||||
m_SortingLayer: 0
|
m_SortingLayer: 1
|
||||||
m_SortingOrder: 0
|
m_SortingOrder: 0
|
||||||
m_Sprite: {fileID: 2249565037559538771, guid: 836c1ae2997af4045b714ceaff665a6e, type: 3}
|
m_Sprite: {fileID: 2249565037559538771, guid: 836c1ae2997af4045b714ceaff665a6e, type: 3}
|
||||||
m_Color: {r: 1, g: 1, b: 1, a: 1}
|
m_Color: {r: 1, g: 1, b: 1, a: 1}
|
||||||
@@ -113,7 +113,7 @@ Transform:
|
|||||||
m_GameObject: {fileID: 2171518497100337372}
|
m_GameObject: {fileID: 2171518497100337372}
|
||||||
serializedVersion: 2
|
serializedVersion: 2
|
||||||
m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
|
m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
|
||||||
m_LocalPosition: {x: 2.62, y: 0, z: 0}
|
m_LocalPosition: {x: 3.1, y: 0, z: 0}
|
||||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||||
m_ConstrainProportionsScale: 0
|
m_ConstrainProportionsScale: 0
|
||||||
m_Children: []
|
m_Children: []
|
||||||
@@ -160,8 +160,8 @@ SpriteRenderer:
|
|||||||
m_AutoUVMaxDistance: 0.5
|
m_AutoUVMaxDistance: 0.5
|
||||||
m_AutoUVMaxAngle: 89
|
m_AutoUVMaxAngle: 89
|
||||||
m_LightmapParameters: {fileID: 0}
|
m_LightmapParameters: {fileID: 0}
|
||||||
m_SortingLayerID: 0
|
m_SortingLayerID: -1132846201
|
||||||
m_SortingLayer: 0
|
m_SortingLayer: 1
|
||||||
m_SortingOrder: 0
|
m_SortingOrder: 0
|
||||||
m_Sprite: {fileID: 3241551651087908563, guid: 8e7c95ebe5325df4395d97ea2ace65d7, type: 3}
|
m_Sprite: {fileID: 3241551651087908563, guid: 8e7c95ebe5325df4395d97ea2ace65d7, type: 3}
|
||||||
m_Color: {r: 1, g: 1, b: 1, a: 1}
|
m_Color: {r: 1, g: 1, b: 1, a: 1}
|
||||||
|
|||||||
@@ -170,7 +170,7 @@ MonoBehaviour:
|
|||||||
linePoints: 10
|
linePoints: 10
|
||||||
stiffness: 350
|
stiffness: 350
|
||||||
damping: 15
|
damping: 15
|
||||||
ropeLength: 4.19
|
ropeLength: 2
|
||||||
ropeWidth: 0.1
|
ropeWidth: 0.1
|
||||||
midPointWeight: 1
|
midPointWeight: 1
|
||||||
midPointPosition: 0.5
|
midPointPosition: 0.5
|
||||||
@@ -220,17 +220,17 @@ LineRenderer:
|
|||||||
m_SortingLayer: 0
|
m_SortingLayer: 0
|
||||||
m_SortingOrder: 0
|
m_SortingOrder: 0
|
||||||
m_Positions:
|
m_Positions:
|
||||||
- {x: 0, y: 2.07, z: 0}
|
- {x: 0, y: 4.1716814, z: 0}
|
||||||
- {x: -0.002, y: 1.5150144, z: 0}
|
- {x: -0.0011514801, y: 3.9187107, z: 0}
|
||||||
- {x: -0.004, y: 1.0280256, z: 0}
|
- {x: -0.00230296, y: 3.6922278, z: 0}
|
||||||
- {x: -0.006, y: 0.6090335, z: 0}
|
- {x: -0.0034544398, y: 3.4922323, z: 0}
|
||||||
- {x: -0.008, y: 0.25803846, z: 0}
|
- {x: -0.00460592, y: 3.3187256, z: 0}
|
||||||
- {x: -0.01, y: -0.024959907, z: 0}
|
- {x: -0.0057574, y: 3.1717062, z: 0}
|
||||||
- {x: -0.012, y: -0.23996155, z: 0}
|
- {x: -0.0069088796, y: 3.0511749, z: 0}
|
||||||
- {x: -0.013999999, y: -0.3869663, z: 0}
|
- {x: -0.008060359, y: 2.9571314, z: 0}
|
||||||
- {x: -0.016, y: -0.46597433, z: 0}
|
- {x: -0.00921184, y: 2.8895762, z: 0}
|
||||||
- {x: -0.018, y: -0.47698557, z: 0}
|
- {x: -0.010363319, y: 2.8485086, z: 0}
|
||||||
- {x: -0.02, y: -0.42000002, z: 0}
|
- {x: -0.0115148, y: 2.833929, z: 0}
|
||||||
m_Parameters:
|
m_Parameters:
|
||||||
serializedVersion: 3
|
serializedVersion: 3
|
||||||
widthMultiplier: 1
|
widthMultiplier: 1
|
||||||
@@ -488,8 +488,8 @@ Transform:
|
|||||||
m_GameObject: {fileID: 747976396}
|
m_GameObject: {fileID: 747976396}
|
||||||
serializedVersion: 2
|
serializedVersion: 2
|
||||||
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
||||||
m_LocalPosition: {x: 0, y: 0, z: 0}
|
m_LocalPosition: {x: 0, y: 2.9799, z: 0}
|
||||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
m_LocalScale: {x: 0.57574, y: 0.57574, z: 0.57574}
|
||||||
m_ConstrainProportionsScale: 0
|
m_ConstrainProportionsScale: 0
|
||||||
m_Children:
|
m_Children:
|
||||||
- {fileID: 730962733}
|
- {fileID: 730962733}
|
||||||
@@ -573,6 +573,9 @@ MonoBehaviour:
|
|||||||
spawnY: -6.78
|
spawnY: -6.78
|
||||||
wobbleMinScale: 0.5
|
wobbleMinScale: 0.5
|
||||||
wobbleMaxScale: 1.2
|
wobbleMaxScale: 1.2
|
||||||
|
useObjectPooling: 1
|
||||||
|
initialPoolSize: 10
|
||||||
|
maxPoolSize: 30
|
||||||
--- !u!4 &1003335105
|
--- !u!4 &1003335105
|
||||||
Transform:
|
Transform:
|
||||||
m_ObjectHideFlags: 0
|
m_ObjectHideFlags: 0
|
||||||
@@ -639,7 +642,7 @@ MonoBehaviour:
|
|||||||
linePoints: 10
|
linePoints: 10
|
||||||
stiffness: 350
|
stiffness: 350
|
||||||
damping: 15
|
damping: 15
|
||||||
ropeLength: 4.19
|
ropeLength: 2
|
||||||
ropeWidth: 0.1
|
ropeWidth: 0.1
|
||||||
midPointWeight: 1
|
midPointWeight: 1
|
||||||
midPointPosition: 0.5
|
midPointPosition: 0.5
|
||||||
@@ -689,17 +692,17 @@ LineRenderer:
|
|||||||
m_SortingLayer: 0
|
m_SortingLayer: 0
|
||||||
m_SortingOrder: 0
|
m_SortingOrder: 0
|
||||||
m_Positions:
|
m_Positions:
|
||||||
- {x: 0, y: 2.07, z: 0}
|
- {x: 0, y: 4.1716814, z: 0}
|
||||||
- {x: 0.06300001, y: 1.5291233, z: 0}
|
- {x: 0.036271624, y: 3.927396, z: 0}
|
||||||
- {x: 0.126, y: 1.053108, z: 0}
|
- {x: 0.07254324, y: 3.7076683, z: 0}
|
||||||
- {x: 0.18900001, y: 0.6419541, z: 0}
|
- {x: 0.10881486, y: 3.5124984, z: 0}
|
||||||
- {x: 0.25200003, y: 0.29566196, z: 0}
|
- {x: 0.14508648, y: 3.3418865, z: 0}
|
||||||
- {x: 0.315, y: 0.01423122, z: 0}
|
- {x: 0.1813581, y: 3.195832, z: 0}
|
||||||
- {x: 0.37800002, y: -0.20233808, z: 0}
|
- {x: 0.21762972, y: 3.0743358, z: 0}
|
||||||
- {x: 0.44099998, y: -0.35404575, z: 0}
|
- {x: 0.25390133, y: 2.9773972, z: 0}
|
||||||
- {x: 0.504, y: -0.44089204, z: 0}
|
- {x: 0.29017296, y: 2.905017, z: 0}
|
||||||
- {x: 0.567, y: -0.46287674, z: 0}
|
- {x: 0.32644457, y: 2.857194, z: 0}
|
||||||
- {x: 0.63, y: -0.42000002, z: 0}
|
- {x: 0.3627162, y: 2.833929, z: 0}
|
||||||
m_Parameters:
|
m_Parameters:
|
||||||
serializedVersion: 3
|
serializedVersion: 3
|
||||||
widthMultiplier: 1
|
widthMultiplier: 1
|
||||||
@@ -976,7 +979,7 @@ MonoBehaviour:
|
|||||||
linePoints: 10
|
linePoints: 10
|
||||||
stiffness: 350
|
stiffness: 350
|
||||||
damping: 15
|
damping: 15
|
||||||
ropeLength: 4.19
|
ropeLength: 2
|
||||||
ropeWidth: 0.1
|
ropeWidth: 0.1
|
||||||
midPointWeight: 1
|
midPointWeight: 1
|
||||||
midPointPosition: 0.5
|
midPointPosition: 0.5
|
||||||
@@ -1026,17 +1029,17 @@ LineRenderer:
|
|||||||
m_SortingLayer: 0
|
m_SortingLayer: 0
|
||||||
m_SortingOrder: 0
|
m_SortingOrder: 0
|
||||||
m_Positions:
|
m_Positions:
|
||||||
- {x: 0, y: 2.07, z: 0}
|
- {x: 0, y: 4.1716814, z: 0}
|
||||||
- {x: -0.058000002, y: 1.5269984, z: 0}
|
- {x: -0.03339292, y: 3.9260902, z: 0}
|
||||||
- {x: -0.116, y: 1.0493305, z: 0}
|
- {x: -0.066785835, y: 3.705347, z: 0}
|
||||||
- {x: -0.174, y: 0.63699615, z: 0}
|
- {x: -0.10017875, y: 3.5094519, z: 0}
|
||||||
- {x: -0.23200001, y: 0.28999573, z: 0}
|
- {x: -0.13357168, y: 3.3384047, z: 0}
|
||||||
- {x: -0.29, y: 0.00832893, z: 0}
|
- {x: -0.16696459, y: 3.1922054, z: 0}
|
||||||
- {x: -0.348, y: -0.20800425, z: 0}
|
- {x: -0.20035751, y: 3.0708542, z: 0}
|
||||||
- {x: -0.406, y: -0.35900372, z: 0}
|
- {x: -0.2337504, y: 2.9743507, z: 0}
|
||||||
- {x: -0.46400002, y: -0.44466949, z: 0}
|
- {x: -0.26714337, y: 2.9026957, z: 0}
|
||||||
- {x: -0.52199996, y: -0.46500158, z: 0}
|
- {x: -0.30053627, y: 2.8558884, z: 0}
|
||||||
- {x: -0.58, y: -0.42000002, z: 0}
|
- {x: -0.33392918, y: 2.833929, z: 0}
|
||||||
m_Parameters:
|
m_Parameters:
|
||||||
serializedVersion: 3
|
serializedVersion: 3
|
||||||
widthMultiplier: 1
|
widthMultiplier: 1
|
||||||
@@ -1204,8 +1207,14 @@ MonoBehaviour:
|
|||||||
initialTileCount: 3
|
initialTileCount: 3
|
||||||
tileSpawnBuffer: 1
|
tileSpawnBuffer: 1
|
||||||
moveSpeed: 3
|
moveSpeed: 3
|
||||||
speedUpFactor: 0.2
|
speedUpFactor: 0
|
||||||
speedUpInterval: 2
|
speedUpInterval: 0
|
||||||
|
maxMoveSpeed: 12
|
||||||
|
useObjectPooling: 1
|
||||||
|
preInstantiateTiles: 0
|
||||||
|
initialTilesPerPrefab: 1
|
||||||
|
maxPerPrefabPoolSize: 2
|
||||||
|
totalMaxPoolSize: 10
|
||||||
onTileSpawned:
|
onTileSpawned:
|
||||||
m_PersistentCalls:
|
m_PersistentCalls:
|
||||||
m_Calls: []
|
m_Calls: []
|
||||||
@@ -1388,8 +1397,8 @@ Transform:
|
|||||||
m_GameObject: {fileID: 2106431001}
|
m_GameObject: {fileID: 2106431001}
|
||||||
serializedVersion: 2
|
serializedVersion: 2
|
||||||
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
||||||
m_LocalPosition: {x: 0, y: -1, z: 0}
|
m_LocalPosition: {x: 0, y: 2.5, z: 0}
|
||||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
m_LocalScale: {x: 0.57574, y: 0.57574, z: 0.57574}
|
||||||
m_ConstrainProportionsScale: 0
|
m_ConstrainProportionsScale: 0
|
||||||
m_Children:
|
m_Children:
|
||||||
- {fileID: 1834056337}
|
- {fileID: 1834056337}
|
||||||
@@ -1417,7 +1426,7 @@ MonoBehaviour:
|
|||||||
bottleWobble: {fileID: 747976399}
|
bottleWobble: {fileID: 747976399}
|
||||||
followStiffness: 4
|
followStiffness: 4
|
||||||
useWobbleOffset: 1
|
useWobbleOffset: 1
|
||||||
baseY: -1
|
baseY: 2.5
|
||||||
--- !u!114 &2106431004
|
--- !u!114 &2106431004
|
||||||
MonoBehaviour:
|
MonoBehaviour:
|
||||||
m_ObjectHideFlags: 0
|
m_ObjectHideFlags: 0
|
||||||
|
|||||||
@@ -10,39 +10,83 @@ namespace Minigames.DivingForPictures
|
|||||||
public float speed = 1f;
|
public float speed = 1f;
|
||||||
public float wobbleSpeed = 1f;
|
public float wobbleSpeed = 1f;
|
||||||
private SpriteRenderer spriteRenderer;
|
private SpriteRenderer spriteRenderer;
|
||||||
private SpriteRenderer bottleSpriteRenderer;
|
private SpriteRenderer bubbleSpriteRenderer; // Renamed from bottleSpriteRenderer
|
||||||
private float timeOffset;
|
private float timeOffset;
|
||||||
private float minScale = 0.2f;
|
private float minScale = 0.2f;
|
||||||
private float maxScale = 1.2f;
|
private float maxScale = 1.2f;
|
||||||
|
private float baseScale = 1f; // Added to store the initial scale
|
||||||
|
|
||||||
|
private Camera mainCamera; // Cache camera reference
|
||||||
|
private BubblePool parentPool; // Reference to the pool this bubble came from
|
||||||
|
|
||||||
void Awake()
|
void Awake()
|
||||||
{
|
{
|
||||||
// Cache references and randomize time offset for wobble
|
// Cache references and randomize time offset for wobble
|
||||||
spriteRenderer = GetComponent<SpriteRenderer>();
|
spriteRenderer = GetComponent<SpriteRenderer>();
|
||||||
timeOffset = Random.value * 100f;
|
timeOffset = Random.value * 100f;
|
||||||
// Find the child named "BottleSprite" and get its SpriteRenderer
|
// Find the child named "BubbleSprite" and get its SpriteRenderer
|
||||||
Transform bottleSpriteTransform = transform.Find("BubbleSprite");
|
Transform bubbleSpriteTransform = transform.Find("BubbleSprite");
|
||||||
if (bottleSpriteTransform != null)
|
if (bubbleSpriteTransform != null)
|
||||||
{
|
{
|
||||||
bottleSpriteRenderer = bottleSpriteTransform.GetComponent<SpriteRenderer>();
|
bubbleSpriteRenderer = bubbleSpriteTransform.GetComponent<SpriteRenderer>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Cache camera reference
|
||||||
|
mainCamera = Camera.main;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Update()
|
void Update()
|
||||||
{
|
{
|
||||||
// Move bubble upward
|
// Move bubble upward
|
||||||
transform.position += Vector3.up * speed * Time.deltaTime;
|
transform.position += Vector3.up * (speed * Time.deltaTime);
|
||||||
|
|
||||||
// Wobble effect (smooth oscillation between min and max scale)
|
// Wobble effect (smooth oscillation between min and max scale)
|
||||||
float t = (Mathf.Sin((Time.time + timeOffset) * wobbleSpeed) + 1f) * 0.5f; // t in [0,1]
|
float t = (Mathf.Sin((Time.time + timeOffset) * wobbleSpeed) + 1f) * 0.5f; // t in [0,1]
|
||||||
float newScale = Mathf.Lerp(minScale, maxScale, t);
|
float wobbleFactor = Mathf.Lerp(minScale, maxScale, t);
|
||||||
transform.localScale = Vector3.one * newScale;
|
transform.localScale = Vector3.one * (baseScale * wobbleFactor);
|
||||||
// Destroy when off screen
|
|
||||||
if (transform.position.y > Camera.main.orthographicSize + 2f)
|
// Destroy when off screen - using cached camera reference
|
||||||
|
if (mainCamera != null && transform.position.y > mainCamera.orthographicSize + 2f)
|
||||||
{
|
{
|
||||||
Destroy(gameObject);
|
OnBubbleDestroy();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Called when bubble is about to be destroyed
|
||||||
|
/// </summary>
|
||||||
|
private void OnBubbleDestroy()
|
||||||
|
{
|
||||||
|
// Use the cached pool reference instead of finding it each time
|
||||||
|
if (parentPool != null)
|
||||||
|
{
|
||||||
|
parentPool.ReturnBubble(this);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Fallback to find the pool if the reference is somehow lost
|
||||||
|
BubblePool pool = FindFirstObjectByType<BubblePool>();
|
||||||
|
if (pool != null)
|
||||||
|
{
|
||||||
|
Debug.LogWarning("Bubble is missing its parent pool reference, finding pool as fallback");
|
||||||
|
pool.ReturnBubble(this);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Destroy(gameObject);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Sets the parent pool for this bubble
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="pool">The bubble pool that created this bubble</param>
|
||||||
|
public void SetPool(BubblePool pool)
|
||||||
|
{
|
||||||
|
parentPool = pool;
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Sets the main sprite for the bubble.
|
/// Sets the main sprite for the bubble.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -54,13 +98,22 @@ namespace Minigames.DivingForPictures
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Sets the sprite for the child "BottleSprite" renderer.
|
/// Sets the sprite for the child "BubbleSprite" renderer.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="sprite">Sprite to assign.</param>
|
/// <param name="sprite">Sprite to assign.</param>
|
||||||
public void SetBottleSprite(Sprite sprite)
|
public void SetBubbleSprite(Sprite sprite)
|
||||||
{
|
{
|
||||||
if (bottleSpriteRenderer != null)
|
if (bubbleSpriteRenderer != null)
|
||||||
bottleSpriteRenderer.sprite = sprite;
|
bubbleSpriteRenderer.sprite = sprite;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Sets the base scale for the bubble
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="scale">Base scale value</param>
|
||||||
|
public void SetBaseScale(float scale)
|
||||||
|
{
|
||||||
|
baseScale = scale;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -73,5 +126,13 @@ namespace Minigames.DivingForPictures
|
|||||||
minScale = min;
|
minScale = min;
|
||||||
maxScale = max;
|
maxScale = max;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Resets the bubble state for reuse from object pool
|
||||||
|
/// </summary>
|
||||||
|
public void ResetState()
|
||||||
|
{
|
||||||
|
timeOffset = Random.value * 100f;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
117
Assets/Scripts/Minigames/DivingForPictures/BubblePool.cs
Normal file
117
Assets/Scripts/Minigames/DivingForPictures/BubblePool.cs
Normal file
@@ -0,0 +1,117 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
namespace Minigames.DivingForPictures
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Manages a pool of bubble objects to reduce garbage collection overhead.
|
||||||
|
/// </summary>
|
||||||
|
public class BubblePool : MonoBehaviour
|
||||||
|
{
|
||||||
|
[Tooltip("Initial number of bubbles to pre-instantiate")]
|
||||||
|
public int initialPoolSize = 10;
|
||||||
|
|
||||||
|
[Tooltip("Maximum number of bubbles to keep in the pool")]
|
||||||
|
public int maxPoolSize = 30;
|
||||||
|
|
||||||
|
private Stack<Bubble> pooledBubbles = new Stack<Bubble>();
|
||||||
|
private Bubble bubblePrefab;
|
||||||
|
private int totalBubblesCreated = 0;
|
||||||
|
private int totalBubblesReturned = 0;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Initialize the pool with the bubble prefab
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="prefab">The bubble prefab to use</param>
|
||||||
|
public void Initialize(Bubble prefab)
|
||||||
|
{
|
||||||
|
bubblePrefab = prefab;
|
||||||
|
|
||||||
|
// Pre-instantiate bubbles
|
||||||
|
for (int i = 0; i < initialPoolSize; i++)
|
||||||
|
{
|
||||||
|
CreateNewBubble();
|
||||||
|
}
|
||||||
|
|
||||||
|
Debug.Log($"BubblePool initialized with {initialPoolSize} bubbles");
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Creates a new bubble instance and adds it to the pool
|
||||||
|
/// </summary>
|
||||||
|
private Bubble CreateNewBubble()
|
||||||
|
{
|
||||||
|
if (bubblePrefab == null)
|
||||||
|
{
|
||||||
|
Debug.LogError("BubblePool: bubblePrefab is null! Call Initialize first.");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
Bubble bubble = Instantiate(bubblePrefab, transform);
|
||||||
|
bubble.gameObject.SetActive(false);
|
||||||
|
// Set the pool reference so the bubble knows where to return
|
||||||
|
bubble.SetPool(this);
|
||||||
|
pooledBubbles.Push(bubble);
|
||||||
|
totalBubblesCreated++;
|
||||||
|
return bubble;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets a bubble from the pool, or creates a new one if the pool is empty
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>A bubble instance ready to use</returns>
|
||||||
|
public Bubble GetBubble()
|
||||||
|
{
|
||||||
|
Bubble bubble;
|
||||||
|
|
||||||
|
if (pooledBubbles.Count > 0)
|
||||||
|
{
|
||||||
|
bubble = pooledBubbles.Pop();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
bubble = CreateNewBubble();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ensure the bubble has a reference to this pool
|
||||||
|
bubble.SetPool(this);
|
||||||
|
bubble.gameObject.SetActive(true);
|
||||||
|
bubble.ResetState();
|
||||||
|
|
||||||
|
return bubble;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Returns a bubble to the pool
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="bubble">The bubble to return to the pool</param>
|
||||||
|
public void ReturnBubble(Bubble bubble)
|
||||||
|
{
|
||||||
|
if (bubble == null) return;
|
||||||
|
|
||||||
|
// Only add to pool if we're under the maximum size
|
||||||
|
if (pooledBubbles.Count < maxPoolSize)
|
||||||
|
{
|
||||||
|
// Deactivate and reparent
|
||||||
|
bubble.gameObject.SetActive(false);
|
||||||
|
bubble.transform.SetParent(transform);
|
||||||
|
|
||||||
|
// Add to pool
|
||||||
|
pooledBubbles.Push(bubble);
|
||||||
|
totalBubblesReturned++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Destroy(bubble.gameObject);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Logs pool statistics
|
||||||
|
/// </summary>
|
||||||
|
public void LogPoolStats()
|
||||||
|
{
|
||||||
|
Debug.Log($"[BubblePool] Pooled bubbles: {pooledBubbles.Count}/{maxPoolSize} (Created: {totalBubblesCreated}, Returned: {totalBubblesReturned})");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 45cdaed0c047423bbb0b7380cd3687f3
|
||||||
|
timeCreated: 1758015081
|
||||||
@@ -19,9 +19,32 @@ namespace Minigames.DivingForPictures
|
|||||||
public float spawnY = -5f;
|
public float spawnY = -5f;
|
||||||
public float wobbleMinScale = 0.2f;
|
public float wobbleMinScale = 0.2f;
|
||||||
public float wobbleMaxScale = 1.2f;
|
public float wobbleMaxScale = 1.2f;
|
||||||
|
|
||||||
|
[Header("Object Pooling")]
|
||||||
|
public bool useObjectPooling = true;
|
||||||
|
public int initialPoolSize = 10;
|
||||||
|
public int maxPoolSize = 30;
|
||||||
|
|
||||||
private float _timer;
|
private float _timer;
|
||||||
private float _nextSpawnInterval;
|
private float _nextSpawnInterval;
|
||||||
|
private BubblePool _bubblePool;
|
||||||
|
private Camera _mainCamera; // Cache camera reference
|
||||||
|
|
||||||
|
void Awake()
|
||||||
|
{
|
||||||
|
_mainCamera = Camera.main;
|
||||||
|
|
||||||
|
if (useObjectPooling)
|
||||||
|
{
|
||||||
|
// Create the bubble pool
|
||||||
|
GameObject poolGO = new GameObject("BubblePool");
|
||||||
|
poolGO.transform.SetParent(transform);
|
||||||
|
_bubblePool = poolGO.AddComponent<BubblePool>();
|
||||||
|
_bubblePool.initialPoolSize = initialPoolSize;
|
||||||
|
_bubblePool.maxPoolSize = maxPoolSize;
|
||||||
|
_bubblePool.Initialize(bubblePrefab);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void Start()
|
void Start()
|
||||||
{
|
{
|
||||||
@@ -56,21 +79,36 @@ namespace Minigames.DivingForPictures
|
|||||||
{
|
{
|
||||||
float x = Random.Range(spawnXMin, spawnXMax);
|
float x = Random.Range(spawnXMin, spawnXMax);
|
||||||
Vector3 spawnPos = new Vector3(x, spawnY, 0f);
|
Vector3 spawnPos = new Vector3(x, spawnY, 0f);
|
||||||
Bubble bubble = Instantiate(bubblePrefab, spawnPos, Quaternion.identity, transform);
|
|
||||||
|
Bubble bubble;
|
||||||
|
if (useObjectPooling && _bubblePool != null)
|
||||||
|
{
|
||||||
|
bubble = _bubblePool.GetBubble();
|
||||||
|
bubble.transform.position = spawnPos;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
bubble = Instantiate(bubblePrefab, spawnPos, Quaternion.identity, transform);
|
||||||
|
}
|
||||||
|
|
||||||
// Randomize bubble properties
|
// Randomize bubble properties
|
||||||
bubble.speed = Random.Range(speedRange.x, speedRange.y);
|
bubble.speed = Random.Range(speedRange.x, speedRange.y);
|
||||||
bubble.wobbleSpeed = Random.Range(wobbleSpeedRange.x, wobbleSpeedRange.y);
|
bubble.wobbleSpeed = Random.Range(wobbleSpeedRange.x, wobbleSpeedRange.y);
|
||||||
float scale = Random.Range(scaleRange.x, scaleRange.y);
|
|
||||||
bubble.transform.localScale = Vector3.one * scale;
|
// Set base scale (initial size) for the bubble
|
||||||
// Assign random sprite to BottleSprite
|
float baseScale = Random.Range(scaleRange.x, scaleRange.y);
|
||||||
|
bubble.SetBaseScale(baseScale);
|
||||||
|
|
||||||
|
// Assign random sprite to BubbleSprite (fixed naming from BottleSprite)
|
||||||
if (bubbleSprites != null && bubbleSprites.Length > 0)
|
if (bubbleSprites != null && bubbleSprites.Length > 0)
|
||||||
{
|
{
|
||||||
Sprite randomSprite = bubbleSprites[Random.Range(0, bubbleSprites.Length)];
|
Sprite randomSprite = bubbleSprites[Random.Range(0, bubbleSprites.Length)];
|
||||||
bubble.SetBottleSprite(randomSprite);
|
bubble.SetBubbleSprite(randomSprite);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Random rotation
|
// Random rotation
|
||||||
bubble.transform.rotation = Quaternion.Euler(0f, 0f, Random.Range(0f, 360f));
|
bubble.transform.rotation = Quaternion.Euler(0f, 0f, Random.Range(0f, 360f));
|
||||||
|
|
||||||
// Pass min/max scale for wobble clamping
|
// Pass min/max scale for wobble clamping
|
||||||
bubble.SetWobbleScaleLimits(wobbleMinScale, wobbleMaxScale);
|
bubble.SetWobbleScaleLimits(wobbleMinScale, wobbleMaxScale);
|
||||||
}
|
}
|
||||||
|
|||||||
244
Assets/Scripts/Minigames/DivingForPictures/TrenchTilePool.cs
Normal file
244
Assets/Scripts/Minigames/DivingForPictures/TrenchTilePool.cs
Normal file
@@ -0,0 +1,244 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
namespace Minigames.DivingForPictures
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Manages a pool of trench tile objects to reduce garbage collection overhead.
|
||||||
|
/// Optimized for handling a large number of different prefab types.
|
||||||
|
/// </summary>
|
||||||
|
public class TrenchTilePool : MonoBehaviour
|
||||||
|
{
|
||||||
|
[Tooltip("Whether to pre-instantiate tiles during initialization or create them on demand")]
|
||||||
|
public bool preInstantiateTiles = false;
|
||||||
|
|
||||||
|
[Tooltip("Initial number of tiles to pre-instantiate per prefab (if preInstantiateTiles is true)")]
|
||||||
|
public int initialTilesPerPrefab = 2;
|
||||||
|
|
||||||
|
[Tooltip("Maximum number of tiles to keep in the pool across all prefab types")]
|
||||||
|
public int totalMaxPoolSize = 50;
|
||||||
|
|
||||||
|
[Tooltip("Maximum number of inactive instances to keep per prefab type")]
|
||||||
|
public int maxPerPrefabPoolSize = 5;
|
||||||
|
|
||||||
|
[Tooltip("Maximum number of tiles to keep in the pool (legacy, use maxPerPrefabPoolSize instead)")]
|
||||||
|
public int maxPoolSize = 5;
|
||||||
|
|
||||||
|
private Dictionary<int, Stack<GameObject>> pooledTiles = new Dictionary<int, Stack<GameObject>>();
|
||||||
|
private Dictionary<int, int> prefabUsageCount = new Dictionary<int, int>();
|
||||||
|
private List<GameObject> tilePrefabs;
|
||||||
|
private int totalPooledCount = 0;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Initialize the pool with the tile prefabs
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="prefabs">List of tile prefabs to use</param>
|
||||||
|
public void Initialize(List<GameObject> prefabs)
|
||||||
|
{
|
||||||
|
tilePrefabs = prefabs;
|
||||||
|
|
||||||
|
// Initialize usage tracking
|
||||||
|
for (int i = 0; i < prefabs.Count; i++)
|
||||||
|
{
|
||||||
|
prefabUsageCount[i] = 0;
|
||||||
|
pooledTiles[i] = new Stack<GameObject>();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Pre-instantiate tiles only if enabled
|
||||||
|
if (preInstantiateTiles)
|
||||||
|
{
|
||||||
|
// Calculate how many to pre-instantiate based on available pool size
|
||||||
|
int totalToCreate = Mathf.Min(totalMaxPoolSize, prefabs.Count * initialTilesPerPrefab);
|
||||||
|
int perPrefab = Mathf.Max(1, totalToCreate / prefabs.Count);
|
||||||
|
|
||||||
|
for (int i = 0; i < prefabs.Count; i++)
|
||||||
|
{
|
||||||
|
for (int j = 0; j < perPrefab; j++)
|
||||||
|
{
|
||||||
|
if (totalPooledCount >= totalMaxPoolSize) break;
|
||||||
|
CreateNewTile(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Creates a new tile instance and adds it to the pool
|
||||||
|
/// </summary>
|
||||||
|
private GameObject CreateNewTile(int prefabIndex)
|
||||||
|
{
|
||||||
|
if (tilePrefabs == null || prefabIndex >= tilePrefabs.Count)
|
||||||
|
{
|
||||||
|
Debug.LogError("TrenchTilePool: Invalid prefab index or tilePrefabs is null!");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
GameObject prefab = tilePrefabs[prefabIndex];
|
||||||
|
GameObject tile = Instantiate(prefab, transform);
|
||||||
|
tile.SetActive(false);
|
||||||
|
|
||||||
|
if (!pooledTiles.ContainsKey(prefabIndex))
|
||||||
|
{
|
||||||
|
pooledTiles[prefabIndex] = new Stack<GameObject>();
|
||||||
|
}
|
||||||
|
|
||||||
|
pooledTiles[prefabIndex].Push(tile);
|
||||||
|
totalPooledCount++;
|
||||||
|
return tile;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets a tile from the pool, or creates a new one if the pool is empty
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>A tile instance ready to use</returns>
|
||||||
|
public GameObject GetTile(int prefabIndex)
|
||||||
|
{
|
||||||
|
GameObject tile;
|
||||||
|
|
||||||
|
// Track usage frequency
|
||||||
|
if (prefabUsageCount.ContainsKey(prefabIndex))
|
||||||
|
{
|
||||||
|
prefabUsageCount[prefabIndex]++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
prefabUsageCount[prefabIndex] = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pooledTiles.ContainsKey(prefabIndex) && pooledTiles[prefabIndex].Count > 0)
|
||||||
|
{
|
||||||
|
tile = pooledTiles[prefabIndex].Pop();
|
||||||
|
totalPooledCount--;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Create new tile without adding to pool
|
||||||
|
GameObject prefab = tilePrefabs[prefabIndex];
|
||||||
|
tile = Instantiate(prefab, transform);
|
||||||
|
}
|
||||||
|
|
||||||
|
tile.SetActive(true);
|
||||||
|
return tile;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Returns a tile to the pool
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="tile">The tile to return to the pool</param>
|
||||||
|
/// <param name="prefabIndex">The index of the prefab this tile was created from</param>
|
||||||
|
public void ReturnTile(GameObject tile, int prefabIndex)
|
||||||
|
{
|
||||||
|
if (tile == null) return;
|
||||||
|
|
||||||
|
// Check if we're under the maximum pool size for this prefab type
|
||||||
|
bool keepTile = totalPooledCount < totalMaxPoolSize;
|
||||||
|
|
||||||
|
// Additional constraint: don't keep too many of any single prefab type
|
||||||
|
if (pooledTiles.ContainsKey(prefabIndex) &&
|
||||||
|
pooledTiles[prefabIndex].Count >= maxPerPrefabPoolSize)
|
||||||
|
{
|
||||||
|
keepTile = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (keepTile)
|
||||||
|
{
|
||||||
|
tile.SetActive(false);
|
||||||
|
tile.transform.SetParent(transform);
|
||||||
|
|
||||||
|
if (!pooledTiles.ContainsKey(prefabIndex))
|
||||||
|
{
|
||||||
|
pooledTiles[prefabIndex] = new Stack<GameObject>();
|
||||||
|
}
|
||||||
|
|
||||||
|
pooledTiles[prefabIndex].Push(tile);
|
||||||
|
totalPooledCount++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Destroy(tile);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Trims the pool to remove excess objects
|
||||||
|
/// Can be called periodically or when memory pressure is high
|
||||||
|
/// </summary>
|
||||||
|
public void TrimExcess()
|
||||||
|
{
|
||||||
|
// If we're under the limit, no need to trim
|
||||||
|
if (totalPooledCount <= totalMaxPoolSize) return;
|
||||||
|
|
||||||
|
// Calculate how many to remove
|
||||||
|
int excessCount = totalPooledCount - totalMaxPoolSize;
|
||||||
|
|
||||||
|
// Get prefab indices sorted by usage (least used first)
|
||||||
|
List<KeyValuePair<int, int>> sortedUsage = new List<KeyValuePair<int, int>>(prefabUsageCount);
|
||||||
|
sortedUsage.Sort((a, b) => a.Value.CompareTo(b.Value));
|
||||||
|
|
||||||
|
// Remove tiles from least used prefabs first
|
||||||
|
foreach (var usage in sortedUsage)
|
||||||
|
{
|
||||||
|
int prefabIndex = usage.Key;
|
||||||
|
if (!pooledTiles.ContainsKey(prefabIndex) || pooledTiles[prefabIndex].Count == 0) continue;
|
||||||
|
|
||||||
|
// How many to remove from this prefab type
|
||||||
|
int toRemove = Mathf.Min(pooledTiles[prefabIndex].Count, excessCount);
|
||||||
|
|
||||||
|
for (int i = 0; i < toRemove; i++)
|
||||||
|
{
|
||||||
|
if (pooledTiles[prefabIndex].Count == 0) break;
|
||||||
|
|
||||||
|
GameObject tile = pooledTiles[prefabIndex].Pop();
|
||||||
|
Destroy(tile);
|
||||||
|
totalPooledCount--;
|
||||||
|
excessCount--;
|
||||||
|
|
||||||
|
if (excessCount <= 0) return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Logs pool statistics to the console
|
||||||
|
/// </summary>
|
||||||
|
public void LogPoolStats()
|
||||||
|
{
|
||||||
|
Debug.Log($"[TrenchTilePool] Total pooled objects: {totalPooledCount}/{totalMaxPoolSize}");
|
||||||
|
|
||||||
|
string prefabDetails = "";
|
||||||
|
int index = 0;
|
||||||
|
foreach (var entry in pooledTiles)
|
||||||
|
{
|
||||||
|
int prefabIndex = entry.Key;
|
||||||
|
int count = entry.Value.Count;
|
||||||
|
int usageCount = prefabUsageCount.ContainsKey(prefabIndex) ? prefabUsageCount[prefabIndex] : 0;
|
||||||
|
|
||||||
|
string prefabName = prefabIndex < tilePrefabs.Count ? tilePrefabs[prefabIndex].name : "Unknown";
|
||||||
|
prefabDetails += $"\n - {prefabName}: {count} pooled, {usageCount} usages";
|
||||||
|
|
||||||
|
// Limit the output to avoid too much text
|
||||||
|
if (++index >= 10 && pooledTiles.Count > 10)
|
||||||
|
{
|
||||||
|
prefabDetails += $"\n - ...and {pooledTiles.Count - 10} more prefab types";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Debug.Log($"[TrenchTilePool] Pool details:{prefabDetails}");
|
||||||
|
}
|
||||||
|
|
||||||
|
#if UNITY_EDITOR
|
||||||
|
private float _lastLogTime = 0f;
|
||||||
|
|
||||||
|
void Update()
|
||||||
|
{
|
||||||
|
// Log pool stats every 5 seconds if in the editor
|
||||||
|
if (Time.time - _lastLogTime > 5f)
|
||||||
|
{
|
||||||
|
LogPoolStats();
|
||||||
|
_lastLogTime = Time.time;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: fc32ce01955e4e44b4c1d28871d64049
|
||||||
|
timeCreated: 1758015121
|
||||||
@@ -15,7 +15,7 @@ namespace Minigames.DivingForPictures
|
|||||||
public List<GameObject> tilePrefabs;
|
public List<GameObject> tilePrefabs;
|
||||||
|
|
||||||
[Header("Tile Settings")]
|
[Header("Tile Settings")]
|
||||||
private const float TileHeight = 5f; // Set to match prefab height
|
private Dictionary<GameObject, float> _tileHeights = new Dictionary<GameObject, float>();
|
||||||
public int initialTileCount = 3;
|
public int initialTileCount = 3;
|
||||||
public float tileSpawnBuffer = 1f;
|
public float tileSpawnBuffer = 1f;
|
||||||
|
|
||||||
@@ -23,6 +23,14 @@ namespace Minigames.DivingForPictures
|
|||||||
public float moveSpeed = 3f;
|
public float moveSpeed = 3f;
|
||||||
public float speedUpFactor = 0.2f;
|
public float speedUpFactor = 0.2f;
|
||||||
public float speedUpInterval = 10f;
|
public float speedUpInterval = 10f;
|
||||||
|
public float maxMoveSpeed = 12f; // Added a cap to the movement speed
|
||||||
|
|
||||||
|
[Header("Object Pooling")]
|
||||||
|
public bool useObjectPooling = true;
|
||||||
|
public bool preInstantiateTiles = false; // Added option to control pre-instantiation
|
||||||
|
public int initialTilesPerPrefab = 2;
|
||||||
|
public int maxPerPrefabPoolSize = 2;
|
||||||
|
public int totalMaxPoolSize = 10; // Total pool size across all prefab types
|
||||||
|
|
||||||
[FormerlySerializedAs("OnTileSpawned")] [Header("Events")]
|
[FormerlySerializedAs("OnTileSpawned")] [Header("Events")]
|
||||||
public UnityEvent<GameObject> onTileSpawned;
|
public UnityEvent<GameObject> onTileSpawned;
|
||||||
@@ -37,14 +45,61 @@ namespace Minigames.DivingForPictures
|
|||||||
private Camera _mainCamera;
|
private Camera _mainCamera;
|
||||||
private float _screenBottom;
|
private float _screenBottom;
|
||||||
private float _screenTop;
|
private float _screenTop;
|
||||||
|
private TrenchTilePool _tilePool;
|
||||||
|
|
||||||
|
private const float TileSpawnZ = -1f; // All spawned tiles should have z = -1
|
||||||
|
|
||||||
|
void Awake()
|
||||||
|
{
|
||||||
|
_mainCamera = Camera.main;
|
||||||
|
|
||||||
|
// Calculate tile heights for each prefab
|
||||||
|
foreach (var prefab in tilePrefabs)
|
||||||
|
{
|
||||||
|
Renderer renderer = prefab.GetComponentInChildren<Renderer>();
|
||||||
|
if (renderer != null)
|
||||||
|
{
|
||||||
|
_tileHeights[prefab] = renderer.bounds.size.y;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Fallback in case no renderer is found
|
||||||
|
_tileHeights[prefab] = 5f;
|
||||||
|
Debug.LogWarning($"No renderer found in prefab {prefab.name}. Using default height of 5.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (useObjectPooling)
|
||||||
|
{
|
||||||
|
// Create the tile pool
|
||||||
|
GameObject poolGO = new GameObject("TrenchTilePool");
|
||||||
|
poolGO.transform.SetParent(transform);
|
||||||
|
_tilePool = poolGO.AddComponent<TrenchTilePool>();
|
||||||
|
_tilePool.preInstantiateTiles = preInstantiateTiles;
|
||||||
|
_tilePool.initialTilesPerPrefab = initialTilesPerPrefab;
|
||||||
|
_tilePool.maxPerPrefabPoolSize = maxPerPrefabPoolSize;
|
||||||
|
_tilePool.totalMaxPoolSize = totalMaxPoolSize;
|
||||||
|
_tilePool.Initialize(tilePrefabs);
|
||||||
|
|
||||||
|
// Periodically trim the pool to optimize memory usage
|
||||||
|
InvokeRepeating(nameof(TrimExcessPooledTiles), 10f, 30f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void Start()
|
void Start()
|
||||||
{
|
{
|
||||||
_mainCamera = Camera.main;
|
|
||||||
CalculateScreenBounds();
|
CalculateScreenBounds();
|
||||||
for (int i = 0; i < initialTileCount; i++)
|
for (int i = 0; i < initialTileCount; i++)
|
||||||
{
|
{
|
||||||
SpawnTileAtY(_screenBottom + i * TileHeight);
|
float y = _screenBottom;
|
||||||
|
// Calculate proper Y position based on previous tiles
|
||||||
|
if (i > 0 && _activeTiles.Count > 0)
|
||||||
|
{
|
||||||
|
GameObject prevTile = _activeTiles[_activeTiles.Count - 1];
|
||||||
|
float prevHeight = GetTileHeight(prevTile);
|
||||||
|
y = prevTile.transform.position.y - prevHeight;
|
||||||
|
}
|
||||||
|
SpawnTileAtY(y);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -80,11 +135,29 @@ namespace Minigames.DivingForPictures
|
|||||||
{
|
{
|
||||||
if (_activeTiles.Count == 0) return;
|
if (_activeTiles.Count == 0) return;
|
||||||
GameObject topTile = _activeTiles[0];
|
GameObject topTile = _activeTiles[0];
|
||||||
if (topTile.transform.position.y - TileHeight / 2 > _screenTop + tileSpawnBuffer)
|
float tileHeight = GetTileHeight(topTile);
|
||||||
|
if (topTile.transform.position.y - tileHeight / 2 > _screenTop + tileSpawnBuffer)
|
||||||
{
|
{
|
||||||
_activeTiles.RemoveAt(0);
|
_activeTiles.RemoveAt(0);
|
||||||
onTileDestroyed?.Invoke(topTile);
|
onTileDestroyed?.Invoke(topTile);
|
||||||
Destroy(topTile);
|
|
||||||
|
if (useObjectPooling && _tilePool != null)
|
||||||
|
{
|
||||||
|
// Find the prefab index for this tile
|
||||||
|
int prefabIndex = GetPrefabIndex(topTile);
|
||||||
|
if (prefabIndex >= 0)
|
||||||
|
{
|
||||||
|
_tilePool.ReturnTile(topTile, prefabIndex);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Destroy(topTile);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Destroy(topTile);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -92,10 +165,11 @@ namespace Minigames.DivingForPictures
|
|||||||
{
|
{
|
||||||
if (_activeTiles.Count == 0) return;
|
if (_activeTiles.Count == 0) return;
|
||||||
GameObject bottomTile = _activeTiles[^1];
|
GameObject bottomTile = _activeTiles[^1];
|
||||||
float bottomEdge = bottomTile.transform.position.y - TileHeight / 2;
|
float tileHeight = GetTileHeight(bottomTile);
|
||||||
|
float bottomEdge = bottomTile.transform.position.y - tileHeight / 2;
|
||||||
if (bottomEdge > _screenBottom - tileSpawnBuffer)
|
if (bottomEdge > _screenBottom - tileSpawnBuffer)
|
||||||
{
|
{
|
||||||
float newY = bottomTile.transform.position.y - TileHeight;
|
float newY = bottomTile.transform.position.y - tileHeight;
|
||||||
SpawnTileAtY(newY);
|
SpawnTileAtY(newY);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -105,7 +179,7 @@ namespace Minigames.DivingForPictures
|
|||||||
_speedUpTimer += Time.deltaTime;
|
_speedUpTimer += Time.deltaTime;
|
||||||
if (_speedUpTimer >= speedUpInterval)
|
if (_speedUpTimer >= speedUpInterval)
|
||||||
{
|
{
|
||||||
moveSpeed += speedUpFactor;
|
moveSpeed = Mathf.Min(moveSpeed + speedUpFactor, maxMoveSpeed);
|
||||||
_speedUpTimer = 0f;
|
_speedUpTimer = 0f;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -114,8 +188,21 @@ namespace Minigames.DivingForPictures
|
|||||||
{
|
{
|
||||||
int prefabIndex = GetWeightedRandomTileIndex();
|
int prefabIndex = GetWeightedRandomTileIndex();
|
||||||
GameObject prefab = tilePrefabs[prefabIndex];
|
GameObject prefab = tilePrefabs[prefabIndex];
|
||||||
// Use the prefab's original rotation
|
GameObject tile;
|
||||||
GameObject tile = Instantiate(prefab, new Vector3(0f, y, 0f), prefab.transform.rotation, transform);
|
|
||||||
|
if (useObjectPooling && _tilePool != null)
|
||||||
|
{
|
||||||
|
tile = _tilePool.GetTile(prefabIndex);
|
||||||
|
tile.transform.position = new Vector3(0f, y, TileSpawnZ);
|
||||||
|
tile.transform.rotation = prefab.transform.rotation;
|
||||||
|
tile.transform.SetParent(transform);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Use the prefab's original rotation
|
||||||
|
tile = Instantiate(prefab, new Vector3(0f, y, TileSpawnZ), prefab.transform.rotation, transform);
|
||||||
|
}
|
||||||
|
|
||||||
_activeTiles.Add(tile);
|
_activeTiles.Add(tile);
|
||||||
_tileLastUsed[prefabIndex] = _spawnCounter++;
|
_tileLastUsed[prefabIndex] = _spawnCounter++;
|
||||||
onTileSpawned?.Invoke(tile);
|
onTileSpawned?.Invoke(tile);
|
||||||
@@ -143,6 +230,65 @@ namespace Minigames.DivingForPictures
|
|||||||
}
|
}
|
||||||
return Random.Range(0, n); // fallback
|
return Random.Range(0, n); // fallback
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the height of a tile based on its prefab or renderer bounds
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="tile">The tile to measure</param>
|
||||||
|
/// <returns>The height of the tile</returns>
|
||||||
|
private float GetTileHeight(GameObject tile)
|
||||||
|
{
|
||||||
|
// Check if this is a known prefab
|
||||||
|
foreach (var prefab in tilePrefabs)
|
||||||
|
{
|
||||||
|
// Check if this tile was created from this prefab
|
||||||
|
if (tile.name.StartsWith(prefab.name))
|
||||||
|
{
|
||||||
|
if (_tileHeights.TryGetValue(prefab, out float height))
|
||||||
|
{
|
||||||
|
return height;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// If not found, calculate it from the renderer
|
||||||
|
Renderer renderer = tile.GetComponentInChildren<Renderer>();
|
||||||
|
if (renderer != null)
|
||||||
|
{
|
||||||
|
return renderer.bounds.size.y;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fallback
|
||||||
|
return 5f;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the index of the prefab that was used to create this tile
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="tile">The tile to check</param>
|
||||||
|
/// <returns>The index of the prefab or -1 if not found</returns>
|
||||||
|
private int GetPrefabIndex(GameObject tile)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < tilePrefabs.Count; i++)
|
||||||
|
{
|
||||||
|
if (tile.name.StartsWith(tilePrefabs[i].name))
|
||||||
|
{
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Called periodically to trim excess pooled tiles
|
||||||
|
/// </summary>
|
||||||
|
private void TrimExcessPooledTiles()
|
||||||
|
{
|
||||||
|
if (_tilePool != null)
|
||||||
|
{
|
||||||
|
_tilePool.TrimExcess();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#if UNITY_EDITOR
|
#if UNITY_EDITOR
|
||||||
void OnDrawGizmosSelected()
|
void OnDrawGizmosSelected()
|
||||||
@@ -151,8 +297,13 @@ namespace Minigames.DivingForPictures
|
|||||||
Gizmos.color = Color.cyan;
|
Gizmos.color = Color.cyan;
|
||||||
for (int i = 0; i < initialTileCount; i++)
|
for (int i = 0; i < initialTileCount; i++)
|
||||||
{
|
{
|
||||||
Vector3 center = new Vector3(0f, _screenBottom + i * TileHeight, 0f);
|
float height = 5f;
|
||||||
Gizmos.DrawWireCube(center, new Vector3(10f, TileHeight, 1f));
|
if (tilePrefabs.Count > 0 && _tileHeights.TryGetValue(tilePrefabs[0], out float h))
|
||||||
|
{
|
||||||
|
height = h;
|
||||||
|
}
|
||||||
|
Vector3 center = new Vector3(0f, _screenBottom + i * height, 0f);
|
||||||
|
Gizmos.DrawWireCube(center, new Vector3(10f, height, 1f));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
Reference in New Issue
Block a user