init: add project

This commit is contained in:
Bragin Stepan
2026-02-18 23:02:28 +05:00
commit 4f01e66894
620 changed files with 52253 additions and 0 deletions

View File

@@ -0,0 +1,201 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using UnityEditor;
using UnityEngine;
using System.Reflection;
using _Project.Develop.Runtime.Entities;
namespace _Project.Develop.Editor
{
public class EntityAPIGenerator
{
private const string AssemblyName = "Assembly-CSharp";
private static string OutputPath
=> Path.Combine(Application.dataPath, "_Project/Develop/Runtime/Logic/Gameplay/Entities/Generated/EntityAPI.cs");
[InitializeOnLoadMethod]
[MenuItem("Tools/GenerateEntityAPI")]
private static void Generate()
{
StringBuilder sb = new StringBuilder();
sb.AppendLine($"namespace {typeof(Entity).Namespace}");
sb.AppendLine("{");
sb.AppendLine($"\tpublic partial class {typeof(Entity).Name}");
sb.AppendLine("\t{");
Assembly assembly = Assembly.Load(AssemblyName);
IEnumerable<Type> componentTypes = GetComponentTypesFrom(assembly);
foreach (Type componentType in componentTypes)
{
string typeName = componentType.Name;
string fullTypeName = componentType.FullName;
string componentName = RemoveSuffixIsExists(typeName, "Component");
string modifiedComponentName = componentName + "C";
// Свойство для получения компонента
sb.AppendLine($"\t\tpublic {fullTypeName} {modifiedComponentName} => GetComponent<{fullTypeName}>();");
sb.AppendLine();
if(HasSingleField(componentType, out FieldInfo field) && field.Name == "Value")
{
// Свойство для получения поля из компонента
sb.AppendLine($"\t\tpublic {GetValidTypeName(field.FieldType)} {componentName} => {modifiedComponentName}.{field.Name};");
sb.AppendLine();
//метод TryGet
sb.AppendLine($"\t\tpublic bool TryGet{componentName}(out {GetValidTypeName(field.FieldType)} {GetVariableNameFrom(field.Name)})");
sb.AppendLine("\t\t{");
sb.AppendLine($"\t\t\tbool result = TryGetComponent(out {fullTypeName} component);");
sb.AppendLine($"\t\t\tif(result)");
sb.AppendLine($"\t\t\t\t{GetVariableNameFrom(field.Name)} = component.{field.Name};");
sb.AppendLine($"\t\t\telse");
sb.AppendLine($"\t\t\t\t{GetVariableNameFrom(field.Name)} = default({GetValidTypeName(field.FieldType)});");
sb.AppendLine($"\t\t\treturn result;");
sb.AppendLine("\t\t}");
sb.AppendLine();
//метод add если есть одно поле с пустым конструктором
if (HasEmptyConstructor(field.FieldType))
{
string initializer = "{ " + field.Name + " = new " + GetValidTypeName(field.FieldType) + "() }";
sb.AppendLine($"\t\tpublic {typeof(Entity).FullName} Add{componentName}()");
sb.AppendLine("\t\t{");
sb.AppendLine($"\t\t\treturn AddComponent(new {fullTypeName}() {initializer}); ");
sb.AppendLine("\t\t}");
sb.AppendLine();
}
}
//метод add с указание параметров
string componentParameters = GetParametrs(componentType);
sb.AppendLine($"\t\tpublic {typeof(Entity).FullName} Add{componentName}({componentParameters})");
sb.AppendLine("\t\t{");
sb.AppendLine($"\t\t\treturn AddComponent(new {fullTypeName}() {GetInitializer(componentType)}); ");
sb.AppendLine("\t\t}");
sb.AppendLine();
}
sb.AppendLine("\t}");
sb.AppendLine("}");
File.WriteAllText(OutputPath, sb.ToString());
AssetDatabase.Refresh();
AssetDatabase.SaveAssets();
}
private static bool HasEmptyConstructor(Type type)
{
return
type.GetConstructor(Type.EmptyTypes) != null
&& type.IsSubclassOf(typeof(UnityEngine.Object)) == false;
}
private static string GetParametrs(Type type)
{
FieldInfo[] fields = type.GetFields(BindingFlags.Public | BindingFlags.Instance);
if (fields.Any() == false)
return "";
IEnumerable<string> parameters = fields
.Select(field => $"{GetValidTypeName(field.FieldType)} {GetVariableNameFrom(field.Name)}");
return string.Join(",", parameters);
}
private static string GetInitializer(Type type)
{
FieldInfo[] fields = type.GetFields(BindingFlags.Public | BindingFlags.Instance);
if (fields.Any() == false)
return "";
IEnumerable<string> initializers = fields
.Select(field => $"{field.Name} = {GetVariableNameFrom(field.Name)}");
return "{" + string.Join(", ", initializers) + "}";
}
public static string GetVariableNameFrom(string name) => char.ToLowerInvariant(name[0]) + name.Substring(1);
private static bool HasSingleField(Type type, out FieldInfo field)
{
FieldInfo[] fields = type.GetFields(BindingFlags.Public | BindingFlags.Instance);
if(fields.Length != 1)
{
field = null;
return false;
}
field = fields[0];
return true;
}
private static string RemoveSuffixIsExists(string str, string suffix)
{
if (str.EndsWith(suffix))
{
return str.Substring(0, str.Length - suffix.Length);
}
return str;
}
private static IEnumerable<Type> GetComponentTypesFrom(Assembly assembly)
{
return assembly
.GetTypes()
.Where(type => type.IsInterface == false
&& type.IsAbstract == false
&& typeof(IEntityComponent).IsAssignableFrom(type));
}
public static string GetValidTypeName(Type type)
{
if (type.IsGenericType)
{
StringBuilder sb = new StringBuilder();
string fullTypeName = type.FullName;
var backtickIndex = fullTypeName.IndexOf('`');
if (backtickIndex >= 0)
fullTypeName = fullTypeName.Substring(0, backtickIndex);
sb.Append(fullTypeName);
sb.Append("<");
Type[] genericArgs = type.GetGenericArguments();
for (int i = 0; i < genericArgs.Length; i++)
{
if (i > 0)
sb.Append(", ");
sb.Append(GetValidTypeName(genericArgs[i]));
}
sb.Append(">");
return sb.ToString();
}
else
{
return type.FullName;
}
}
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 06b2695cdf194d57b085ad7a3146f61c
timeCreated: 1771425293

View File

@@ -0,0 +1,18 @@
using UnityEditor;
using UnityEditor.SceneManagement;
namespace _Project.Develop.Editor
{
[InitializeOnLoad]
public static class EntryPointSceneAutoLoader
{
static EntryPointSceneAutoLoader()
{
if (EditorBuildSettings.scenes.Length == 0)
return;
EditorSceneManager.playModeStartScene = AssetDatabase
.LoadAssetAtPath<SceneAsset>(EditorBuildSettings.scenes[0].path);
}
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 6381b293a23a4b838e130ade65283f77
timeCreated: 1770306127