Compare commits

...

20 Commits

Author SHA1 Message Date
Michal Pikulski
a455e34ed0 Add a sprite collider generator tool window 2025-09-16 15:39:49 +02:00
Michal Pikulski
75be338065 Working generic object pooling, pool monitor editor tool and batch component adder editor tool 2025-09-16 15:02:57 +02:00
Michal Pikulski
bcc6f05058 Working single-purpose object pooling solution 2025-09-16 15:02:57 +02:00
2c56d0e1de Merge pull request 'Introduce unit and integration tests' (#3) from integration_test into main
Reviewed-on: #3
2025-09-15 07:32:18 +00:00
Michal Pikulski
793da5e568 [Test] Cleanup assemblies for Android build test. Working game flow, working build, passing unit tests 2025-09-15 09:30:27 +02:00
Michal Pikulski
15414f9414 [Test] Add unit tests for base code 2025-09-14 13:35:35 +02:00
Michal Pikulski
8cffe0b161 Fix build issues due to comparison operators 2025-09-12 16:47:45 +02:00
Michal Pikulski
0057ae9fa3 Fix issues with scene loading, introduce an intermediate bootstrap scene 2025-09-12 15:37:26 +02:00
Michal Pikulski
cec661586e Fix issues with disabled puzzle steps not registering with puzzle manager 2025-09-12 14:39:08 +02:00
DamianCorazza
a580a5f35a Eyes are working now 2025-09-12 13:57:26 +02:00
Michal Pikulski
c0df46f9f8 Update dispatchers and message for slotting items 2025-09-12 13:24:04 +02:00
Michal Pikulski
9a12a79698 Fix item removed being called one too many times, fix Pulver movement 2025-09-12 13:14:21 +02:00
DamianCorazza
d62516f0cb Added Bird Spawning and Copied behaviour for the hammer bird 2025-09-12 12:49:07 +02:00
Michal Pikulski
445e36975d Interactable items - slotting working correctly and calling the dispatchers each time 2025-09-12 12:26:44 +02:00
Michal Pikulski
ef96d80d51 Small touchups of input and A* graphing 2025-09-12 10:36:23 +02:00
DamianCorazza
afd3bc3863 Eyes Work nicely now, switching items is a bit iffy though 2025-09-12 10:30:49 +02:00
9b590ca6ec Made Changes To slotted items (not fully functional but progressing)
Added Unity events to the Slotting Items, the eyes react fine but sometimes they fuck up. gonna check that out later.
2025-09-11 17:03:56 +02:00
Michal Pikulski
15b8146815 Update Puzzle Manager's initialization sequence 2025-09-11 15:48:44 +02:00
Michal Pikulski
c5b8561b73 Quick scene browser tab 2025-09-11 15:29:28 +02:00
fd220de298 Merge pull request 'rewrite_interactables' (#2) from rewrite_interactables into main
Reviewed-on: #2
2025-09-11 12:39:22 +00:00
119 changed files with 6213 additions and 737 deletions

View File

@@ -15,7 +15,7 @@ MonoBehaviour:
m_DefaultGroup: 6f3207429a65b3e4b83935ac19791077
m_currentHash:
serializedVersion: 2
Hash: c0cf00979528ae95d3583c572e4eb343
Hash: 00000000000000000000000000000000
m_OptimizeCatalogSize: 0
m_BuildRemoteCatalog: 0
m_CatalogRequestsTimeout: 0

View File

@@ -1,5 +1,30 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!1101 &-8622141701191891965
AnimatorStateTransition:
m_ObjectHideFlags: 1
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_Name:
m_Conditions:
- m_ConditionMode: 1
m_ConditionEvent: NoGuess
m_EventTreshold: 0
m_DstStateMachine: {fileID: 0}
m_DstState: {fileID: 5993408738867988234}
m_Solo: 0
m_Mute: 0
m_IsExit: 0
serializedVersion: 3
m_TransitionDuration: 0
m_TransitionOffset: 0
m_ExitTime: 0
m_HasExitTime: 1
m_HasFixedDuration: 1
m_InterruptionSource: 0
m_OrderedInterruption: 1
m_CanTransitionToSelf: 1
--- !u!1101 &-7993130233709895848
AnimatorStateTransition:
m_ObjectHideFlags: 1
@@ -17,7 +42,7 @@ AnimatorStateTransition:
m_Mute: 0
m_IsExit: 0
serializedVersion: 3
m_TransitionDuration: 0.25
m_TransitionDuration: 0
m_TransitionOffset: 0
m_ExitTime: 0.9594595
m_HasExitTime: 0
@@ -37,6 +62,7 @@ AnimatorState:
m_CycleOffset: 0
m_Transitions:
- {fileID: -169883073761575190}
- {fileID: -953515106580102534}
m_StateMachineBehaviours: []
m_Position: {x: 50, y: 50, z: 0}
m_IKOnFeet: 0
@@ -52,6 +78,31 @@ AnimatorState:
m_MirrorParameter:
m_CycleOffsetParameter:
m_TimeParameter:
--- !u!1101 &-953515106580102534
AnimatorStateTransition:
m_ObjectHideFlags: 1
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_Name:
m_Conditions:
- m_ConditionMode: 1
m_ConditionEvent: RightGuess
m_EventTreshold: 0
m_DstStateMachine: {fileID: 0}
m_DstState: {fileID: -92837137932308198}
m_Solo: 0
m_Mute: 0
m_IsExit: 0
serializedVersion: 3
m_TransitionDuration: 0
m_TransitionOffset: 0
m_ExitTime: 0.87903225
m_HasExitTime: 1
m_HasFixedDuration: 1
m_InterruptionSource: 0
m_OrderedInterruption: 1
m_CanTransitionToSelf: 1
--- !u!1101 &-169883073761575190
AnimatorStateTransition:
m_ObjectHideFlags: 1
@@ -59,14 +110,17 @@ AnimatorStateTransition:
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_Name:
m_Conditions: []
m_Conditions:
- m_ConditionMode: 1
m_ConditionEvent: NoGuess
m_EventTreshold: 0
m_DstStateMachine: {fileID: 0}
m_DstState: {fileID: 5993408738867988234}
m_Solo: 0
m_Mute: 0
m_IsExit: 0
serializedVersion: 3
m_TransitionDuration: 0.25
m_TransitionDuration: 0
m_TransitionOffset: 0
m_ExitTime: 0.8076923
m_HasExitTime: 1
@@ -84,7 +138,9 @@ AnimatorState:
m_Name: ANIM_BirdEyes_Correct
m_Speed: 1
m_CycleOffset: 0
m_Transitions: []
m_Transitions:
- {fileID: -8622141701191891965}
- {fileID: 1249646924704393990}
m_StateMachineBehaviours: []
m_Position: {x: 50, y: 50, z: 0}
m_IKOnFeet: 0
@@ -121,6 +177,12 @@ AnimatorController:
m_DefaultInt: 0
m_DefaultBool: 0
m_Controller: {fileID: 9100000}
- m_Name: NoGuess
m_Type: 9
m_DefaultFloat: 0
m_DefaultInt: 0
m_DefaultBool: 0
m_Controller: {fileID: 9100000}
m_AnimatorLayers:
- serializedVersion: 5
m_Name: Base Layer
@@ -134,6 +196,31 @@ AnimatorController:
m_IKPass: 0
m_SyncedLayerAffectsTiming: 0
m_Controller: {fileID: 9100000}
--- !u!1101 &1249646924704393990
AnimatorStateTransition:
m_ObjectHideFlags: 1
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_Name:
m_Conditions:
- m_ConditionMode: 1
m_ConditionEvent: WrongGuess
m_EventTreshold: 0
m_DstStateMachine: {fileID: 0}
m_DstState: {fileID: -2838832837941805979}
m_Solo: 0
m_Mute: 0
m_IsExit: 0
serializedVersion: 3
m_TransitionDuration: 0
m_TransitionOffset: 0
m_ExitTime: 0
m_HasExitTime: 1
m_HasFixedDuration: 1
m_InterruptionSource: 0
m_OrderedInterruption: 1
m_CanTransitionToSelf: 1
--- !u!1101 &4511680777278260622
AnimatorStateTransition:
m_ObjectHideFlags: 1
@@ -151,7 +238,7 @@ AnimatorStateTransition:
m_Mute: 0
m_IsExit: 0
serializedVersion: 3
m_TransitionDuration: 0.25
m_TransitionDuration: 0
m_TransitionOffset: 0
m_ExitTime: 0.9594595
m_HasExitTime: 0
@@ -201,10 +288,10 @@ AnimatorStateMachine:
m_Position: {x: 40, y: 350, z: 0}
- serializedVersion: 1
m_State: {fileID: -2838832837941805979}
m_Position: {x: -70, y: 450, z: 0}
m_Position: {x: -100, y: 450, z: 0}
- serializedVersion: 1
m_State: {fileID: -92837137932308198}
m_Position: {x: 150, y: 450, z: 0}
m_Position: {x: 200, y: 450, z: 0}
m_ChildStateMachines: []
m_AnyStateTransitions: []
m_EntryTransitions: []

View File

@@ -0,0 +1,19 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!114 &11400000
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 84e39aac66cf4a10a89abc01b04b13af, type: 3}
m_Name: InteractWithFootballBird
m_EditorClassIdentifier:
stepId: InteractFootballBird
displayName: Interact Football Bird
description: Take a picture of the Football bird
icon: {fileID: 0}
unlocks: []

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 0df54e69020c39e44b3b486cd6ac475a
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 11400000
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -16,4 +16,5 @@ MonoBehaviour:
displayName: Football in luring spot A
description: Place the Football into luring spot A
icon: {fileID: 0}
unlocks: []
unlocks:
- {fileID: 11400000, guid: 0df54e69020c39e44b3b486cd6ac475a, type: 2}

View File

@@ -0,0 +1,19 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!114 &11400000
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 84e39aac66cf4a10a89abc01b04b13af, type: 3}
m_Name: InteractWithHammerBird
m_EditorClassIdentifier:
stepId: InteractHammerBird
displayName: Interact With HammerBird
description: TAke picture of the HammerBird
icon: {fileID: 0}
unlocks: []

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 829fc7c8046e0844f93bf810dc1f0ebd
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 11400000
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -16,4 +16,5 @@ MonoBehaviour:
displayName: Nails In Lure C
description: Place the Nails in the Luring Spot C
icon: {fileID: 0}
unlocks: []
unlocks:
- {fileID: 11400000, guid: 829fc7c8046e0844f93bf810dc1f0ebd, type: 2}

View File

