Skip to content

Commit 9aff1d7

Browse files
committed
- Implemented EntityTemplate feature
- Build fix
1 parent c0fa2cc commit 9aff1d7

17 files changed

+518
-3
lines changed

Entity System/Unity Layer/Actor.cs

Lines changed: 51 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
using System.Collections.Generic;
33
using System.Linq;
44
using TriInspector;
5-
using UnityEditor;
65
using UnityEngine;
76

87
namespace EasyCS
@@ -84,6 +83,9 @@ public Actor Root
8483
private Dictionary<Type, ActorComponent> _actorComponents = new Dictionary<Type, ActorComponent>();
8584
private readonly Dictionary<Type, object> _actorComponentsAndData = new();
8685

86+
[field: SerializeField]
87+
public EntityTemplateAsset EntityTemplate { get; private set; }
88+
8789
[SerializeField, ReadOnly]
8890
private List<ActorComponent> _allComponents = new List<ActorComponent>();
8991

@@ -96,7 +98,8 @@ public Actor Root
9698
[ShowInInspector, ReadOnly, ShowIf("EditorHasMissingEntityComponentsDependencies"),
9799
LabelText("Missing Entity Dependencies"),
98100
ListDrawerSettings(AlwaysExpanded = true),
99-
InfoBox("Entity Dependencies is not resolved! Default instances will be created.", TriMessageType.Warning, "EditorHasMissingEntityComponentsDependencies")]
101+
InfoBox("Entity Dependencies is not resolved! Default instances will be created.", TriMessageType.Warning, "EditorHasMissingEntityComponentsDependencies"),
102+
MaxDrawDepth(2)]
100103
private List<IEntityComponent> EditorEntityComponentsMissingRequired
101104
{
102105
get
@@ -566,6 +569,7 @@ int GetPriority(Component c)
566569
foreach (var component in _allComponents)
567570
component.SetActor(this);
568571

572+
EditorApplyEntityTemplate();
569573
EditorValidateAllComponentDependencies();
570574
ValidateSetup();
571575
EditorUpdateUnusedDependencies();
@@ -685,6 +689,45 @@ private void EditorValidateActorComponentsDependencies()
685689
EditorUpdateMissingActorDependenciesList();
686690
}
687691

692+
private void EditorApplyEntityTemplate()
693+
{
694+
if (EntityTemplate == null)
695+
return;
696+
697+
var componentTypes = EntityTemplate.GetComponentTypes();
698+
699+
List<Type> providersToAdd = new List<Type>();
700+
701+
foreach (var type in componentTypes)
702+
{
703+
Type providerType = EntityComponentProviderFinder.FindEntityComponentProviderMatching(type);
704+
705+
if (providerType != null)
706+
{
707+
if (_allComponents.Exists(c => c.GetType() == providerType))
708+
continue;
709+
if (_entityComponentsMissing.Exists(c => c.GetType() == type))
710+
continue;
711+
712+
providersToAdd.Add(providerType);
713+
}
714+
}
715+
716+
if (providersToAdd.Count > 0)
717+
{
718+
UnityEditor.EditorApplication.delayCall += () =>
719+
{
720+
if (this == null) return;
721+
722+
foreach (var provider in providersToAdd)
723+
if (gameObject.GetComponent(provider) == null)
724+
UnityEditor.Undo.AddComponent(gameObject, provider);
725+
726+
UnityEditor.EditorUtility.SetDirty(gameObject);
727+
};
728+
}
729+
}
730+
688731
public List<string> EditorGetMissingDependenciesNamesForAllComponents(EditorDependenciesType dependenciesType)
689732
{
690733
List<string> missingList = EditorGetMissingDependenciesForAllComponents(dependenciesType)
@@ -833,6 +876,12 @@ public List<ActorComponent> EditorGetUnusedActorComponentsForComponent(ActorComp
833876
}
834877

835878
public bool EditorHasUnusedDependencies() => _editorUnusedDependencies.Count > 0;
879+
880+
public void EditorSetEntityTemplate(EntityTemplateAsset entityTemplateAsset)
881+
{
882+
EntityTemplate = entityTemplateAsset;
883+
EditorApplyEntityTemplate();
884+
}
836885
#endif
837886
}
838887
}

