Skip to content

Commit 1b4b9f8

Browse files
authored
fix: wrong avatar base destruction (Angzaar teleport) (#4014)
1 parent c0c882f commit 1b4b9f8

File tree

4 files changed

+26
-8
lines changed

4 files changed

+26
-8
lines changed

Explorer/Assets/DCL/Infrastructure/Global/StaticContainer.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -254,7 +254,7 @@ await UniTask.WhenAll(
254254
new MaterialsPlugin(sharedDependencies, videoTexturePool),
255255
textureResolvePlugin,
256256
new AssetsCollidersPlugin(sharedDependencies, container.PhysicsTickProvider),
257-
new AvatarShapePlugin(globalWorld),
257+
new AvatarShapePlugin(globalWorld, componentsContainer.ComponentPoolsRegistry),
258258
new AvatarAttachPlugin(globalWorld, container.MainPlayerAvatarBaseProxy, componentsContainer.ComponentPoolsRegistry, container.EntityParticipantTableProxy),
259259
new PrimitivesRenderingPlugin(sharedDependencies),
260260
new VisibilityPlugin(),

Explorer/Assets/DCL/PluginSystem/World/AvatarShapePlugin.cs

+6-2
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,25 @@
11
using Arch.SystemGroups;
22
using DCL.ECSComponents;
3+
using DCL.Optimization.Pools;
34
using DCL.PluginSystem.World.Dependencies;
45
using DCL.SDKComponents.AvatarShape.Systems;
56
using ECS.LifeCycle;
67
using ECS.LifeCycle.Systems;
78
using ECS.Unity.AvatarShape.Systems;
89
using System.Collections.Generic;
10+
using UnityEngine;
911

1012
namespace DCL.PluginSystem.World
1113
{
1214
public class AvatarShapePlugin : IDCLWorldPlugin
1315
{
1416
private readonly Arch.Core.World globalWorld;
17+
public IComponentPool<Transform> globalTransformPool;
1518

16-
public AvatarShapePlugin(Arch.Core.World globalWorld)
19+
public AvatarShapePlugin(Arch.Core.World globalWorld, IComponentPoolsRegistry poolRegistry)
1720
{
1821
this.globalWorld = globalWorld;
22+
this.globalTransformPool = poolRegistry.GetReferenceTypePool<Transform>();
1923
}
2024

2125
public void Dispose()
@@ -26,7 +30,7 @@ public void Dispose()
2630
public void InjectToWorld(ref ArchSystemsWorldBuilder<Arch.Core.World> builder, in ECSWorldInstanceSharedDependencies sharedDependencies, in PersistentEntities persistentEntities, List<IFinalizeWorldSystem> finalizeWorldSystems, List<ISceneIsCurrentListener> sceneIsCurrentListeners)
2731
{
2832
ResetDirtyFlagSystem<PBAvatarShape>.InjectToWorld(ref builder);
29-
var avatarShapeHandlerSystem = AvatarShapeHandlerSystem.InjectToWorld(ref builder, globalWorld);
33+
var avatarShapeHandlerSystem = AvatarShapeHandlerSystem.InjectToWorld(ref builder, globalWorld, globalTransformPool);
3034
finalizeWorldSystems.Add(avatarShapeHandlerSystem);
3135
UpdateAvatarShapeInterpolateMovementSystem.InjectToWorld(ref builder, globalWorld, sharedDependencies.SceneData.SceneShortInfo.BaseParcel);
3236
}

Explorer/Assets/DCL/SDKComponents/AvatarShape/Systems/AvatarShapeHandlerSystem.cs

+13-4
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,15 @@
88
using DCL.CharacterMotion.Components;
99
using DCL.Diagnostics;
1010
using DCL.ECSComponents;
11+
using DCL.Optimization.Pools;
1112
using ECS.Abstract;
1213
using ECS.LifeCycle;
1314
using ECS.LifeCycle.Components;
1415
using ECS.Prioritization.Components;
1516
using ECS.Unity.AvatarShape.Components;
1617
using ECS.Unity.Groups;
1718
using ECS.Unity.Transforms.Components;
19+
using UnityEngine;
1820
using Utility.Arch;
1921

2022
namespace ECS.Unity.AvatarShape.Systems
@@ -25,10 +27,12 @@ namespace ECS.Unity.AvatarShape.Systems
2527
public partial class AvatarShapeHandlerSystem : BaseUnityLoopSystem, IFinalizeWorldSystem
2628
{
2729
private readonly World globalWorld;
30+
private readonly IComponentPool<Transform> globalTransformPool;
2831

29-
public AvatarShapeHandlerSystem(World world, World globalWorld) : base(world)
32+
public AvatarShapeHandlerSystem(World world, World globalWorld, IComponentPool<Transform> globalTransformPool) : base(world)
3033
{
3134
this.globalWorld = globalWorld;
35+
this.globalTransformPool = globalTransformPool;
3236
}
3337

3438
protected override void Update(float t)
@@ -44,9 +48,14 @@ protected override void Update(float t)
4448
[None(typeof(SDKAvatarShapeComponent), typeof(DeleteEntityIntention))]
4549
private void LoadAvatarShape(Entity entity, ref PBAvatarShape pbAvatarShape, ref PartitionComponent partitionComponent, ref TransformComponent transformComponent)
4650
{
51+
// We have to create a global transform to hold the CharacterTransform. Using the Transform from the TransformComponent
52+
// may lead to unexpected consequences, since that one is disposed by the scene, while the avatar lives in the global world
53+
Transform globalTransform = globalTransformPool.Get();
54+
globalTransform.SetParent(transformComponent.Transform);
55+
4756
var globalWorldEntity = globalWorld.Create(
4857
pbAvatarShape, partitionComponent,
49-
new CharacterTransform(transformComponent.Transform),
58+
new CharacterTransform(globalTransform),
5059
new CharacterInterpolationMovementComponent(transformComponent.Transform.position, transformComponent.Transform.position, transformComponent.Transform.rotation),
5160
new CharacterAnimationComponent(),
5261
new CharacterEmoteComponent());
@@ -95,8 +104,8 @@ public void FinalizeComponents(in Query query) =>
95104

96105
public void MarkGlobalWorldEntityForDeletion(Entity globalEntity)
97106
{
98-
// Has to be removed, otherwise scene loading may break after teleportation (no error anywhere to know why)
99-
globalWorld.Remove<CharacterTransform>(globalEntity);
107+
// Need to remove parenting, since it may unintenionally deleted when
108+
globalWorld.Get<CharacterTransform>(globalEntity).Transform.SetParent(null);
100109

101110
// Has to be deferred because many times it happens that the entity is marked for deletion AFTER the
102111
// AvatarCleanUpSystem.Update() and BEFORE the DestroyEntitiesSystem.Update(), probably has to do with

Explorer/Assets/DCL/SDKComponents/AvatarShape/Tests/AvatarShapeHandlerSystemShould.cs

+6-1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,9 @@
77
using ECS.Unity.AvatarShape.Systems;
88
using NUnit.Framework;
99
using DCL.Character.Components;
10+
using DCL.Optimization.Pools;
11+
using NSubstitute;
12+
using UnityEngine;
1013

1114
namespace ECS.Unity.AvatarShape.Tests
1215
{
@@ -17,7 +20,9 @@ public class AvatarShapeHandlerSystemShould : UnitySystemTestBase<AvatarShapeHan
1720
public void SetUp()
1821
{
1922
globalWorld = World.Create();
20-
system = new AvatarShapeHandlerSystem(world, globalWorld);
23+
IComponentPool<Transform> pool = Substitute.For<IComponentPool<Transform>>();
24+
pool.Get().Returns(new GameObject().transform);
25+
system = new AvatarShapeHandlerSystem(world, globalWorld, pool);
2126

2227
entity = world.Create(PartitionComponent.TOP_PRIORITY);
2328
AddTransformToEntity(entity);

0 commit comments

Comments
 (0)