@@ -0,0 +1,123 @@
using UnityEditor;
using UnityEditor.SceneManagement;
using UnityEngine;
using System.Collections.Generic;
using System.IO;
using System.Linq;
public class SceneBrowserWindow : EditorWindow
{
private class SceneInfo
{
public string path;
public string name;
public string folder;
public bool inBuildSettings;
}
private Vector2 _scroll;
private List<SceneInfo> _scenes = new List<SceneInfo>();
private Dictionary<string, List<SceneInfo>> _scenesByFolder = new Dictionary<string, List<SceneInfo>>();
[MenuItem("Tools/Scene Browser")]
public static void ShowWindow()
{
var window = GetWindow<SceneBrowserWindow>(false, "Scene Browser", true);
window.RefreshScenes();
}
private void OnFocus()
{
RefreshScenes();
}
private void RefreshScenes()
{
_scenes.Clear();
_scenesByFolder.Clear();
string[] guids = AssetDatabase.FindAssets("t:Scene", new[] { "Assets/Scenes" });
var buildScenes = EditorBuildSettings.scenes.Select(s => s.path).ToHashSet();
foreach (var guid in guids)
{
string path = AssetDatabase.GUIDToAssetPath(guid);
string name = Path.GetFileNameWithoutExtension(path);
string folder = Path.GetDirectoryName(path).Replace("\\", "/");
if (folder == "Assets/Scenes") folder = "";
var info = new SceneInfo
{
path = path,
name = name,
folder = folder,
inBuildSettings = buildScenes.Contains(path)
};
_scenes.Add(info);
if (!_scenesByFolder.ContainsKey(folder))
_scenesByFolder[folder] = new List<SceneInfo>();
_scenesByFolder[folder].Add(info);
}
}
private void OnGUI()
{
if (GUILayout.Button("Refresh"))
RefreshScenes();
_scroll = EditorGUILayout.BeginScrollView(_scroll);
// Top-level scenes
if (_scenesByFolder.ContainsKey(""))
{
foreach (var scene in _scenesByFolder[""])
DrawSceneRow(scene);
EditorGUILayout.Space();
}
// Subfolders
foreach (var kvp in _scenesByFolder)
{
if (string.IsNullOrEmpty(kvp.Key)) continue;
EditorGUILayout.LabelField(kvp.Key, EditorStyles.boldLabel);
foreach (var scene in kvp.Value)
DrawSceneRow(scene);
EditorGUILayout.Space();
}
EditorGUILayout.EndScrollView();
}
private void DrawSceneRow(SceneInfo scene)
{
EditorGUILayout.BeginHorizontal();
EditorGUILayout.LabelField(scene.name, GUILayout.Width(180));
if (GUILayout.Button("Open", GUILayout.Width(50)))
{
if (EditorSceneManager.SaveCurrentModifiedScenesIfUserWantsTo())
EditorSceneManager.OpenScene(scene.path);
}
if (GUILayout.Button("Locate", GUILayout.Width(50)))
{
var obj = AssetDatabase.LoadAssetAtPath<SceneAsset>(scene.path);
EditorGUIUtility.PingObject(obj);
}
bool inBuild = scene.inBuildSettings;
bool newInBuild = GUILayout.Toggle(inBuild, "In Build", GUILayout.Width(70));
if (newInBuild != inBuild)
{
ToggleSceneInBuildSettings(scene.path, newInBuild);
scene.inBuildSettings = newInBuild;
}
EditorGUILayout.EndHorizontal();
}
private void ToggleSceneInBuildSettings(string path, bool add)
{
var scenes = EditorBuildSettings.scenes.ToList();
if (add)
{
if (!scenes.Any(s => s.path == path))
scenes.Add(new EditorBuildSettingsScene(path, true));
}
else
{
scenes = scenes.Where(s => s.path != path).ToList();
}
EditorBuildSettings.scenes = scenes.ToArray();
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: bda5b0c96582450e94a8b332f86c726d
timeCreated: 1757596929

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 8b28cee1553b4a15aa1c3be950983fee
timeCreated: 1758016486

View File

@@ -0,0 +1,227 @@
using System;
using System.Collections.Generic;
using System.Linq;
using UnityEditor;
using UnityEngine;
namespace Editor.Utilities
{
public class BatchComponentAdder : EditorWindow
{
private Vector2 scrollPosition;
private List<GameObject> selectedPrefabs = new List<GameObject>();
private string searchText = "";
private List<Type> availableComponentTypes = new List<Type>();
private List<Type> filteredComponentTypes = new List<Type>();
private int selectedComponentIndex = -1;
private bool showScriptsOnly = true;
private bool showBuiltInComponents = false;
[MenuItem("Tools/Batch Component Adder")]
public static void ShowWindow()
{
GetWindow<BatchComponentAdder>("Batch Component Adder");
}
private void OnEnable()
{
// Get all component types when the window is opened
RefreshComponentTypes();
}
private void RefreshComponentTypes()
{
// Get all types that derive from Component
availableComponentTypes = AppDomain.CurrentDomain.GetAssemblies()
.SelectMany(assembly => assembly.GetTypes())
.Where(type => type.IsSubclassOf(typeof(Component)) && !type.IsAbstract)
.OrderBy(type => type.Name)
.ToList();
// Apply initial filtering
FilterComponentTypes();
}
private void FilterComponentTypes()
{
filteredComponentTypes = availableComponentTypes
.Where(type => {
if (!showBuiltInComponents && type.Namespace != null && type.Namespace.StartsWith("UnityEngine"))
return false;
if (showScriptsOnly && type.Namespace != null && type.Namespace.StartsWith("UnityEngine"))
return false;
if (!string.IsNullOrEmpty(searchText))
return type.Name.ToLower().Contains(searchText.ToLower());
return true;
})
.ToList();
// Reset selection if it's no longer valid
if (selectedComponentIndex >= filteredComponentTypes.Count)
selectedComponentIndex = -1;
}
private void OnGUI()
{
EditorGUILayout.BeginVertical();
EditorGUILayout.LabelField("Batch Component Adder", EditorStyles.boldLabel);
EditorGUILayout.HelpBox("Select multiple prefabs, choose a component type, and add it to the root of all selected prefabs.", MessageType.Info);
EditorGUILayout.Space();
// Prefab selection section
EditorGUILayout.LabelField("Selected Prefabs", EditorStyles.boldLabel);
if (GUILayout.Button("Add Selected Assets"))
{
AddSelectedAssets();
}
scrollPosition = EditorGUILayout.BeginScrollView(scrollPosition, GUILayout.Height(150));
for (int i = 0; i < selectedPrefabs.Count; i++)
{
EditorGUILayout.BeginHorizontal();
selectedPrefabs[i] = (GameObject)EditorGUILayout.ObjectField(selectedPrefabs[i], typeof(GameObject), false);
if (GUILayout.Button("X", GUILayout.Width(20)))
{
selectedPrefabs.RemoveAt(i);
i--;
}
EditorGUILayout.EndHorizontal();
}
EditorGUILayout.EndScrollView();
if (GUILayout.Button("Clear All"))
{
selectedPrefabs.Clear();
}
EditorGUILayout.Space();
// Component selection section
EditorGUILayout.LabelField("Component to Add", EditorStyles.boldLabel);
EditorGUILayout.BeginHorizontal();
showScriptsOnly = EditorGUILayout.Toggle("Scripts Only", showScriptsOnly);
showBuiltInComponents = EditorGUILayout.Toggle("Show Built-in Components", showBuiltInComponents);
EditorGUILayout.EndHorizontal();
string newSearchText = EditorGUILayout.TextField("Search", searchText);
if (newSearchText != searchText)
{
searchText = newSearchText;
FilterComponentTypes();
}
string[] componentNames = filteredComponentTypes.Select(t => t.Name).ToArray();
selectedComponentIndex = EditorGUILayout.Popup("Component Type", selectedComponentIndex, componentNames);
EditorGUILayout.Space();
// Validate and add the component
GUI.enabled = selectedPrefabs.Count > 0 && selectedComponentIndex >= 0 && selectedComponentIndex < filteredComponentTypes.Count;
if (GUILayout.Button("Add Component to Prefabs"))
{
AddComponentToPrefabs();
}
GUI.enabled = true;
EditorGUILayout.EndVertical();
}
private void AddSelectedAssets()
{
UnityEngine.Object[] selectedObjects = Selection.objects;
foreach (var obj in selectedObjects)
{
if (obj is GameObject go)
{
string path = AssetDatabase.GetAssetPath(go);
if (!string.IsNullOrEmpty(path) && path.EndsWith(".prefab"))
{
if (!selectedPrefabs.Contains(go))
{
selectedPrefabs.Add(go);
}
}
}
}
}
private void AddComponentToPrefabs()
{
if (selectedComponentIndex < 0 || selectedComponentIndex >= filteredComponentTypes.Count)
return;
Type componentType = filteredComponentTypes[selectedComponentIndex];
int successCount = 0;
List<string> failedPrefabs = new List<string>();
// For undo operations
Undo.RecordObjects(selectedPrefabs.ToArray(), "Add Component To Prefabs");
foreach (GameObject prefab in selectedPrefabs)
{
// Skip null entries
if (prefab == null) continue;
try
{
// Open the prefab for editing
string prefabPath = AssetDatabase.GetAssetPath(prefab);
GameObject prefabRoot = PrefabUtility.LoadPrefabContents(prefabPath);
// Check if the component already exists
if (prefabRoot.GetComponent(componentType) == null)
{
// Add the component
prefabRoot.AddComponent(componentType);
// Save the prefab
PrefabUtility.SaveAsPrefabAsset(prefabRoot, prefabPath);
successCount++;
}
else
{
failedPrefabs.Add($"{prefab.name} (already has component)");
}
// Unload the prefab
PrefabUtility.UnloadPrefabContents(prefabRoot);
}
catch (Exception e)
{
Debug.LogError($"Error adding component to {prefab.name}: {e.Message}");
failedPrefabs.Add($"{prefab.name} (error)");
}
}
// Show results
if (successCount > 0)
{
Debug.Log($"Successfully added {componentType.Name} to {successCount} prefabs.");
}
if (failedPrefabs.Count > 0)
{
Debug.LogWarning($"Failed to add component to {failedPrefabs.Count} prefabs: {string.Join(", ", failedPrefabs)}");
}
// Refresh the asset database to show changes
AssetDatabase.Refresh();
}
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 34bcaf56206d4ec29cfa108c96622c37
timeCreated: 1758027437

View File

@@ -0,0 +1,432 @@
using UnityEngine;
using UnityEditor;
using System.Collections.Generic;
using System;
using System.Reflection;
using System.Collections;
using Pooling;
namespace Editor.Utilities
{
public class PoolMonitorWindow : EditorWindow
{
private Vector2 scrollPosition;
private bool autoRefresh = true;
private float refreshInterval = 1.0f;
private float lastRefreshTime;
private bool showSinglePrefabPools = true;
private bool showMultiPrefabPools = 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();
showSinglePrefabPools = EditorGUILayout.ToggleLeft("Show Single Prefab Pools", showSinglePrefabPools, GUILayout.Width(200));
showMultiPrefabPools = EditorGUILayout.ToggleLeft("Show Multi-Prefab Pools", showMultiPrefabPools, 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;
// Find all pool types and call LogPoolStats
if (showSinglePrefabPools)
{
// Find all types that derive from BaseObjectPool<T>
foreach (var pool in FindObjectsOfBaseType(typeof(Component), typeof(BaseObjectPool<>)))
{
if (pool != null && pool.gameObject.activeInHierarchy)
{
var logMethod = pool.GetType().GetMethod("LogPoolStats");
if (logMethod != null)
{
logMethod.Invoke(pool, null);
}
}
}
}
if (showMultiPrefabPools)
{
// Find all types that derive from MultiPrefabPool<T>
foreach (var pool in FindObjectsOfBaseType(typeof(Component), typeof(MultiPrefabPool<>)))
{
if (pool != null && pool.gameObject.activeInHierarchy)
{
var logMethod = pool.GetType().GetMethod("LogPoolStats");
if (logMethod != null)
{
logMethod.Invoke(pool, null);
}
}
}
}
}
void DisplayPoolInfo()
{
EditorGUILayout.LabelField("Scene Statistics:", EditorStyles.boldLabel);
EditorGUILayout.LabelField($"Total GameObjects: {UnityEngine.Object.FindObjectsByType<GameObject>(FindObjectsSortMode.None).Length}");
EditorGUILayout.Space();
if (showSinglePrefabPools)
{
DisplaySinglePrefabPoolInfo();
}
if (showMultiPrefabPools)
{
DisplayMultiPrefabPoolInfo();
}
}
void DisplaySinglePrefabPoolInfo()
{
// Find all types that derive from BaseObjectPool<T>
Component[] pools = FindObjectsOfBaseType(typeof(Component), typeof(BaseObjectPool<>));
if (pools.Length == 0)
{
EditorGUILayout.HelpBox("No single prefab pools found in the scene.", MessageType.Info);
return;
}
EditorGUILayout.LabelField("Single Prefab Pools", EditorStyles.boldLabel);
foreach (var poolComponent in pools)
{
EditorGUILayout.LabelField($"Pool: {poolComponent.name} ({poolComponent.GetType().Name})", EditorStyles.boldLabel);
EditorGUI.indentLevel++;
// Get private field values using reflection
Type poolType = poolComponent.GetType();
FieldInfo pooledObjectsField = poolType.GetField("pooledObjects",
BindingFlags.NonPublic | BindingFlags.Instance);
FieldInfo totalCreatedField = poolType.GetField("totalCreated",
BindingFlags.NonPublic | BindingFlags.Instance);
FieldInfo totalReturnedField = poolType.GetField("totalReturned",
BindingFlags.NonPublic | BindingFlags.Instance);
PropertyInfo maxPoolSizeProp = poolType.GetProperty("maxPoolSize") ??
poolType.GetField("maxPoolSize")?.DeclaringType.GetProperty("maxPoolSize");
PropertyInfo initialPoolSizeProp = poolType.GetProperty("initialPoolSize") ??
poolType.GetField("initialPoolSize")?.DeclaringType.GetProperty("initialPoolSize");
if (pooledObjectsField != null)
{
object pooledObjects = pooledObjectsField.GetValue(poolComponent);
int count = 0;
// Handle Stack<T>
if (pooledObjects is System.Collections.ICollection collection)
{
count = collection.Count;
}
int maxSize = 0;
if (maxPoolSizeProp != null)
{
maxSize = (int)maxPoolSizeProp.GetValue(poolComponent);
}
else
{
FieldInfo maxPoolSizeField = poolType.GetField("maxPoolSize",
BindingFlags.Public | BindingFlags.Instance);
if (maxPoolSizeField != null)
{
maxSize = (int)maxPoolSizeField.GetValue(poolComponent);
}
}
EditorGUILayout.LabelField($"Pooled Objects: {count}/{maxSize}");
int initialSize = 0;
if (initialPoolSizeProp != null)
{
initialSize = (int)initialPoolSizeProp.GetValue(poolComponent);
}
else
{
FieldInfo initialPoolSizeField = poolType.GetField("initialPoolSize",
BindingFlags.Public | BindingFlags.Instance);
if (initialPoolSizeField != null)
{
initialSize = (int)initialPoolSizeField.GetValue(poolComponent);
}
}
EditorGUILayout.LabelField($"Initial Pool Size: {initialSize}");
if (totalCreatedField != null && totalReturnedField != null)
{
int created = (int)totalCreatedField.GetValue(poolComponent);
int returned = (int)totalReturnedField.GetValue(poolComponent);
EditorGUILayout.LabelField($"Created: {created}, Returned: {returned}");
}
}
// Try to find active objects of the pool's type
if (poolType.BaseType.IsGenericType)
{
Type elementType = poolType.BaseType.GetGenericArguments()[0];
// More accurately count only active objects in the current scene
int activeCount = 0;
// First, try to get a more accurate count from the current scene
foreach (var obj in UnityEngine.Object.FindObjectsByType(elementType, FindObjectsSortMode.None))
{
var comp = obj as Component;
if (comp != null && comp.gameObject.activeInHierarchy)
{
activeCount++;
}
}
EditorGUILayout.LabelField($"Active Objects (Current Scene): {activeCount}");
// Add a note about pooling status
if (activeCount > 0)
{
int pooledCount = 0;
if (pooledObjectsField != null)
{
object pooledObjects = pooledObjectsField.GetValue(poolComponent);
if (pooledObjects is ICollection collection)
{
pooledCount = collection.Count;
}
}
EditorGUILayout.LabelField($"Pooling Efficiency: {pooledCount} ready in pool, {activeCount} active");
}
}
EditorGUI.indentLevel--;
EditorGUILayout.Space();
}
}
void DisplayMultiPrefabPoolInfo()
{
// Find all types that derive from MultiPrefabPool<T>
Component[] pools = FindObjectsOfBaseType(typeof(Component), typeof(MultiPrefabPool<>));
if (pools.Length == 0)
{
EditorGUILayout.HelpBox("No multi-prefab pools found in the scene.", MessageType.Info);
return;
}
EditorGUILayout.LabelField("Multi-Prefab Pools", EditorStyles.boldLabel);
foreach (var poolComponent in pools)
{
EditorGUILayout.LabelField($"Pool: {poolComponent.name} ({poolComponent.GetType().Name})", EditorStyles.boldLabel);
EditorGUI.indentLevel++;
// Get private field values using reflection
Type poolType = poolComponent.GetType();
FieldInfo totalPooledCountField = poolType.GetField("totalPooledCount",
BindingFlags.NonPublic | BindingFlags.Instance);
FieldInfo pooledObjectsField = poolType.GetField("pooledObjects",
BindingFlags.NonPublic | BindingFlags.Instance);
FieldInfo prefabUsageField = poolType.GetField("prefabUsageCount",
BindingFlags.NonPublic | BindingFlags.Instance);
PropertyInfo totalMaxPoolSizeProp = poolType.GetProperty("totalMaxPoolSize") ??
poolType.GetField("totalMaxPoolSize")?.DeclaringType.GetProperty("totalMaxPoolSize");
if (totalPooledCountField != null && totalMaxPoolSizeProp != null)
{
int totalCount = (int)totalPooledCountField.GetValue(poolComponent);
int maxSize = 0;
if (totalMaxPoolSizeProp != null)
{
maxSize = (int)totalMaxPoolSizeProp.GetValue(poolComponent);
}
else
{
FieldInfo totalMaxPoolSizeField = poolType.GetField("totalMaxPoolSize",
BindingFlags.Public | BindingFlags.Instance);
if (totalMaxPoolSizeField != null)
{
maxSize = (int)totalMaxPoolSizeField.GetValue(poolComponent);
}
}
EditorGUILayout.LabelField($"Total Pooled Objects: {totalCount}/{maxSize}");
}
if (pooledObjectsField != null && prefabUsageField != null)
{
// This is more complex because we don't know the exact generic types
// Just show basic information
object pooledTiles = pooledObjectsField.GetValue(poolComponent);
object usageCounts = prefabUsageField.GetValue(poolComponent);
if (pooledTiles != null && pooledTiles is IDictionary poolDict)
{
EditorGUILayout.LabelField("Prefab Details:", EditorStyles.boldLabel);
EditorGUI.indentLevel++;
foreach (DictionaryEntry entry in poolDict)
{
int prefabIndex = Convert.ToInt32(entry.Key);
object value = entry.Value;
int count = 0;
// Handle Stack<T>
if (value is ICollection collection)
{
count = collection.Count;
}
int usageCount = 0;
if (usageCounts is IDictionary usageDict)
{
if (usageDict.Contains(entry.Key))
{
usageCount = Convert.ToInt32(usageDict[entry.Key]);
}
}
EditorGUILayout.LabelField($"Prefab {prefabIndex}: {count} pooled, {usageCount} usages");
}
EditorGUI.indentLevel--;
}
}
// Try to find active objects of the pool's type
if (poolType.BaseType.IsGenericType)
{
Type elementType = poolType.BaseType.GetGenericArguments()[0];
int activeCount = 0;
// Count active objects of the specific pool's component type
foreach (var obj in UnityEngine.Object.FindObjectsByType(elementType, FindObjectsSortMode.None))
{
var comp = obj as Component;
if (comp != null && comp.gameObject.activeInHierarchy)
{
activeCount++;
}
}
EditorGUILayout.LabelField($"Active Objects (Current Scene): {activeCount}");
// Add a note about pooling status
if (activeCount > 0 && totalPooledCountField != null)
{
int pooledCount = (int)totalPooledCountField.GetValue(poolComponent);
EditorGUILayout.LabelField($"Pooling Efficiency: {pooledCount} ready in pool, {activeCount} active");
}
}
EditorGUI.indentLevel--;
EditorGUILayout.Space();
}
}
/// <summary>
/// Finds all objects that derive from a generic base type
/// </summary>
private Component[] FindObjectsOfBaseType(Type baseComponentType, Type genericBaseType)
{
List<Component> results = new List<Component>();
// Find all components in the scene
Component[] allComponents = UnityEngine.Object.FindObjectsByType<Component>(FindObjectsSortMode.None);
foreach (var component in allComponents)
{
Type componentType = component.GetType();
// Check if this type derives from the generic base type
while (componentType != null && componentType != typeof(object))
{
if (componentType.IsGenericType &&
componentType.GetGenericTypeDefinition() == genericBaseType)
{
results.Add(component);
break;
}
// Also check for non-generic derived types
if (componentType.BaseType != null &&
componentType.BaseType.IsGenericType &&
componentType.BaseType.GetGenericTypeDefinition() == genericBaseType)
{
results.Add(component);
break;
}
componentType = componentType.BaseType;
}
}
return results.ToArray();
}
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 17d6e42e7ca549b8b209f0714c8d106b
timeCreated: 1758016486

View File

@@ -0,0 +1,819 @@
using System;
using System.Collections.Generic;
using System.Linq;
using UnityEditor;
using UnityEngine;
namespace Editor.Utilities
{
public class SpriteColliderGenerator : EditorWindow
{
private Vector2 scrollPosition;
[Tooltip("List of GameObjects with SpriteRenderers to generate colliders for")]
private List<GameObject> selectedObjects = new List<GameObject>();
[Tooltip("Controls how much to simplify the collider shape (lower values create more complex colliders)")]
private float simplificationTolerance = 0.05f;
[Tooltip("When enabled, removes any existing PolygonCollider2D components before adding new ones")]
private bool replaceExistingColliders = true;
[Tooltip("When enabled, applies colliders to all child objects with SpriteRenderers")]
private bool applyToChildren = false;
[Tooltip("When enabled, allows scaling the collider outward or inward from the sprite center")]
private bool offsetFromCenter = false;
[Tooltip("Distance to offset the collider from the sprite outline (positive values expand, negative values contract)")]
private float offsetDistance = 0f;
[Tooltip("When enabled, creates trigger colliders instead of solid colliders")]
private bool generateTriggerColliders = false;
[Tooltip("Threshold for transparency detection (pixels with alpha below this value are considered transparent)")]
private int alphaCutoff = 128; // Used when generating colliders (0-255)
[Tooltip("Controls the level of detail for the generated collider (affects vertex count)")]
private int detailLevel = 2; // 1 = low, 2 = medium, 3 = high
[Tooltip("When enabled, shows a preview of the colliders in the scene view before generating them")]
private bool previewColliders = true;
[Tooltip("Color used for previewing colliders in the scene view")]
private Color previewColor = new Color(0.2f, 1f, 0.3f, 0.5f);
private List<Mesh> previewMeshes = new List<Mesh>();
[MenuItem("Tools/Sprite Collider Generator")]
public static void ShowWindow()
{
GetWindow<SpriteColliderGenerator>("Sprite Collider Generator");
}
private void OnDisable()
{
// Clean up any preview meshes when window is closed
foreach (var mesh in previewMeshes)
{
if (mesh != null)
{
DestroyImmediate(mesh);
}
}
previewMeshes.Clear();
}
private void OnGUI()
{
EditorGUILayout.BeginVertical();
EditorGUILayout.LabelField("Sprite Collider Generator", EditorStyles.boldLabel);
EditorGUILayout.HelpBox("Select GameObjects with SpriteRenderers and generate accurate PolygonCollider2D components based on the sprite outlines.", MessageType.Info);
EditorGUILayout.Space();
// Object selection section
EditorGUILayout.LabelField("Selected Objects", EditorStyles.boldLabel);
EditorGUILayout.BeginHorizontal();
if (GUILayout.Button(new GUIContent("Add Selected GameObjects", "Add GameObjects currently selected in the scene or project to the list for processing.")))
{
AddSelectedGameObjects();
}
EditorGUILayout.EndHorizontal();
scrollPosition = EditorGUILayout.BeginScrollView(scrollPosition, GUILayout.Height(150));
for (int i = 0; i < selectedObjects.Count; i++)
{
EditorGUILayout.BeginHorizontal();
selectedObjects[i] = (GameObject)EditorGUILayout.ObjectField(selectedObjects[i], typeof(GameObject), true);
if (GUILayout.Button("X", GUILayout.Width(20)))
{
selectedObjects.RemoveAt(i);
i--;
}
EditorGUILayout.EndHorizontal();
}
EditorGUILayout.EndScrollView();
if (GUILayout.Button(new GUIContent("Clear All", "Remove all objects from the selection list.")))
{
selectedObjects.Clear();
}
EditorGUILayout.Space();
// Collider generation options
EditorGUILayout.LabelField("Generation Options", EditorStyles.boldLabel);
// Detail level for collider generation (affects vertex count)
string[] detailOptions = new string[] { "Low", "Medium", "High" };
EditorGUILayout.BeginHorizontal();
EditorGUILayout.LabelField(new GUIContent("Detail Level:", "Controls the level of detail for the generated collider (affects vertex count)."), GUILayout.Width(180));
detailLevel = EditorGUILayout.Popup(detailLevel - 1, detailOptions) + 1;
EditorGUILayout.EndHorizontal();
// Simplification tolerance (how much to simplify the collider)
EditorGUILayout.BeginHorizontal();
EditorGUILayout.LabelField(new GUIContent("Simplification Tolerance:", "Controls how much to simplify the collider shape (lower values create more complex colliders)."), GUILayout.Width(180));
simplificationTolerance = EditorGUILayout.Slider(simplificationTolerance, 0.01f, 0.2f);
EditorGUILayout.EndHorizontal();
// Alpha cutoff for transparency
EditorGUILayout.BeginHorizontal();
EditorGUILayout.LabelField(new GUIContent("Alpha Cutoff (0-255):", "Threshold for transparency detection (pixels with alpha below this value are considered transparent)."), GUILayout.Width(180));
alphaCutoff = EditorGUILayout.IntSlider(alphaCutoff, 0, 255);
EditorGUILayout.EndHorizontal();
EditorGUILayout.Space();
// Additional options
replaceExistingColliders = EditorGUILayout.Toggle(
new GUIContent("Replace Existing Colliders", "When enabled, removes any existing PolygonCollider2D components before adding new ones."),
replaceExistingColliders);
applyToChildren = EditorGUILayout.Toggle(
new GUIContent("Apply To Children", "When enabled, applies colliders to all child objects with SpriteRenderers."),
applyToChildren);
generateTriggerColliders = EditorGUILayout.Toggle(
new GUIContent("Generate Trigger Colliders", "When enabled, creates trigger colliders instead of solid colliders."),
generateTriggerColliders);
// Offset option
offsetFromCenter = EditorGUILayout.Toggle(
new GUIContent("Offset From Center", "When enabled, allows scaling the collider outward or inward from the sprite center."),
offsetFromCenter);
if (offsetFromCenter)
{
EditorGUI.indentLevel++;
offsetDistance = EditorGUILayout.FloatField(
new GUIContent("Offset Distance", "Distance to offset the collider from the sprite outline (positive values expand, negative values contract)."),
offsetDistance);
EditorGUI.indentLevel--;
}
// Preview option
previewColliders = EditorGUILayout.Toggle(
new GUIContent("Preview Colliders", "When enabled, shows a preview of the colliders in the scene view before generating them."),
previewColliders);
if (previewColliders)
{
EditorGUI.indentLevel++;
previewColor = EditorGUILayout.ColorField(
new GUIContent("Preview Color", "Color used for previewing colliders in the scene view."),
previewColor);
// Create a horizontal layout for the preview buttons
EditorGUILayout.BeginHorizontal();
if (GUILayout.Button(new GUIContent("Update Preview", "Refresh the preview display in the scene view.")))
{
GenerateColliderPreviews();
}
if (GUILayout.Button(new GUIContent("Clear Preview", "Remove all preview colliders from the scene view.")))
{
ClearPreviews();
}
EditorGUILayout.EndHorizontal();
EditorGUI.indentLevel--;
}
EditorGUILayout.Space();
// Generate colliders button
GUI.enabled = selectedObjects.Count > 0;
if (GUILayout.Button(new GUIContent("Generate Colliders", "Create polygon colliders for all selected sprites based on current settings.")))
{
GenerateColliders();
}
GUI.enabled = true;
EditorGUILayout.EndVertical();
// Force the scene view to repaint if we're showing previews
if (previewColliders && Event.current.type == EventType.Repaint)
{
SceneView.RepaintAll();
}
}
private void AddSelectedGameObjects()
{
foreach (GameObject obj in Selection.gameObjects)
{
if (!selectedObjects.Contains(obj))
{
// Only add if it has a SpriteRenderer or any of its children do
if (obj.GetComponent<SpriteRenderer>() != null ||
(applyToChildren && obj.GetComponentInChildren<SpriteRenderer>() != null))
{
selectedObjects.Add(obj);
}
}
}
}
private void GenerateColliderPreviews()
{
// Clean up existing preview meshes
foreach (var mesh in previewMeshes)
{
if (mesh != null)
{
DestroyImmediate(mesh);
}
}
previewMeshes.Clear();
if (!previewColliders || selectedObjects.Count == 0)
return;
foreach (var obj in selectedObjects)
{
if (obj == null) continue;
var spriteRenderers = applyToChildren ?
obj.GetComponentsInChildren<SpriteRenderer>() :
new SpriteRenderer[] { obj.GetComponent<SpriteRenderer>() };
foreach (var renderer in spriteRenderers)
{
if (renderer == null || renderer.sprite == null)
continue;
Sprite sprite = renderer.sprite;
List<Vector2[]> paths = GetSpritePaths(sprite, simplificationTolerance);
if (paths.Count == 0)
continue;
foreach (var path in paths)
{
// Create a preview mesh from the path
Mesh previewMesh = CreateMeshFromPath(path, renderer.transform);
if (previewMesh != null)
previewMeshes.Add(previewMesh);
}
}
}
}
/// <summary>
/// Clears all preview meshes from the scene view
/// </summary>
private void ClearPreviews()
{
foreach (var mesh in previewMeshes)
{
if (mesh != null)
{
DestroyImmediate(mesh);
}
}
previewMeshes.Clear();
// Force a repaint of the scene view
SceneView.RepaintAll();
}
private Mesh CreateMeshFromPath(Vector2[] path, Transform transform)
{
if (path.Length < 3)
return null;
Mesh mesh = new Mesh();
// Convert the path to 3D vertices and apply the sprite's transform
Vector3[] vertices = new Vector3[path.Length];
for (int i = 0; i < path.Length; i++)
{
// Convert the local position to world space using the transform
vertices[i] = transform.TransformPoint(new Vector3(path[i].x, path[i].y, 0));
}
// Triangulate the polygon
Triangulator triangulator = new Triangulator(path);
int[] triangles = triangulator.Triangulate();
mesh.vertices = vertices;
mesh.triangles = triangles;
mesh.RecalculateNormals();
return mesh;
}
private void GenerateColliders()
{
int successCount = 0;
List<string> errors = new List<string>();
Undo.RecordObjects(selectedObjects.ToArray(), "Generate Sprite Colliders");
foreach (var obj in selectedObjects)
{
if (obj == null) continue;
try
{
var spriteRenderers = applyToChildren ?
obj.GetComponentsInChildren<SpriteRenderer>() :
new SpriteRenderer[] { obj.GetComponent<SpriteRenderer>() };
foreach (var renderer in spriteRenderers)
{
if (renderer == null || renderer.sprite == null)
continue;
// Check if we're working with a prefab
bool isPrefab = PrefabUtility.IsPartOfPrefabAsset(renderer.gameObject);
GameObject targetObject = renderer.gameObject;
if (isPrefab)
{
// If it's a prefab, we need special handling
string prefabPath = AssetDatabase.GetAssetPath(targetObject);
targetObject = PrefabUtility.LoadPrefabContents(prefabPath);
SpriteRenderer prefabRenderer = targetObject.GetComponent<SpriteRenderer>();
if (prefabRenderer == null || prefabRenderer.sprite == null)
{
PrefabUtility.UnloadPrefabContents(targetObject);
continue;
}
if (GenerateColliderForRenderer(prefabRenderer))
{
// Save the changes to the prefab
PrefabUtility.SaveAsPrefabAsset(targetObject, prefabPath);
successCount++;
}
PrefabUtility.UnloadPrefabContents(targetObject);
}
else
{
// For scene objects, just generate the collider directly
if (GenerateColliderForRenderer(renderer))
{
successCount++;
}
}
}
}
catch (Exception e)
{
errors.Add($"{obj.name}: {e.Message}");
}
}
// Clean up any preview meshes as we've now generated real colliders
ClearPreviews();
if (successCount > 0)
{
Debug.Log($"Successfully generated colliders for {successCount} sprite(s).");
}
if (errors.Count > 0)
{
Debug.LogError($"Errors occurred while generating colliders:\n{string.Join("\n", errors)}");
}
}
private bool GenerateColliderForRenderer(SpriteRenderer renderer)
{
if (renderer == null || renderer.sprite == null)
return false;
Sprite sprite = renderer.sprite;
GameObject targetObject = renderer.gameObject;
// Remove existing colliders if specified
if (replaceExistingColliders)
{
PolygonCollider2D[] existingColliders = targetObject.GetComponents<PolygonCollider2D>();
foreach (var collider in existingColliders)
{
Undo.DestroyObjectImmediate(collider);
}
}
// Create a new polygon collider
PolygonCollider2D polygonCollider = Undo.AddComponent<PolygonCollider2D>(targetObject);
if (polygonCollider == null)
return false;
// Set as trigger if specified
polygonCollider.isTrigger = generateTriggerColliders;
// Get paths from the sprite
List<Vector2[]> paths = GetSpritePaths(sprite, simplificationTolerance);
if (paths.Count == 0)
return false;
// Apply offset if needed
if (offsetFromCenter && offsetDistance != 0)
{
for (int i = 0; i < paths.Count; i++)
{
Vector2[] offsetPath = new Vector2[paths[i].Length];
for (int j = 0; j < paths[i].Length; j++)
{
// Calculate direction from center (0,0) to the point
Vector2 dir = paths[i][j].normalized;
// Apply offset in that direction
offsetPath[j] = paths[i][j] + dir * offsetDistance;
}
paths[i] = offsetPath;
}
}
// Set the paths on the collider
polygonCollider.pathCount = paths.Count;
for (int i = 0; i < paths.Count; i++)
{
polygonCollider.SetPath(i, paths[i]);
}
return true;
}
private List<Vector2[]> GetSpritePaths(Sprite sprite, float tolerance)
{
List<Vector2[]> result = new List<Vector2[]>();
if (sprite == null)
return result;
// Get the raw physics shape data from the sprite
int physicsShapeCount = sprite.GetPhysicsShapeCount();
if (physicsShapeCount == 0)
{
// Use the sprite's bounds if no physics shape is defined
Vector2[] boundingBoxPath = new Vector2[4];
Bounds bounds = sprite.bounds;
boundingBoxPath[0] = new Vector2(bounds.min.x, bounds.min.y);
boundingBoxPath[1] = new Vector2(bounds.min.x, bounds.max.y);
boundingBoxPath[2] = new Vector2(bounds.max.x, bounds.max.y);
boundingBoxPath[3] = new Vector2(bounds.max.x, bounds.min.y);
result.Add(boundingBoxPath);
return result;
}
// Adjust the detail level based on the setting
float actualTolerance = tolerance;
switch (detailLevel)
{
case 1: // Low
actualTolerance = tolerance * 2.0f;
break;
case 2: // Medium - default
actualTolerance = tolerance;
break;
case 3: // High
actualTolerance = tolerance * 0.5f;
break;
}
// Get all physics shapes from the sprite
for (int i = 0; i < physicsShapeCount; i++)
{
List<Vector2> path = new List<Vector2>();
sprite.GetPhysicsShape(i, path);
// Apply simplification if needed
if (actualTolerance > 0.01f)
{
path = SimplifyPath(path, actualTolerance);
}
if (path.Count >= 3) // Need at least 3 points for a valid polygon
{
result.Add(path.ToArray());
}
}
return result;
}
private List<Vector2> SimplifyPath(List<Vector2> points, float tolerance)
{
if (points.Count <= 3)
return points;
// Implementation of Ramer-Douglas-Peucker algorithm for simplifying a polygon
List<Vector2> result = new List<Vector2>();
List<int> markers = new List<int>(new int[points.Count]);
markers[0] = 1;
markers[points.Count - 1] = 1;
SimplifyDouglasPeucker(points, tolerance, markers, 0, points.Count - 1);
for (int i = 0; i < points.Count; i++)
{
if (markers[i] == 1)
{
result.Add(points[i]);
}
}
return result;
}
private void SimplifyDouglasPeucker(List<Vector2> points, float tolerance, List<int> markers, int start, int end)
{
if (end <= start + 1)
return;
float maxDistance = 0;
int maxIndex = start;
Vector2 startPoint = points[start];
Vector2 endPoint = points[end];
// Find the point furthest from the line segment
for (int i = start + 1; i < end; i++)
{
float distance = PerpendicularDistance(points[i], startPoint, endPoint);
if (distance > maxDistance)
{
maxDistance = distance;
maxIndex = i;
}
}
// If the furthest point is beyond tolerance, mark it for keeping and recurse
if (maxDistance > tolerance)
{
markers[maxIndex] = 1;
SimplifyDouglasPeucker(points, tolerance, markers, start, maxIndex);
SimplifyDouglasPeucker(points, tolerance, markers, maxIndex, end);
}
}
private float PerpendicularDistance(Vector2 point, Vector2 lineStart, Vector2 lineEnd)
{
if (lineStart == lineEnd)
return Vector2.Distance(point, lineStart);
float dx = lineEnd.x - lineStart.x;
float dy = lineEnd.y - lineStart.y;
// Normalize
float norm = Mathf.Sqrt(dx * dx + dy * dy);
if (norm < float.Epsilon)
return Vector2.Distance(point, lineStart);
dx /= norm;
dy /= norm;
// Calculate perpendicular distance
float px = point.x - lineStart.x;
float py = point.y - lineStart.y;
float projectionLength = px * dx + py * dy;
Vector2 projection = new Vector2(
lineStart.x + projectionLength * dx,
lineStart.y + projectionLength * dy);
return Vector2.Distance(point, projection);
}
// Scene view event handling for previewing colliders
[InitializeOnLoadMethod]
static void Initialize()
{
SceneView.duringSceneGui += OnSceneGUI;
}
static void OnSceneGUI(SceneView sceneView)
{
// Find all open collider generator windows
var windows = Resources.FindObjectsOfTypeAll<SpriteColliderGenerator>();
foreach (var window in windows)
{
window.DrawColliderPreviews(sceneView);
}
}
void DrawColliderPreviews(SceneView sceneView)
{
if (!previewColliders || previewMeshes.Count == 0)
return;
// Draw all preview meshes with the selected color
Material previewMaterial = new Material(Shader.Find("Hidden/Internal-Colored"));
previewMaterial.SetPass(0);
previewMaterial.SetColor("_Color", previewColor);
if (Event.current.type == EventType.Repaint)
{
GL.PushMatrix();
GL.MultMatrix(Matrix4x4.identity);
// Enable blending for transparency
GL.Begin(GL.TRIANGLES);
GL.Color(previewColor);
foreach (var mesh in previewMeshes)
{
if (mesh != null)
{
// Draw each triangle in the mesh
for (int i = 0; i < mesh.triangles.Length; i += 3)
{
Vector3 v0 = mesh.vertices[mesh.triangles[i]];
Vector3 v1 = mesh.vertices[mesh.triangles[i + 1]];
Vector3 v2 = mesh.vertices[mesh.triangles[i + 2]];
GL.Vertex(v0);
GL.Vertex(v1);
GL.Vertex(v2);
}
}
}
GL.End();
GL.PopMatrix();
// Also draw the outline
GL.PushMatrix();
GL.MultMatrix(Matrix4x4.identity);
GL.Begin(GL.LINES);
// Set a more visible outline color
Color outlineColor = new Color(previewColor.r, previewColor.g, previewColor.b, 1f);
GL.Color(outlineColor);
foreach (var mesh in previewMeshes)
{
if (mesh != null)
{
// Create a dictionary to track which edges we've drawn
HashSet<string> drawnEdges = new HashSet<string>();
// Draw edges of each triangle
for (int i = 0; i < mesh.triangles.Length; i += 3)
{
DrawEdgeIfNotDrawn(mesh.vertices[mesh.triangles[i]], mesh.vertices[mesh.triangles[i + 1]], drawnEdges);
DrawEdgeIfNotDrawn(mesh.vertices[mesh.triangles[i + 1]], mesh.vertices[mesh.triangles[i + 2]], drawnEdges);
DrawEdgeIfNotDrawn(mesh.vertices[mesh.triangles[i + 2]], mesh.vertices[mesh.triangles[i]], drawnEdges);
}
}
}
GL.End();
GL.PopMatrix();
}
}
private void DrawEdgeIfNotDrawn(Vector3 v1, Vector3 v2, HashSet<string> drawnEdges)
{
// Create a unique key for this edge (order vertices to ensure uniqueness)
string edgeKey;
if (v1.x < v2.x || (v1.x == v2.x && v1.y < v2.y))
edgeKey = $"{v1.x},{v1.y},{v1.z}_{v2.x},{v2.y},{v2.z}";
else
edgeKey = $"{v2.x},{v2.y},{v2.z}_{v1.x},{v1.y},{v1.z}";
// Only draw if we haven't drawn this edge yet
if (!drawnEdges.Contains(edgeKey))
{
GL.Vertex(v1);
GL.Vertex(v2);
drawnEdges.Add(edgeKey);
}
}
}
// Helper class for triangulating polygons
public class Triangulator
{
private List<Vector2> m_points;
public Triangulator(Vector2[] points)
{
m_points = new List<Vector2>(points);
}
public int[] Triangulate()
{
List<int> indices = new List<int>();
int n = m_points.Count;
if (n < 3)
return indices.ToArray();
int[] V = new int[n];
if (Area() > 0)
{
for (int v = 0; v < n; v++)
V[v] = v;
}
else
{
for (int v = 0; v < n; v++)
V[v] = (n - 1) - v;
}
int nv = n;
int count = 2 * nv;
for (int v = nv - 1; nv > 2; )
{
if ((count--) <= 0)
return indices.ToArray();
int u = v;
if (nv <= u)
u = 0;
v = u + 1;
if (nv <= v)
v = 0;
int w = v + 1;
if (nv <= w)
w = 0;
if (Snip(u, v, w, nv, V))
{
int a, b, c, s, t;
a = V[u];
b = V[v];
c = V[w];
indices.Add(a);
indices.Add(b);
indices.Add(c);
for (s = v, t = v + 1; t < nv; s++, t++)
V[s] = V[t];
nv--;
count = 2 * nv;
}
}
indices.Reverse();
return indices.ToArray();
}
private float Area()
{
int n = m_points.Count;
float A = 0.0f;
for (int p = n - 1, q = 0; q < n; p = q++)
{
Vector2 pval = m_points[p];
Vector2 qval = m_points[q];
A += pval.x * qval.y - qval.x * pval.y;
}
return (A * 0.5f);
}
private bool Snip(int u, int v, int w, int n, int[] V)
{
int p;
Vector2 A = m_points[V[u]];
Vector2 B = m_points[V[v]];
Vector2 C = m_points[V[w]];
if (Mathf.Epsilon > (((B.x - A.x) * (C.y - A.y)) - ((B.y - A.y) * (C.x - A.x))))
return false;
for (p = 0; p < n; p++)
{
if ((p == u) || (p == v) || (p == w))
continue;
Vector2 P = m_points[V[p]];
if (InsideTriangle(A, B, C, P))
return false;
}
return true;
}
private bool InsideTriangle(Vector2 A, Vector2 B, Vector2 C, Vector2 P)
{
float ax, ay, bx, by, cx, cy, apx, apy, bpx, bpy, cpx, cpy;
float cCROSSap, bCROSScp, aCROSSbp;
ax = C.x - B.x; ay = C.y - B.y;
bx = A.x - C.x; by = A.y - C.y;
cx = B.x - A.x; cy = B.y - A.y;
apx = P.x - A.x; apy = P.y - A.y;
bpx = P.x - B.x; bpy = P.y - B.y;
cpx = P.x - C.x; cpy = P.y - C.y;
aCROSSbp = ax * bpy - ay * bpx;
cCROSSap = cx * apy - cy * apx;
bCROSScp = bx * cpy - by * cpx;
return ((aCROSSbp >= 0.0f) && (bCROSScp >= 0.0f) && (cCROSSap >= 0.0f));
}
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 420526c0ea5943bb930e3e0913b9dee7
timeCreated: 1758028488

View File

@@ -0,0 +1,3 @@
{
"name": "PixelplacementAssembly"
}

View File

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

View File

@@ -0,0 +1,18 @@
{
"name": "PixelplacementEditor",
"rootNamespace": "",
"references": [
"GUID:db4a9769b2b9c5a4788bcd189eea1f0b"
],
"includePlatforms": [
"Editor"
],
"excludePlatforms": [],
"allowUnsafeCode": false,
"overrideReferences": false,
"precompiledReferences": [],
"autoReferenced": true,
"defineConstraints": [],
"versionDefines": [],
"noEngineReferences": false
}

View File

@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 0547315a6b16c1a48bf1db2b83869a5a
AssemblyDefinitionImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,9 +0,0 @@
fileFormatVersion: 2
guid: 274948d5adb104b28a8d42ee1308cee0
folderAsset: yes
timeCreated: 1500598980
licenseType: Store
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,9 +0,0 @@
fileFormatVersion: 2
guid: f588a5a76c3094128955cddb5540e896
folderAsset: yes
timeCreated: 1500598980
licenseType: Store
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -119,7 +119,7 @@ MonoBehaviour:
traversableTags: -1
tagPenalties: 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
graphMask:
value: -1
value: 1
--- !u!114 &7393789300602426170
MonoBehaviour:
m_ObjectHideFlags: 0

View File

@@ -119,7 +119,7 @@ MonoBehaviour:
traversableTags: -1
tagPenalties: 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
graphMask:
value: -1
value: 2
--- !u!114 &7852204877518954380
MonoBehaviour:
m_ObjectHideFlags: 0
@@ -137,7 +137,7 @@ MonoBehaviour:
height: 2
canMove: 1
maxSpeed: 15
gravity: {x: NaN, y: NaN, z: NaN}
gravity: {x: 0, y: 0, z: 0}
groundMask:
serializedVersion: 2
m_Bits: 4294967295
@@ -153,11 +153,11 @@ MonoBehaviour:
maximumInterval: 2
visualizeSensitivity: 0
targetCompatibility: {fileID: 0}
maxAcceleration: -2.5
maxAcceleration: 10000
rotationSpeed: 360
slowdownDistance: 3
pickNextWaypointDist: 2
endReachedDistance: 1
endReachedDistance: 0.5
alwaysDrawGizmos: 0
slowWhenNotFacingTarget: 1
whenCloseToDestination: 0
@@ -279,6 +279,10 @@ PrefabInstance:
serializedVersion: 3
m_TransformParent: {fileID: 2264394306674147778}
m_Modifications:
- target: {fileID: 566650525959955209, guid: e3b439d398cffdd4194cdb360a46c5a6, type: 3}
propertyPath: m_SpriteSortPoint
value: 1
objectReference: {fileID: 0}
- target: {fileID: 1102468210854536367, guid: e3b439d398cffdd4194cdb360a46c5a6, type: 3}
propertyPath: m_Name
value: Pulver

View File

@@ -11,7 +11,7 @@ GameObject:
- component: {fileID: 7442421452951837692}
- component: {fileID: 4110666412151536905}
m_Layer: 0
m_Name: SlottedItem
m_Name: SlottedItemA
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
@@ -87,6 +87,116 @@ SpriteRenderer:
m_WasSpriteAssigned: 0
m_MaskInteraction: 0
m_SpriteSortPoint: 0
--- !u!1 &3617455498829757156
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 4388395494483065101}
- component: {fileID: 4237100461469772044}
- component: {fileID: 2472695135799577718}
m_Layer: 0
m_Name: FootballBird
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!4 &4388395494483065101
Transform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 3617455498829757156}
serializedVersion: 2
m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
m_LocalPosition: {x: 2.8479085, y: -0.13594438, z: 0}
m_LocalScale: {x: 0.5, y: 0.50000006, z: 0.50000006}
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 1924342418841580}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!212 &4237100461469772044
SpriteRenderer:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 3617455498829757156}
m_Enabled: 1
m_CastShadows: 0
m_ReceiveShadows: 0
m_DynamicOccludee: 1
m_StaticShadowCaster: 0
m_MotionVectors: 1
m_LightProbeUsage: 1
m_ReflectionProbeUsage: 1
m_RayTracingMode: 0
m_RayTraceProcedural: 0
m_RayTracingAccelStructBuildFlagsOverride: 0
m_RayTracingAccelStructBuildFlags: 1
m_SmallMeshCulling: 1
m_RenderingLayerMask: 1
m_RendererPriority: 0
m_Materials:
- {fileID: 2100000, guid: a97c105638bdf8b4a8650670310a4cd3, type: 2}
m_StaticBatchInfo:
firstSubMesh: 0
subMeshCount: 0
m_StaticBatchRoot: {fileID: 0}
m_ProbeAnchor: {fileID: 0}
m_LightProbeVolumeOverride: {fileID: 0}
m_ScaleInLightmap: 1
m_ReceiveGI: 1
m_PreserveUVs: 0
m_IgnoreNormalsForChartDetection: 0
m_ImportantGI: 0
m_StitchLightmapSeams: 1
m_SelectedEditorRenderState: 0
m_MinimumChartSize: 4
m_AutoUVMaxDistance: 0.5
m_AutoUVMaxAngle: 89
m_LightmapParameters: {fileID: 0}
m_SortingLayerID: 0
m_SortingLayer: 0
m_SortingOrder: 0
m_Sprite: {fileID: 0}
m_Color: {r: 1, g: 1, b: 1, a: 1}
m_FlipX: 0
m_FlipY: 0
m_DrawMode: 0
m_Size: {x: 1, y: 1}
m_AdaptiveModeThreshold: 0.5
m_SpriteTileMode: 0
m_WasSpriteAssigned: 0
m_MaskInteraction: 0
m_SpriteSortPoint: 0
--- !u!95 &2472695135799577718
Animator:
serializedVersion: 7
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 3617455498829757156}
m_Enabled: 1
m_Avatar: {fileID: 0}
m_Controller: {fileID: 0}
m_CullingMode: 0
m_UpdateMode: 0
m_ApplyRootMotion: 0
m_LinearVelocityBlending: 0
m_StabilizeFeet: 0
m_AnimatePhysics: 0
m_WarningMessage:
m_HasTransformHierarchy: 1
m_AllowConstantClipSamplingOptimization: 1
m_KeepAnimatorStateOnDisable: 0
m_WriteDefaultValuesOnDisable: 0
--- !u!1 &7249528695393012044
GameObject:
m_ObjectHideFlags: 0
@@ -98,9 +208,9 @@ GameObject:
- component: {fileID: 2045549771447434109}
- component: {fileID: 6258593095132504700}
- component: {fileID: 5475802662781903683}
- component: {fileID: 3906996712691464207}
- component: {fileID: 8818689886719637838}
- component: {fileID: 8578055200319571631}
- component: {fileID: 3487003259787903584}
m_Layer: 10
m_Name: LureSpotA
m_TagString: Untagged
@@ -226,20 +336,6 @@ BoxCollider2D:
m_AutoTiling: 0
m_Size: {x: 5.75, y: 2.78}
m_EdgeRadius: 0
--- !u!114 &3906996712691464207
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 7249528695393012044}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 7846448751da4bdbaaa5cb87890dca42, type: 3}
m_Name:
m_EditorClassIdentifier:
itemData: {fileID: 11400000, guid: aaf36cd26cf74334e9c7db6c1b03b3fb, type: 2}
iconRenderer: {fileID: 6258593095132504700}
--- !u!114 &8818689886719637838
MonoBehaviour:
m_ObjectHideFlags: 0
@@ -252,6 +348,21 @@ MonoBehaviour:
m_Script: {fileID: 11500000, guid: 73d6494a73174ffabc6a7d3089d51e73, type: 3}
m_Name:
m_EditorClassIdentifier:
isOneTime: 0
cooldown: -1
characterToInteract: 1
interactionStarted:
m_PersistentCalls:
m_Calls: []
interactionInterrupted:
m_PersistentCalls:
m_Calls: []
characterArrived:
m_PersistentCalls:
m_Calls: []
interactionComplete:
m_PersistentCalls:
m_Calls: []
--- !u!114 &8578055200319571631
MonoBehaviour:
m_ObjectHideFlags: 0
@@ -264,14 +375,74 @@ MonoBehaviour:
m_Script: {fileID: 11500000, guid: ec1a2e6e32f746c4990c579e13b79104, type: 3}
m_Name:
m_EditorClassIdentifier:
OnSuccess:
itemData: {fileID: 11400000, guid: aaf36cd26cf74334e9c7db6c1b03b3fb, type: 2}
iconRenderer: {fileID: 6258593095132504700}
onItemSlotted:
m_PersistentCalls:
m_Calls: []
OnFailure:
onItemSlotRemoved:
m_PersistentCalls:
m_Calls:
- m_Target: {fileID: 7602419655779381936}
m_TargetAssemblyTypeName: BirdEyesBehavior, Assembly-CSharp
m_MethodName: NoItem
m_Mode: 1
m_Arguments:
m_ObjectArgument: {fileID: 0}
m_ObjectArgumentAssemblyTypeName: UnityEngine.Object, UnityEngine
m_IntArgument: 0
m_FloatArgument: 0
m_StringArgument:
m_BoolArgument: 0
m_CallState: 2
onCorrectItemSlotted:
m_PersistentCalls:
m_Calls:
- m_Target: {fileID: 7602419655779381936}
m_TargetAssemblyTypeName: BirdEyesBehavior, Assembly-CSharp
m_MethodName: CorrectItem
m_Mode: 1
m_Arguments:
m_ObjectArgument: {fileID: 0}
m_ObjectArgumentAssemblyTypeName: UnityEngine.Object, UnityEngine
m_IntArgument: 0
m_FloatArgument: 0
m_StringArgument:
m_BoolArgument: 0
m_CallState: 2
onIncorrectItemSlotted:
m_PersistentCalls:
m_Calls:
- m_Target: {fileID: 7602419655779381936}
m_TargetAssemblyTypeName: BirdEyesBehavior, Assembly-CSharp
m_MethodName: IncorrectItem
m_Mode: 1
m_Arguments:
m_ObjectArgument: {fileID: 0}
m_ObjectArgumentAssemblyTypeName: UnityEngine.Object, UnityEngine
m_IntArgument: 0
m_FloatArgument: 0
m_StringArgument:
m_BoolArgument: 0
m_CallState: 2
onForbiddenItemSlotted:
m_PersistentCalls:
m_Calls: []
currentlySlottedItem: {fileID: 0}
slottedItemRenderer: {fileID: 0}
slottedItemRenderer: {fileID: 4110666412151536905}
--- !u!114 &3487003259787903584
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 7249528695393012044}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 2226aecbed4b1f143a5a5c5be4236957, type: 3}
m_Name:
m_EditorClassIdentifier:
playerToPlaceDistance: 40
birdEyes: {fileID: 7602419655779381936}
--- !u!1001 &7700829900874995671
PrefabInstance:
m_ObjectHideFlags: 0
@@ -282,27 +453,27 @@ PrefabInstance:
m_Modifications:
- target: {fileID: 1370564349707122423, guid: 185f4e1548ec9754893c0a17f2207c44, type: 3}
propertyPath: m_Name
value: BirdEyes
value: BirdEyesA
objectReference: {fileID: 0}
- target: {fileID: 2326086342663433936, guid: 185f4e1548ec9754893c0a17f2207c44, type: 3}
propertyPath: m_LocalScale.x
value: 0.5
value: 1
objectReference: {fileID: 0}
- target: {fileID: 2326086342663433936, guid: 185f4e1548ec9754893c0a17f2207c44, type: 3}
propertyPath: m_LocalScale.y
value: 0.5
value: 1
objectReference: {fileID: 0}
- target: {fileID: 2326086342663433936, guid: 185f4e1548ec9754893c0a17f2207c44, type: 3}
propertyPath: m_LocalScale.z
value: 0.5
value: 1
objectReference: {fileID: 0}
- target: {fileID: 2326086342663433936, guid: 185f4e1548ec9754893c0a17f2207c44, type: 3}
propertyPath: m_LocalPosition.x
value: 5.47
value: 6.25
objectReference: {fileID: 0}
- target: {fileID: 2326086342663433936, guid: 185f4e1548ec9754893c0a17f2207c44, type: 3}
propertyPath: m_LocalPosition.y
value: 8.65
value: 8.87
objectReference: {fileID: 0}
- target: {fileID: 2326086342663433936, guid: 185f4e1548ec9754893c0a17f2207c44, type: 3}
propertyPath: m_LocalPosition.z
@@ -336,17 +507,78 @@ PrefabInstance:
propertyPath: m_LocalEulerAnglesHint.z
value: 0
objectReference: {fileID: 0}
- target: {fileID: 2326086342663433936, guid: 185f4e1548ec9754893c0a17f2207c44, type: 3}
propertyPath: m_ConstrainProportionsScale
value: 1
objectReference: {fileID: 0}
- target: {fileID: 3013218424693156287, guid: 185f4e1548ec9754893c0a17f2207c44, type: 3}
propertyPath: m_FlipX
value: 1
objectReference: {fileID: 0}
- target: {fileID: 3532512445619884959, guid: 185f4e1548ec9754893c0a17f2207c44, type: 3}
propertyPath: m_IsActive
value: 1
objectReference: {fileID: 0}
- target: {fileID: 7034773904088491925, guid: 185f4e1548ec9754893c0a17f2207c44, type: 3}
propertyPath: m_FlipX
value: 0
objectReference: {fileID: 0}
m_RemovedComponents: []
- target: {fileID: 7698905571408300091, guid: 185f4e1548ec9754893c0a17f2207c44, type: 3}
propertyPath: m_LocalScale.x
value: 1
objectReference: {fileID: 0}
- target: {fileID: 7698905571408300091, guid: 185f4e1548ec9754893c0a17f2207c44, type: 3}
propertyPath: m_LocalScale.y
value: 0.99999994
objectReference: {fileID: 0}
- target: {fileID: 7698905571408300091, guid: 185f4e1548ec9754893c0a17f2207c44, type: 3}
propertyPath: m_LocalScale.z
value: 0.99999994
objectReference: {fileID: 0}
- target: {fileID: 7698905571408300091, guid: 185f4e1548ec9754893c0a17f2207c44, type: 3}
propertyPath: m_LocalPosition.x
value: -6.89
objectReference: {fileID: 0}
- target: {fileID: 7698905571408300091, guid: 185f4e1548ec9754893c0a17f2207c44, type: 3}
propertyPath: m_LocalPosition.y
value: -7.05
objectReference: {fileID: 0}
- target: {fileID: 7698905571408300091, guid: 185f4e1548ec9754893c0a17f2207c44, type: 3}
propertyPath: m_ConstrainProportionsScale
value: 1
objectReference: {fileID: 0}
- target: {fileID: 8828658103663197825, guid: 185f4e1548ec9754893c0a17f2207c44, type: 3}
propertyPath: m_IsActive
value: 1
objectReference: {fileID: 0}
m_RemovedComponents:
- {fileID: 5210033153524231666, guid: 185f4e1548ec9754893c0a17f2207c44, type: 3}
- {fileID: 4408373410605328204, guid: 185f4e1548ec9754893c0a17f2207c44, type: 3}
m_RemovedGameObjects: []
m_AddedGameObjects: []
m_AddedGameObjects:
- targetCorrespondingSourceObject: {fileID: 7698905571408300091, guid: 185f4e1548ec9754893c0a17f2207c44, type: 3}
insertIndex: -1
addedObject: {fileID: 4388395494483065101}
m_AddedComponents: []
m_SourcePrefab: {fileID: 100100000, guid: 185f4e1548ec9754893c0a17f2207c44, type: 3}
--- !u!4 &1924342418841580 stripped
Transform:
m_CorrespondingSourceObject: {fileID: 7698905571408300091, guid: 185f4e1548ec9754893c0a17f2207c44, type: 3}
m_PrefabInstance: {fileID: 7700829900874995671}
m_PrefabAsset: {fileID: 0}
--- !u!4 &5375394469162727687 stripped
Transform:
m_CorrespondingSourceObject: {fileID: 2326086342663433936, guid: 185f4e1548ec9754893c0a17f2207c44, type: 3}
m_PrefabInstance: {fileID: 7700829900874995671}
m_PrefabAsset: {fileID: 0}
--- !u!114 &7602419655779381936 stripped
MonoBehaviour:
m_CorrespondingSourceObject: {fileID: 243176356944356711, guid: 185f4e1548ec9754893c0a17f2207c44, type: 3}
m_PrefabInstance: {fileID: 7700829900874995671}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 13d59d3c42170824b8f92557822d9bf0, type: 3}
m_Name:
m_EditorClassIdentifier:

