OctoCore 0.0.1

This commit is contained in:
Alexandre Coirier
2026-02-09 23:53:14 +01:00
parent 85bf743cba
commit 80d0faf8a7
235 changed files with 13656 additions and 32 deletions
@@ -0,0 +1,274 @@
using UnityEngine;
#if UNITY_EDITOR
using UnityEditor;
using System.IO;
using System.Collections.Generic;
using System.Text;
using System.Linq;
namespace OctoCore.Inputs
{
/// <summary>
/// Automatically restores OctoActions.cs from backup JSON when package is updated.
/// </summary>
[InitializeOnLoad]
public class OctoActionsPostImport
{
private const string BACKUP_FILE = "Assets/OctoCore/Editor/OctoActions.json";
private static string GetActionsFilePath()
{
// Find OctoInputs.cs to locate the package
string[] guids = AssetDatabase.FindAssets("OctoInputs t:script");
foreach (string guid in guids)
{
string path = AssetDatabase.GUIDToAssetPath(guid);
if (path.Contains("/Inputs/OctoInputs.cs"))
{
// Found it! Same directory
string directory = Path.GetDirectoryName(path);
return Path.Combine(directory, "OctoActions.cs").Replace("\\", "/");
}
}
// Fallback
return "Assets/OctoCore/Generated/OctoActions.cs";
}
static OctoActionsPostImport()
{
// Restore from backup if needed
EditorApplication.delayCall += RestoreFromBackup;
}
[MenuItem("OctoCore/Input Actions/Restore from Backup")]
public static void ForceRestore()
{
RestoreFromBackup();
}
[MenuItem("OctoCore/Input Actions/Reset to Template")]
public static void ResetToTemplate()
{
if (!EditorUtility.DisplayDialog(
"Reset OctoActions",
"This will reset OctoActions.cs to the template (None = 0).\n\n" +
"The backup JSON will be kept, so you can restore later.\n\n" +
"Are you sure?",
"Reset",
"Cancel"))
{
return;
}
string actionsFile = GetActionsFilePath();
CreateTemplate(actionsFile);
AssetDatabase.Refresh();
Debug.Log("[OctoCore] OctoActions.cs reset to template.");
}
[MenuItem("OctoCore/Input Actions/Delete Backup")]
public static void DeleteBackup()
{
if (!File.Exists(BACKUP_FILE))
{
EditorUtility.DisplayDialog("No Backup", "No backup file found.", "OK");
return;
}
if (!EditorUtility.DisplayDialog(
"Delete Backup",
"This will permanently delete the backup JSON.\n\n" +
"You won't be able to restore your actions after a package update.\n\n" +
"Are you sure?",
"Delete",
"Cancel"))
{
return;
}
File.Delete(BACKUP_FILE);
// Delete meta file too
string metaFile = BACKUP_FILE + ".meta";
if (File.Exists(metaFile))
{
File.Delete(metaFile);
}
AssetDatabase.Refresh();
Debug.Log("[OctoCore] Backup file deleted.");
}
private static void RestoreFromBackup()
{
string actionsFile = GetActionsFilePath();
// Check if backup exists
if (!File.Exists(BACKUP_FILE))
{
Debug.Log("[OctoCore] No backup found. Generate your actions via OctoSettings.");
return;
}
// Check if actions file needs restoration (is it the template?)
if (File.Exists(actionsFile))
{
string currentContent = File.ReadAllText(actionsFile);
// If it contains real actions (not just None), skip restoration
if (currentContent.Contains("_PLACEHOLDER_") || currentContent.Contains("None = 0"))
{
Debug.Log("[OctoCore] Restoring actions from backup...");
RestoreActionsFile(actionsFile);
}
else
{
// File already has real actions, don't overwrite
return;
}
}
else
{
// File doesn't exist, restore it
RestoreActionsFile(actionsFile);
}
}
private static void RestoreActionsFile(string actionsFile)
{
try
{
// Read backup JSON
string json = File.ReadAllText(BACKUP_FILE);
var backup = JsonUtility.FromJson<ActionsBackup>(json);
if (backup == null || backup.Actions == null || backup.Actions.Count == 0)
{
Debug.LogWarning("[OctoCore] Backup file is empty or invalid.");
return;
}
// Generate enum file from backup
StringBuilder sb = new StringBuilder();
sb.AppendLine("// ═══════════════════════════════════════════════════════════════════════════");
sb.AppendLine("// AUTO-GENERATED FILE - DO NOT EDIT MANUALLY");
sb.AppendLine("// ═══════════════════════════════════════════════════════════════════════════");
sb.AppendLine("// Restored from backup by OctoActionsPostImport");
sb.AppendLine($"// Original source: {backup.GeneratedFrom}");
sb.AppendLine($"// Originally generated on: {backup.GeneratedOn}");
sb.AppendLine($"// Restored on: {System.DateTime.Now:yyyy-MM-dd HH:mm:ss}");
sb.AppendLine("// ═══════════════════════════════════════════════════════════════════════════");
sb.AppendLine();
sb.AppendLine("namespace OctoCore.Inputs");
sb.AppendLine("{");
sb.AppendLine(" /// <summary>");
sb.AppendLine(" /// Actions from Unity Input Actions.");
sb.AppendLine($" /// Generated from: {backup.GeneratedFrom}");
sb.AppendLine(" /// Format: ActionMap_ActionName");
sb.AppendLine(" /// Values are stable hashes to prevent serialization issues when regenerating.");
sb.AppendLine(" /// </summary>");
sb.AppendLine(" public enum OctoActions");
sb.AppendLine(" {");
for (int i = 0; i < backup.Actions.Count; i++)
{
var action = backup.Actions[i];
if (i > 0)
sb.AppendLine(",");
sb.AppendLine($" /// <summary>{action.MapName} > {action.ActionName}</summary>");
sb.Append($" {action.Name} = {action.Hash}");
}
sb.AppendLine();
sb.AppendLine(" }");
sb.AppendLine("}");
// Ensure directory exists
string directory = Path.GetDirectoryName(actionsFile);
if (!Directory.Exists(directory))
{
Directory.CreateDirectory(directory);
}
// Write restored file
File.WriteAllText(actionsFile, sb.ToString());
AssetDatabase.Refresh();
Debug.Log($"[OctoCore] Actions successfully restored from backup! ({backup.Actions.Count} actions)");
}
catch (System.Exception ex)
{
Debug.LogError($"[OctoCore] Failed to restore actions from backup: {ex.Message}");
}
}
private static void CreateTemplate(string actionsFile)
{
string template =
@"// ═══════════════════════════════════════════════════════════════════════════
// TEMPLATE FILE
// ═══════════════════════════════════════════════════════════════════════════
// This is a template file for OctoActions.
//
// TO GENERATE YOUR REAL ACTIONS:
// 1. Open OctoSettings in the Inspector
// 2. Go to Mapping section
// 3. Assign your Input Action Asset
// 4. Click 'Generate Inputs' button
//
// This template allows the package to compile before actions are generated.
// ═══════════════════════════════════════════════════════════════════════════
namespace OctoCore.Inputs
{
/// <summary>
/// Template enum for input actions.
/// Generate your real actions via OctoSettings > Mapping > Generate Inputs.
/// </summary>
public enum OctoActions
{
/// <summary>
/// Placeholder value.
/// This will be replaced when you generate your input actions.
/// </summary>
None = 0
}
}
";
// Ensure directory exists
string directory = Path.GetDirectoryName(actionsFile);
if (!Directory.Exists(directory))
{
Directory.CreateDirectory(directory);
}
// Write template file
File.WriteAllText(actionsFile, template);
}
[System.Serializable]
private class ActionBackupData
{
public string Name;
public int Hash;
public string MapName;
public string ActionName;
}
[System.Serializable]
private class ActionsBackup
{
public string GeneratedFrom;
public string GeneratedOn;
public List<ActionBackupData> Actions;
}
}
}
#endif
@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 1341efd2cf48e6a42b0e4d82542aa728
@@ -0,0 +1,19 @@
{
"name": "OctoCore.Editor",
"rootNamespace": "OctoCore",
"references": [
"OctoCore.Runtime",
"Unity.InputSystem"
],
"includePlatforms": [
"Editor"
],
"excludePlatforms": [],
"allowUnsafeCode": false,
"overrideReferences": false,
"precompiledReferences": [],
"autoReferenced": true,
"defineConstraints": [],
"versionDefines": [],
"noEngineReferences": false
}
@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 5506ba4596c093544967197d0014b667
AssemblyDefinitionImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,30 @@
using UnityEditor;
using UnityEngine;
namespace OctoCore.LevelBuilder
{
/*[CustomEditor(typeof(OctoLevelGrid))]
public class OctoLevelGridEditor : Editor
{
public override void OnInspectorGUI()
{
DrawDefaultInspector();
OctoLevelGrid grid = (OctoLevelGrid)target;
EditorGUILayout.Space(10);
if (GUILayout.Button("Rebuild All Tiles"))
{
grid.RebuildAllTiles();
Debug.Log("[OctoLevelGrid] All tiles rebuilt.");
}
if (GUILayout.Button("Update All Wall Shapes"))
{
grid.UpdateAllWallShapes();
Debug.Log("[OctoLevelGrid] All wall shapes updated.");
}
}
}*/
}
@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: a8928c5f72a929c489249d7e786c24fa
@@ -0,0 +1,34 @@
using System;
using UnityEditor;
using UnityEngine;
namespace OctoCore.Localization.Editor
{
[CustomEditor(typeof(OctoLocalizedTextData))]
public class OctoLocalizedTextDataEditor : UnityEditor.Editor
{
public override void OnInspectorGUI()
{
//DrawDefaultInspector();
OctoLocalizedTextData data = (OctoLocalizedTextData)target;
//if (GUILayout.Button("Init Languages")) data.Init();
//EditorGUILayout.Space();
foreach (string lang in Enum.GetNames(typeof(OctoLanguages)))
{
if (!data.Languages.ContainsKey(lang))
data.Languages[lang] = string.Empty;
EditorGUILayout.LabelField(lang.ToString(), EditorStyles.boldLabel);
data.Languages[lang] = EditorGUILayout.TextArea(data.Languages[lang], GUILayout.MinHeight(40));
EditorGUILayout.Space(5);
}
if (GUI.changed)
EditorUtility.SetDirty(data);
}
}
}
@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 1d98f82f8b1fb3746884002ecd24fed2
@@ -0,0 +1,52 @@
using UnityEditor;
using UnityEngine;
namespace OctoCore.Localization.Editor
{
[CustomEditor(typeof(OctoLocalizedText))]
public class OctoLocalizedTextEditor : UnityEditor.Editor
{
SerializedProperty dataProp;
SerializedProperty textProp;
SerializedProperty textMeshProProp;
SerializedProperty textMeshProUGUIProp;
void OnEnable()
{
dataProp = serializedObject.FindProperty("data");
textProp = serializedObject.FindProperty("text");
textMeshProProp = serializedObject.FindProperty("textMeshPro");
textMeshProUGUIProp = serializedObject.FindProperty("textMeshProUGUI");
}
public override void OnInspectorGUI()
{
serializedObject.Update();
EditorGUILayout.PropertyField(dataProp);
GUI.enabled = false;
if (textProp.objectReferenceValue != null)
{
EditorGUILayout.PropertyField(textProp, new GUIContent("Text"));
}
else if (textMeshProProp.objectReferenceValue != null)
{
EditorGUILayout.PropertyField(textMeshProProp, new GUIContent("Text"));
}
else if (textMeshProUGUIProp.objectReferenceValue != null)
{
EditorGUILayout.PropertyField(textMeshProUGUIProp, new GUIContent("Text"));
}
else
{
EditorGUILayout.HelpBox("No text componant found.", MessageType.Info);
}
GUI.enabled = true;
serializedObject.ApplyModifiedProperties();
}
}
}
@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: d0318152d87e6de409c214f43199b6de
@@ -0,0 +1,22 @@
using UnityEditor;
using UnityEngine;
namespace OctoCore.Components.Editor
{
[CustomPropertyDrawer(typeof(OctoReadOnlyAttribute))]
public class OCtoReadOnlyEditor: PropertyDrawer
{
public override float GetPropertyHeight(SerializedProperty property, GUIContent label)
{
return EditorGUI.GetPropertyHeight(property, label, true);
}
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
{
GUI.enabled = false;
EditorGUI.PropertyField(position, property, label, true);
GUI.enabled = true;
}
}
}
@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 7f4b5fb27a48beb4698f946e9513bcf9
@@ -0,0 +1,52 @@
using UnityEditor;
namespace OctoCore.Components.Editor
{
[CustomEditor(typeof(OctoSaveEvent))]
public class OctoSaveEventEditor : UnityEditor.Editor
{
public override void OnInspectorGUI()
{
serializedObject.Update();
SerializedProperty dataProp = serializedObject.FindProperty("data");
EditorGUILayout.PropertyField(dataProp);
OctoSaveEvent script = (OctoSaveEvent)target;
global::OctoCore.Save.Data.OctoData data = dataProp.objectReferenceValue as global::OctoCore.Save.Data.OctoData;
if (data != null)
{
if (data is global::OctoCore.Save.Data.OctoDataBool)
{
EditorGUILayout.PropertyField(serializedObject.FindProperty("invertValue"));
EditorGUILayout.PropertyField(serializedObject.FindProperty("onInitBool"));
EditorGUILayout.PropertyField(serializedObject.FindProperty("onChangeBool"));
}
else if (data is global::OctoCore.Save.Data.OctoDataInt)
{
EditorGUILayout.PropertyField(serializedObject.FindProperty("onInitInt"));
EditorGUILayout.PropertyField(serializedObject.FindProperty("onChangeInt"));
}
else if (data is global::OctoCore.Save.Data.OctoDataFloat)
{
EditorGUILayout.PropertyField(serializedObject.FindProperty("onInitFloat"));
EditorGUILayout.PropertyField(serializedObject.FindProperty("onChangeFloat"));
}
else if (data is global::OctoCore.Save.Data.OctoDataString)
{
EditorGUILayout.PropertyField(serializedObject.FindProperty("onInitString"));
EditorGUILayout.PropertyField(serializedObject.FindProperty("onChangeString"));
}
else if (data is global::OctoCore.Save.Data.OctoDataVector)
{
EditorGUILayout.PropertyField(serializedObject.FindProperty("onInitVector"));
EditorGUILayout.PropertyField(serializedObject.FindProperty("onChangeVector"));
}
}
serializedObject.ApplyModifiedProperties();
}
}
}
@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: bbf314ffdf8b0384589bfb20c78c5b67
@@ -0,0 +1,257 @@
using OctoCore.Inputs;
using UnityEditor;
using UnityEngine;
namespace OctoCore
{
[CustomEditor(typeof(OctoSettings))]
public class OctoSettingsEditor : UnityEditor.Editor
{
SerializedProperty saveProp;
SerializedProperty saveBooleansProp;
SerializedProperty saveFloatsProp;
SerializedProperty saveIntegersProp;
SerializedProperty saveStringsProp;
SerializedProperty saveVectorsProp;
SerializedProperty mappingProp;
SerializedProperty mappingInputActionAssetProp;
SerializedProperty mappingActionsProp;
SerializedProperty languagesProp;
SerializedProperty languagesDefaultProp;
SerializedProperty languagesSaveWrittenProp;
SerializedProperty languagesSaveAudioProp;
SerializedProperty languagesOverridesProp;
SerializedProperty scenesProp;
SerializedProperty scenesSceneDatasProp;
SerializedProperty scenesUseAddressablesProp;
SerializedProperty scenesFadeSettingsProp;
SerializedProperty UiProp;
SerializedProperty UiReferenceSizeProp;
SerializedProperty UiIconsBackgroundProp;
bool foldoutSave;
bool foldoutMapping;
bool foldoutLanguages;
bool foldoutScenes;
bool foldoutUi;
void OnEnable()
{
saveProp = serializedObject.FindProperty("Save");
saveBooleansProp = saveProp.FindPropertyRelative("Booleans");
saveIntegersProp = saveProp.FindPropertyRelative("Integers");
saveFloatsProp = saveProp.FindPropertyRelative("Floats");
saveStringsProp = saveProp.FindPropertyRelative("Strings");
saveVectorsProp = saveProp.FindPropertyRelative("Vectors");
mappingProp = serializedObject.FindProperty("Mapping");
mappingInputActionAssetProp = mappingProp.FindPropertyRelative("InputActionAsset");
mappingActionsProp = mappingProp.FindPropertyRelative("Actions");
languagesProp = serializedObject.FindProperty("Languages");
languagesDefaultProp = languagesProp.FindPropertyRelative("Default");
languagesSaveWrittenProp = languagesProp.FindPropertyRelative("SaveWritten");
languagesSaveAudioProp = languagesProp.FindPropertyRelative("SaveAudio");
languagesOverridesProp = languagesProp.FindPropertyRelative("Overrides");
scenesProp = serializedObject.FindProperty("Scenes");
scenesSceneDatasProp = scenesProp.FindPropertyRelative("SceneDatas");
scenesUseAddressablesProp = scenesProp.FindPropertyRelative("UseAddressables");
scenesFadeSettingsProp = scenesProp.FindPropertyRelative("FadeSettings");
UiProp = serializedObject.FindProperty("Ui");
UiReferenceSizeProp = UiProp.FindPropertyRelative("ReferenceSize");
UiIconsBackgroundProp = UiProp.FindPropertyRelative("IconsBackground");
}
public override void OnInspectorGUI()
{
OctoSettings data = (OctoSettings)target;
serializedObject.Update();
GUIStyle foldout = new GUIStyle(EditorStyles.foldout) { fontStyle = FontStyle.Bold };
// ═══════════════════════════════════════════════════════════════════
// SAVE
// ═══════════════════════════════════════════════════════════════════
EditorGUILayout.BeginVertical("box");
EditorGUI.indentLevel++;
foldoutSave = EditorGUILayout.Foldout(foldoutSave, "SAVE", true, foldout);
if (foldoutSave)
{
EditorGUILayout.Space();
EditorGUI.indentLevel++;
if (GUILayout.Button("Get All Datas"))
{
data.GetAllDatas();
}
EditorGUILayout.Space();
EditorGUILayout.PropertyField(saveBooleansProp);
EditorGUILayout.PropertyField(saveFloatsProp);
EditorGUILayout.PropertyField(saveIntegersProp);
EditorGUILayout.PropertyField(saveStringsProp);
EditorGUILayout.PropertyField(saveVectorsProp);
EditorGUI.indentLevel--;
EditorGUILayout.Space(4);
}
EditorGUI.indentLevel--;
EditorGUILayout.EndVertical();
EditorGUILayout.Space();
// ═══════════════════════════════════════════════════════════════════
// MAPPING
// ═══════════════════════════════════════════════════════════════════
EditorGUILayout.BeginVertical("box");
EditorGUI.indentLevel++;
foldoutMapping = EditorGUILayout.Foldout(foldoutMapping, "MAPPING", true, foldout);
if (foldoutMapping)
{
EditorGUILayout.Space();
#if ENABLE_INPUT_SYSTEM
EditorGUILayout.PropertyField(mappingInputActionAssetProp);
EditorGUI.indentLevel++;
EditorGUILayout.PropertyField(mappingActionsProp);
EditorGUI.indentLevel--;
EditorGUILayout.Space();
EditorGUILayout.HelpBox(
"To generate OctoActions enum:\n" +
"1. Assign an Input Action Asset first\n" +
"2. Click 'Generate Inputs'\n\n" +
"Note: The enum will be generated in Assets/OctoCore/ (safe from package updates)",
MessageType.Info
);
EditorGUILayout.Space(5);
GUI.enabled = data.Mapping.InputActionAsset != null;
if (GUILayout.Button("Generate Inputs", GUILayout.Height(20)))
{
data.GenerateInputs();
}
GUI.enabled = true;
#else
EditorGUILayout.HelpBox(
"Input System Package is not enabled.\n" +
"Please enable it in Project Settings > Player > Active Input Handling.",
MessageType.Warning
);
#endif
EditorGUILayout.Space(4);
}
EditorGUI.indentLevel--;
EditorGUILayout.EndVertical();
EditorGUILayout.Space();
// ═══════════════════════════════════════════════════════════════════
// LANGUAGES
// ═══════════════════════════════════════════════════════════════════
EditorGUILayout.BeginVertical("box");
EditorGUI.indentLevel++;
foldoutLanguages = EditorGUILayout.Foldout(foldoutLanguages, "LANGUAGES", true, foldout);
if (foldoutLanguages)
{
EditorGUILayout.Space();
EditorGUILayout.PropertyField(languagesDefaultProp);
EditorGUILayout.PropertyField(languagesSaveWrittenProp);
EditorGUILayout.PropertyField(languagesSaveAudioProp);
EditorGUI.indentLevel++;
EditorGUILayout.PropertyField(languagesOverridesProp);
EditorGUI.indentLevel--;
EditorGUILayout.Space(4);
}
EditorGUI.indentLevel--;
EditorGUILayout.EndVertical();
EditorGUILayout.Space();
// ═══════════════════════════════════════════════════════════════════
// SCENES
// ═══════════════════════════════════════════════════════════════════
EditorGUILayout.BeginVertical("box");
EditorGUI.indentLevel++;
foldoutScenes = EditorGUILayout.Foldout(foldoutScenes, "SCENES", true, foldout);
if (foldoutScenes)
{
EditorGUILayout.Space();
EditorGUI.indentLevel++;
if (GUILayout.Button("Get All Scene Datas"))
{
data.GetAllSceneDatas();
}
EditorGUILayout.Space();
EditorGUILayout.PropertyField(scenesSceneDatasProp);
EditorGUILayout.PropertyField(scenesUseAddressablesProp);
EditorGUILayout.Space();
EditorGUILayout.LabelField("Fade Settings", EditorStyles.boldLabel);
EditorGUI.indentLevel++;
EditorGUILayout.PropertyField(scenesFadeSettingsProp);
EditorGUI.indentLevel--;
EditorGUI.indentLevel--;
EditorGUILayout.Space(4);
}
EditorGUI.indentLevel--;
EditorGUILayout.EndVertical();
EditorGUILayout.Space();
// ═══════════════════════════════════════════════════════════════════
// UI
// ═══════════════════════════════════════════════════════════════════
EditorGUILayout.BeginVertical("box");
EditorGUI.indentLevel++;
foldoutUi = EditorGUILayout.Foldout(foldoutUi, "INTERFACE", true, foldout);
if (foldoutUi)
{
EditorGUILayout.Space();
EditorGUILayout.PropertyField(UiReferenceSizeProp);
EditorGUILayout.PropertyField(UiIconsBackgroundProp);
EditorGUILayout.Space(4);
}
EditorGUI.indentLevel--;
EditorGUILayout.EndVertical();
EditorGUILayout.Space();
serializedObject.ApplyModifiedProperties();
}
}
}
@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 9ce5e44ae6718e44fa7cf22c8cc4df5d
@@ -0,0 +1,65 @@
using UnityEditor;
using UnityEngine;
namespace OctoCore.LevelBuilder
{
/*[CustomEditor(typeof(OctoTile))]
[CanEditMultipleObjects]
public class OctoTileEditor : Editor
{
private SerializedProperty _configurationProp;
private SerializedProperty _referencesProp;
private SerializedProperty _placementProp;
private SerializedProperty _wallProp;
private void OnEnable()
{
_configurationProp = serializedObject.FindProperty("Configuration");
_referencesProp = serializedObject.FindProperty("References");
_placementProp = serializedObject.FindProperty("Placement");
_wallProp = serializedObject.FindProperty("Wall");
}
public override void OnInspectorGUI()
{
serializedObject.Update();
EditorGUILayout.PropertyField(_configurationProp, true);
EditorGUILayout.PropertyField(_referencesProp, true);
EditorGUILayout.PropertyField(_placementProp, true);
bool hasWall = false;
if (targets.Length == 1)
{
OctoTile tile = (OctoTile)target;
hasWall = tile.HasWall();
}
else
{
foreach (var t in targets)
{
OctoTile tile = (OctoTile)t;
if (tile.HasWall())
{
hasWall = true;
break;
}
}
}
if (hasWall)
{
EditorGUILayout.PropertyField(_wallProp, true);
}
if (serializedObject.ApplyModifiedProperties())
{
foreach (var t in targets)
{
OctoTile tile = (OctoTile)t;
tile.RefreshTile();
}
}
}
}*/
}
@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 0fdd28ef8abb6df47b9e13a6b6df43aa