Factory System/Editor/EntityPrefabBuilder.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,7 @@ public static GameObject BuildEntityObject(EntityData entityData, Transform curr
131131
{
132132
GameObject entityGO = current == null ? new GameObject() : current.gameObject;
133133
entityGO.AddComponent<EntityEditorComponentFlag>().hideFlags = HideFlags.HideInInspector;
134-
entityGO.AddComponent<Actor>();
134+
Actor actor= entityGO.AddComponent<Actor>();
135135

136136
if (string.IsNullOrEmpty(entityData.Name) == false)
137137
entityGO.name = entityData.Name;
@@ -186,6 +186,8 @@ public static GameObject BuildEntityObject(EntityData entityData, Transform curr
186186
}
187187
}
188188

189+
actor.EditorSetEntityTemplate(entityData.Template);
190+
189191
return entityGO;
190192
}
191193

Factory System/Editor/PrefabEditSessionManager.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,8 @@ private static EntityFactory.EntityData BuildEntityDataRecursive(Transform trans
122122
entityData.ChildEntities.Add(childEntityData);
123123
}
124124

125+
entityData.Template = transform.GetComponent<Actor>().EntityTemplate;
126+
125127
return entityData;
126128
}
127129
}

Factory System/EntityFactory.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ public class EntityData
2323

2424
[ListDrawerSettings(AlwaysExpanded = true), OnValueChanged("EditorValidate")]
2525
public List<ComponentData> Components = new List<ComponentData>();
26+
public EntityTemplateAsset Template;
2627
[Required]
2728
public List<EntityFactory> NestedFactories = new List<EntityFactory>();
2829

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
using System;
2+
using UnityEngine;
3+
4+
namespace EasyCS
5+
{
6+
public static class EntityComponentProviderFinder
7+
{
8+
public static Type FindEntityComponentProviderMatching(Type targetType)
9+
{
10+
if (typeof(IEntityData).IsAssignableFrom(targetType))
11+
{
12+
return EntityDataProviderFinder.FindEntityDataProviderMatching(targetType);
13+
}
14+
else if (typeof(IEntityBehavior).IsAssignableFrom(targetType))
15+
{
16+
return EntityBehaviorProviderFinder.FindEntityBehaviorProviderMatching(targetType);
17+
}
18+
else
19+
{
20+
Debug.LogError(string.Format("Not found provider for type {type}", targetType));
21+
return null;
22+
}
23+
}
24+
}
25+
}

Factory System/Helpers/EntityComponentProviderFinder.cs.meta

Lines changed: 11 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
5+
namespace EasyCS
6+
{
7+
public static class EntityDependencyHelper
8+
{
9+
public static List<Type> EditorGetMissingEntityBehaviorDependencies(IEnumerable<IEntityComponent> allComponents)
10+
{
11+
List<Type> missingBehaviors = new List<Type>();
12+
13+
// Collect all existing IEntityBehavior types from the provided components
14+
HashSet<Type> existingBehaviorTypes = new HashSet<Type>(
15+
allComponents
16+
.OfType<IEntityBehavior>() // Directly existing behaviors
17+
.Select(c => c.GetType())
18+
);
19+
20+
// Also consider types provided by IEntityBehaviorProvider
21+
foreach (var comp in allComponents.OfType<IEntityBehaviorProvider>())
22+
{
23+
existingBehaviorTypes.Add(comp.GetEntityComponentType());
24+
}
25+
26+
// Iterate through all components to find what they require
27+
foreach (var component in allComponents)
28+
{
29+
if (component == null) continue;
30+
31+
Type componentType = null;
32+
// Determine the type to get dependencies for.
33+
// If it's an IEntityBehaviorProvider, use its provided type.
34+
// Otherwise, use the component's own type.
35+
if (component is IEntityBehaviorProvider entityBehaviorProvider)
36+
componentType = entityBehaviorProvider.GetEntityComponentType();
37+
else
38+
componentType = component.GetType();
39+
40+
var requiredTypes = Injector.GetRequiredInjectionTypes(componentType);
41+
42+
foreach (var depType in requiredTypes)
43+
{
44+
// Check if the dependency is an IEntityBehavior
45+
if (typeof(IEntityBehavior).IsAssignableFrom(depType))
46+
{
47+
// Ignore runtime-only components for editor-time missing checks
48+
if (Attribute.IsDefined(depType, typeof(RuntimeOnlyAttribute)))
49+
continue;
50+
51+
// If the required behavior type is not already existing
52+
if (!existingBehaviorTypes.Contains(depType))
53+
{
54+
// And it's not already in our missing list (to avoid duplicates)
55+
if (!missingBehaviors.Contains(depType))
56+
{
57+
missingBehaviors.Add(depType);
58+
}
59+
}
60+
}
61+
}
62+
}
63+
64+
return missingBehaviors;
65+
}
66+
}
67+
}

Factory System/Helpers/EntityDependencyHelper.cs.meta

Lines changed: 11 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Template System.meta

Lines changed: 8 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Template System/Entity Layer.meta

Lines changed: 8 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)