View File

@@ -11,7 +11,7 @@ GameObject:
- component: {fileID: 779234943217098985}
- component: {fileID: 7990414055343410434}
m_Layer: 0
m_Name: SlottedItem
m_Name: SlottedItemB
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
@@ -26,7 +26,7 @@ Transform:
m_GameObject: {fileID: 1985797937494910982}
serializedVersion: 2
m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalPosition: {x: -0.279, y: -0.097, z: 0}
m_LocalScale: {x: 0.5, y: 0.5, z: 0.5}
m_ConstrainProportionsScale: 0
m_Children: []
@@ -99,7 +99,6 @@ GameObject:
- component: {fileID: 6583028881099676536}
- component: {fileID: 8374056515464764762}
- component: {fileID: 4289780218821574471}
- component: {fileID: 4191908717467096214}
- component: {fileID: 3093816592344978065}
- component: {fileID: 8758136668472096799}
m_Layer: 10
@@ -238,20 +237,21 @@ MonoBehaviour:
m_Script: {fileID: 11500000, guid: 73d6494a73174ffabc6a7d3089d51e73, type: 3}
m_Name:
m_EditorClassIdentifier:
--- !u!114 &4191908717467096214
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 5835735262203788332}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 7846448751da4bdbaaa5cb87890dca42, type: 3}
m_Name:
m_EditorClassIdentifier:
itemData: {fileID: 11400000, guid: f97b9e24d6dceb145b56426c1152ebeb, type: 2}
iconRenderer: {fileID: 6583028881099676536}
isOneTime: 0
cooldown: -1
characterToInteract: 1
interactionStarted:
m_PersistentCalls:
m_Calls: []
interactionInterrupted:
m_PersistentCalls:
m_Calls: []
characterArrived:
m_PersistentCalls:
m_Calls: []
interactionComplete:
m_PersistentCalls:
m_Calls: []
--- !u!114 &3093816592344978065
MonoBehaviour:
m_ObjectHideFlags: 0
@@ -264,14 +264,24 @@ MonoBehaviour:
m_Script: {fileID: 11500000, guid: ec1a2e6e32f746c4990c579e13b79104, type: 3}
m_Name:
m_EditorClassIdentifier:
OnSuccess:
itemData: {fileID: 11400000, guid: f97b9e24d6dceb145b56426c1152ebeb, type: 2}
iconRenderer: {fileID: 6583028881099676536}
onItemSlotted:
m_PersistentCalls:
m_Calls: []
OnFailure:
onItemSlotRemoved:
m_PersistentCalls:
m_Calls: []
currentlySlottedItem: {fileID: 0}
slottedItemRenderer: {fileID: 0}
onCorrectItemSlotted:
m_PersistentCalls:
m_Calls: []
onIncorrectItemSlotted:
m_PersistentCalls:
m_Calls: []
onForbiddenItemSlotted:
m_PersistentCalls:
m_Calls: []
slottedItemRenderer: {fileID: 7990414055343410434}
--- !u!114 &8758136668472096799
MonoBehaviour:
m_ObjectHideFlags: 0

