Add resource pool manager

This commit is contained in:
ud18010
2026-07-30 20:57:59 +08:00
parent 576aa6c14e
commit d1a526094e
5 changed files with 426 additions and 20 deletions
@@ -133,7 +133,7 @@ namespace XGame.ActorBehavior
target.Version = NextActorVersion(actorId);
for (int i = target.SpawnedEffects.Count - 1; i >= 0; i--)
{
DestroyUnityObject(target.SpawnedEffects[i]);
ReleaseEffectInstance(target.SpawnedEffects[i]);
}
target.SpawnedEffects.Clear();
}
@@ -154,24 +154,18 @@ namespace XGame.ActorBehavior
ActorPresentationTarget startTarget = null;
bool actorBoundEffect = !hasExplicitPosition && actors.TryGetValue(actorId, out startTarget);
int startVersion = actorBoundEffect && startTarget != null ? startTarget.Version : 0;
UObject loaded = null;
yield return XResLoader.coLoadRes(prefabPath, typeof(GameObject), obj => loaded = obj);
GameObject prefab = loaded as GameObject;
if (prefab == null)
{
Debug.LogWarning("[ActorBehaviorPresentation] effect prefab load failed: " + prefabPath);
yield break;
}
GameObject instance = null;
yield return LoadEffectInstance(actorId, prefabPath, position, hasExplicitPosition, startTarget, obj => instance = obj);
if (actorBoundEffect && (!actors.TryGetValue(actorId, out ActorPresentationTarget currentTarget) || currentTarget.Version != startVersion))
{
ReleaseEffectInstance(instance);
yield break;
}
GameObject instance = InstantiateEffect(actorId, prefab, position, hasExplicitPosition);
if (instance == null)
{
Debug.LogWarning("[ActorBehaviorPresentation] effect prefab load failed: " + prefabPath);
yield break;
}
@@ -185,7 +179,7 @@ namespace XGame.ActorBehavior
}
else if (defaultEffectLifetime > 0f)
{
Destroy(instance, defaultEffectLifetime);
StartCoroutine(ReleaseEffectAfterLifetime(instance, defaultEffectLifetime));
}
}
@@ -196,27 +190,35 @@ namespace XGame.ActorBehavior
{
target.SpawnedEffects.Remove(instance);
}
DestroyUnityObject(instance);
ReleaseEffectInstance(instance);
}
private GameObject InstantiateEffect(int actorId, GameObject prefab, BehaviorVector3 position, bool hasExplicitPosition)
private IEnumerator ReleaseEffectAfterLifetime(GameObject instance, float lifetime)
{
actors.TryGetValue(actorId, out ActorPresentationTarget target);
yield return new WaitForSeconds(lifetime);
ReleaseEffectInstance(instance);
}
private IEnumerator LoadEffectInstance(int actorId, string prefabPath, BehaviorVector3 position, bool hasExplicitPosition, ActorPresentationTarget startTarget, System.Action<GameObject> action)
{
ActorPresentationTarget target = startTarget;
if (target == null)
{
actors.TryGetValue(actorId, out target);
}
if (target != null && !hasExplicitPosition && attachActorEffects)
{
Transform parent = target.EffectRoot != null ? target.EffectRoot : target.ActorTransform;
GameObject instance = Instantiate(prefab, parent);
instance.transform.localPosition = Vector3.zero;
instance.transform.localRotation = Quaternion.identity;
return instance;
yield return ResourcePoolManager.coLoadGameObject(prefabPath, parent, Vector3.zero, Quaternion.identity, action);
yield break;
}
Vector3 worldPosition = hasExplicitPosition ? ToUnity(position) : GetActorPosition(target);
Quaternion worldRotation = target != null && target.ActorTransform != null
? target.ActorTransform.rotation
: Quaternion.identity;
return Instantiate(prefab, worldPosition, worldRotation);
yield return ResourcePoolManager.coLoadGameObjectWorld(prefabPath, worldPosition, worldRotation, action);
}
private int NextActorVersion(int actorId)
@@ -264,6 +266,19 @@ namespace XGame.ActorBehavior
}
}
private static void ReleaseEffectInstance(GameObject instance)
{
if (instance == null)
{
return;
}
if (!ResourcePoolManager.Release(instance))
{
DestroyUnityObject(instance);
}
}
private sealed class ActorPresentationTarget
{
public readonly Animator Animator;