Some checks failed
Gitea Actions Demo / Explore-Gitea-Actions (push) Has been cancelled
- доработан flow призовой витрины и связанного UI: добавлены `PrizeStandButtonView` и `RulesPrizeListPage`, обновлены `PrizeStandController`, `PrizeStandPrize`, `PrizeStandModal`, `PrizeStandSettingsModal`, `LevelPrizeSettingsModal`, `QRCodeSettingsModal`, `BalanceDisplay`, `ButtonTextFocusColor` и связанные prefab'ы, чтобы улучшить настройку, навигацию, отображение кнопок и prize flow - расширена система настроек и сохранения значений: `OptionPicker` получил отдельный формат `ValueSelector`, обновлены `SettingsDatabase`, `SettingEntryDrawer`, `SettingUIItem`, `SettingsUIGenerator`, `ValueSelectorRow` и `MainSettingsDatabase.asset`, а сохранение option picker-значений, включая `gameplay.gameDifficulty`, исправлено и синхронизировано с остальными настройками - добавлены универсальные спавнеры сущностей: реализованы `EntitySpawner` и `EntitySpawnerManager` с поддержкой весов префабов, точек спавна, заполнения по проценту, ограничений на количество и автоспавна при инициализации - доработана логика игрового спавна и сложности: процент инициализационного спавна может зависеть от настройки `gameplay.gameDifficulty` с градациями 25/50/75/100, в одном цикле массового спавна повторно не используется та же точка, а gizmo спавнера теперь показывает только сами точки без линий - упрощена работа в редакторе Unity и добавлены editor-инструменты: в `GameManager` лицензия пропускается при запуске в `UNITY_EDITOR`, а `HierarchySelectionCounter`, `HierarchySelectionCountOverlay` и `HierarchyBulkRenamerWindow` добавляют подсчет выделения, realtime overlay в `SceneView` и массовое переименование объектов по правилам нумерации из Unity Project Settings - синхронизированы сцены, ресурсы и UI-ассеты под новый flow: обновлены `MainMenu`, `Level UI`, уровни `1-1` и `1-2`, строки настроек, кнопки, TMP/font assets, изображения UI, `prizes.json` и recovery-данные после правок интерфейса и логики - очищены и переразложены часть внешних и служебных ресурсов: удалён пакет `Lava_Flowing_Shader`, переименованы/заменены отдельные UI-prefab'ы и добавлены сопутствующие проектные артефакты, которые сейчас используются обновлённой конфигурацией проекта
251 lines
8.9 KiB
C#
251 lines
8.9 KiB
C#
#if UNITY_EDITOR
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Reflection;
|
|
using UnityEditor;
|
|
using UnityEditor.SceneManagement;
|
|
using UnityEngine;
|
|
|
|
namespace RR.Common.InspectorOverrides
|
|
{
|
|
public sealed class HierarchyBulkRenamerWindow : EditorWindow
|
|
{
|
|
private enum NamingScheme
|
|
{
|
|
SpaceParenthesis,
|
|
Dot,
|
|
Underscore
|
|
}
|
|
|
|
private struct NamingSettings
|
|
{
|
|
public NamingScheme Scheme;
|
|
public int Digits;
|
|
public bool StartsAtZero;
|
|
}
|
|
|
|
private string _baseName = "GameObject";
|
|
private Vector2 _scrollPosition;
|
|
|
|
[MenuItem("Tools/Hierarchy/Bulk Rename Selected")]
|
|
private static void OpenWindow()
|
|
{
|
|
HierarchyBulkRenamerWindow window = GetWindow<HierarchyBulkRenamerWindow>();
|
|
window.titleContent = new GUIContent("Bulk Rename");
|
|
window.minSize = new Vector2(360f, 260f);
|
|
window.Show();
|
|
}
|
|
|
|
private void OnEnable()
|
|
{
|
|
Selection.selectionChanged += Repaint;
|
|
}
|
|
|
|
private void OnDisable()
|
|
{
|
|
Selection.selectionChanged -= Repaint;
|
|
}
|
|
|
|
private void OnGUI()
|
|
{
|
|
List<GameObject> selectedObjects = GetSelectedHierarchyObjects();
|
|
NamingSettings namingSettings = ReadProjectNamingSettings();
|
|
|
|
EditorGUILayout.LabelField("Mass Rename Hierarchy Objects", EditorStyles.boldLabel);
|
|
EditorGUILayout.Space(4f);
|
|
|
|
using (new EditorGUILayout.VerticalScope(EditorStyles.helpBox))
|
|
{
|
|
EditorGUILayout.LabelField("Base Name", EditorStyles.miniBoldLabel);
|
|
_baseName = EditorGUILayout.TextField(_baseName);
|
|
}
|
|
|
|
using (new EditorGUILayout.VerticalScope(EditorStyles.helpBox))
|
|
{
|
|
EditorGUILayout.LabelField("Project Numbering Settings", EditorStyles.miniBoldLabel);
|
|
EditorGUILayout.LabelField("Scheme", NamingSchemeToText(namingSettings.Scheme));
|
|
EditorGUILayout.LabelField("Digits", namingSettings.Digits.ToString());
|
|
EditorGUILayout.LabelField("Starts At", namingSettings.StartsAtZero ? "0" : "1");
|
|
}
|
|
|
|
using (new EditorGUILayout.VerticalScope(EditorStyles.helpBox))
|
|
{
|
|
EditorGUILayout.LabelField("Selection", EditorStyles.miniBoldLabel);
|
|
EditorGUILayout.LabelField($"Selected objects: {selectedObjects.Count}");
|
|
|
|
string previewBaseName = string.IsNullOrWhiteSpace(_baseName) ? "GameObject" : _baseName.Trim();
|
|
string previewName = BuildName(previewBaseName, namingSettings, 0);
|
|
EditorGUILayout.LabelField("First preview", previewName);
|
|
}
|
|
|
|
EditorGUILayout.Space(4f);
|
|
DrawSelectionPreview(selectedObjects, namingSettings);
|
|
|
|
using (new EditorGUI.DisabledScope(selectedObjects.Count == 0))
|
|
{
|
|
if (GUILayout.Button("Rename Selected"))
|
|
RenameSelected(selectedObjects, namingSettings);
|
|
}
|
|
}
|
|
|
|
private void DrawSelectionPreview(List<GameObject> selectedObjects, NamingSettings namingSettings)
|
|
{
|
|
EditorGUILayout.LabelField("Preview", EditorStyles.boldLabel);
|
|
|
|
using (new EditorGUILayout.VerticalScope(EditorStyles.helpBox))
|
|
{
|
|
_scrollPosition = EditorGUILayout.BeginScrollView(_scrollPosition, GUILayout.MinHeight(120f));
|
|
|
|
if (selectedObjects.Count == 0)
|
|
{
|
|
EditorGUILayout.LabelField("No hierarchy objects selected.");
|
|
}
|
|
else
|
|
{
|
|
string normalizedBaseName = string.IsNullOrWhiteSpace(_baseName) ? "GameObject" : _baseName.Trim();
|
|
for (int i = 0; i < selectedObjects.Count; i++)
|
|
{
|
|
string renamed = BuildName(normalizedBaseName, namingSettings, i);
|
|
EditorGUILayout.LabelField($"{selectedObjects[i].name} -> {renamed}");
|
|
}
|
|
}
|
|
|
|
EditorGUILayout.EndScrollView();
|
|
}
|
|
}
|
|
|
|
private void RenameSelected(List<GameObject> selectedObjects, NamingSettings namingSettings)
|
|
{
|
|
if (selectedObjects.Count == 0)
|
|
return;
|
|
|
|
string normalizedBaseName = string.IsNullOrWhiteSpace(_baseName) ? "GameObject" : _baseName.Trim();
|
|
|
|
Undo.RecordObjects(selectedObjects.ToArray(), "Bulk Rename Hierarchy Objects");
|
|
|
|
for (int i = 0; i < selectedObjects.Count; i++)
|
|
{
|
|
GameObject gameObject = selectedObjects[i];
|
|
if (gameObject == null)
|
|
continue;
|
|
|
|
gameObject.name = BuildName(normalizedBaseName, namingSettings, i);
|
|
|
|
if (gameObject.scene.IsValid())
|
|
EditorSceneManager.MarkSceneDirty(gameObject.scene);
|
|
}
|
|
|
|
EditorUtility.DisplayDialog(
|
|
"Bulk Rename",
|
|
$"Переименовано объектов: {selectedObjects.Count}",
|
|
"OK");
|
|
}
|
|
|
|
private static List<GameObject> GetSelectedHierarchyObjects()
|
|
{
|
|
return Selection.gameObjects
|
|
.Where(gameObject => gameObject != null && gameObject.scene.IsValid())
|
|
.OrderBy(gameObject => GetHierarchySortKey(gameObject.transform))
|
|
.ToList();
|
|
}
|
|
|
|
private static string GetHierarchySortKey(Transform target)
|
|
{
|
|
List<int> indices = new();
|
|
Transform current = target;
|
|
|
|
while (current != null)
|
|
{
|
|
indices.Add(current.GetSiblingIndex());
|
|
current = current.parent;
|
|
}
|
|
|
|
indices.Reverse();
|
|
return string.Join("/", indices.Select(index => index.ToString("D6")));
|
|
}
|
|
|
|
private static NamingSettings ReadProjectNamingSettings()
|
|
{
|
|
NamingSettings settings = new NamingSettings
|
|
{
|
|
Scheme = NamingScheme.SpaceParenthesis,
|
|
Digits = 1,
|
|
StartsAtZero = false
|
|
};
|
|
|
|
Type editorSettingsType = typeof(EditorSettings);
|
|
|
|
PropertyInfo schemeProperty = editorSettingsType.GetProperty(
|
|
"gameObjectNamingScheme",
|
|
BindingFlags.Public | BindingFlags.Static);
|
|
if (schemeProperty != null)
|
|
{
|
|
object value = schemeProperty.GetValue(null);
|
|
if (value != null)
|
|
settings.Scheme = ParseNamingScheme(value.ToString());
|
|
}
|
|
|
|
PropertyInfo digitsProperty = editorSettingsType.GetProperty(
|
|
"gameObjectNamingDigits",
|
|
BindingFlags.Public | BindingFlags.Static);
|
|
if (digitsProperty != null)
|
|
{
|
|
object value = digitsProperty.GetValue(null);
|
|
if (value is int digits)
|
|
settings.Digits = Mathf.Max(1, digits);
|
|
}
|
|
|
|
PropertyInfo startsAtZeroProperty = editorSettingsType.GetProperty(
|
|
"gameObjectNamingStartsAtZero",
|
|
BindingFlags.Public | BindingFlags.Static);
|
|
if (startsAtZeroProperty != null)
|
|
{
|
|
object value = startsAtZeroProperty.GetValue(null);
|
|
if (value is bool startsAtZero)
|
|
settings.StartsAtZero = startsAtZero;
|
|
}
|
|
|
|
return settings;
|
|
}
|
|
|
|
private static NamingScheme ParseNamingScheme(string rawValue)
|
|
{
|
|
if (string.IsNullOrEmpty(rawValue))
|
|
return NamingScheme.SpaceParenthesis;
|
|
|
|
if (rawValue.IndexOf("dot", StringComparison.OrdinalIgnoreCase) >= 0)
|
|
return NamingScheme.Dot;
|
|
|
|
if (rawValue.IndexOf("underscore", StringComparison.OrdinalIgnoreCase) >= 0)
|
|
return NamingScheme.Underscore;
|
|
|
|
return NamingScheme.SpaceParenthesis;
|
|
}
|
|
|
|
private static string BuildName(string baseName, NamingSettings namingSettings, int sequenceIndex)
|
|
{
|
|
int displayIndex = namingSettings.StartsAtZero ? sequenceIndex : sequenceIndex + 1;
|
|
string number = displayIndex.ToString($"D{Mathf.Max(1, namingSettings.Digits)}");
|
|
|
|
return namingSettings.Scheme switch
|
|
{
|
|
NamingScheme.Dot => $"{baseName}.{number}",
|
|
NamingScheme.Underscore => $"{baseName}_{number}",
|
|
_ => $"{baseName} ({number})"
|
|
};
|
|
}
|
|
|
|
private static string NamingSchemeToText(NamingScheme namingScheme)
|
|
{
|
|
return namingScheme switch
|
|
{
|
|
NamingScheme.Dot => "Dot",
|
|
NamingScheme.Underscore => "Underscore",
|
|
_ => "Space Parenthesis"
|
|
};
|
|
}
|
|
}
|
|
}
|
|
#endif
|