View File

@@ -94,7 +94,7 @@ GameObject:
- component: {fileID: 1828079450404796388}
- component: {fileID: 3806274462998212361}
m_Layer: 0
m_Name: SlottedItem
m_Name: SlottedItemC
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
@@ -182,8 +182,8 @@ GameObject:
- component: {fileID: 5015123355472106337}
- component: {fileID: 1857323601952658682}
- component: {fileID: 519585874127847016}
- component: {fileID: 3177191571756140058}
- component: {fileID: 106497079666291966}
- component: {fileID: 3169137887822749614}
m_Layer: 10
m_Name: LureSpotC
m_TagString: Untagged
@@ -321,20 +321,21 @@ MonoBehaviour:
m_Script: {fileID: 11500000, guid: 73d6494a73174ffabc6a7d3089d51e73, type: 3}
m_Name:
m_EditorClassIdentifier:
--- !u!114 &3177191571756140058
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 7145022056631397938}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 7846448751da4bdbaaa5cb87890dca42, type: 3}
m_Name:
m_EditorClassIdentifier:
itemData: {fileID: 11400000, guid: c68dea945fecbf44094359769db04f31, type: 2}
iconRenderer: {fileID: 5015123355472106337}
isOneTime: 0
cooldown: -1
characterToInteract: 1
interactionStarted:
m_PersistentCalls:
m_Calls: []
interactionInterrupted:
m_PersistentCalls:
m_Calls: []
characterArrived:
m_PersistentCalls:
m_Calls: []
interactionComplete:
m_PersistentCalls:
m_Calls: []
--- !u!114 &106497079666291966
MonoBehaviour:
m_ObjectHideFlags: 0
@@ -347,11 +348,34 @@ MonoBehaviour:
m_Script: {fileID: 11500000, guid: ec1a2e6e32f746c4990c579e13b79104, type: 3}
m_Name:
m_EditorClassIdentifier:
OnSuccess:
itemData: {fileID: 11400000, guid: c68dea945fecbf44094359769db04f31, type: 2}
iconRenderer: {fileID: 5015123355472106337}
onItemSlotted:
m_PersistentCalls:
m_Calls: []
OnFailure:
onItemSlotRemoved:
m_PersistentCalls:
m_Calls: []
currentlySlottedItem: {fileID: 0}
slottedItemRenderer: {fileID: 0}
onCorrectItemSlotted:
m_PersistentCalls:
m_Calls: []
onIncorrectItemSlotted:
m_PersistentCalls:
m_Calls: []
onForbiddenItemSlotted:
m_PersistentCalls:
m_Calls: []
slottedItemRenderer: {fileID: 3806274462998212361}
--- !u!114 &3169137887822749614
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 7145022056631397938}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 1101f6c4eb04423b89dc78dc7c9f1aae, type: 3}
m_Name:
m_EditorClassIdentifier:
stepData: {fileID: 11400000, guid: 28848561ff31fe24ea9f8590dee0bf8f, type: 2}

View File

@@ -12,7 +12,6 @@ GameObject:
- component: {fileID: 8875860401447896107}
- component: {fileID: 5057760771402457000}
- component: {fileID: 5387498764853775290}
- component: {fileID: 6499593962557772468}
- component: {fileID: 2433130051631076285}
m_Layer: 10
m_Name: SoundBird
@@ -150,20 +149,21 @@ MonoBehaviour:
m_Script: {fileID: 11500000, guid: 73d6494a73174ffabc6a7d3089d51e73, type: 3}
m_Name:
m_EditorClassIdentifier:
--- !u!114 &6499593962557772468
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 588897581313790951}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 7846448751da4bdbaaa5cb87890dca42, type: 3}
m_Name:
m_EditorClassIdentifier:
itemData: {fileID: 11400000, guid: d28f5774afad9d14f823601707150700, type: 2}
iconRenderer: {fileID: 8875860401447896107}
isOneTime: 0
cooldown: -1
characterToInteract: 1
interactionStarted:
m_PersistentCalls:
m_Calls: []
interactionInterrupted:
m_PersistentCalls:
m_Calls: []
characterArrived:
m_PersistentCalls:
m_Calls: []
interactionComplete:
m_PersistentCalls:
m_Calls: []
--- !u!114 &2433130051631076285
MonoBehaviour:
m_ObjectHideFlags: 0
@@ -176,13 +176,23 @@ MonoBehaviour:
m_Script: {fileID: 11500000, guid: ec1a2e6e32f746c4990c579e13b79104, type: 3}
m_Name:
m_EditorClassIdentifier:
OnSuccess:
itemData: {fileID: 11400000, guid: d28f5774afad9d14f823601707150700, type: 2}
iconRenderer: {fileID: 8875860401447896107}
onItemSlotted:
m_PersistentCalls:
m_Calls: []
OnFailure:
onItemSlotRemoved:
m_PersistentCalls:
m_Calls: []
onCorrectItemSlotted:
m_PersistentCalls:
m_Calls: []
onIncorrectItemSlotted:
m_PersistentCalls:
m_Calls: []
onForbiddenItemSlotted:
m_PersistentCalls:
m_Calls: []
currentlySlottedItem: {fileID: 0}
slottedItemRenderer: {fileID: 6941190210788968874}
--- !u!1 &4624889622840393752
GameObject:

View File

@@ -73,8 +73,8 @@ SpriteRenderer:
m_AutoUVMaxDistance: 0.5
m_AutoUVMaxAngle: 89
m_LightmapParameters: {fileID: 0}
m_SortingLayerID: 0
m_SortingLayer: 0
m_SortingLayerID: 622133659
m_SortingLayer: -1
m_SortingOrder: 0
m_Sprite: {fileID: 8944853044452083345, guid: 4ad95f797558b28478685ca60bd90ff4, type: 3}
m_Color: {r: 1, g: 1, b: 1, a: 1}
@@ -134,4 +134,3 @@ MonoBehaviour:
m_EditorClassIdentifier:
speed: 1
wobbleSpeed: 1
wobbleAmount: 0.1

View File

@@ -14,7 +14,7 @@ GameObject:
- component: {fileID: 7616859841301711022}
- component: {fileID: 592045584872845087}
m_Layer: 10
m_Name: BasePickup
m_Name: BurgerBuns
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
@@ -30,8 +30,8 @@ Transform:
serializedVersion: 2
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 3.405, y: 0, z: 0}
m_LocalScale: {x: 4, y: 4, z: 1}
m_ConstrainProportionsScale: 0
m_LocalScale: {x: 2.5, y: 2.5, z: 0.625}
m_ConstrainProportionsScale: 1
m_Children: []
m_Father: {fileID: 0}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
@@ -79,15 +79,15 @@ SpriteRenderer:
m_SortingLayerID: 0
m_SortingLayer: 0
m_SortingOrder: 1
m_Sprite: {fileID: 0}
m_Sprite: {fileID: 4273613496703388379, guid: 1d2396d3a6e78544083da828beb20888, type: 3}
m_Color: {r: 1, g: 1, b: 1, a: 1}
m_FlipX: 0
m_FlipY: 0
m_DrawMode: 0
m_Size: {x: 1, y: 1}
m_Size: {x: 1.76, y: 0.75}
m_AdaptiveModeThreshold: 0.5
m_SpriteTileMode: 0
m_WasSpriteAssigned: 0
m_WasSpriteAssigned: 1
m_MaskInteraction: 0
m_SpriteSortPoint: 0
--- !u!61 &3070149615425714466
@@ -127,14 +127,14 @@ BoxCollider2D:
m_Offset: {x: 0, y: 0}
m_SpriteTilingProperty:
border: {x: 0, y: 0, z: 0, w: 0}
pivot: {x: 0, y: 0}
oldSize: {x: 0, y: 0}
newSize: {x: 0, y: 0}
adaptiveTilingThreshold: 0
pivot: {x: 0.5, y: 0.5}
oldSize: {x: 1.76, y: 0.75}
newSize: {x: 1.76, y: 0.75}
adaptiveTilingThreshold: 0.5
drawMode: 0
adaptiveTiling: 0
m_AutoTiling: 0
m_Size: {x: 1, y: 1}
m_Size: {x: 2, y: 1.5}
m_EdgeRadius: 0
--- !u!114 &7616859841301711022
MonoBehaviour:
@@ -148,6 +148,21 @@ MonoBehaviour:
m_Script: {fileID: 11500000, guid: 73d6494a73174ffabc6a7d3089d51e73, type: 3}
m_Name:
m_EditorClassIdentifier:
isOneTime: 0
cooldown: -1
characterToInteract: 1
interactionStarted:
m_PersistentCalls:
m_Calls: []
interactionInterrupted:
m_PersistentCalls:
m_Calls: []
characterArrived:
m_PersistentCalls:
m_Calls: []
interactionComplete:
m_PersistentCalls:
m_Calls: []
--- !u!114 &592045584872845087
MonoBehaviour:
m_ObjectHideFlags: 0
@@ -160,5 +175,5 @@ MonoBehaviour:
m_Script: {fileID: 11500000, guid: 7846448751da4bdbaaa5cb87890dca42, type: 3}
m_Name:
m_EditorClassIdentifier:
itemData: {fileID: 0}
itemData: {fileID: 11400000, guid: 0c6986639ca176a419c92f5a327d95ce, type: 2}
iconRenderer: {fileID: 7494677664706785084}

View File

@@ -127,31 +127,5 @@ PrefabInstance:
m_RemovedComponents: []
m_RemovedGameObjects: []
m_AddedGameObjects: []
m_AddedComponents:
- targetCorrespondingSourceObject: {fileID: 7447346505753002421, guid: bf4b9d7045397f946b2125b1ad4a3fbd, type: 3}
insertIndex: -1
addedObject: {fileID: 200688012287672078}
m_AddedComponents: []
m_SourcePrefab: {fileID: 100100000, guid: bf4b9d7045397f946b2125b1ad4a3fbd, type: 3}
--- !u!1 &5336239774528417475 stripped
GameObject:
m_CorrespondingSourceObject: {fileID: 7447346505753002421, guid: bf4b9d7045397f946b2125b1ad4a3fbd, type: 3}
m_PrefabInstance: {fileID: 3266354364519034742}
m_PrefabAsset: {fileID: 0}
--- !u!114 &200688012287672078
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 5336239774528417475}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 21401a3b30134380bb205964d9e5c67d, type: 3}
m_Name:
m_EditorClassIdentifier:
OnSuccess:
m_PersistentCalls:
m_Calls: []
OnFailure:
m_PersistentCalls:
m_Calls: []

View File

@@ -0,0 +1,161 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!1001 &9194176465486785202
PrefabInstance:
m_ObjectHideFlags: 0
serializedVersion: 2
m_Modification:
serializedVersion: 3
m_TransformParent: {fileID: 0}
m_Modifications:
- target: {fileID: 592045584872845087, guid: bf4b9d7045397f946b2125b1ad4a3fbd, type: 3}
propertyPath: itemData
value:
objectReference: {fileID: 11400000, guid: ab57c8237aac144439a18d69f56d36c6, type: 2}
- target: {fileID: 1730119453103664125, guid: bf4b9d7045397f946b2125b1ad4a3fbd, type: 3}
propertyPath: m_LocalScale.x
value: 0.8000001
objectReference: {fileID: 0}
- target: {fileID: 1730119453103664125, guid: bf4b9d7045397f946b2125b1ad4a3fbd, type: 3}
propertyPath: m_LocalScale.y
value: 0.8000001
objectReference: {fileID: 0}
- target: {fileID: 1730119453103664125, guid: bf4b9d7045397f946b2125b1ad4a3fbd, type: 3}
propertyPath: m_LocalScale.z
value: 0.26666668
objectReference: {fileID: 0}
- target: {fileID: 1730119453103664125, guid: bf4b9d7045397f946b2125b1ad4a3fbd, type: 3}
propertyPath: m_LocalPosition.x
value: 0.15
objectReference: {fileID: 0}
- target: {fileID: 1730119453103664125, guid: bf4b9d7045397f946b2125b1ad4a3fbd, type: 3}
propertyPath: m_LocalPosition.y
value: -0.4
objectReference: {fileID: 0}
- target: {fileID: 1730119453103664125, guid: bf4b9d7045397f946b2125b1ad4a3fbd, type: 3}
propertyPath: m_LocalPosition.z
value: 0
objectReference: {fileID: 0}
- target: {fileID: 1730119453103664125, guid: bf4b9d7045397f946b2125b1ad4a3fbd, type: 3}
propertyPath: m_LocalRotation.w
value: 1
objectReference: {fileID: 0}
- target: {fileID: 1730119453103664125, guid: bf4b9d7045397f946b2125b1ad4a3fbd, type: 3}
propertyPath: m_LocalRotation.x
value: 0
objectReference: {fileID: 0}
- target: {fileID: 1730119453103664125, guid: bf4b9d7045397f946b2125b1ad4a3fbd, type: 3}
propertyPath: m_LocalRotation.y
value: 0
objectReference: {fileID: 0}
- target: {fileID: 1730119453103664125, guid: bf4b9d7045397f946b2125b1ad4a3fbd, type: 3}
propertyPath: m_LocalRotation.z
value: 0
objectReference: {fileID: 0}
- target: {fileID: 1730119453103664125, guid: bf4b9d7045397f946b2125b1ad4a3fbd, type: 3}
propertyPath: m_LocalEulerAnglesHint.x
value: 0
objectReference: {fileID: 0}
- target: {fileID: 1730119453103664125, guid: bf4b9d7045397f946b2125b1ad4a3fbd, type: 3}
propertyPath: m_LocalEulerAnglesHint.y
value: 0
objectReference: {fileID: 0}
- target: {fileID: 1730119453103664125, guid: bf4b9d7045397f946b2125b1ad4a3fbd, type: 3}
propertyPath: m_LocalEulerAnglesHint.z
value: 0
objectReference: {fileID: 0}
- target: {fileID: 1730119453103664125, guid: bf4b9d7045397f946b2125b1ad4a3fbd, type: 3}
propertyPath: m_ConstrainProportionsScale
value: 1
objectReference: {fileID: 0}
- target: {fileID: 3070149615425714466, guid: bf4b9d7045397f946b2125b1ad4a3fbd, type: 3}
propertyPath: m_Size.x
value: 3.5
objectReference: {fileID: 0}
- target: {fileID: 3070149615425714466, guid: bf4b9d7045397f946b2125b1ad4a3fbd, type: 3}
propertyPath: m_Size.y
value: 3.5
objectReference: {fileID: 0}
- target: {fileID: 3070149615425714466, guid: bf4b9d7045397f946b2125b1ad4a3fbd, type: 3}
propertyPath: m_SpriteTilingProperty.pivot.x
value: 0.5
objectReference: {fileID: 0}
- target: {fileID: 3070149615425714466, guid: bf4b9d7045397f946b2125b1ad4a3fbd, type: 3}
propertyPath: m_SpriteTilingProperty.pivot.y
value: 0.5
objectReference: {fileID: 0}
- target: {fileID: 3070149615425714466, guid: bf4b9d7045397f946b2125b1ad4a3fbd, type: 3}
propertyPath: m_SpriteTilingProperty.newSize.x
value: 2.24
objectReference: {fileID: 0}
- target: {fileID: 3070149615425714466, guid: bf4b9d7045397f946b2125b1ad4a3fbd, type: 3}
propertyPath: m_SpriteTilingProperty.newSize.y
value: 2.11
objectReference: {fileID: 0}
- target: {fileID: 3070149615425714466, guid: bf4b9d7045397f946b2125b1ad4a3fbd, type: 3}
propertyPath: m_SpriteTilingProperty.oldSize.x
value: 2.52
objectReference: {fileID: 0}
- target: {fileID: 3070149615425714466, guid: bf4b9d7045397f946b2125b1ad4a3fbd, type: 3}
propertyPath: m_SpriteTilingProperty.oldSize.y
value: 3.07
objectReference: {fileID: 0}
- target: {fileID: 3070149615425714466, guid: bf4b9d7045397f946b2125b1ad4a3fbd, type: 3}
propertyPath: m_SpriteTilingProperty.adaptiveTilingThreshold
value: 0.5
objectReference: {fileID: 0}
- target: {fileID: 7447346505753002421, guid: bf4b9d7045397f946b2125b1ad4a3fbd, type: 3}
propertyPath: m_Name
value: FootballBird
objectReference: {fileID: 0}
- target: {fileID: 7494677664706785084, guid: bf4b9d7045397f946b2125b1ad4a3fbd, type: 3}
propertyPath: m_Size.x
value: 2.24
objectReference: {fileID: 0}
- target: {fileID: 7494677664706785084, guid: bf4b9d7045397f946b2125b1ad4a3fbd, type: 3}
propertyPath: m_Size.y
value: 2.11
objectReference: {fileID: 0}
- target: {fileID: 7494677664706785084, guid: bf4b9d7045397f946b2125b1ad4a3fbd, type: 3}
propertyPath: m_Sprite
value:
objectReference: {fileID: 804776353370782802, guid: b187e41d8728aba4b90917cc22005463, type: 3}
- target: {fileID: 7494677664706785084, guid: bf4b9d7045397f946b2125b1ad4a3fbd, type: 3}
propertyPath: m_WasSpriteAssigned
value: 1
objectReference: {fileID: 0}
- target: {fileID: 7616859841301711022, guid: bf4b9d7045397f946b2125b1ad4a3fbd, type: 3}
propertyPath: isOneTime
value: 1
objectReference: {fileID: 0}
- target: {fileID: 7616859841301711022, guid: bf4b9d7045397f946b2125b1ad4a3fbd, type: 3}
propertyPath: characterToInteract
value: 0
objectReference: {fileID: 0}
m_RemovedComponents:
- {fileID: 592045584872845087, guid: bf4b9d7045397f946b2125b1ad4a3fbd, type: 3}
m_RemovedGameObjects: []
m_AddedGameObjects: []
m_AddedComponents:
- targetCorrespondingSourceObject: {fileID: 7447346505753002421, guid: bf4b9d7045397f946b2125b1ad4a3fbd, type: 3}
insertIndex: -1
addedObject: {fileID: 1972611059221495588}
m_SourcePrefab: {fileID: 100100000, guid: bf4b9d7045397f946b2125b1ad4a3fbd, type: 3}
--- !u!1 &1784002662241348359 stripped
GameObject:
m_CorrespondingSourceObject: {fileID: 7447346505753002421, guid: bf4b9d7045397f946b2125b1ad4a3fbd, type: 3}
m_PrefabInstance: {fileID: 9194176465486785202}
m_PrefabAsset: {fileID: 0}
--- !u!114 &1972611059221495588
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1784002662241348359}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 1101f6c4eb04423b89dc78dc7c9f1aae, type: 3}
m_Name:
m_EditorClassIdentifier:
stepData: {fileID: 11400000, guid: 0df54e69020c39e44b3b486cd6ac475a, type: 2}

View File

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

View File

@@ -0,0 +1,157 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!1001 &9194176465486785202
PrefabInstance:
m_ObjectHideFlags: 0
serializedVersion: 2
m_Modification:
serializedVersion: 3
m_TransformParent: {fileID: 0}
m_Modifications:
- target: {fileID: 592045584872845087, guid: bf4b9d7045397f946b2125b1ad4a3fbd, type: 3}
propertyPath: itemData
value:
objectReference: {fileID: 11400000, guid: ab57c8237aac144439a18d69f56d36c6, type: 2}
- target: {fileID: 1730119453103664125, guid: bf4b9d7045397f946b2125b1ad4a3fbd, type: 3}
propertyPath: m_LocalScale.x
value: 1.5
objectReference: {fileID: 0}
- target: {fileID: 1730119453103664125, guid: bf4b9d7045397f946b2125b1ad4a3fbd, type: 3}
propertyPath: m_LocalScale.y
value: 1.5
objectReference: {fileID: 0}
- target: {fileID: 1730119453103664125, guid: bf4b9d7045397f946b2125b1ad4a3fbd, type: 3}
propertyPath: m_LocalScale.z
value: 0.5
objectReference: {fileID: 0}
- target: {fileID: 1730119453103664125, guid: bf4b9d7045397f946b2125b1ad4a3fbd, type: 3}
propertyPath: m_LocalPosition.x
value: 54.83
objectReference: {fileID: 0}
- target: {fileID: 1730119453103664125, guid: bf4b9d7045397f946b2125b1ad4a3fbd, type: 3}
propertyPath: m_LocalPosition.y
value: -35.53
objectReference: {fileID: 0}
- target: {fileID: 1730119453103664125, guid: bf4b9d7045397f946b2125b1ad4a3fbd, type: 3}
propertyPath: m_LocalPosition.z
value: 0
objectReference: {fileID: 0}
- target: {fileID: 1730119453103664125, guid: bf4b9d7045397f946b2125b1ad4a3fbd, type: 3}
propertyPath: m_LocalRotation.w
value: 1
objectReference: {fileID: 0}
- target: {fileID: 1730119453103664125, guid: bf4b9d7045397f946b2125b1ad4a3fbd, type: 3}
propertyPath: m_LocalRotation.x
value: 0
objectReference: {fileID: 0}
- target: {fileID: 1730119453103664125, guid: bf4b9d7045397f946b2125b1ad4a3fbd, type: 3}
propertyPath: m_LocalRotation.y
value: 0
objectReference: {fileID: 0}
- target: {fileID: 1730119453103664125, guid: bf4b9d7045397f946b2125b1ad4a3fbd, type: 3}
propertyPath: m_LocalRotation.z
value: 0
objectReference: {fileID: 0}
- target: {fileID: 1730119453103664125, guid: bf4b9d7045397f946b2125b1ad4a3fbd, type: 3}
propertyPath: m_LocalEulerAnglesHint.x
value: 0
objectReference: {fileID: 0}
- target: {fileID: 1730119453103664125, guid: bf4b9d7045397f946b2125b1ad4a3fbd, type: 3}
propertyPath: m_LocalEulerAnglesHint.y
value: 0
objectReference: {fileID: 0}
- target: {fileID: 1730119453103664125, guid: bf4b9d7045397f946b2125b1ad4a3fbd, type: 3}
propertyPath: m_LocalEulerAnglesHint.z
value: 0
objectReference: {fileID: 0}
- target: {fileID: 1730119453103664125, guid: bf4b9d7045397f946b2125b1ad4a3fbd, type: 3}
propertyPath: m_ConstrainProportionsScale
value: 1
objectReference: {fileID: 0}
- target: {fileID: 3070149615425714466, guid: bf4b9d7045397f946b2125b1ad4a3fbd, type: 3}
propertyPath: m_Size.x
value: 3.5
objectReference: {fileID: 0}
- target: {fileID: 3070149615425714466, guid: bf4b9d7045397f946b2125b1ad4a3fbd, type: 3}
propertyPath: m_Size.y
value: 3.5
objectReference: {fileID: 0}
- target: {fileID: 3070149615425714466, guid: bf4b9d7045397f946b2125b1ad4a3fbd, type: 3}
propertyPath: m_SpriteTilingProperty.pivot.x
value: 0.5
objectReference: {fileID: 0}
- target: {fileID: 3070149615425714466, guid: bf4b9d7045397f946b2125b1ad4a3fbd, type: 3}
propertyPath: m_SpriteTilingProperty.pivot.y
value: 0.5
objectReference: {fileID: 0}
- target: {fileID: 3070149615425714466, guid: bf4b9d7045397f946b2125b1ad4a3fbd, type: 3}
propertyPath: m_SpriteTilingProperty.newSize.x
value: 2.24
objectReference: {fileID: 0}
- target: {fileID: 3070149615425714466, guid: bf4b9d7045397f946b2125b1ad4a3fbd, type: 3}
propertyPath: m_SpriteTilingProperty.newSize.y
value: 2.11
objectReference: {fileID: 0}
- target: {fileID: 3070149615425714466, guid: bf4b9d7045397f946b2125b1ad4a3fbd, type: 3}
propertyPath: m_SpriteTilingProperty.oldSize.x
value: 2.08
objectReference: {fileID: 0}
- target: {fileID: 3070149615425714466, guid: bf4b9d7045397f946b2125b1ad4a3fbd, type: 3}
propertyPath: m_SpriteTilingProperty.oldSize.y
value: 2.83
objectReference: {fileID: 0}
- target: {fileID: 3070149615425714466, guid: bf4b9d7045397f946b2125b1ad4a3fbd, type: 3}
propertyPath: m_SpriteTilingProperty.adaptiveTilingThreshold
value: 0.5
objectReference: {fileID: 0}
- target: {fileID: 7447346505753002421, guid: bf4b9d7045397f946b2125b1ad4a3fbd, type: 3}
propertyPath: m_Name
value: HammerBird
objectReference: {fileID: 0}
- target: {fileID: 7494677664706785084, guid: bf4b9d7045397f946b2125b1ad4a3fbd, type: 3}
propertyPath: m_Size.x
value: 2.24
objectReference: {fileID: 0}
- target: {fileID: 7494677664706785084, guid: bf4b9d7045397f946b2125b1ad4a3fbd, type: 3}
propertyPath: m_Size.y
value: 2.11
objectReference: {fileID: 0}
- target: {fileID: 7494677664706785084, guid: bf4b9d7045397f946b2125b1ad4a3fbd, type: 3}
propertyPath: m_Sprite
value:
objectReference: {fileID: -5464640192890044756, guid: 1bf1b8625c66fa142a1ac7ce275cd4a6, type: 3}
- target: {fileID: 7494677664706785084, guid: bf4b9d7045397f946b2125b1ad4a3fbd, type: 3}
propertyPath: m_WasSpriteAssigned
value: 1
objectReference: {fileID: 0}
- target: {fileID: 7616859841301711022, guid: bf4b9d7045397f946b2125b1ad4a3fbd, type: 3}
propertyPath: characterToInteract
value: 0
objectReference: {fileID: 0}
m_RemovedComponents:
- {fileID: 592045584872845087, guid: bf4b9d7045397f946b2125b1ad4a3fbd, type: 3}
m_RemovedGameObjects: []
m_AddedGameObjects: []
m_AddedComponents:
- targetCorrespondingSourceObject: {fileID: 7447346505753002421, guid: bf4b9d7045397f946b2125b1ad4a3fbd, type: 3}
insertIndex: -1
addedObject: {fileID: 1972611059221495588}
m_SourcePrefab: {fileID: 100100000, guid: bf4b9d7045397f946b2125b1ad4a3fbd, type: 3}
--- !u!1 &1784002662241348359 stripped
GameObject:
m_CorrespondingSourceObject: {fileID: 7447346505753002421, guid: bf4b9d7045397f946b2125b1ad4a3fbd, type: 3}
m_PrefabInstance: {fileID: 9194176465486785202}
m_PrefabAsset: {fileID: 0}
--- !u!114 &1972611059221495588
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1784002662241348359}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 1101f6c4eb04423b89dc78dc7c9f1aae, type: 3}
m_Name:
m_EditorClassIdentifier:
stepData: {fileID: 11400000, guid: 829fc7c8046e0844f93bf810dc1f0ebd, type: 2}

View File

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

View File

@@ -128,9 +128,6 @@ PrefabInstance:
m_RemovedGameObjects: []
m_AddedGameObjects: []
m_AddedComponents:
- targetCorrespondingSourceObject: {fileID: 7447346505753002421, guid: bf4b9d7045397f946b2125b1ad4a3fbd, type: 3}
insertIndex: -1
addedObject: {fileID: 5935055277585311711}
- targetCorrespondingSourceObject: {fileID: 7447346505753002421, guid: bf4b9d7045397f946b2125b1ad4a3fbd, type: 3}
insertIndex: -1
addedObject: {fileID: 5172306257923753614}
@@ -140,24 +137,6 @@ GameObject:
m_CorrespondingSourceObject: {fileID: 7447346505753002421, guid: bf4b9d7045397f946b2125b1ad4a3fbd, type: 3}
m_PrefabInstance: {fileID: 8543660602505065938}
m_PrefabAsset: {fileID: 0}
--- !u!114 &5935055277585311711
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1282228733406082151}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 21401a3b30134380bb205964d9e5c67d, type: 3}
m_Name:
m_EditorClassIdentifier:
OnSuccess:
m_PersistentCalls:
m_Calls: []
OnFailure:
m_PersistentCalls:
m_Calls: []
--- !u!114 &5172306257923753614
MonoBehaviour:
m_ObjectHideFlags: 0

View File

@@ -10,6 +10,7 @@ GameObject:
m_Component:
- component: {fileID: 7111145574660306503}
- component: {fileID: 3889795708575321074}
- component: {fileID: 7249681423942450184}
m_Layer: 0
m_Name: Left_Tile2_0
m_TagString: Untagged
@@ -26,7 +27,7 @@ Transform:
m_GameObject: {fileID: 864595161669782950}
serializedVersion: 2
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_ConstrainProportionsScale: 0
m_Children: []
@@ -73,8 +74,8 @@ SpriteRenderer:
m_AutoUVMaxDistance: 0.5
m_AutoUVMaxAngle: 89
m_LightmapParameters: {fileID: 0}
m_SortingLayerID: 0
m_SortingLayer: 0
m_SortingLayerID: -1132846201
m_SortingLayer: 1
m_SortingOrder: 0
m_Sprite: {fileID: 7559449286846427561, guid: e3d18475ab86b1246912f497417465f8, type: 3}
m_Color: {r: 1, g: 1, b: 1, a: 1}
@@ -87,6 +88,63 @@ SpriteRenderer:
m_WasSpriteAssigned: 1
m_MaskInteraction: 0
m_SpriteSortPoint: 0
--- !u!60 &7249681423942450184
PolygonCollider2D:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 864595161669782950}
m_Enabled: 1
serializedVersion: 3
m_Density: 1
m_Material: {fileID: 0}
m_IncludeLayers:
serializedVersion: 2
m_Bits: 0
m_ExcludeLayers:
serializedVersion: 2
m_Bits: 0
m_LayerOverridePriority: 0
m_ForceSendLayers:
serializedVersion: 2
m_Bits: 4294967295
m_ForceReceiveLayers:
serializedVersion: 2
m_Bits: 4294967295
m_ContactCaptureLayers:
serializedVersion: 2
m_Bits: 4294967295
m_CallbackLayers:
serializedVersion: 2
m_Bits: 4294967295
m_IsTrigger: 0
m_UsedByEffector: 0
m_CompositeOperation: 0
m_CompositeOrder: 0
m_Offset: {x: 0, y: 0}
m_SpriteTilingProperty:
border: {x: 0, y: 0, z: 0, w: 0}
pivot: {x: 0.5, y: 0.5}
oldSize: {x: 2.37, y: 5}
newSize: {x: 2.37, y: 5}
adaptiveTilingThreshold: 0.5
drawMode: 0
adaptiveTiling: 0
m_AutoTiling: 0
m_Points:
m_Paths:
- - {x: 0.575, y: -1.5}
- {x: 0.185, y: -0.63}
- {x: 1.145, y: 0.85999995}
- {x: 1.185, y: 1.41}
- {x: 0.835, y: 1.8499999}
- {x: 0.635, y: 2.5}
- {x: -1.185, y: 2.5}
- {x: -1.185, y: -2.5}
- {x: 0.635, y: -2.5}
- {x: 0.625, y: -1.64}
m_UseDelaunayMesh: 0
--- !u!1 &2171518497100337372
GameObject:
m_ObjectHideFlags: 0
@@ -97,6 +155,7 @@ GameObject:
m_Component:
- component: {fileID: 1003080013996268193}
- component: {fileID: 4856205316150460481}
- component: {fileID: 2843103852598642252}
m_Layer: 0
m_Name: Right_Tile1_0
m_TagString: Untagged
@@ -113,7 +172,7 @@ Transform:
m_GameObject: {fileID: 2171518497100337372}
serializedVersion: 2
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_ConstrainProportionsScale: 0
m_Children: []
@@ -160,8 +219,8 @@ SpriteRenderer:
m_AutoUVMaxDistance: 0.5
m_AutoUVMaxAngle: 89
m_LightmapParameters: {fileID: 0}
m_SortingLayerID: 0
m_SortingLayer: 0
m_SortingLayerID: -1132846201
m_SortingLayer: 1
m_SortingOrder: 0
m_Sprite: {fileID: 3241551651087908563, guid: 8e7c95ebe5325df4395d97ea2ace65d7, type: 3}
m_Color: {r: 1, g: 1, b: 1, a: 1}
@@ -174,6 +233,69 @@ SpriteRenderer:
m_WasSpriteAssigned: 1
m_MaskInteraction: 0
m_SpriteSortPoint: 0
--- !u!60 &2843103852598642252
PolygonCollider2D:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 2171518497100337372}
m_Enabled: 1
serializedVersion: 3
m_Density: 1
m_Material: {fileID: 0}
m_IncludeLayers:
serializedVersion: 2
m_Bits: 0
m_ExcludeLayers:
serializedVersion: 2
m_Bits: 0
m_LayerOverridePriority: 0
m_ForceSendLayers:
serializedVersion: 2
m_Bits: 4294967295
m_ForceReceiveLayers:
serializedVersion: 2
m_Bits: 4294967295
m_ContactCaptureLayers:
serializedVersion: 2
m_Bits: 4294967295
m_CallbackLayers:
serializedVersion: 2
m_Bits: 4294967295
m_IsTrigger: 0
m_UsedByEffector: 0
m_CompositeOperation: 0
m_CompositeOrder: 0
m_Offset: {x: 0, y: 0}
m_SpriteTilingProperty:
border: {x: 0, y: 0, z: 0, w: 0}
pivot: {x: 0.5, y: 0.5}
oldSize: {x: 2.65, y: 5}
newSize: {x: 2.65, y: 5}
adaptiveTilingThreshold: 0.5
drawMode: 0
adaptiveTiling: 0
m_AutoTiling: 0
m_Points:
m_Paths:
- - {x: -0.48499998, y: 2.5}
- {x: -0.49499997, y: 2.19}
- {x: 0.035, y: 1.66}
- {x: 0.035, y: 1.42}
- {x: -0.24499999, y: 1.15}
- {x: -0.285, y: 0.90999997}
- {x: -0.13499999, y: 0.45999998}
- {x: -1.115, y: -0.03}
- {x: -1.3249999, y: -0.35}
- {x: -1.2049999, y: -0.84999996}
- {x: -0.36499998, y: -1.0699999}
- {x: -0.585, y: -1.27}
- {x: -0.625, y: -1.65}
- {x: -0.48499998, y: -2.5}
- {x: 1.3249999, y: -2.5}
- {x: 1.3249999, y: 2.5}
m_UseDelaunayMesh: 0
--- !u!1 &2956826569642009690
GameObject:
m_ObjectHideFlags: 0
@@ -183,6 +305,7 @@ GameObject:
serializedVersion: 6
m_Component:
- component: {fileID: 4925660644986369589}
- component: {fileID: 2488201930835981397}
m_Layer: 0
m_Name: Tile1
m_TagString: Untagged
@@ -207,3 +330,16 @@ Transform:
- {fileID: 1003080013996268193}
m_Father: {fileID: 0}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!114 &2488201930835981397
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 2956826569642009690}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 41def183b6714aca97663d74cc2d0678, type: 3}
m_Name:
m_EditorClassIdentifier:
tileIndex: 0

View File

@@ -26,7 +26,7 @@ Transform:
m_GameObject: {fileID: 864595161669782950}
serializedVersion: 2
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_ConstrainProportionsScale: 0
m_Children: []
@@ -73,8 +73,8 @@ SpriteRenderer:
m_AutoUVMaxDistance: 0.5
m_AutoUVMaxAngle: 89
m_LightmapParameters: {fileID: 0}
m_SortingLayerID: 0
m_SortingLayer: 0
m_SortingLayerID: -1132846201
m_SortingLayer: 1
m_SortingOrder: 0
m_Sprite: {fileID: 7559449286846427561, guid: e3d18475ab86b1246912f497417465f8, type: 3}
m_Color: {r: 1, g: 1, b: 1, a: 1}
@@ -113,7 +113,7 @@ Transform:
m_GameObject: {fileID: 2171518497100337372}
serializedVersion: 2
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_ConstrainProportionsScale: 0
m_Children: []
@@ -160,8 +160,8 @@ SpriteRenderer:
m_AutoUVMaxDistance: 0.5
m_AutoUVMaxAngle: 89
m_LightmapParameters: {fileID: 0}
m_SortingLayerID: 0
m_SortingLayer: 0
m_SortingLayerID: -1132846201
m_SortingLayer: 1
m_SortingOrder: 0
m_Sprite: {fileID: 3241551651087908563, guid: 8e7c95ebe5325df4395d97ea2ace65d7, type: 3}
m_Color: {r: 1, g: 1, b: 1, a: 1}
@@ -183,6 +183,7 @@ GameObject:
serializedVersion: 6
m_Component:
- component: {fileID: 4925660644986369589}
- component: {fileID: 7876353970701168068}
m_Layer: 0
m_Name: Tile1_flipped
m_TagString: Untagged
@@ -207,3 +208,16 @@ Transform:
- {fileID: 1003080013996268193}
m_Father: {fileID: 0}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 180}
--- !u!114 &7876353970701168068
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 2956826569642009690}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 41def183b6714aca97663d74cc2d0678, type: 3}
m_Name:
m_EditorClassIdentifier:
tileIndex: 0

View File

@@ -26,7 +26,7 @@ Transform:
m_GameObject: {fileID: 864595161669782950}
serializedVersion: 2
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_ConstrainProportionsScale: 0
m_Children: []
@@ -73,8 +73,8 @@ SpriteRenderer:
m_AutoUVMaxDistance: 0.5
m_AutoUVMaxAngle: 89
m_LightmapParameters: {fileID: 0}
m_SortingLayerID: 0
m_SortingLayer: 0
m_SortingLayerID: -1132846201
m_SortingLayer: 1
m_SortingOrder: 0
m_Sprite: {fileID: 2249565037559538771, guid: 836c1ae2997af4045b714ceaff665a6e, type: 3}
m_Color: {r: 1, g: 1, b: 1, a: 1}
@@ -113,7 +113,7 @@ Transform:
m_GameObject: {fileID: 2171518497100337372}
serializedVersion: 2
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_ConstrainProportionsScale: 0
m_Children: []
@@ -160,8 +160,8 @@ SpriteRenderer:
m_AutoUVMaxDistance: 0.5
m_AutoUVMaxAngle: 89
m_LightmapParameters: {fileID: 0}
m_SortingLayerID: 0
m_SortingLayer: 0
m_SortingLayerID: -1132846201
m_SortingLayer: 1
m_SortingOrder: 0
m_Sprite: {fileID: 2764166773722941650, guid: f7ec8080b46b20f459d02e73b12f1694, type: 3}
m_Color: {r: 1, g: 1, b: 1, a: 1}
@@ -183,6 +183,7 @@ GameObject:
serializedVersion: 6
m_Component:
- component: {fileID: 4925660644986369589}
- component: {fileID: 2017387953723006367}
m_Layer: 0
m_Name: Tile2
m_TagString: Untagged
@@ -207,3 +208,16 @@ Transform:
- {fileID: 1003080013996268193}
m_Father: {fileID: 0}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!114 &2017387953723006367
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 2956826569642009690}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 41def183b6714aca97663d74cc2d0678, type: 3}
m_Name:
m_EditorClassIdentifier:
tileIndex: 0

View File

@@ -26,7 +26,7 @@ Transform:
m_GameObject: {fileID: 864595161669782950}
serializedVersion: 2
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_ConstrainProportionsScale: 0
m_Children: []
@@ -73,8 +73,8 @@ SpriteRenderer:
m_AutoUVMaxDistance: 0.5
m_AutoUVMaxAngle: 89
m_LightmapParameters: {fileID: 0}
m_SortingLayerID: 0
m_SortingLayer: 0
m_SortingLayerID: -1132846201
m_SortingLayer: 1
m_SortingOrder: 0
m_Sprite: {fileID: 2249565037559538771, guid: 836c1ae2997af4045b714ceaff665a6e, type: 3}
m_Color: {r: 1, g: 1, b: 1, a: 1}
@@ -113,7 +113,7 @@ Transform:
m_GameObject: {fileID: 2171518497100337372}
serializedVersion: 2
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_ConstrainProportionsScale: 0
m_Children: []
@@ -160,8 +160,8 @@ SpriteRenderer:
m_AutoUVMaxDistance: 0.5
m_AutoUVMaxAngle: 89
m_LightmapParameters: {fileID: 0}
m_SortingLayerID: 0
m_SortingLayer: 0
m_SortingLayerID: -1132846201
m_SortingLayer: 1
m_SortingOrder: 0
m_Sprite: {fileID: 2764166773722941650, guid: f7ec8080b46b20f459d02e73b12f1694, type: 3}
m_Color: {r: 1, g: 1, b: 1, a: 1}
@@ -183,6 +183,7 @@ GameObject:
serializedVersion: 6
m_Component:
- component: {fileID: 4925660644986369589}
- component: {fileID: 451715946189956124}
m_Layer: 0
m_Name: Tile2_flipped
m_TagString: Untagged
@@ -207,3 +208,16 @@ Transform:
- {fileID: 1003080013996268193}
m_Father: {fileID: 0}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 180}
--- !u!114 &451715946189956124
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 2956826569642009690}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 41def183b6714aca97663d74cc2d0678, type: 3}
m_Name:
m_EditorClassIdentifier:
tileIndex: 0

View File

@@ -26,7 +26,7 @@ Transform:
m_GameObject: {fileID: 864595161669782950}
serializedVersion: 2
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_ConstrainProportionsScale: 0
m_Children: []
@@ -73,8 +73,8 @@ SpriteRenderer:
m_AutoUVMaxDistance: 0.5
m_AutoUVMaxAngle: 89
m_LightmapParameters: {fileID: 0}
m_SortingLayerID: 0
m_SortingLayer: 0
m_SortingLayerID: -1132846201
m_SortingLayer: 1
m_SortingOrder: 0
m_Sprite: {fileID: 2249565037559538771, guid: 836c1ae2997af4045b714ceaff665a6e, type: 3}
m_Color: {r: 1, g: 1, b: 1, a: 1}
@@ -113,7 +113,7 @@ Transform:
m_GameObject: {fileID: 2171518497100337372}
serializedVersion: 2
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_ConstrainProportionsScale: 0
m_Children: []
@@ -160,8 +160,8 @@ SpriteRenderer:
m_AutoUVMaxDistance: 0.5
m_AutoUVMaxAngle: 89
m_LightmapParameters: {fileID: 0}
m_SortingLayerID: 0
m_SortingLayer: 0
m_SortingLayerID: -1132846201
m_SortingLayer: 1
m_SortingOrder: 0
m_Sprite: {fileID: 3241551651087908563, guid: 8e7c95ebe5325df4395d97ea2ace65d7, type: 3}
m_Color: {r: 1, g: 1, b: 1, a: 1}
@@ -183,6 +183,7 @@ GameObject:
serializedVersion: 6
m_Component:
- component: {fileID: 4925660644986369589}
- component: {fileID: 8822397971507360111}
m_Layer: 0
m_Name: Tile3
m_TagString: Untagged
@@ -207,3 +208,16 @@ Transform:
- {fileID: 1003080013996268193}
m_Father: {fileID: 0}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!114 &8822397971507360111
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 2956826569642009690}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 41def183b6714aca97663d74cc2d0678, type: 3}
m_Name:
m_EditorClassIdentifier:
tileIndex: 0

View File

@@ -26,7 +26,7 @@ Transform:
m_GameObject: {fileID: 864595161669782950}
serializedVersion: 2
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_ConstrainProportionsScale: 0
m_Children: []
@@ -73,8 +73,8 @@ SpriteRenderer:
m_AutoUVMaxDistance: 0.5
m_AutoUVMaxAngle: 89
m_LightmapParameters: {fileID: 0}
m_SortingLayerID: 0
m_SortingLayer: 0
m_SortingLayerID: -1132846201
m_SortingLayer: 1
m_SortingOrder: 0
m_Sprite: {fileID: 2249565037559538771, guid: 836c1ae2997af4045b714ceaff665a6e, type: 3}
m_Color: {r: 1, g: 1, b: 1, a: 1}
@@ -113,7 +113,7 @@ Transform:
m_GameObject: {fileID: 2171518497100337372}
serializedVersion: 2
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_ConstrainProportionsScale: 0
m_Children: []
@@ -160,8 +160,8 @@ SpriteRenderer:
m_AutoUVMaxDistance: 0.5
m_AutoUVMaxAngle: 89
m_LightmapParameters: {fileID: 0}
m_SortingLayerID: 0
m_SortingLayer: 0
m_SortingLayerID: -1132846201
m_SortingLayer: 1
m_SortingOrder: 0
m_Sprite: {fileID: 3241551651087908563, guid: 8e7c95ebe5325df4395d97ea2ace65d7, type: 3}
m_Color: {r: 1, g: 1, b: 1, a: 1}
@@ -183,6 +183,7 @@ GameObject:
serializedVersion: 6
m_Component:
- component: {fileID: 4925660644986369589}
- component: {fileID: 2006557459409230470}
m_Layer: 0
m_Name: Tile3_flipped
m_TagString: Untagged
@@ -207,3 +208,16 @@ Transform:
- {fileID: 1003080013996268193}
m_Father: {fileID: 0}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 180}
--- !u!114 &2006557459409230470
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 2956826569642009690}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 41def183b6714aca97663d74cc2d0678, type: 3}
m_Name:
m_EditorClassIdentifier:
tileIndex: 0

View File

@@ -50,7 +50,7 @@ PrefabInstance:
objectReference: {fileID: 0}
- target: {fileID: 7447346505753002421, guid: bf4b9d7045397f946b2125b1ad4a3fbd, type: 3}
propertyPath: m_Name
value: BasePuzzlePickup
value: BurgerBuns
objectReference: {fileID: 0}
m_RemovedComponents: []
m_RemovedGameObjects: []

View File

@@ -0,0 +1,125 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!29 &1
OcclusionCullingSettings:
m_ObjectHideFlags: 0
serializedVersion: 2
m_OcclusionBakeSettings:
smallestOccluder: 5
smallestHole: 0.25
backfaceThreshold: 100
m_SceneGUID: 00000000000000000000000000000000
m_OcclusionCullingData: {fileID: 0}
--- !u!104 &2
RenderSettings:
m_ObjectHideFlags: 0
serializedVersion: 10
m_Fog: 0
m_FogColor: {r: 0.5, g: 0.5, b: 0.5, a: 1}
m_FogMode: 3
m_FogDensity: 0.01
m_LinearFogStart: 0
m_LinearFogEnd: 300
m_AmbientSkyColor: {r: 0.212, g: 0.227, b: 0.259, a: 1}
m_AmbientEquatorColor: {r: 0.114, g: 0.125, b: 0.133, a: 1}
m_AmbientGroundColor: {r: 0.047, g: 0.043, b: 0.035, a: 1}
m_AmbientIntensity: 1
m_AmbientMode: 3
m_SubtractiveShadowColor: {r: 0.42, g: 0.478, b: 0.627, a: 1}
m_SkyboxMaterial: {fileID: 0}
m_HaloStrength: 0.5
m_FlareStrength: 1
m_FlareFadeSpeed: 3
m_HaloTexture: {fileID: 0}
m_SpotCookie: {fileID: 10001, guid: 0000000000000000e000000000000000, type: 0}
m_DefaultReflectionMode: 0
m_DefaultReflectionResolution: 128
m_ReflectionBounces: 1
m_ReflectionIntensity: 1
m_CustomReflection: {fileID: 0}
m_Sun: {fileID: 0}
m_UseRadianceAmbientProbe: 0
--- !u!157 &3
LightmapSettings:
m_ObjectHideFlags: 0
serializedVersion: 13
m_BakeOnSceneLoad: 0
m_GISettings:
serializedVersion: 2
m_BounceScale: 1
m_IndirectOutputScale: 1
m_AlbedoBoost: 1
m_EnvironmentLightingMode: 0
m_EnableBakedLightmaps: 0
m_EnableRealtimeLightmaps: 0
m_LightmapEditorSettings:
serializedVersion: 12
m_Resolution: 2
m_BakeResolution: 40
m_AtlasSize: 1024
m_AO: 0
m_AOMaxDistance: 1
m_CompAOExponent: 1
m_CompAOExponentDirect: 0
m_ExtractAmbientOcclusion: 0
m_Padding: 2
m_LightmapParameters: {fileID: 0}
m_LightmapsBakeMode: 1
m_TextureCompression: 1
m_ReflectionCompression: 2
m_MixedBakeMode: 2
m_BakeBackend: 1
m_PVRSampling: 1
m_PVRDirectSampleCount: 32
m_PVRSampleCount: 512
m_PVRBounces: 2
m_PVREnvironmentSampleCount: 256
m_PVREnvironmentReferencePointCount: 2048
m_PVRFilteringMode: 1
m_PVRDenoiserTypeDirect: 1
m_PVRDenoiserTypeIndirect: 1
m_PVRDenoiserTypeAO: 1
m_PVRFilterTypeDirect: 0
m_PVRFilterTypeIndirect: 0
m_PVRFilterTypeAO: 0
m_PVREnvironmentMIS: 1
m_PVRCulling: 1
m_PVRFilteringGaussRadiusDirect: 1
m_PVRFilteringGaussRadiusIndirect: 1
m_PVRFilteringGaussRadiusAO: 1
m_PVRFilteringAtrousPositionSigmaDirect: 0.5
m_PVRFilteringAtrousPositionSigmaIndirect: 2
m_PVRFilteringAtrousPositionSigmaAO: 1
m_ExportTrainingData: 0
m_TrainingDataDestination: TrainingData
m_LightProbeSampleCountMultiplier: 4
m_LightingDataAsset: {fileID: 20201, guid: 0000000000000000f000000000000000, type: 0}
m_LightingSettings: {fileID: 0}
--- !u!196 &4
NavMeshSettings:
serializedVersion: 2
m_ObjectHideFlags: 0
m_BuildSettings:
serializedVersion: 3
agentTypeID: 0
agentRadius: 0.5
agentHeight: 2
agentSlope: 45
agentClimb: 0.4
ledgeDropHeight: 0
maxJumpAcrossDistance: 0
minRegionArea: 2
manualCellSize: 0
cellSize: 0.16666667
manualTileSize: 0
tileSize: 256
buildHeightMesh: 0
maxJobWorkers: 0
preserveTilesOutsideBounds: 0
debug:
m_Flags: 0
m_NavMeshData: {fileID: 0}
--- !u!1660057539 &9223372036854775807
SceneRoots:
m_ObjectHideFlags: 0
m_Roots: []

View File

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

View File

@@ -1612,6 +1612,21 @@ MonoBehaviour:
m_EditorClassIdentifier:
itemData: {fileID: 11400000, guid: e0fad48a84a6b6346ac17c84bc512500, type: 2}
iconRenderer: {fileID: 1631660128}
onItemSlotted:
m_PersistentCalls:
m_Calls: []
onItemSlotRemoved:
m_PersistentCalls:
m_Calls: []
onCorrectItemSlotted:
m_PersistentCalls:
m_Calls: []
onIncorrectItemSlotted:
m_PersistentCalls:
m_Calls: []
onForbiddenItemSlotted:
m_PersistentCalls:
m_Calls: []
slottedItemRenderer: {fileID: 124275613}
--- !u!212 &1631660128 stripped
SpriteRenderer:
@@ -1819,7 +1834,7 @@ MonoBehaviour:
m_EditorClassIdentifier:
version: 1
data:
dataString: UEsDBBQAAAgIAAAIIewb8cShXAIAABIFAAALACQAZ3JhcGgwLmpzb24KACAAAAAAAAEAGAAAgD7V3rGdAQCAPtXesZ0BAIA+1d6xnQF1VE1z2jAQ/SuMzk3HkNBAby0E0gMJE9rJxRchrbEGWfJIcoBk+O/dlW3s0OnJ0nv78fZD/mDK+BJEsG7plFxZCez7gNGZfRl05CMc+c6ajXqH1uZVyZCTEY82Lzwoi/iQ3LwtIDglfpidJuMEwcqozLriQe5gZn3wCGdce0DK2UDeBqGPATvi52ZKLic8je7p9I6naTI441GACeA609awNautKiM0L0qQJLkzHiWXuEltaLCcxmZE0a3WyjdaWDiVsdZNmYMDKlYqjqXF/Ld4zUHt8kCXr3d97+cs8xAaVY6f5sphj+qw7KetG1dwv6+lvXFdUaJvd1FTHXX1D30zjHTmbPHYJh7GikKuxP6FnwT3odfYPjzvlA9jgw5c7/lWw2sO5skuna2MRDK4ilwrD6N5d71UNstB7Du8lnoFVuX/x0M1nGPxx5lWxZao2DsENtrGfsfhg8PJ/ELBcTV8EwJRUvHHw2++6+9QQyyU8wGppkpD8ra2cmTKFnigxosqzKwzENFGcwmG63BaY5RwPcArrpf1illweixN7oZr38CVS4Q7+yS5otb2cJmVz+1hBT5/roJWBjrRRDxhm2bWmHq//GeSvDaVy7joee0qJT8vFpuOJxM+hXEi72+HYnx3MwSRZeMJl9tMZnwyYXHzlMEyuV7XOpvu4MxMF9zglrW/kMHS8TKuunT8sFTvhe3pUyazG+EAzHMdoe2QB4dJ8E3KB6mwPxsIQZk4bfaRMm3FHmR6CZTGSh+OwfG0i5KyUr3ZQEjKZvGfkTKCL5u8dvCm4EDJ22Bndv4LUEsDBBQAAAgIAAAIIewRqbRYbQAAAHgAAAAJACQAbWV0YS5qc29uCgAgAAAAAAABABgAAIA+1d6xnQEAgD7V3rGdAQCAPtXesZ0Bq1YqSy0qzszPU7JSMNEz0jM011FQSi9KLMgoBooYgjilmSkgdrSSpamFRaJlqqlBirmxYbKpia5hanJamqlFYkpSWkpaooWFUixQfUllQapfYm4qRE9AYklGWmZeSmZeup57UWaKO8hopdhaAFBLAQItABQAAAgIAAAIIewb8cShXAIAABIFAAALACQAAAAAAAAAAAAAAAAAAABncmFwaDAuanNvbgoAIAAAAAAAAQAYAACAPtXesZ0BAIA+1d6xnQEAgD7V3rGdAVBLAQItABQAAAgIAAAIIewRqbRYbQAAAHgAAAAJACQAAAAAAAAAAAAAAKkCAABtZXRhLmpzb24KACAAAAAAAAEAGAAAgD7V3rGdAQCAPtXesZ0BAIA+1d6xnQFQSwUGAAAAAAIAAgC4AAAAYQMAAAAA
dataString: UEsDBBQAAAgIAAAIIezWWttFWgIAABMFAAALACQAZ3JhcGgwLmpzb24KACAAAAAAAAEAGAAAgD7V3rGdAQCAPtXesZ0BAIA+1d6xnQF1VMty2jAU/RVG66ZjSGigu5YkpAsSJrSTjTdCusYaZMkjyTyS4d97r2xjQ6crS+fcx7kP+ZMp40sQwbq5U3JhJbDvA0Zn9mXQkc9w4BtrVuoDWpt3JUNORjzavPGgLOJDcvO2gOCU+GE2mowTBCujMuuKR7mBmfXBI5xx7QEpZwN5G4Q+B+yAn5spuRzxNLqn0weepsnghEcBJoDrTFvD1qy2qozQvChBkuTOeJSc4ya1ocFyGpsRRbdaK99oYeFYxlpXZQ4OqFipOJYW89/iNQe1yQNdvt71vV+zzENoVDl+fFAOe1SHZT9t3biC+20tbcd1RYm+3UVNddTFP/TNMNKZs8Vzm3gYKwq5Ets3fhTch15j+/BDp3wYG7TnesvXGt5zMC927mxlJJLBVeRaeRg9dNdzZbMcxLbDa6lXYFX+fzxUwykWf5hpVayJir1DYKVt7HccPjiczC8UHFfDNyEQJRV/PPzmm/4ONcSTcj4g1VRpSN7aVo5M2RMeqPGiCjPrDES00VyC4ToclxglXA/wiutlvWKeOD2WJnfDtW/gyiXCnX2SXFFLuz/Pyud2vwCfv1ZBKwOdaCJesE0za0y9X/6SJK9V5TIuel6bSsnLxWLT8WTCpzBO5P3tUIzvboYgsmw84XKdyYxPJixunjJYJtfLWmfTHZxZvyUG16z9hwzmjpdx16Xj+7n6KGxPoDKZXQkHYF4vQ3hwmAUfpXyUChu0ghCUieNmnynTVmxBpudAaSz18RAcT7soKSvVzgZCUjaLP42UEXxe5aWDnYI9JW+DndjpL1BLAwQUAAAICAAACCHsldWPv1oCAAASBQAACwAkAGdyYXBoMS5qc29uCgAgAAAAAAABABgAAIA+1d6xnQEAgD7V3rGdAQCAPtXesZ0BdVRLc9owEP4rjM5Nx+C86K11EtJDEqa0k4svi7XGGmTJo0eAZPjvXck2duj0xPLtt7vfPuQPJpRtsHDaLIzgT5oj+zZhwWZfJoPzEfew0Wol3rHnvAruqkCCyPkFTmjCpyHM6hqdEcV3tZGBnBDolSi1qe/5BjNtnSW4BGmRXEa7EK0I+piwPf1czEPIgazZTbDeyZonkyOZBSqHZqD2xJ7WsrwqJNQN8iB5IF9dX3b0q3QaiYra6ThpyK6lFLbTwtyhib1m0FhPnRCBC6DeooDQaoViU7mgcxz8UpYWXSfKwOFOGBpRm5X90O3carDbVtkbSI8n6W3Kp3+8F63g0uj6sa86TUIFV4li+wsOBVg3GusYvvss26sdyC2sJb5WqJ71wmivODmd8SHUW5zdDX9PjWUVFttRiVZrj/bBzf+3E5o4xub3mRT1Ori+XrbASuo47rh7NLSYn6Q4XobtUhAaZPyx+Bs24xPqHA/CWEeurk0V5K21N4HKHsgIgy+8y7RRGNFOc4MKpDssKYs7X+CZb1T1zPMA4a10tTtf/wTOQiI88JPkzLXUu9OybKV3T2irF++kUDiIDo5nGlOmlWrvazySPmzlTQnFKGzjBf98Wixdp7c3ZYJJWqSIt7MLWPNyBpheTsv5/PoWWLw9oahPkMtWaDceWpoakiu6s/4TMlkYaOKtcwO7hXiv9WjkQpV6VRhE9dJmOAlHQ0XoTfJ7LmhAK3ROqLhu9pEzqYst8vyUKI+d3u+dgXzIkrNGvGkXkJxl8ZuRswCfbnlp8E3gLhTvkx3Z8S9QSwMEFAAACAgAAAgh7H7sEB6KAAAAtgAAAAkAJABtZXRhLmpzb24KACAAAAAAAAEAGAAAgD7V3rGdAQCAPtXesZ0BAIA+1d6xnQFtjbsOgkAQRX+FbC2EfcmsP0Bn7A3FwMzAFiIBNDHGf3c3tnb3cXLvWz153eJ9VqfCVabSzaFQ44rLtKXEZPOIlPVVBQ+AgX1NjdWDd6XmQcQDUi8kCKASbnsLjdRc28EygymxJzHI1mkJ4QioukTtr4XPeOPf8AX3SeJMcR6rdo3U5v889r/oPl9QSwECLQAUAAAICAAACCHs1lrbRVoCAAATBQAACwAkAAAAAAAAAAAAAAAAAAAAZ3JhcGgwLmpzb24KACAAAAAAAAEAGAAAgD7V3rGdAQCAPtXesZ0BAIA+1d6xnQFQSwECLQAUAAAICAAACCHsldWPv1oCAAASBQAACwAkAAAAAAAAAAAAAACnAgAAZ3JhcGgxLmpzb24KACAAAAAAAAEAGAAAgD7V3rGdAQCAPtXesZ0BAIA+1d6xnQFQSwECLQAUAAAICAAACCHsfuwQHooAAAC2AAAACQAkAAAAAAAAAAAAAABOBQAAbWV0YS5qc29uCgAgAAAAAAABABgAAIA+1d6xnQEAgD7V3rGdAQCAPtXesZ0BUEsFBgAAAAADAAMAFQEAACMGAAAAAA==
upgradeData:
file_cachedStartup: {fileID: 0}
data_cachedStartup:

File diff suppressed because it is too large Load Diff

View File

@@ -170,7 +170,7 @@ MonoBehaviour:
linePoints: 10
stiffness: 350
damping: 15
ropeLength: 4.19
ropeLength: 2
ropeWidth: 0.1
midPointWeight: 1
midPointPosition: 0.5
@@ -220,17 +220,17 @@ LineRenderer:
m_SortingLayer: 0
m_SortingOrder: 0
m_Positions:
- {x: 0, y: 2.07, z: 0}
- {x: -0.002, y: 1.5150144, z: 0}
- {x: -0.004, y: 1.0280256, z: 0}
- {x: -0.006, y: 0.6090335, z: 0}
- {x: -0.008, y: 0.25803846, z: 0}
- {x: -0.01, y: -0.024959907, z: 0}
- {x: -0.012, y: -0.23996155, z: 0}
- {x: -0.013999999, y: -0.3869663, z: 0}
- {x: -0.016, y: -0.46597433, z: 0}
- {x: -0.018, y: -0.47698557, z: 0}
- {x: -0.02, y: -0.42000002, z: 0}
- {x: 0, y: 4.1716814, z: 0}
- {x: -0.0011514801, y: 3.9187107, z: 0}
- {x: -0.00230296, y: 3.6922278, z: 0}
- {x: -0.0034544398, y: 3.4922323, z: 0}
- {x: -0.00460592, y: 3.3187256, z: 0}
- {x: -0.0057574, y: 3.1717062, z: 0}
- {x: -0.0069088796, y: 3.0511749, z: 0}
- {x: -0.008060359, y: 2.9571314, z: 0}
- {x: -0.00921184, y: 2.8895762, z: 0}
- {x: -0.010363319, y: 2.8485086, z: 0}
- {x: -0.0115148, y: 2.833929, z: 0}
m_Parameters:
serializedVersion: 3
widthMultiplier: 1
@@ -488,8 +488,8 @@ Transform:
m_GameObject: {fileID: 747976396}
serializedVersion: 2
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_LocalPosition: {x: 0, y: 2.9799, z: 0}
m_LocalScale: {x: 0.57574, y: 0.57574, z: 0.57574}
m_ConstrainProportionsScale: 0
m_Children:
- {fileID: 730962733}
@@ -573,6 +573,9 @@ MonoBehaviour:
spawnY: -6.78
wobbleMinScale: 0.5
wobbleMaxScale: 1.2
useObjectPooling: 1
initialPoolSize: 10
maxPoolSize: 30
--- !u!4 &1003335105
Transform:
m_ObjectHideFlags: 0
@@ -639,7 +642,7 @@ MonoBehaviour:
linePoints: 10
stiffness: 350
damping: 15
ropeLength: 4.19
ropeLength: 2
ropeWidth: 0.1
midPointWeight: 1
midPointPosition: 0.5
@@ -689,17 +692,17 @@ LineRenderer:
m_SortingLayer: 0
m_SortingOrder: 0
m_Positions:
- {x: 0, y: 2.07, z: 0}
- {x: 0.06300001, y: 1.5291233, z: 0}
- {x: 0.126, y: 1.053108, z: 0}
- {x: 0.18900001, y: 0.6419541, z: 0}
- {x: 0.25200003, y: 0.29566196, z: 0}
- {x: 0.315, y: 0.01423122, z: 0}
- {x: 0.37800002, y: -0.20233808, z: 0}
- {x: 0.44099998, y: -0.35404575, z: 0}
- {x: 0.504, y: -0.44089204, z: 0}
- {x: 0.567, y: -0.46287674, z: 0}
- {x: 0.63, y: -0.42000002, z: 0}
- {x: 0, y: 4.1716814, z: 0}
- {x: 0.036271624, y: 3.927396, z: 0}
- {x: 0.07254324, y: 3.7076683, z: 0}
- {x: 0.10881486, y: 3.5124984, z: 0}
- {x: 0.14508648, y: 3.3418865, z: 0}
- {x: 0.1813581, y: 3.195832, z: 0}
- {x: 0.21762972, y: 3.0743358, z: 0}
- {x: 0.25390133, y: 2.9773972, z: 0}
- {x: 0.29017296, y: 2.905017, z: 0}
- {x: 0.32644457, y: 2.857194, z: 0}
- {x: 0.3627162, y: 2.833929, z: 0}
m_Parameters:
serializedVersion: 3
widthMultiplier: 1
@@ -976,7 +979,7 @@ MonoBehaviour:
linePoints: 10
stiffness: 350
damping: 15
ropeLength: 4.19
ropeLength: 2
ropeWidth: 0.1
midPointWeight: 1
midPointPosition: 0.5
@@ -1026,17 +1029,17 @@ LineRenderer:
m_SortingLayer: 0
m_SortingOrder: 0
m_Positions:
- {x: 0, y: 2.07, z: 0}
- {x: -0.058000002, y: 1.5269984, z: 0}
- {x: -0.116, y: 1.0493305, z: 0}
- {x: -0.174, y: 0.63699615, z: 0}
- {x: -0.23200001, y: 0.28999573, z: 0}
- {x: -0.29, y: 0.00832893, z: 0}
- {x: -0.348, y: -0.20800425, z: 0}
- {x: -0.406, y: -0.35900372, z: 0}
- {x: -0.46400002, y: -0.44466949, z: 0}
- {x: -0.52199996, y: -0.46500158, z: 0}
- {x: -0.58, y: -0.42000002, z: 0}
- {x: 0, y: 4.1716814, z: 0}
- {x: -0.03339292, y: 3.9260902, z: 0}
- {x: -0.066785835, y: 3.705347, z: 0}
- {x: -0.10017875, y: 3.5094519, z: 0}
- {x: -0.13357168, y: 3.3384047, z: 0}
- {x: -0.16696459, y: 3.1922054, z: 0}
- {x: -0.20035751, y: 3.0708542, z: 0}
- {x: -0.2337504, y: 2.9743507, z: 0}
- {x: -0.26714337, y: 2.9026957, z: 0}
- {x: -0.30053627, y: 2.8558884, z: 0}
- {x: -0.33392918, y: 2.833929, z: 0}
m_Parameters:
serializedVersion: 3
widthMultiplier: 1
@@ -1204,8 +1207,12 @@ MonoBehaviour:
initialTileCount: 3
tileSpawnBuffer: 1
moveSpeed: 3
speedUpFactor: 0.2
speedUpInterval: 2
speedUpFactor: 0
speedUpInterval: 0
maxMoveSpeed: 12
useObjectPooling: 1
maxPerPrefabPoolSize: 2
totalMaxPoolSize: 25
onTileSpawned:
m_PersistentCalls:
m_Calls: []
@@ -1388,8 +1395,8 @@ Transform:
m_GameObject: {fileID: 2106431001}
serializedVersion: 2
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: -1, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_LocalPosition: {x: 0, y: 2.5, z: 0}
m_LocalScale: {x: 0.57574, y: 0.57574, z: 0.57574}
m_ConstrainProportionsScale: 0
m_Children:
- {fileID: 1834056337}
@@ -1417,7 +1424,7 @@ MonoBehaviour:
bottleWobble: {fileID: 747976399}
followStiffness: 4
useWobbleOffset: 1
baseY: -1
baseY: 2.5
--- !u!114 &2106431004
MonoBehaviour:
m_ObjectHideFlags: 0

View File

@@ -5,6 +5,7 @@ public class BirdEyesBehavior : MonoBehaviour
{
private StateMachine statemachine;
private Animator animator;
public bool correctItemIsIn;
// Start is called once before the first execution of Update after the MonoBehaviour is created
void Start()
{
@@ -15,19 +16,25 @@ public class BirdEyesBehavior : MonoBehaviour
// Update is called once per frame
void Update()
{
}
void CorrectItem()
public void CorrectItem()
{
correctItemIsIn = true;
animator.SetTrigger("RightGuess");
}
void IncorrectItem()
public void IncorrectItem()
{
animator.SetTrigger("WrongGuess");
correctItemIsIn = false;
animator.SetTrigger("WrongGuess");
}
void BirdReveal()
public void NoItem()
{
animator.SetTrigger("NoGuess");
}
public void BirdReveal()
{
statemachine.ChangeState ("BirdSpawned");
}

View File

@@ -0,0 +1,21 @@
{
"name": "AppleHillsScripts",
"rootNamespace": "",
"references": [
"PixelplacementAssembly",
"Unity.Addressables",
"AstarPathfindingProject",
"Unity.ResourceManager",
"Unity.InputSystem",
"Unity.TextMeshPro"
],
"includePlatforms": [],
"excludePlatforms": [],
"allowUnsafeCode": false,
"overrideReferences": false,
"precompiledReferences": [],
"autoReferenced": true,
"defineConstraints": [],
"versionDefines": [],
"noEngineReferences": false
}

View File

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

View File

@@ -14,7 +14,8 @@ public class DebugUIMessage : MonoBehaviour
/// </summary>
/// <param name="message">The message to display.</param>
/// <param name="duration">How long to display the message (seconds).</param>
public static void Show(string message, float duration = 2f)
/// <param name="displayColor"></param>
public static void Show(string message, Color displayColor, float duration = 2f)
{
if (instance == null)
{
@@ -23,7 +24,7 @@ public class DebugUIMessage : MonoBehaviour
instance.SetupUI();
DontDestroyOnLoad(go);
}
instance.ShowMessage(message, duration);
instance.ShowMessage(message, duration, displayColor);
}
/// <summary>
@@ -45,7 +46,7 @@ public class DebugUIMessage : MonoBehaviour
messageText.font = customFont;
else
messageText.font = Resources.GetBuiltinResource<Font>("LegacyRuntime.ttf");
messageText.fontSize = 16;
messageText.fontSize = 32;
messageText.color = Color.yellow;
var outline = textGO.AddComponent<Outline>();
outline.effectColor = Color.black;
@@ -55,16 +56,17 @@ public class DebugUIMessage : MonoBehaviour
rect.anchorMax = new Vector2(0.5f, 0.5f);
rect.pivot = new Vector2(0.5f, 0.5f);
rect.anchoredPosition = Vector2.zero;
rect.sizeDelta = new Vector2(400, 40);
rect.sizeDelta = new Vector2(800, 40);
messageText.text = "";
}
/// <summary>
/// Internal method to show a message and start the hide coroutine.
/// </summary>
private void ShowMessage(string message, float duration)
private void ShowMessage(string message, float duration, Color fontColor)
{
messageText.text = message;
messageText.color = fontColor;
messageText.enabled = true;
if (hideCoroutine != null)
StopCoroutine(hideCoroutine);

View File

@@ -35,6 +35,14 @@ public class GameManager : MonoBehaviour
void Awake()
{
_instance = this;
if (gameSettings == null)
{
gameSettings = Resources.Load<GameSettings>("DefaultSettings");
if (gameSettings == null)
{
Debug.LogError("GameSettings asset not found in Resources!");
}
}
// DontDestroyOnLoad(gameObject);
}
@@ -69,7 +77,8 @@ public class GameManager : MonoBehaviour
if (gameSettings == null || gameSettings.combinationRules == null) return null;
foreach (var rule in gameSettings.combinationRules)
{
if ((rule.itemA == item1 && rule.itemB == item2) || (rule.itemA == item2 && rule.itemB == item1))
if ((PickupItemData.AreEquivalent(rule.itemA, item1) && PickupItemData.AreEquivalent(rule.itemB, item2)) ||
(PickupItemData.AreEquivalent(rule.itemA, item2) && PickupItemData.AreEquivalent(rule.itemB, item1)))
{
return rule;
}
@@ -85,7 +94,7 @@ public class GameManager : MonoBehaviour
if (gameSettings == null || gameSettings.slotItemConfigs == null || slotItem == null) return null;
foreach (var config in gameSettings.slotItemConfigs)
{
if (config.slotItem == slotItem)
if (PickupItemData.AreEquivalent(slotItem, config.slotItem))
return config;
}
return null;

View File

@@ -42,11 +42,29 @@ public class SceneManagerService : MonoBehaviour
private readonly Dictionary<string, AsyncOperation> _activeLoads = new();
private readonly Dictionary<string, AsyncOperation> _activeUnloads = new();
private const string BootstrapSceneName = "BootstrapScene";
void Awake()
{
_instance = this;
// DontDestroyOnLoad(gameObject);
#if UNITY_EDITOR
// In Editor, set CurrentGameplayScene to the currently open scene at play start
if (Application.isPlaying)
{
var activeScene = SceneManager.GetActiveScene();
if (activeScene.IsValid())
{
CurrentGameplayScene = activeScene.name;
}
}
#endif
// Ensure BootstrapScene is loaded at startup
var bootstrap = SceneManager.GetSceneByName(BootstrapSceneName);
if (!bootstrap.isLoaded)
{
SceneManager.LoadScene(BootstrapSceneName, LoadSceneMode.Additive);
}
}
void OnApplicationQuit()
@@ -196,7 +214,7 @@ public class SceneManagerService : MonoBehaviour
}
// Tracks the currently loaded gameplay scene (not persistent/bootstrapper)
public string CurrentGameplayScene { get; private set; } = "AppleHillsOverworld";
public string CurrentGameplayScene { get; private set; } = "MainMenu";
// Switches from current gameplay scene to a new one
public async Task SwitchSceneAsync(string newSceneName, IProgress<float> progress = null)
@@ -210,10 +228,8 @@ public class SceneManagerService : MonoBehaviour
else
DestroyImmediate(astar.gameObject);
}
// Load new scene
await LoadSceneAsync(newSceneName, progress);
// Unload previous scene (if not same)
if (!string.IsNullOrEmpty(CurrentGameplayScene) && CurrentGameplayScene != newSceneName)
// Unload previous gameplay scene (if not BootstrapScene and not same as new)
if (!string.IsNullOrEmpty(CurrentGameplayScene) && CurrentGameplayScene != newSceneName && CurrentGameplayScene != BootstrapSceneName)
{
var prevScene = SceneManager.GetSceneByName(CurrentGameplayScene);
if (prevScene.isLoaded)
@@ -225,6 +241,14 @@ public class SceneManagerService : MonoBehaviour
Debug.LogWarning($"SceneManagerService: Previous scene '{CurrentGameplayScene}' is not loaded, skipping unload.");
}
}
// Ensure BootstrapScene is loaded before loading new scene
var bootstrap = SceneManager.GetSceneByName(BootstrapSceneName);
if (!bootstrap.isLoaded)
{
SceneManager.LoadScene(BootstrapSceneName, LoadSceneMode.Additive);
}
// Load new gameplay scene
await LoadSceneAsync(newSceneName, progress);
// Update tracker
CurrentGameplayScene = newSceneName;
}

View File

@@ -0,0 +1,16 @@
using UnityEngine;
public class AnneLiseBehaviour : MonoBehaviour
{
// Start is called once before the first execution of Update after the MonoBehaviour is created
void Start()
{
}
// Update is called once per frame
void Update()
{
}
}

View File

@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: d0d1761ee6769c243b110122f5e17b73

View File

@@ -2,23 +2,33 @@ using UnityEngine;
public class Distancemeasurer : MonoBehaviour
{
public float playerDistanceToChange;
public float playerToPlaceDistance;
public BirdEyesBehavior birdEyes;
private Vector2 eyesPosition;
private Vector2 placePosition;
private Vector2 playerPosition;
private float distance;
private GameObject player;
// Start is called once before the first execution of Update after the MonoBehaviour is created
void Start()
{
eyesPosition = transform.position;
playerPosition = transform.position;
placePosition = transform.position;
player = GameObject.FindWithTag("Player");
playerPosition = player.transform.position;
distance = Vector2.Distance(placePosition, playerPosition);
}
// Update is called once per frame
// TODO: Make this less expensive by not doing it every frame
void Update()
{
playerPosition = player.transform.position;
distance = Vector2.Distance(placePosition, playerPosition);
//Debug.Log("Distance to player: " + distance);
if (distance > playerToPlaceDistance && birdEyes.correctItemIsIn == true)
{
birdEyes.BirdReveal();
}
}

View File

@@ -142,7 +142,7 @@ public class InputManager : MonoBehaviour
Vector2 screenPos = positionAction.ReadValue<Vector2>();
Vector3 worldPos = Camera.main.ScreenToWorldPoint(screenPos);
Vector2 worldPos2D = new Vector2(worldPos.x, worldPos.y);
Debug.Log($"[InputManager] HoldMove update at {worldPos2D}");
// Debug.Log($"[InputManager] HoldMove update at {worldPos2D}");
defaultConsumer?.OnHoldMove(worldPos2D);
}
}

View File

@@ -12,7 +12,7 @@ namespace Input
// --- Movement State ---
private Vector3 targetPosition;
private Vector3 directMoveVelocity; // default is Vector3.zero
private bool isHolding;
internal bool isHolding;
private Vector2 lastHoldPosition;
private Coroutine pathfindingDragCoroutine;
private float pathfindingDragUpdateInterval = 0.1f; // Interval in seconds
@@ -28,6 +28,10 @@ namespace Input
private Transform artTransform;
private SpriteRenderer spriteRenderer;
// --- Last direct movement direction ---
private Vector3 _lastDirectMoveDir = Vector3.right;
public Vector3 LastDirectMoveDir => _lastDirectMoveDir;
// --- MoveToAndNotify State ---
public delegate void ArrivedAtTargetHandler();
private Coroutine moveToCoroutine;
@@ -184,6 +188,9 @@ namespace Input
adjustedMove = toTarget;
}
transform.position += adjustedMove;
// Cache the last direct movement direction
_lastDirectMoveDir = directMoveVelocity.normalized;
}
/// <summary>

View File

@@ -130,7 +130,7 @@ namespace Interactions
var step = GetComponent<PuzzleS.ObjectiveStepBehaviour>();
if (step != null && !step.IsStepUnlocked())
{
DebugUIMessage.Show("This step is locked!", 2f);
DebugUIMessage.Show("This step is locked!", Color.yellow);
BroadcastInteractionComplete(false);
// Reset variables for next time
_interactionInProgress = false;

View File

@@ -1,5 +1,6 @@
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;
namespace Interactions
{
@@ -9,10 +10,14 @@ namespace Interactions
[RequireComponent(typeof(Interactable))]
public class ItemSlot : Pickup
{
public UnityEvent onItemSlotted;
public UnityEvent onItemSlotRemoved;
public UnityEvent onCorrectItemSlotted;
public UnityEvent onIncorrectItemSlotted;
public UnityEvent onForbiddenItemSlotted;
private PickupItemData _currentlySlottedItemData;
public SpriteRenderer slottedItemRenderer;
private GameObject _currentlySlottedItemObject = null;
public GameObject GetSlottedObject()
{
@@ -32,71 +37,41 @@ namespace Interactions
{
var heldItemData = FollowerController.CurrentlyHeldItemData;
var heldItemObj = FollowerController.GetHeldPickupObject();
var pickup = GetComponent<Pickup>();
var slotItem = pickup != null ? pickup.itemData : null;
var config = GameManager.Instance.GetSlotItemConfig(slotItem);
var allowed = config?.allowedItems ?? new List<PickupItemData>();
var config = GameManager.Instance.GetSlotItemConfig(itemData);
var forbidden = config?.forbiddenItems ?? new List<PickupItemData>();
// Held item, slot empty -> try to slot item
if (heldItemData != null && _currentlySlottedItemObject == null)
{
// First check for forbidden items at the very start so we don't continue unnecessarily
if (PickupItemData.ListContainsEquivalent(forbidden, heldItemData))
{
DebugUIMessage.Show("Can't place that here.", Color.red);
onForbiddenItemSlotted?.Invoke();
Interactable.BroadcastInteractionComplete(false);
return;
}
SlotItem(heldItemObj, heldItemData, true);
return;
}
// Either pickup or swap items
if ((heldItemData == null && _currentlySlottedItemObject != null)
|| (heldItemData != null && _currentlySlottedItemObject != null))
{
FollowerController.TryPickupItem(_currentlySlottedItemObject, _currentlySlottedItemData);
_currentlySlottedItemObject = null;
_currentlySlottedItemData = null;
UpdateSlottedSprite();
FollowerController.TryPickupItem(_currentlySlottedItemObject, _currentlySlottedItemData, false);
onItemSlotRemoved?.Invoke();
SlotItem(heldItemObj, heldItemData, _currentlySlottedItemObject == null);
return;
}
// // CASE 1: No held item, slot has item -> pick up slotted item
// if (heldItemData == null && _cachedSlottedObject != null)
// {
// InteractionOrchestrator.Instance.PickupItem(FollowerController, _cachedSlottedObject);
// _cachedSlottedObject = null;
// currentlySlottedItem = null;
// UpdateSlottedSprite();
// Interactable.BroadcastInteractionComplete(false);
// return;
// }
// // CASE 2: Held item, slot has item -> swap
// if
// {
// InteractionOrchestrator.Instance.SwapItems(FollowerController, this);
// currentlySlottedItem = heldItemData;
// UpdateSlottedSprite();
// return;
// }
// CASE 3: Held item, slot empty -> slot the held item
if (heldItemData != null && _currentlySlottedItemObject == null)
{
if (forbidden.Contains(heldItemData))
{
DebugUIMessage.Show("Can't place that here.");
Interactable.BroadcastInteractionComplete(false);
return;
}
SlotItem(heldItemObj, heldItemData);
if (allowed.Contains(heldItemData))
{
Interactable.BroadcastInteractionComplete(true);
return;
}
else
{
DebugUIMessage.Show("I'm not sure this works.");
Interactable.BroadcastInteractionComplete(false);
return;
}
}
// CASE 4: No held item, slot empty -> show warning
// No held item, slot empty -> show warning
if (heldItemData == null && _currentlySlottedItemObject == null)
{
DebugUIMessage.Show("This requires an item.");
DebugUIMessage.Show("This requires an item.", Color.red);
return;
}
return;
}
/// <summary>
@@ -128,18 +103,49 @@ namespace Interactions
}
}
public void SlotItem(GameObject itemToSlot, PickupItemData itemToSlotData)
public void SlotItem(GameObject itemToSlot, PickupItemData itemToSlotData, bool clearFollowerHeldItem = true)
{
if (itemToSlot == null)
return;
itemToSlot.SetActive(false);
itemToSlot.transform.SetParent(null);
SetSlottedObject(itemToSlot);
_currentlySlottedItemData = itemToSlotData;
if (itemToSlot == null)
{
_currentlySlottedItemObject = null;
_currentlySlottedItemData = null;
}
else
{
itemToSlot.SetActive(false);
itemToSlot.transform.SetParent(null);
SetSlottedObject(itemToSlot);
_currentlySlottedItemData = itemToSlotData;
}
if (clearFollowerHeldItem)
{
FollowerController.ClearHeldItem();
}
UpdateSlottedSprite();
FollowerController.ClearHeldItem();
// Once an item is slotted, we know it is not forbidden, so we can skip that check, but now check if it was
// the correct item we're looking for
var config = GameManager.Instance.GetSlotItemConfig(itemData);
var allowed = config?.allowedItems ?? new List<PickupItemData>();
if (PickupItemData.ListContainsEquivalent(allowed, itemToSlotData))
{
if (itemToSlot != null)
{
DebugUIMessage.Show("You correctly slotted " + itemToSlotData.itemName + " into: " + itemData.itemName, Color.green);
onCorrectItemSlotted?.Invoke();
}
Interactable.BroadcastInteractionComplete(true);
}
else
{
if (itemToSlot != null)
{
DebugUIMessage.Show("I'm not sure this works.", Color.yellow);
onIncorrectItemSlotted?.Invoke();
}
Interactable.BroadcastInteractionComplete(false);
}
}
}
}

View File

@@ -1,4 +1,5 @@
using UnityEngine;
using System.Collections.Generic;
[CreateAssetMenu(fileName = "PickupItemData", menuName = "Game/Pickup Item Data")]
public class PickupItemData : ScriptableObject
@@ -7,4 +8,22 @@ public class PickupItemData : ScriptableObject
[TextArea]
public string description;
public Sprite mapSprite;
public static bool AreEquivalent(PickupItemData a, PickupItemData b)
{
if (ReferenceEquals(a, b)) return true;
if (a is null || b is null) return false;
// Compare by itemName as a fallback
return a.itemName == b.itemName;
}
public static bool ListContainsEquivalent(List<PickupItemData> list, PickupItemData item)
{
foreach (var entry in list)
{
if (AreEquivalent(entry, item))
return true;
}
return false;
}
}

View File

@@ -1,48 +1,109 @@
using UnityEngine;
using Pooling;
namespace Minigames.DivingForPictures
{
/// <summary>
/// Represents a single bubble, handling its movement, wobble effect, scaling, and sprite assignment.
/// </summary>
public class Bubble : MonoBehaviour
public class Bubble : MonoBehaviour, IPoolableWithReference<BubblePool>
{
public float speed = 1f;
public float wobbleSpeed = 1f;
private SpriteRenderer spriteRenderer;
private SpriteRenderer bottleSpriteRenderer;
private SpriteRenderer bubbleSpriteRenderer; // Renamed from bottleSpriteRenderer
private float timeOffset;
private float minScale = 0.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()
{
// Cache references and randomize time offset for wobble
spriteRenderer = GetComponent<SpriteRenderer>();
timeOffset = Random.value * 100f;
// Find the child named "BottleSprite" and get its SpriteRenderer
Transform bottleSpriteTransform = transform.Find("BubbleSprite");
if (bottleSpriteTransform != null)
// Find the child named "BubbleSprite" and get its SpriteRenderer
Transform bubbleSpriteTransform = transform.Find("BubbleSprite");
if (bubbleSpriteTransform != null)
{
bottleSpriteRenderer = bottleSpriteTransform.GetComponent<SpriteRenderer>();
bubbleSpriteRenderer = bubbleSpriteTransform.GetComponent<SpriteRenderer>();
}
// Cache camera reference
mainCamera = Camera.main;
}
void Update()
{
// 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)
float t = (Mathf.Sin((Time.time + timeOffset) * wobbleSpeed) + 1f) * 0.5f; // t in [0,1]
float newScale = Mathf.Lerp(minScale, maxScale, t);
transform.localScale = Vector3.one * newScale;
// Destroy when off screen
if (transform.position.y > Camera.main.orthographicSize + 2f)
float wobbleFactor = Mathf.Lerp(minScale, maxScale, t);
transform.localScale = Vector3.one * (baseScale * wobbleFactor);
// 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>
/// Called when the object is retrieved from the pool.
/// </summary>
public void OnSpawn()
{
ResetState();
}
/// <summary>
/// Called when the object is returned to the pool.
/// </summary>
public void OnDespawn()
{
// Nothing to do here for now, but we could clean up resources
}
/// <summary>
/// Sets the main sprite for the bubble.
/// </summary>
@@ -54,13 +115,22 @@ namespace Minigames.DivingForPictures
}
/// <summary>
/// Sets the sprite for the child "BottleSprite" renderer.
/// Sets the sprite for the child "BubbleSprite" renderer.
/// </summary>
/// <param name="sprite">Sprite to assign.</param>
public void SetBottleSprite(Sprite sprite)
public void SetBubbleSprite(Sprite sprite)
{
if (bottleSpriteRenderer != null)
bottleSpriteRenderer.sprite = sprite;
if (bubbleSpriteRenderer != null)
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>
@@ -73,5 +143,13 @@ namespace Minigames.DivingForPictures
minScale = min;
maxScale = max;
}
/// <summary>
/// Resets the bubble state for reuse from object pool
/// </summary>
public void ResetState()
{
timeOffset = Random.value * 100f;
}
}
}

View File

@@ -0,0 +1,42 @@
using UnityEngine;
using Pooling;
namespace Minigames.DivingForPictures
{
/// <summary>
/// Manages a pool of bubble objects to reduce garbage collection overhead.
/// </summary>
public class BubblePool : BaseObjectPool<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 = Get();
// Set reference to this pool so the bubble can return itself
bubble.SetPool(this);
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)
{
Return(bubble);
}
/// <summary>
/// Logs pool statistics
/// </summary>
public override void LogPoolStats()
{
Debug.Log($"[BubblePool] Pooled bubbles: {pooledObjects.Count}/{maxPoolSize} (Created: {totalCreated}, Returned: {totalReturned})");
}
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 45cdaed0c047423bbb0b7380cd3687f3
timeCreated: 1758015081

View File

@@ -1,4 +1,5 @@
using UnityEngine;
using Pooling;
namespace Minigames.DivingForPictures
{
@@ -19,9 +20,37 @@ namespace Minigames.DivingForPictures
public float spawnY = -5f;
public float wobbleMinScale = 0.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 _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);
// Periodically check for pool statistics in debug builds
#if DEVELOPMENT_BUILD || UNITY_EDITOR
InvokeRepeating(nameof(LogPoolStats), 5f, 30f);
#endif
}
}
void Start()
{
@@ -56,23 +85,49 @@ namespace Minigames.DivingForPictures
{
float x = Random.Range(spawnXMin, spawnXMax);
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
bubble.speed = Random.Range(speedRange.x, speedRange.y);
bubble.wobbleSpeed = Random.Range(wobbleSpeedRange.x, wobbleSpeedRange.y);
float scale = Random.Range(scaleRange.x, scaleRange.y);
bubble.transform.localScale = Vector3.one * scale;
// Assign random sprite to BottleSprite
// Set base scale (initial size) for the bubble
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)
{
Sprite randomSprite = bubbleSprites[Random.Range(0, bubbleSprites.Length)];
bubble.SetBottleSprite(randomSprite);
bubble.SetBubbleSprite(randomSprite);
}
// Random rotation
bubble.transform.rotation = Quaternion.Euler(0f, 0f, Random.Range(0f, 360f));
// Pass min/max scale for wobble clamping
bubble.SetWobbleScaleLimits(wobbleMinScale, wobbleMaxScale);
}
/// <summary>
/// Logs the current pool statistics for debugging
/// </summary>
private void LogPoolStats()
{
if (_bubblePool != null)
{
_bubblePool.LogPoolStats();
}
}
}
}

View File

@@ -0,0 +1,45 @@
using System.Collections.Generic;
using UnityEngine;
using Pooling;
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 : MultiPrefabPool<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)
{
Tile tileComponent = tile.GetComponent<Tile>();
if (tileComponent != null)
{
Return(tileComponent, prefabIndex);
}
else
{
Debug.LogWarning($"Attempted to return a GameObject without a Tile component: {tile.name}");
Destroy(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)
{
Tile tileComponent = Get(prefabIndex);
return tileComponent.gameObject;
}
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: fc32ce01955e4e44b4c1d28871d64049
timeCreated: 1758015121

View File

@@ -2,6 +2,7 @@
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.Serialization;
using Pooling;
namespace Minigames.DivingForPictures
{
@@ -12,43 +13,85 @@ namespace Minigames.DivingForPictures
{
[Header("Tile Prefabs")]
[Tooltip("List of possible trench tile prefabs.")]
public List<GameObject> tilePrefabs;
[SerializeField] private List<GameObject> tilePrefabs;
[Header("Tile Settings")]
private const float TileHeight = 5f; // Set to match prefab height
public int initialTileCount = 3;
public float tileSpawnBuffer = 1f;
[SerializeField] private int initialTileCount = 3;
[SerializeField] private float tileSpawnBuffer = 1f;
[Header("Movement Settings")]
public float moveSpeed = 3f;
public float speedUpFactor = 0.2f;
public float speedUpInterval = 10f;
[SerializeField] private float moveSpeed = 3f;
[SerializeField] private float speedUpFactor = 0.2f;
[SerializeField] private float speedUpInterval = 10f;
[SerializeField] private float maxMoveSpeed = 12f;
[FormerlySerializedAs("OnTileSpawned")] [Header("Events")]
[Header("Object Pooling")]
[SerializeField] private bool useObjectPooling = true;
[SerializeField] private int maxPerPrefabPoolSize = 2;
[SerializeField] private int totalMaxPoolSize = 10;
[Header("Events")]
[FormerlySerializedAs("OnTileSpawned")]
public UnityEvent<GameObject> onTileSpawned;
[FormerlySerializedAs("OnTileDestroyed")]
public UnityEvent<GameObject> onTileDestroyed;
// Private fields
private readonly Dictionary<GameObject, float> _tileHeights = new Dictionary<GameObject, float>();
private readonly List<GameObject> _activeTiles = new List<GameObject>();
private readonly Dictionary<int, int> _tileLastUsed = new Dictionary<int, int>();
private int _spawnCounter;
private float _speedUpTimer;
private Camera _mainCamera;
private float _screenBottom;
private float _screenTop;
private TrenchTilePool _tilePool;
void Start()
private const float TileSpawnZ = -1f;
private const float DefaultTileHeight = 5f;
private void Awake()
{
_mainCamera = Camera.main;
CalculateScreenBounds();
for (int i = 0; i < initialTileCount; i++)
// Calculate tile heights for each prefab
CalculateTileHeights();
// Ensure all prefabs have Tile components
ValidateTilePrefabs();
if (useObjectPooling)
{
SpawnTileAtY(_screenBottom + i * TileHeight);
InitializeObjectPool();
}
}
void Update()
// Validate that all prefabs have Tile components
private void ValidateTilePrefabs()
{
for (int i = 0; i < tilePrefabs.Count; i++)
{
if (tilePrefabs[i] == null) continue;
// Check if the prefab has a Tile component
if (tilePrefabs[i].GetComponent<Tile>() == null)
{
Debug.LogWarning($"Prefab {tilePrefabs[i].name} does not have a Tile component. Adding one automatically.");
// Add the Tile component if it doesn't exist
tilePrefabs[i].AddComponent<Tile>();
}
}
}
private void Start()
{
CalculateScreenBounds();
SpawnInitialTiles();
}
private void Update()
{
MoveTiles();
HandleTileDestruction();
@@ -56,14 +99,115 @@ namespace Minigames.DivingForPictures
HandleSpeedRamping();
}
/// <summary>
/// Calculate height values for all tile prefabs
/// </summary>
private void CalculateTileHeights()
{
foreach (var prefab in tilePrefabs)
{
if (prefab == null)
{
Debug.LogError("Null prefab found in tilePrefabs list!");
continue;
}
Renderer renderer = prefab.GetComponentInChildren<Renderer>();
if (renderer != null)
{
_tileHeights[prefab] = renderer.bounds.size.y;
}
else
{
// Fallback in case no renderer is found
_tileHeights[prefab] = DefaultTileHeight;
Debug.LogWarning($"No renderer found in prefab {prefab.name}. Using default height of {DefaultTileHeight}.");
}
}
}
/// <summary>
/// Initialize the object pool system
/// </summary>
private void InitializeObjectPool()
{
// Create the tile pool
GameObject poolGO = new GameObject("TrenchTilePool");
poolGO.transform.SetParent(transform);
_tilePool = poolGO.AddComponent<TrenchTilePool>();
// Set up the pool configuration
_tilePool.maxPerPrefabPoolSize = maxPerPrefabPoolSize;
_tilePool.totalMaxPoolSize = totalMaxPoolSize;
// Convert the GameObject list to a Tile list
List<Tile> prefabTiles = new List<Tile>(tilePrefabs.Count);
foreach (var prefab in tilePrefabs)
{
if (prefab != null)
{
Tile tileComponent = prefab.GetComponent<Tile>();
if (tileComponent != null)
{
prefabTiles.Add(tileComponent);
}
else
{
Debug.LogError($"Prefab {prefab.name} is missing a Tile component!");
}
}
}
// Initialize the pool with the tile component list
_tilePool.Initialize(prefabTiles);
// Periodically trim the pool to optimize memory usage
InvokeRepeating(nameof(TrimExcessPooledTiles), 10f, 30f);
}
/// <summary>
/// Spawn the initial set of tiles
/// </summary>
private void SpawnInitialTiles()
{
for (int i = 0; i < initialTileCount; i++)
{
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);
}
}
/// <summary>
/// Calculate the screen bounds in world space
/// </summary>
private void CalculateScreenBounds()
{
if (_mainCamera == null)
{
_mainCamera = Camera.main;
if (_mainCamera == null)
{
Debug.LogError("No main camera found!");
return;
}
}
Vector3 bottom = _mainCamera.ViewportToWorldPoint(new Vector3(0.5f, 0f, _mainCamera.nearClipPlane));
Vector3 top = _mainCamera.ViewportToWorldPoint(new Vector3(0.5f, 1f, _mainCamera.nearClipPlane));
_screenBottom = bottom.y;
_screenTop = top.y;
}
/// <summary>
/// Move all active tiles upward
/// </summary>
private void MoveTiles()
{
float moveDelta = moveSpeed * Time.deltaTime;
@@ -76,83 +220,264 @@ namespace Minigames.DivingForPictures
}
}
/// <summary>
/// Check for tiles that have moved off screen and should be destroyed or returned to pool
/// </summary>
private void HandleTileDestruction()
{
if (_activeTiles.Count == 0) return;
GameObject topTile = _activeTiles[0];
if (topTile.transform.position.y - TileHeight / 2 > _screenTop + tileSpawnBuffer)
if (topTile == null)
{
_activeTiles.RemoveAt(0);
return;
}
float tileHeight = GetTileHeight(topTile);
if (topTile.transform.position.y - tileHeight / 2 > _screenTop + tileSpawnBuffer)
{
_activeTiles.RemoveAt(0);
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);
}
}
}
/// <summary>
/// Check if new tiles need to be spawned
/// </summary>
private void HandleTileSpawning()
{
if (_activeTiles.Count == 0) return;
GameObject bottomTile = _activeTiles[^1];
float bottomEdge = bottomTile.transform.position.y - TileHeight / 2;
if (bottomTile == null)
{
_activeTiles.RemoveAt(_activeTiles.Count - 1);
return;
}
float tileHeight = GetTileHeight(bottomTile);
float bottomEdge = bottomTile.transform.position.y - tileHeight / 2;
if (bottomEdge > _screenBottom - tileSpawnBuffer)
{
float newY = bottomTile.transform.position.y - TileHeight;
float newY = bottomTile.transform.position.y - tileHeight;
SpawnTileAtY(newY);
}
}
/// <summary>
/// Handle increasing the movement speed over time
/// </summary>
private void HandleSpeedRamping()
{
_speedUpTimer += Time.deltaTime;
if (_speedUpTimer >= speedUpInterval)
{
moveSpeed += speedUpFactor;
moveSpeed = Mathf.Min(moveSpeed + speedUpFactor, maxMoveSpeed);
_speedUpTimer = 0f;
}
}
/// <summary>
/// Spawn a new tile at the specified Y position
/// </summary>
/// <param name="y">The Y position to spawn at</param>
private void SpawnTileAtY(float y)
{
if (tilePrefabs == null || tilePrefabs.Count == 0)
{
Debug.LogError("No tile prefabs available for spawning!");
return;
}
int prefabIndex = GetWeightedRandomTileIndex();
GameObject prefab = tilePrefabs[prefabIndex];
// Use the prefab's original rotation
GameObject tile = Instantiate(prefab, new Vector3(0f, y, 0f), prefab.transform.rotation, transform);
if (prefab == null)
{
Debug.LogError($"Tile prefab at index {prefabIndex} is null!");
return;
}
GameObject tile;
if (useObjectPooling && _tilePool != null)
{
tile = _tilePool.GetTile(prefabIndex);
if (tile == null)
{
Debug.LogError("Failed to get tile from pool!");
return;
}
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);
_tileLastUsed[prefabIndex] = _spawnCounter++;
onTileSpawned?.Invoke(tile);
}
/// <summary>
/// Gets a weighted random tile index, favoring tiles that haven't been used recently
/// </summary>
/// <returns>The selected prefab index</returns>
private int GetWeightedRandomTileIndex()
{
// Weight tiles not used recently higher
int n = tilePrefabs.Count;
List<float> weights = new List<float>(n);
for (int i = 0; i < n; i++)
int prefabCount = tilePrefabs.Count;
List<float> weights = new List<float>(prefabCount);
for (int i = 0; i < prefabCount; i++)
{
int lastUsed = _tileLastUsed.TryGetValue(i, out var value) ? value : -n;
int lastUsed = _tileLastUsed.TryGetValue(i, out var value) ? value : -prefabCount;
int age = _spawnCounter - lastUsed;
float weight = Mathf.Clamp(age, 1, n * 2); // More unused = higher weight
float weight = Mathf.Clamp(age, 1, prefabCount * 2); // More unused = higher weight
weights.Add(weight);
}
float total = 0f;
foreach (var w in weights) total += w;
float r = Random.value * total;
for (int i = 0; i < n; i++)
float totalWeight = 0f;
foreach (var weight in weights)
{
if (r < weights[i]) return i;
r -= weights[i];
totalWeight += weight;
}
float randomValue = Random.value * totalWeight;
for (int i = 0; i < prefabCount; i++)
{
if (randomValue < weights[i])
{
return i;
}
randomValue -= weights[i];
}
return Random.Range(0, prefabCount); // 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)
{
if (tile == null)
{
Debug.LogWarning("Attempted to get height of null tile!");
return DefaultTileHeight;
}
// Check if this is a known prefab
foreach (var prefab in tilePrefabs)
{
if (prefab == null) continue;
// 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 DefaultTileHeight;
}
/// <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)
{
if (tile == null || tilePrefabs == null)
{
return -1;
}
for (int i = 0; i < tilePrefabs.Count; i++)
{
if (tilePrefabs[i] == null) continue;
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();
}
return Random.Range(0, n); // fallback
}
#if UNITY_EDITOR
void OnDrawGizmosSelected()
private void OnDrawGizmosSelected()
{
if (!Application.isPlaying)
{
// Only try to calculate this if _screenBottom hasn't been set by the game
Camera editorCam = Camera.main;
if (editorCam != null)
{
Vector3 bottom = editorCam.ViewportToWorldPoint(new Vector3(0.5f, 0f, editorCam.nearClipPlane));
_screenBottom = bottom.y;
}
}
// Draw tile bounds for debugging
Gizmos.color = Color.cyan;
for (int i = 0; i < initialTileCount; i++)
{
Vector3 center = new Vector3(0f, _screenBottom + i * TileHeight, 0f);
Gizmos.DrawWireCube(center, new Vector3(10f, TileHeight, 1f));
float height = DefaultTileHeight;
if (tilePrefabs != null && tilePrefabs.Count > 0 && tilePrefabs[0] != null &&
_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

View File

@@ -20,6 +20,7 @@ public class FollowerController: MonoBehaviour
/// </summary>
public float manualMoveSmooth = 8f;
private GameObject _playerRef;
private Transform _playerTransform;
private AIPath _playerAIPath;
private AIPath _aiPath;
@@ -58,10 +59,9 @@ public class FollowerController: MonoBehaviour
/// </summary>
public event FollowerPickupHandler OnPickupReturned;
private Coroutine _pickupCoroutine;
private bool _lastInteractionSuccess = true;
private Input.PlayerTouchController _playerTouchController;
void Awake()
{
_aiPath = GetComponent<AIPath>();
@@ -186,8 +186,10 @@ public class FollowerController: MonoBehaviour
GameObject playerObj = GameObject.FindGameObjectWithTag("Player");
if (playerObj != null)
{
_playerRef = playerObj;
_playerTransform = playerObj.transform;
_playerAIPath = playerObj.GetComponent<AIPath>();
_playerTouchController = playerObj.GetComponent<Input.PlayerTouchController>();
if (_playerAIPath != null)
{
_playerMaxSpeed = _playerAIPath.maxSpeed;
@@ -199,6 +201,7 @@ public class FollowerController: MonoBehaviour
{
_playerTransform = null;
_playerAIPath = null;
_playerTouchController = null;
}
}
@@ -225,6 +228,11 @@ public class FollowerController: MonoBehaviour
moveDir = _playerAIPath.velocity.normalized;
_lastMoveDir = moveDir;
}
else if (_playerTouchController != null && _playerTouchController.isHolding && _playerTouchController.LastDirectMoveDir.sqrMagnitude > 0.01f)
{
moveDir = _playerTouchController.LastDirectMoveDir;
_lastMoveDir = moveDir;
}
else
{
moveDir = _lastMoveDir;
@@ -314,9 +322,9 @@ public class FollowerController: MonoBehaviour
#endregion Movement
#region ItemInteractions
public void TryPickupItem(GameObject itemObject, PickupItemData itemData)
public void TryPickupItem(GameObject itemObject, PickupItemData itemData, bool dropItem = true)
{
if (_currentlyHeldItemData != null && _cachedPickupObject != null)
if (_currentlyHeldItemData != null && _cachedPickupObject != null && dropItem)
{
// Drop the currently held item at the current position
DropHeldItemAt(transform.position);

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: a4883b41055949e99282264685fcd4f8
timeCreated: 1758019051

View File

@@ -0,0 +1,148 @@
using System.Collections.Generic;
using UnityEngine;
namespace Pooling
{
/// <summary>
/// Abstract base class for object pools.
/// Provides common functionality for creating, retrieving, and returning pooled objects.
/// </summary>
/// <typeparam name="T">The type of component to pool</typeparam>
public abstract class BaseObjectPool<T> : MonoBehaviour where T : Component
{
[Tooltip("Initial number of objects to pre-instantiate")]
public int initialPoolSize = 10;
[Tooltip("Maximum number of objects to keep in the pool")]
public int maxPoolSize = 30;
protected Stack<T> pooledObjects = new Stack<T>();
protected T prefab;
protected int totalCreated = 0;
protected int totalReturned = 0;
/// <summary>
/// Initialize the pool with the specified prefab
/// </summary>
/// <param name="prefabToPool">The prefab to use for this pool</param>
public virtual void Initialize(T prefabToPool)
{
prefab = prefabToPool;
// Pre-instantiate objects
for (int i = 0; i < initialPoolSize; i++)
{
CreateNew();
}
Debug.Log($"[{GetType().Name}] Initialized with {initialPoolSize} objects");
}
/// <summary>
/// Creates a new instance and adds it to the pool
/// </summary>
protected virtual T CreateNew()
{
if (prefab == null)
{
Debug.LogError($"[{GetType().Name}] Prefab is null! Call Initialize first.");
return null;
}
T obj = Instantiate(prefab, transform);
obj.gameObject.SetActive(false);
// Initialize IPoolable components if present
IPoolable poolable = obj.GetComponent<IPoolable>();
if (poolable != null)
{
poolable.OnDespawn();
}
pooledObjects.Push(obj);
totalCreated++;
return obj;
}
/// <summary>
/// Gets an object from the pool, or creates a new one if the pool is empty
/// </summary>
/// <returns>An object ready to use</returns>
public virtual T Get()
{
T obj;
if (pooledObjects.Count > 0)
{
obj = pooledObjects.Pop();
}
else
{
obj = CreateNew();
pooledObjects.Pop(); // Remove from pool since we're returning it
}
obj.gameObject.SetActive(true);
// Call OnSpawn for IPoolable components
IPoolable poolable = obj.GetComponent<IPoolable>();
if (poolable != null)
{
poolable.OnSpawn();
}
return obj;
}
/// <summary>
/// Returns an object to the pool
/// </summary>
/// <param name="obj">The object to return</param>
public virtual void Return(T obj)
{
if (obj == null) return;
// Call OnDespawn for IPoolable components
IPoolable poolable = obj.GetComponent<IPoolable>();
if (poolable != null)
{
poolable.OnDespawn();
}
// Only add to pool if we're under the maximum size
if (pooledObjects.Count < maxPoolSize)
{
obj.gameObject.SetActive(false);
obj.transform.SetParent(transform);
pooledObjects.Push(obj);
totalReturned++;
}
else
{
Destroy(obj.gameObject);
}
}
/// <summary>
/// Logs pool statistics
/// </summary>
public virtual void LogPoolStats()
{
Debug.Log($"[{GetType().Name}] Pooled objects: {pooledObjects.Count}/{maxPoolSize} (Created: {totalCreated}, Returned: {totalReturned})");
}
#if UNITY_EDITOR
private float _lastLogTime = 0f;
protected virtual void Update()
{
// Log pool stats every 5 seconds if in the editor
if (Time.time - _lastLogTime > 5f)
{
LogPoolStats();
_lastLogTime = Time.time;
}
}
#endif
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 693c1b68b3cd4ad695dce000d53b04ee
timeCreated: 1758019542

View File

@@ -0,0 +1,21 @@
namespace Pooling
{
/// <summary>
/// Interface for objects that can be pooled.
/// Implement this interface on any component that should be managed by an ObjectPool.
/// </summary>
public interface IPoolable
{
/// <summary>
/// Called when the object is retrieved from the pool.
/// Use this to reset the object's state.
/// </summary>
void OnSpawn();
/// <summary>
/// Called when the object is returned to the pool.
/// Use this to clean up any resources or state.
/// </summary>
void OnDespawn();
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 13d9095c12514097b9d5953c5b2a45a2
timeCreated: 1758019051

View File

@@ -0,0 +1,18 @@
using UnityEngine;
namespace Pooling
{
/// <summary>
/// Interface for poolable objects that need to reference their parent pool.
/// Implement this interface on objects that need to return themselves to their pool.
/// </summary>
/// <typeparam name="T">The type of pool component</typeparam>
public interface IPoolableWithReference<T> : IPoolable where T : Component
{
/// <summary>
/// Sets the parent pool for this object
/// </summary>
/// <param name="pool">The pool this object belongs to</param>
void SetPool(T pool);
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 99a99ac50049492195a73883d9129ea8
timeCreated: 1758019587

View File

@@ -0,0 +1,266 @@
using System.Collections.Generic;
using UnityEngine;
namespace Pooling
{
/// <summary>
/// Object pool that supports multiple prefab types with usage tracking and intelligent trimming.
/// </summary>
/// <typeparam name="T">The type of component to pool</typeparam>
public abstract class MultiPrefabPool<T> : MonoBehaviour where T : Component
{
[Tooltip("Whether to pre-instantiate objects during initialization or create them on demand")]
public bool preInstantiatePrefabs = false;
[Tooltip("Initial number of objects to pre-instantiate per prefab (if preInstantiatePrefabs is true)")]
public int initialObjectsPerPrefab = 2;
[Tooltip("Maximum number of objects 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;
protected Dictionary<int, Stack<T>> pooledObjects = new Dictionary<int, Stack<T>>();
protected Dictionary<int, int> prefabUsageCount = new Dictionary<int, int>();
protected List<T> prefabs;
protected int totalPooledCount = 0;
/// <summary>
/// Initialize the pool with the specified prefabs
/// </summary>
/// <param name="prefabsToPool">The list of prefabs to use for this pool</param>
public virtual void Initialize(List<T> prefabsToPool)
{
prefabs = prefabsToPool;
// Initialize usage tracking
for (int i = 0; i < prefabs.Count; i++)
{
prefabUsageCount[i] = 0;
pooledObjects[i] = new Stack<T>();
}
// Pre-instantiate objects only if enabled
if (preInstantiatePrefabs)
{
// Calculate how many to pre-instantiate based on available pool size
int totalToCreate = Mathf.Min(totalMaxPoolSize, prefabs.Count * initialObjectsPerPrefab);
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;
CreateNew(i);
}
}
}
Debug.Log($"[{GetType().Name}] Initialized with {prefabs.Count} prefab types");
}
/// <summary>
/// Creates a new instance and adds it to the pool
/// </summary>
protected virtual T CreateNew(int prefabIndex)
{
if (prefabs == null || prefabIndex >= prefabs.Count)
{
Debug.LogError($"[{GetType().Name}] Invalid prefab index or prefabs list is null!");
return null;
}
T prefab = prefabs[prefabIndex];
T obj = Instantiate(prefab, transform);
obj.gameObject.SetActive(false);
// Initialize IPoolable components if present
IPoolable poolable = obj.GetComponent<IPoolable>();
if (poolable != null)
{
poolable.OnDespawn();
}
if (!pooledObjects.ContainsKey(prefabIndex))
{
pooledObjects[prefabIndex] = new Stack<T>();
}
pooledObjects[prefabIndex].Push(obj);
totalPooledCount++;
return obj;
}
/// <summary>
/// Gets an object from the pool for the specified prefab index, or creates a new one if the pool is empty
/// </summary>
/// <param name="prefabIndex">The index of the prefab to get from the pool</param>
/// <returns>An object ready to use</returns>
public virtual T Get(int prefabIndex)
{
T obj;
// Track usage frequency
if (prefabUsageCount.ContainsKey(prefabIndex))
{
prefabUsageCount[prefabIndex]++;
}
else
{
prefabUsageCount[prefabIndex] = 1;
}
if (pooledObjects.ContainsKey(prefabIndex) && pooledObjects[prefabIndex].Count > 0)
{
obj = pooledObjects[prefabIndex].Pop();
totalPooledCount--;
}
else
{
// Create new object without adding to pool
T prefab = prefabs[prefabIndex];
obj = Instantiate(prefab, transform);
}
obj.gameObject.SetActive(true);
// Call OnSpawn for IPoolable components
IPoolable poolable = obj.GetComponent<IPoolable>();
if (poolable != null)
{
poolable.OnSpawn();
}
return obj;
}
/// <summary>
/// Returns an object to the pool
/// </summary>
/// <param name="obj">The object to return</param>
/// <param name="prefabIndex">The index of the prefab this object was created from</param>
public virtual void Return(T obj, int prefabIndex)
{
if (obj == null) return;
// Call OnDespawn for IPoolable components
IPoolable poolable = obj.GetComponent<IPoolable>();
if (poolable != null)
{
poolable.OnDespawn();
}
// Check if we're under the maximum pool size for this prefab type
bool keepObject = totalPooledCount < totalMaxPoolSize;
// Additional constraint: don't keep too many of any single prefab type
if (pooledObjects.ContainsKey(prefabIndex) &&
pooledObjects[prefabIndex].Count >= maxPerPrefabPoolSize)
{
keepObject = false;
}
if (keepObject)
{
obj.gameObject.SetActive(false);
obj.transform.SetParent(transform);
if (!pooledObjects.ContainsKey(prefabIndex))
{
pooledObjects[prefabIndex] = new Stack<T>();
}
pooledObjects[prefabIndex].Push(obj);
totalPooledCount++;
}
else
{
Destroy(obj.gameObject);
}
}
/// <summary>
/// Trims the pool to remove excess objects
/// Can be called periodically or when memory pressure is high
/// </summary>
public virtual 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 objects from least used prefabs first
foreach (var usage in sortedUsage)
{
int prefabIndex = usage.Key;
if (!pooledObjects.ContainsKey(prefabIndex) || pooledObjects[prefabIndex].Count == 0) continue;
// How many to remove from this prefab type
int toRemove = Mathf.Min(pooledObjects[prefabIndex].Count, excessCount);
for (int i = 0; i < toRemove; i++)
{
if (pooledObjects[prefabIndex].Count == 0) break;
T obj = pooledObjects[prefabIndex].Pop();
Destroy(obj.gameObject);
totalPooledCount--;
excessCount--;
if (excessCount <= 0) return;
}
}
}
/// <summary>
/// Logs pool statistics to the console
/// </summary>
public virtual void LogPoolStats()
{
Debug.Log($"[{GetType().Name}] Total pooled objects: {totalPooledCount}/{totalMaxPoolSize}");
string prefabDetails = "";
int index = 0;
foreach (var entry in pooledObjects)
{
int prefabIndex = entry.Key;
int count = entry.Value.Count;
int usageCount = prefabUsageCount.ContainsKey(prefabIndex) ? prefabUsageCount[prefabIndex] : 0;
string prefabName = prefabIndex < prefabs.Count ? prefabs[prefabIndex].name : "Unknown";
prefabDetails += $"\n - {prefabName}: {count} pooled, {usageCount} usages";
// Limit the output to avoid too much text
if (++index >= 10 && pooledObjects.Count > 10)
{
prefabDetails += $"\n - ...and {pooledObjects.Count - 10} more prefab types";
break;
}
}
Debug.Log($"[{GetType().Name}] Pool details:{prefabDetails}");
}
#if UNITY_EDITOR
private float _lastLogTime = 0f;
protected virtual void Update()
{
// Log pool stats every 5 seconds if in the editor
if (Time.time - _lastLogTime > 5f)
{
LogPoolStats();
_lastLogTime = Time.time;
}
}
#endif
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 344a70ff5291463bbd636705705ace79
timeCreated: 1758019578

View File

@@ -32,6 +32,11 @@ namespace PuzzleS
_interactable.interactionComplete.AddListener(OnInteractionComplete);
}
PuzzleManager.Instance?.RegisterStepBehaviour(this);
// Check if this step was already unlocked
if (stepData != null && PuzzleManager.Instance != null && PuzzleManager.Instance.IsStepUnlocked(stepData))
{
UnlockStep();
}
}
void OnDestroy()

View File

@@ -1,6 +1,7 @@
using UnityEngine;
using System.Collections.Generic;
using PuzzleS;
using UnityEngine.SceneManagement;
/// <summary>
/// Manages puzzle step registration, dependency management, and step completion for the puzzle system.
@@ -44,6 +45,18 @@ public class PuzzleManager : MonoBehaviour
{
_instance = this;
// DontDestroyOnLoad(gameObject);
SceneManager.sceneLoaded += OnSceneLoaded;
}
void OnDestroy()
{
SceneManager.sceneLoaded -= OnSceneLoaded;
}
private void OnSceneLoaded(Scene scene, LoadSceneMode mode)
{
BuildRuntimeDependencies();
UnlockInitialSteps();
}
/// <summary>
@@ -71,12 +84,6 @@ public class PuzzleManager : MonoBehaviour
Debug.Log($"[Puzzles] Unregistered step: {behaviour.stepData.stepId} on {behaviour.gameObject.name}");
}
void Start()
{
BuildRuntimeDependencies();
UnlockInitialSteps();
}
/// <summary>
/// Builds the runtime dependency graph for all registered steps.
/// </summary>
@@ -172,6 +179,14 @@ public class PuzzleManager : MonoBehaviour
}
}
/// <summary>
/// Returns whether a step is already unlocked.
/// </summary>
public bool IsStepUnlocked(PuzzleStepSO step)
{
return unlockedSteps.Contains(step);
}
void OnApplicationQuit()
{
_isQuitting = true;

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