diff --git a/Explorer/Assets/AddressableAssetsData/AssetGroups/Settings.asset b/Explorer/Assets/AddressableAssetsData/AssetGroups/Settings.asset
index 4723dc1408..cb817038c9 100644
--- a/Explorer/Assets/AddressableAssetsData/AssetGroups/Settings.asset
+++ b/Explorer/Assets/AddressableAssetsData/AssetGroups/Settings.asset
@@ -22,6 +22,11 @@ MonoBehaviour:
m_ReadOnly: 0
m_SerializedLabels: []
FlaggedDuringContentUpdateRestriction: 0
+ - m_GUID: 12f48d0297bd3f746b92a97878478086
+ m_Address: VideoPrioritizationSettings
+ m_ReadOnly: 0
+ m_SerializedLabels: []
+ FlaggedDuringContentUpdateRestriction: 0
- m_GUID: 134b7bf082a11ae499e9e62958051ca7
m_Address: AnalyticsConfiguration
m_ReadOnly: 0
diff --git a/Explorer/Assets/DCL/Audio/Prefabs/MediaPlayer.prefab b/Explorer/Assets/DCL/Audio/Prefabs/MediaPlayer.prefab
index fe2d12e763..d4828e9d10 100644
--- a/Explorer/Assets/DCL/Audio/Prefabs/MediaPlayer.prefab
+++ b/Explorer/Assets/DCL/Audio/Prefabs/MediaPlayer.prefab
@@ -250,7 +250,7 @@ AudioSource:
MinDistance: 40
MaxDistance: 60
Pan2D: 0
- rolloffMode: 1
+ rolloffMode: 2
BypassEffects: 0
BypassListenerEffects: 0
BypassReverbZones: 0
@@ -258,23 +258,23 @@ AudioSource:
serializedVersion: 2
m_Curve:
- serializedVersion: 3
- time: 0
+ time: 0.16666667
value: 1
- inSlope: 0
- outSlope: 0
- tangentMode: 0
- weightedMode: 0
- inWeight: 0.33333334
- outWeight: 0.33333334
+ inSlope: -1.6265876
+ outSlope: 0.01024792
+ tangentMode: 1
+ weightedMode: 3
+ inWeight: 0
+ outWeight: 0.29192546
- serializedVersion: 3
time: 1
value: 0
- inSlope: 0
- outSlope: 0
+ inSlope: 0.013024294
+ outSlope: 0.013024294
tangentMode: 0
weightedMode: 0
- inWeight: 0.33333334
- outWeight: 0.33333334
+ inWeight: 0.28074533
+ outWeight: 0
m_PreInfinity: 2
m_PostInfinity: 2
m_RotationOrder: 4
@@ -283,7 +283,7 @@ AudioSource:
m_Curve:
- serializedVersion: 3
time: 0
- value: 0
+ value: 1
inSlope: 0
outSlope: 0
tangentMode: 0
diff --git a/Explorer/Assets/DCL/AvatarRendering/AvatarShape/Systems/AvatarLoaderSystem.cs b/Explorer/Assets/DCL/AvatarRendering/AvatarShape/Systems/AvatarLoaderSystem.cs
index eae9f7723e..8c6827388b 100644
--- a/Explorer/Assets/DCL/AvatarRendering/AvatarShape/Systems/AvatarLoaderSystem.cs
+++ b/Explorer/Assets/DCL/AvatarRendering/AvatarShape/Systems/AvatarLoaderSystem.cs
@@ -89,8 +89,9 @@ private void UpdateAvatarFromSDKComponent(ref PBAvatarShape pbAvatarShape, ref A
avatarShapeComponent.WearablePromise.ForgetLoading(World);
WearablePromise newPromise = CreateWearablePromise(pbAvatarShape, partition);
+ avatarShapeComponent.ID = pbAvatarShape.Id;
+ avatarShapeComponent.Name = pbAvatarShape.Name;
avatarShapeComponent.WearablePromise = newPromise;
-
avatarShapeComponent.BodyShape = pbAvatarShape;
avatarShapeComponent.HairColor = pbAvatarShape.GetHairColor().ToUnityColor();
avatarShapeComponent.SkinColor = pbAvatarShape.GetSkinColor().ToUnityColor();
diff --git a/Explorer/Assets/DCL/Character/CharacterMotion/Components/PlayerTeleportIntent.cs b/Explorer/Assets/DCL/Character/CharacterMotion/Components/PlayerTeleportIntent.cs
index 7148a4e9ab..390ed3e34c 100644
--- a/Explorer/Assets/DCL/Character/CharacterMotion/Components/PlayerTeleportIntent.cs
+++ b/Explorer/Assets/DCL/Character/CharacterMotion/Components/PlayerTeleportIntent.cs
@@ -25,17 +25,20 @@ public JustTeleported(int expireFrame)
public readonly CancellationToken CancellationToken;
///
- /// Strictly it's the same report added to "SceneReadinessReportQueue"
+ /// Strictly it's the same report added to "SceneReadinessReportQueue"
+ /// Teleport operation will wait for this report to be resolved before finishing the teleport operation
+ /// Otherwise the teleport operation will be executed immediately
///
- public readonly AsyncLoadProcessReport? LoadReport;
+ public readonly AsyncLoadProcessReport? AssetsResolution;
+
public readonly float CreationTime;
- public PlayerTeleportIntent(Vector3 position, Vector2Int parcel, CancellationToken cancellationToken, AsyncLoadProcessReport? loadReport = null)
+ public PlayerTeleportIntent(Vector3 position, Vector2Int parcel, CancellationToken cancellationToken, AsyncLoadProcessReport? assetsResolution = null)
{
Position = position;
Parcel = parcel;
CancellationToken = cancellationToken;
- LoadReport = loadReport;
+ AssetsResolution = assetsResolution;
CreationTime = Time.realtimeSinceStartup;
}
diff --git a/Explorer/Assets/DCL/Character/CharacterMotion/Systems/RotateCharacterSystem.cs b/Explorer/Assets/DCL/Character/CharacterMotion/Systems/RotateCharacterSystem.cs
index 1db0f2384f..14d3ac4ed1 100644
--- a/Explorer/Assets/DCL/Character/CharacterMotion/Systems/RotateCharacterSystem.cs
+++ b/Explorer/Assets/DCL/Character/CharacterMotion/Systems/RotateCharacterSystem.cs
@@ -8,6 +8,7 @@
using DCL.CharacterMotion.Platforms;
using DCL.CharacterMotion.Settings;
using DCL.Diagnostics;
+using DCL.ECSComponents;
using ECS.Abstract;
using ECS.Unity.Transforms.Components;
using UnityEngine;
@@ -32,7 +33,7 @@ protected override void Update(float t)
}
[Query]
- [None(typeof(PlayerLookAtIntent))]
+ [None(typeof(PlayerLookAtIntent), typeof(PBAvatarShape))]
private void LerpRotation(
[Data] float dt,
ref ICharacterControllerSettings settings,
@@ -55,6 +56,7 @@ private void LerpRotation(
}
[Query]
+ [None(typeof(PBAvatarShape))]
private void ForceLookAt(in Entity entity, ref CharacterRigidTransform rigidTransform, ref CharacterTransform transform, in PlayerLookAtIntent lookAtIntent)
{
// Rotate player to look at camera target
diff --git a/Explorer/Assets/DCL/Character/CharacterMotion/Systems/TeleportCharacterSystem.cs b/Explorer/Assets/DCL/Character/CharacterMotion/Systems/TeleportCharacterSystem.cs
index 03f30b5b27..5d70b4df2f 100644
--- a/Explorer/Assets/DCL/Character/CharacterMotion/Systems/TeleportCharacterSystem.cs
+++ b/Explorer/Assets/DCL/Character/CharacterMotion/Systems/TeleportCharacterSystem.cs
@@ -40,9 +40,12 @@ protected override void Update(float t)
[Query]
private void TeleportPlayer(Entity entity, CharacterController controller, ref CharacterPlatformComponent platformComponent, in PlayerTeleportIntent teleportIntent)
{
- AsyncLoadProcessReport? loadReport = teleportIntent.LoadReport;
+ AsyncLoadProcessReport? loadReport = teleportIntent.AssetsResolution;
- if (loadReport != null)
+ if (loadReport == null)
+ // If there are no assets to wait for, teleport immediately
+ ResolveAsSuccess(entity, in teleportIntent, controller, ref platformComponent);
+ else
{
AsyncLoadProcessReport.Status status = loadReport.GetStatus();
@@ -58,22 +61,22 @@ private void TeleportPlayer(Entity entity, CharacterController controller, ref C
ResolveAsFailure(entity, in teleportIntent, status.Exception!);
return;
}
- }
- // pending cases left
+ // pending cases left
- if (teleportIntent.TimedOut)
- {
- var exception = new TimeoutException("Teleport timed out");
- loadReport?.SetException(exception);
- ResolveAsFailure(entity, in teleportIntent, exception);
- return;
- }
+ if (teleportIntent.TimedOut)
+ {
+ var exception = new TimeoutException("Teleport timed out");
+ loadReport?.SetException(exception);
+ ResolveAsFailure(entity, in teleportIntent, exception);
+ return;
+ }
- if (teleportIntent.CancellationToken.IsCancellationRequested)
- {
- loadReport?.SetCancelled();
- ResolveAsCancelled(entity, in teleportIntent);
+ if (teleportIntent.CancellationToken.IsCancellationRequested)
+ {
+ loadReport?.SetCancelled();
+ ResolveAsCancelled(entity, in teleportIntent);
+ }
}
}
@@ -91,7 +94,7 @@ private void FinalizeQueuedLoadReport(in PlayerTeleportIntent intent, Action(e), Is.False);
+ Assert.That(characterController.transform.position, Is.EqualTo(new Vector3(100, 100, 100)));
+ }
+
[Test]
public async Task RestoreCameraDataOnFailureAsync([Values(UniTaskStatus.Faulted, UniTaskStatus.Canceled)] UniTaskStatus status)
{
diff --git a/Explorer/Assets/DCL/Editor/DCL.Editor.asmdef b/Explorer/Assets/DCL/Editor/DCL.Editor.asmdef
index c2770eb0e0..9e93c3e1a4 100644
--- a/Explorer/Assets/DCL/Editor/DCL.Editor.asmdef
+++ b/Explorer/Assets/DCL/Editor/DCL.Editor.asmdef
@@ -20,7 +20,8 @@
"GUID:166b65e6dfc848bb9fb075f53c293a38",
"GUID:fa7b3fdbb04d67549916da7bd2af58ab",
"GUID:d28a7e4beeca475418c15757abf1b6f1",
- "GUID:286980af24684da6acc1caa413039811"
+ "GUID:286980af24684da6acc1caa413039811",
+ "GUID:fc37ca6521833154cab08ec51af097d9"
],
"includePlatforms": [
"Editor"
diff --git a/Explorer/Assets/DCL/MapRenderer/MapLayers/PlayerMarker/PlayerMarkerController.cs b/Explorer/Assets/DCL/MapRenderer/MapLayers/PlayerMarker/PlayerMarkerController.cs
index 0f506947b1..ef11c748c3 100644
--- a/Explorer/Assets/DCL/MapRenderer/MapLayers/PlayerMarker/PlayerMarkerController.cs
+++ b/Explorer/Assets/DCL/MapRenderer/MapLayers/PlayerMarker/PlayerMarkerController.cs
@@ -4,6 +4,7 @@
using Arch.SystemGroups.DefaultSystemGroups;
using Cysharp.Threading.Tasks;
using DCL.Character.Components;
+using DCL.ECSComponents;
using DCL.MapRenderer.CoordsUtils;
using DCL.MapRenderer.Culling;
using MVC;
@@ -54,8 +55,9 @@ public void CreateSystems(ref ArchSystemsWorldBuilder builder)
system.Activate();
}
- [All(typeof(PlayerComponent))]
[Query]
+ [All(typeof(PlayerComponent))]
+ [None(typeof(PBAvatarShape))]
private void SetPlayerTransform(in CharacterTransform transformComponent)
{
SetPosition(transformComponent.Transform.position);
diff --git a/Explorer/Assets/DCL/MapRenderer/MapLayers/UsersMarker/UsersMarkersHotAreaController.cs b/Explorer/Assets/DCL/MapRenderer/MapLayers/UsersMarker/UsersMarkersHotAreaController.cs
index 4d2d6d08e3..879a7b9c66 100644
--- a/Explorer/Assets/DCL/MapRenderer/MapLayers/UsersMarker/UsersMarkersHotAreaController.cs
+++ b/Explorer/Assets/DCL/MapRenderer/MapLayers/UsersMarker/UsersMarkersHotAreaController.cs
@@ -7,6 +7,7 @@
using DCL.AvatarRendering.AvatarShape.Components;
using DCL.Character.Components;
using DCL.CharacterPreview.Components;
+using DCL.ECSComponents;
using DCL.MapRenderer.CoordsUtils;
using DCL.MapRenderer.Culling;
using DCL.MapRenderer.MapLayers.UsersMarker;
@@ -59,7 +60,7 @@ public void CreateSystems(ref ArchSystemsWorldBuilder builder)
}
[Query]
- [None(typeof(PlayerComponent), typeof(CharacterPreviewComponent), typeof(DeleteEntityIntention))]
+ [None(typeof(PlayerComponent), typeof(CharacterPreviewComponent), typeof(PBAvatarShape), typeof(DeleteEntityIntention))]
private void SetPlayerMarker(in CharacterTransform transformComponent, in AvatarShapeComponent avatarShape)
{
if (!isEnabled)
diff --git a/Explorer/Assets/DCL/Minimap/Minimap.asmdef b/Explorer/Assets/DCL/Minimap/Minimap.asmdef
index 635aa781de..9262fdb9db 100644
--- a/Explorer/Assets/DCL/Minimap/Minimap.asmdef
+++ b/Explorer/Assets/DCL/Minimap/Minimap.asmdef
@@ -25,7 +25,8 @@
"GUID:766b242fb43af451aaa331f39872177d",
"GUID:d832748739a186646b8656bdbd447ad0",
"GUID:286980af24684da6acc1caa413039811",
- "GUID:1300820cd310d4584b09afde765bdd16"
+ "GUID:1300820cd310d4584b09afde765bdd16",
+ "GUID:3c7b57a14671040bd8c549056adc04f5"
],
"includePlatforms": [],
"excludePlatforms": [],
diff --git a/Explorer/Assets/DCL/Minimap/MinimapController.cs b/Explorer/Assets/DCL/Minimap/MinimapController.cs
index 4a5476955f..fc22c706c9 100644
--- a/Explorer/Assets/DCL/Minimap/MinimapController.cs
+++ b/Explorer/Assets/DCL/Minimap/MinimapController.cs
@@ -7,6 +7,7 @@
using DCL.Chat.Commands;
using DCL.Chat.MessageBus;
using DCL.Diagnostics;
+using DCL.ECSComponents;
using DCL.ExplorePanel;
using DCL.MapRenderer;
using DCL.MapRenderer.CommonBehavior;
@@ -155,8 +156,9 @@ private void HidePinInMinimapEdge()
}
- [All(typeof(PlayerComponent))]
[Query]
+ [All(typeof(PlayerComponent))]
+ [None(typeof(PBAvatarShape))]
private void QueryPlayerPosition(in CharacterTransform transformComponent)
{
Vector3 position = transformComponent.Position;
diff --git a/Explorer/Assets/DCL/Multiplayer/Movement/Systems/RemotePlayersMovementSystem.cs b/Explorer/Assets/DCL/Multiplayer/Movement/Systems/RemotePlayersMovementSystem.cs
index 3f1356fafe..32a33a1ce0 100644
--- a/Explorer/Assets/DCL/Multiplayer/Movement/Systems/RemotePlayersMovementSystem.cs
+++ b/Explorer/Assets/DCL/Multiplayer/Movement/Systems/RemotePlayersMovementSystem.cs
@@ -8,6 +8,7 @@
using DCL.CharacterMotion.Settings;
using DCL.CharacterMotion.Utils;
using DCL.Diagnostics;
+using DCL.ECSComponents;
using DCL.Multiplayer.Movement.Settings;
using ECS.Abstract;
using ECS.LifeCycle.Components;
@@ -47,7 +48,7 @@ private void HandleFirstMessage(ref CharacterTransform transComp, in NetworkMove
}
[Query]
- [None(typeof(PlayerComponent), typeof(DeleteEntityIntention))]
+ [None(typeof(PlayerComponent), typeof(PBAvatarShape), typeof(DeleteEntityIntention))]
private void UpdateRemotePlayersMovement([Data] float deltaTime, ref CharacterTransform transComp,
ref RemotePlayerMovementComponent remotePlayerMovement, ref InterpolationComponent intComp, ref ExtrapolationComponent extComp)
{
diff --git a/Explorer/Assets/DCL/Multiplayer/SDK/Systems/GlobalWorld/PlayerCRDTEntitiesHandlerSystem.cs b/Explorer/Assets/DCL/Multiplayer/SDK/Systems/GlobalWorld/PlayerCRDTEntitiesHandlerSystem.cs
index ced9534ce7..d8d01df495 100644
--- a/Explorer/Assets/DCL/Multiplayer/SDK/Systems/GlobalWorld/PlayerCRDTEntitiesHandlerSystem.cs
+++ b/Explorer/Assets/DCL/Multiplayer/SDK/Systems/GlobalWorld/PlayerCRDTEntitiesHandlerSystem.cs
@@ -6,6 +6,7 @@
using CrdtEcsBridge.Components;
using DCL.Character.Components;
using DCL.Diagnostics;
+using DCL.ECSComponents;
using DCL.Multiplayer.Profiles.Systems;
using DCL.Multiplayer.SDK.Components;
using DCL.Profiles;
@@ -46,7 +47,7 @@ protected override void Update(float t)
[Query]
[All(typeof(Profile))]
- [None(typeof(PlayerCRDTEntity), typeof(DeleteEntityIntention))]
+ [None(typeof(PlayerCRDTEntity), typeof(PBAvatarShape), typeof(DeleteEntityIntention))]
private void AddPlayerCRDTEntity(Entity entity, in CharacterTransform characterTransform)
{
// Reserve entity straight-away, numeration will be preserved across all scenes
@@ -63,7 +64,7 @@ private void AddPlayerCRDTEntity(Entity entity, in CharacterTransform characterT
}
[Query]
- [None(typeof(DeleteEntityIntention))]
+ [None(typeof(DeleteEntityIntention), typeof(PBAvatarShape))]
private void ModifyPlayerScene(in CharacterTransform characterTransform, ref PlayerCRDTEntity playerCRDTEntity)
{
ResolvePlayerCRDTScene(characterTransform, ref playerCRDTEntity, playerCRDTEntity.CRDTEntity);
diff --git a/Explorer/Assets/DCL/Multiplayer/SDK/Systems/GlobalWorld/PlayerTransformPropagationSystem.cs b/Explorer/Assets/DCL/Multiplayer/SDK/Systems/GlobalWorld/PlayerTransformPropagationSystem.cs
index 65a868d959..98749d7e9a 100644
--- a/Explorer/Assets/DCL/Multiplayer/SDK/Systems/GlobalWorld/PlayerTransformPropagationSystem.cs
+++ b/Explorer/Assets/DCL/Multiplayer/SDK/Systems/GlobalWorld/PlayerTransformPropagationSystem.cs
@@ -9,11 +9,7 @@
using DCL.Multiplayer.SDK.Components;
using DCL.Optimization.Pools;
using ECS.Abstract;
-using ECS.Groups;
using ECS.LifeCycle.Components;
-using Utility;
-using Quaternion = UnityEngine.Quaternion;
-using Vector3 = UnityEngine.Vector3;
namespace DCL.Multiplayer.SDK.Systems.GlobalWorld
{
diff --git a/Explorer/Assets/DCL/NameTags/NametagView.cs b/Explorer/Assets/DCL/NameTags/NametagView.cs
index 20084b8635..f5ba2026b2 100644
--- a/Explorer/Assets/DCL/NameTags/NametagView.cs
+++ b/Explorer/Assets/DCL/NameTags/NametagView.cs
@@ -87,7 +87,7 @@ public void InjectConfiguration(ChatBubbleConfigurationSO chatBubbleConfiguratio
messageContentAnchoredPosition = new (0, chatBubbleConfiguration.bubbleMarginOffsetHeight / 3);
}
- public void SetUsername(string username, string walletId, bool hasClaimedName)
+ public void SetUsername(string username, string walletId, bool hasClaimedName, bool useVerifiedIcon)
{
ResetElement();
@@ -95,7 +95,7 @@ public void SetUsername(string username, string walletId, bool hasClaimedName)
cts = new CancellationTokenSource();
isClaimedName = hasClaimedName;
- VerifiedIcon.gameObject.SetActive(hasClaimedName);
+ VerifiedIcon.gameObject.SetActive(hasClaimedName && useVerifiedIcon);
Username.text = hasClaimedName ? username : $"{username}#{walletId}";
Username.rectTransform.sizeDelta = new Vector2(Username.preferredWidth, DEFAULT_HEIGHT);
MessageContent.color = startingTextColor;
@@ -103,11 +103,11 @@ public void SetUsername(string username, string walletId, bool hasClaimedName)
float nametagMarginOffsetHeight = chatBubbleConfiguration?.nametagMarginOffsetHeight ?? DEFAULT_MARGIN_OFFSET_HEIGHT;
float nametagMarginOffsetWidth = chatBubbleConfiguration?.nametagMarginOffsetWidth ?? DEFAULT_MARGIN_OFFSET_WIDTH;
- if (hasClaimedName)
+ if (hasClaimedName && useVerifiedIcon)
{
+ usernamePos.x = Username.rectTransform.anchoredPosition.x;
verifiedIconInitialPosition = new Vector2(Username.rectTransform.anchoredPosition.x + (Username.preferredWidth / 2) + (VerifiedIcon.sizeDelta.x / 2) - (nametagMarginOffsetHeight / 2), 0);
VerifiedIcon.anchoredPosition = verifiedIconInitialPosition;
- usernamePos.x = Username.rectTransform.anchoredPosition.x;
usernamePos.x -= VerifiedIcon.sizeDelta.x / 2;
Username.rectTransform.anchoredPosition = usernamePos;
Background.size = new Vector2(Username.preferredWidth + nametagMarginOffsetWidth + VerifiedIcon.sizeDelta.x, Username.preferredHeight + nametagMarginOffsetHeight);
diff --git a/Explorer/Assets/DCL/NameTags/Systems/NametagPlacementSystem.cs b/Explorer/Assets/DCL/NameTags/Systems/NametagPlacementSystem.cs
index b1dca33325..731a615c3e 100644
--- a/Explorer/Assets/DCL/NameTags/Systems/NametagPlacementSystem.cs
+++ b/Explorer/Assets/DCL/NameTags/Systems/NametagPlacementSystem.cs
@@ -14,6 +14,7 @@
using ECS.Prioritization.Components;
using System.Runtime.CompilerServices;
using DCL.AvatarRendering.AvatarShape.UnityInterface;
+using DCL.ECSComponents;
using UnityEngine;
using UnityEngine.Pool;
@@ -29,6 +30,7 @@ namespace DCL.Nametags
public partial class NametagPlacementSystem : BaseUnityLoopSystem
{
private const float NAMETAG_SCALE_MULTIPLIER = 0.15f;
+ private const string NAMETAG_DEFAULT_WALLET_ID = "0000";
private readonly IObjectPool nametagViewPool;
private readonly ChatEntryConfigurationSO chatEntryConfiguration;
@@ -67,26 +69,33 @@ protected override void Update(float t)
CameraComponent camera = playerCamera.GetCameraComponent(World);
UpdateTagQuery(World, camera);
- AddTagQuery(World, camera);
+ AddTagForPlayerAvatarsQuery(World, camera);
+ AddTagForNonPlayerAvatarsQuery(World, camera);
ProcessChatBubbleComponentsQuery(World);
UpdateOwnTagQuery(World, camera);
RemoveUnusedChatBubbleComponentsQuery(World);
}
[Query]
- [None(typeof(NametagView), typeof(DeleteEntityIntention))]
- private void AddTag([Data] in CameraComponent camera, Entity e, in AvatarShapeComponent avatarShape, in CharacterTransform characterTransform, in PartitionComponent partitionComponent, in Profile profile)
+ [None(typeof(NametagView), typeof(PBAvatarShape), typeof(DeleteEntityIntention))]
+ private void AddTagForPlayerAvatars([Data] in CameraComponent camera, Entity e, in AvatarShapeComponent avatarShape, in CharacterTransform characterTransform, in PartitionComponent partitionComponent, in Profile profile)
{
if (partitionComponent.IsBehind || IsOutOfRenderRange(camera, characterTransform) || (camera.Mode == CameraMode.FirstPerson && World.Has(e))) return;
- NametagView nametagView = nametagViewPool.Get();
- nametagView.Id = avatarShape.ID;
- nametagView.Username.color = chatEntryConfiguration.GetNameColor(avatarShape.Name);
- nametagView.InjectConfiguration(chatBubbleConfigurationSo);
- nametagView.SetUsername(avatarShape.Name, avatarShape.ID.Substring(avatarShape.ID.Length - 4), profile.HasClaimedName);
- nametagView.gameObject.name = avatarShape.ID;
- UpdateTagTransparencyAndScale(nametagView, camera.Camera, characterTransform.Position);
+ NametagView nametagView = CreateNameTagView(in avatarShape, profile.HasClaimedName, true);
+ UpdateTagPosition(nametagView, camera.Camera, characterTransform.Position);
+
+ World.Add(e, nametagView);
+ }
+
+ [Query]
+ [None(typeof(NametagView), typeof(Profile), typeof(DeleteEntityIntention))]
+ [All(typeof(PBAvatarShape))]
+ private void AddTagForNonPlayerAvatars([Data] in CameraComponent camera, Entity e, in AvatarShapeComponent avatarShape, in CharacterTransform characterTransform, in PartitionComponent partitionComponent)
+ {
+ if (partitionComponent.IsBehind || IsOutOfRenderRange(camera, characterTransform) || string.IsNullOrEmpty(avatarShape.Name)) return;
+ NametagView nametagView = CreateNameTagView(in avatarShape, true, false);
UpdateTagPosition(nametagView, camera.Camera, characterTransform.Position);
World.Add(e, nametagView);
@@ -104,6 +113,7 @@ private void EnableTag(in NametagView nametagView)
}
[Query]
+ [None(typeof(PBAvatarShape))]
private void UpdateOwnTag([Data] in CameraComponent camera, in AvatarShapeComponent avatarShape, in CharacterTransform characterTransform, in Profile profile, in NametagView nametagView)
{
if (nametagView.Id == avatarShape.ID)
@@ -111,7 +121,7 @@ private void UpdateOwnTag([Data] in CameraComponent camera, in AvatarShapeCompon
nametagView.Id = avatarShape.ID;
nametagView.Username.color = chatEntryConfiguration.GetNameColor(avatarShape.Name);
- nametagView.SetUsername(avatarShape.Name, avatarShape.ID.Substring(avatarShape.ID.Length - 4), profile.HasClaimedName);
+ nametagView.SetUsername(avatarShape.Name, avatarShape.ID.Substring(avatarShape.ID.Length - 4), profile.HasClaimedName, true);
nametagView.gameObject.name = avatarShape.ID;
UpdateTagTransparencyAndScale(nametagView, camera.Camera, characterTransform.Position);
@@ -128,7 +138,6 @@ private void ProcessChatBubbleComponents(Entity e, in ChatBubbleComponent chatBu
World.Remove(e);
}
-
[Query]
[All(typeof(ChatBubbleComponent))]
//This query is used to remove the ChatBubbleComponent from the entity if the chat bubble has not been displayed
@@ -177,5 +186,20 @@ private void UpdateTagTransparencyAndScale(NametagView view, Camera camera, Vect
private bool IsOutOfRenderRange(CameraComponent camera, CharacterTransform characterTransform) =>
Vector3.Distance(camera.Camera.transform.position, characterTransform.Position) > chatBubbleConfigurationSo.maxDistance;
+
+ private NametagView CreateNameTagView(in AvatarShapeComponent avatarShape, bool hasClaimedName, bool useVerifiedIcon)
+ {
+ NametagView nametagView = nametagViewPool.Get();
+ nametagView.gameObject.name = avatarShape.ID;
+ nametagView.Id = avatarShape.ID;
+ nametagView.Username.color = chatEntryConfiguration.GetNameColor(avatarShape.Name);
+ nametagView.InjectConfiguration(chatBubbleConfigurationSo);
+
+ int walletIdLastDigitsIndex = avatarShape.ID.Length - 4;
+ string walletId = walletIdLastDigitsIndex >= 0 ? avatarShape.ID.Substring(walletIdLastDigitsIndex) : NAMETAG_DEFAULT_WALLET_ID;
+ nametagView.SetUsername(avatarShape.Name, walletId, hasClaimedName, useVerifiedIcon);
+
+ return nametagView;
+ }
}
}
diff --git a/Explorer/Assets/DCL/PluginSystem/DCL.Plugins.asmdef b/Explorer/Assets/DCL/PluginSystem/DCL.Plugins.asmdef
index 9d090859e1..806213764b 100644
--- a/Explorer/Assets/DCL/PluginSystem/DCL.Plugins.asmdef
+++ b/Explorer/Assets/DCL/PluginSystem/DCL.Plugins.asmdef
@@ -135,6 +135,7 @@
"GUID:ecd9230b77a12534cbb829d1b5fcd665",
"GUID:887770ff22b647ac864047b3c1af9a8b",
"GUID:f0968673e9444d64b49cde6a40d7df7a",
+ "GUID:fc37ca6521833154cab08ec51af097d9",
"DCL.Clipboard",
"CameraReelGallery",
"ExplorePanelComponents"
diff --git a/Explorer/Assets/DCL/PluginSystem/Global/ExplorePanelPlugin.cs b/Explorer/Assets/DCL/PluginSystem/Global/ExplorePanelPlugin.cs
index 4b205fe06b..7ff2b3016f 100644
--- a/Explorer/Assets/DCL/PluginSystem/Global/ExplorePanelPlugin.cs
+++ b/Explorer/Assets/DCL/PluginSystem/Global/ExplorePanelPlugin.cs
@@ -45,6 +45,8 @@
using DCL.InWorldCamera.CameraReelStorageService;
using DCL.Multiplayer.Connections.DecentralandUrls;
using DCL.Optimization.PerformanceBudgeting;
+using DCL.PluginSystem.World;
+using DCL.SDKComponents.MediaStream.Settings;
using DCL.Settings.Settings;
using UnityEngine;
using UnityEngine.AddressableAssets;
@@ -238,12 +240,12 @@ public async UniTask InitializeAsync(ExplorePanelSettings settings, Cancellation
ProvidedAsset settingsMenuConfiguration = await assetsProvisioner.ProvideMainAssetAsync(settings.SettingsMenuConfiguration, ct);
ProvidedAsset generalAudioMixer = await assetsProvisioner.ProvideMainAssetAsync(settings.GeneralAudioMixer, ct);
ProvidedAsset realmPartitionSettings = await assetsProvisioner.ProvideMainAssetAsync(settings.RealmPartitionSettings, ct);
+ ProvidedAsset videoPrioritizationSettings = await assetsProvisioner.ProvideMainAssetAsync(settings.VideoPrioritizationSettings, ct);
ProvidedAsset landscapeData = await assetsProvisioner.ProvideMainAssetAsync(settings.LandscapeData, ct);
ProvidedAsset qualitySettingsAsset = await assetsProvisioner.ProvideMainAssetAsync(settings.QualitySettingsAsset, ct);
ProvidedAsset controlsSettingsAsset = await assetsProvisioner.ProvideMainAssetAsync(settings.ControlsSettingsAsset, ct);
- settingsController = new SettingsController(explorePanelView.GetComponentInChildren(), settingsMenuConfiguration.Value, generalAudioMixer.Value, realmPartitionSettings.Value, landscapeData.Value, qualitySettingsAsset.Value, controlsSettingsAsset.Value, systemMemoryCap, worldVolumeMacBus);
-
+ settingsController = new SettingsController(explorePanelView.GetComponentInChildren(), settingsMenuConfiguration.Value, generalAudioMixer.Value, realmPartitionSettings.Value, videoPrioritizationSettings.Value, landscapeData.Value, qualitySettingsAsset.Value, controlsSettingsAsset.Value, systemMemoryCap, worldVolumeMacBus);
navmapController = new NavmapController(navmapView: explorePanelView.GetComponentInChildren(),
mapRendererContainer.MapRenderer, placesAPIService, webRequestController, webBrowser, dclInput,
realmNavigator, realmData, mapPathEventBus, world, playerEntity, inputBlock, chatMessagesBus);
@@ -292,6 +294,9 @@ public class ExplorePanelSettings : IDCLPluginSettings
[field: SerializeField]
public StaticSettings.RealmPartitionSettingsRef RealmPartitionSettings { get; private set; }
+ [field: SerializeField]
+ public StaticSettings.VideoPrioritizationSettingsRef VideoPrioritizationSettings { get; private set; }
+
[field: SerializeField]
public LandscapeSettings.LandscapeDataRef LandscapeData { get; private set; }
diff --git a/Explorer/Assets/DCL/PluginSystem/Global/Global Plugins Settings.asset b/Explorer/Assets/DCL/PluginSystem/Global/Global Plugins Settings.asset
index c2e4fb2cf8..396d218c2c 100644
--- a/Explorer/Assets/DCL/PluginSystem/Global/Global Plugins Settings.asset
+++ b/Explorer/Assets/DCL/PluginSystem/Global/Global Plugins Settings.asset
@@ -220,6 +220,11 @@ MonoBehaviour:
m_SubObjectName:
m_SubObjectType:
m_EditorAssetChanged: 0
+ k__BackingField:
+ m_AssetGUID: 12f48d0297bd3f746b92a97878478086
+ m_SubObjectName:
+ m_SubObjectType:
+ m_EditorAssetChanged: 0
k__BackingField:
m_AssetGUID: 32f2b877400526d4cbf648ba5c5064b4
m_SubObjectName:
@@ -263,6 +268,11 @@ MonoBehaviour:
m_SubObjectName:
m_SubObjectType:
m_EditorAssetChanged: 0
+ k__BackingField:
+ m_AssetGUID: 12f48d0297bd3f746b92a97878478086
+ m_SubObjectName:
+ m_SubObjectType:
+ m_EditorAssetChanged: 0
k__BackingField:
m_AssetGUID: 0703f7736b8c9b244953ae7c6ff9a037
m_SubObjectName:
diff --git a/Explorer/Assets/DCL/PluginSystem/Global/StaticSettings.cs b/Explorer/Assets/DCL/PluginSystem/Global/StaticSettings.cs
index 42794bab1e..6c90ea72a5 100644
--- a/Explorer/Assets/DCL/PluginSystem/Global/StaticSettings.cs
+++ b/Explorer/Assets/DCL/PluginSystem/Global/StaticSettings.cs
@@ -5,6 +5,8 @@
using System.Collections.Generic;
using DCL.Roads.Settings;
using DCL.AvatarRendering;
+using DCL.PluginSystem.World;
+using DCL.SDKComponents.MediaStream.Settings;
using UnityEngine;
using UnityEngine.AddressableAssets;
using UnityEngine.Profiling;
@@ -60,6 +62,12 @@ public class RealmPartitionSettingsRef : AssetReferenceT
+ {
+ public VideoPrioritizationSettingsRef(string guid) : base(guid) { }
+ }
+
[Serializable]
public class LODSettingsRef : AssetReferenceT
{
diff --git a/Explorer/Assets/DCL/PluginSystem/World/MediaPlayerPlugin.cs b/Explorer/Assets/DCL/PluginSystem/World/MediaPlayerPlugin.cs
index 1150948bbd..bba4260bd3 100644
--- a/Explorer/Assets/DCL/PluginSystem/World/MediaPlayerPlugin.cs
+++ b/Explorer/Assets/DCL/PluginSystem/World/MediaPlayerPlugin.cs
@@ -1,10 +1,13 @@
using Arch.SystemGroups;
using Cysharp.Threading.Tasks;
using DCL.AssetsProvision;
+using DCL.CharacterCamera;
using DCL.Optimization.PerformanceBudgeting;
using DCL.Optimization.Pools;
+using DCL.PluginSystem.Global;
using DCL.PluginSystem.World.Dependencies;
using DCL.ResourcesUnloading;
+using DCL.SDKComponents.MediaStream.Settings;
using DCL.SDKComponents.MediaStream.Wrapper;
using DCL.Settings;
using DCL.WebRequests;
@@ -29,6 +32,7 @@ public class MediaPlayerPlugin : IDCLWorldPlugin builder,
public async UniTask InitializeAsync(MediaPlayerPluginSettings settings, CancellationToken ct)
{
+ VideoPrioritizationSettings videoPrioritizationSettings = (await assetsProvisioner.ProvideMainAssetAsync(settings.VideoPrioritizationSettings, ct: ct)).Value;
mediaPlayerPrefab = (await assetsProvisioner.ProvideMainAssetAsync(settings.MediaPlayerPrefab, ct: ct)).Value.GetComponent();
- mediaPlayerPluginWrapper = new MediaPlayerPluginWrapper(sharedDependencies.ComponentPoolsRegistry, webRequestController, cacheCleaner, videoTexturePool, frameTimeBudget, mediaPlayerPrefab, worldVolumeMacBus);
+ mediaPlayerPluginWrapper = new MediaPlayerPluginWrapper(sharedDependencies.ComponentPoolsRegistry, webRequestController, cacheCleaner, videoTexturePool, frameTimeBudget, mediaPlayerPrefab, worldVolumeMacBus, exposedCameraData, videoPrioritizationSettings);
}
@@ -67,6 +74,8 @@ public class MediaPlayerPluginSettings : IDCLPluginSettings
{
[field: SerializeField]
public AssetReferenceGameObject MediaPlayerPrefab;
+
+ public StaticSettings.VideoPrioritizationSettingsRef VideoPrioritizationSettings;
}
}
}
diff --git a/Explorer/Assets/DCL/PluginSystem/World/World Plugins Container.asset b/Explorer/Assets/DCL/PluginSystem/World/World Plugins Container.asset
index f062e2e290..c349b20c95 100644
--- a/Explorer/Assets/DCL/PluginSystem/World/World Plugins Container.asset
+++ b/Explorer/Assets/DCL/PluginSystem/World/World Plugins Container.asset
@@ -183,6 +183,11 @@ MonoBehaviour:
m_SubObjectName:
m_SubObjectType:
m_EditorAssetChanged: 0
+ VideoPrioritizationSettings:
+ m_AssetGUID: 12f48d0297bd3f746b92a97878478086
+ m_SubObjectName:
+ m_SubObjectType:
+ m_EditorAssetChanged: 0
- rid: 6784895267130048515
type: {class: MaterialsPlugin/Settings, ns: DCL.PluginSystem.World, asm: DCL.Plugins}
data:
diff --git a/Explorer/Assets/DCL/Quality/Container/QualityContainer.cs b/Explorer/Assets/DCL/Quality/Container/QualityContainer.cs
index 46bcf6aff2..4a6a677ecf 100644
--- a/Explorer/Assets/DCL/Quality/Container/QualityContainer.cs
+++ b/Explorer/Assets/DCL/Quality/Container/QualityContainer.cs
@@ -34,6 +34,7 @@ public static async UniTask CreateAsync(IPluginSettingsContain
Settings settings = pluginSettingsContainer.GetSettings();
var realmPartitionSettings = await assetsProvisioner.ProvideMainAssetAsync(settings.RealmPartitionSettings, CancellationToken.None);
+ var videoPrioritizationSettings = await assetsProvisioner.ProvideMainAssetAsync(settings.VideoPrioritizationSettings, CancellationToken.None);
var lodSettingsAsset = await assetsProvisioner.ProvideMainAssetAsync(settings.LODSettingAsset, CancellationToken.None);
var landscapeData = await assetsProvisioner.ProvideMainAssetAsync(settings.LandscapeData, CancellationToken.None);
@@ -42,6 +43,7 @@ public static async UniTask CreateAsync(IPluginSettingsContain
rendererFeaturesCache,
settings.QualitySettings,
realmPartitionSettings.Value,
+ videoPrioritizationSettings.Value,
lodSettingsAsset.Value,
landscapeData.Value);
@@ -108,6 +110,9 @@ public class Settings : IDCLPluginSettings
[field: SerializeField]
public StaticSettings.RealmPartitionSettingsRef RealmPartitionSettings { get; private set; }
+ [field: SerializeField]
+ public StaticSettings.VideoPrioritizationSettingsRef VideoPrioritizationSettings { get; private set; }
+
[field: SerializeField]
public StaticSettings.LODSettingsRef LODSettingAsset { get; set; }
diff --git a/Explorer/Assets/DCL/Quality/DCL.Quality.asmdef b/Explorer/Assets/DCL/Quality/DCL.Quality.asmdef
index 084eef6404..f18cd2276d 100644
--- a/Explorer/Assets/DCL/Quality/DCL.Quality.asmdef
+++ b/Explorer/Assets/DCL/Quality/DCL.Quality.asmdef
@@ -10,7 +10,8 @@
"GUID:275e22790c04e9b47a5085d7b0c4432a",
"GUID:4794e238ed0f65142a4aea5848b513e5",
"GUID:a29f69b42fb1815409464ac7b05381d0",
- "GUID:21c2e77c042a2d34d8cfbf58f8217053"
+ "GUID:21c2e77c042a2d34d8cfbf58f8217053",
+ "GUID:fc37ca6521833154cab08ec51af097d9"
],
"includePlatforms": [],
"excludePlatforms": [],
diff --git a/Explorer/Assets/DCL/Quality/Quality Settings.asset b/Explorer/Assets/DCL/Quality/Quality Settings.asset
index 40d7abed20..57a52f0c90 100644
--- a/Explorer/Assets/DCL/Quality/Quality Settings.asset
+++ b/Explorer/Assets/DCL/Quality/Quality Settings.asset
@@ -322,6 +322,7 @@ MonoBehaviour:
detailDensity: 30
grassDistance: 75
chunkCullDistance: 1000
+ maxSimultaneousVideos: 1
- volumeProfile: {fileID: -4880458653563171804}
fogSettings:
m_Fog: 1
@@ -334,6 +335,7 @@ MonoBehaviour:
detailDensity: 70
grassDistance: 150
chunkCullDistance: 3000
+ maxSimultaneousVideos: 5
- volumeProfile: {fileID: 8971067228855834029}
fogSettings:
m_Fog: 1
@@ -346,6 +348,7 @@ MonoBehaviour:
detailDensity: 100
grassDistance: 300
chunkCullDistance: 7000
+ maxSimultaneousVideos: 10
allRendererFeatures:
- {fileID: -2846649767180898789, guid: 0c7b9d3b12885d541a70add26520ccdb, type: 2}
- {fileID: 8138120187327749282, guid: 0c7b9d3b12885d541a70add26520ccdb, type: 2}
diff --git a/Explorer/Assets/DCL/Quality/Runtime/EnvironmentSettingsRuntime.cs b/Explorer/Assets/DCL/Quality/Runtime/EnvironmentSettingsRuntime.cs
index d94400b127..d9aea1a77b 100644
--- a/Explorer/Assets/DCL/Quality/Runtime/EnvironmentSettingsRuntime.cs
+++ b/Explorer/Assets/DCL/Quality/Runtime/EnvironmentSettingsRuntime.cs
@@ -1,6 +1,7 @@
using DCL.DebugUtilities;
using DCL.Landscape.Settings;
using DCL.LOD;
+using DCL.SDKComponents.MediaStream.Settings;
using ECS.Prioritization;
using System;
using System.Collections.Generic;
@@ -11,6 +12,7 @@ namespace DCL.Quality.Runtime
{
public class EnvironmentSettingsRuntime : IQualitySettingRuntime
{
+ private PersistentSetting maxSimultaneousVideos;
private PersistentSetting sceneLoadRadius;
private PersistentSetting lod1Threshold;
private PersistentSetting terrainLODBias;
@@ -19,6 +21,7 @@ public class EnvironmentSettingsRuntime : IQualitySettingRuntime
private PersistentSetting chunkCullDistance;
private readonly RealmPartitionSettingsAsset? realmPartitionSettings;
+ private readonly VideoPrioritizationSettings? videoPrioritizationSettings;
private readonly ILODSettingsAsset? lodSettingsAsset;
private readonly LandscapeData? landscapeData;
@@ -26,12 +29,16 @@ public class EnvironmentSettingsRuntime : IQualitySettingRuntime
public EnvironmentSettingsRuntime(
RealmPartitionSettingsAsset? realmPartitionSettings,
+ VideoPrioritizationSettings? videoPrioritizationSettings,
ILODSettingsAsset? lodSettingsAsset,
LandscapeData? landscapeData)
{
if (realmPartitionSettings != null)
this.realmPartitionSettings = realmPartitionSettings;
+ if(videoPrioritizationSettings != null)
+ this.videoPrioritizationSettings = videoPrioritizationSettings;
+
if (lodSettingsAsset != null)
this.lodSettingsAsset = lodSettingsAsset;
@@ -62,6 +69,9 @@ public void ApplyPreset(QualitySettingsAsset.QualityCustomLevel preset)
SetChunkCullDistance(preset.environmentSettings.chunkCullDistance);
this.chunkCullDistance.Value = preset.environmentSettings.chunkCullDistance;
+
+ SetMaxSimultaneousVideos(preset.environmentSettings.maxSimultaneousVideos);
+ this.maxSimultaneousVideos.Value = preset.environmentSettings.maxSimultaneousVideos;
}
public void RestoreState(QualitySettingsAsset.QualityCustomLevel currentPreset)
@@ -72,6 +82,7 @@ public void RestoreState(QualitySettingsAsset.QualityCustomLevel currentPreset)
detailDensity = PersistentSetting.CreateFloat("DetailDensity", currentPreset.environmentSettings.detailDensity).WithSetForceDefaultValue();
grassDistance = PersistentSetting.CreateFloat("GrassDistance", currentPreset.environmentSettings.grassDistance).WithSetForceDefaultValue();
chunkCullDistance = PersistentSetting.CreateFloat("ChunkCullDistance", currentPreset.environmentSettings.chunkCullDistance).WithSetForceDefaultValue();
+ maxSimultaneousVideos = PersistentSetting.CreateInt("MaxSimultaneousVideos", currentPreset.environmentSettings.lod1Threshold).WithSetForceDefaultValue();
// Apply settings
SetSceneLoadRadius(sceneLoadRadius.Value);
@@ -80,6 +91,7 @@ public void RestoreState(QualitySettingsAsset.QualityCustomLevel currentPreset)
SetDetailDensity(detailDensity.Value);
SetGrassDistance(grassDistance.Value);
SetChunkCullDistance(chunkCullDistance.Value);
+ SetMaxSimultaneousVideos(maxSimultaneousVideos.Value);
}
private void SetSceneLoadRadius(int maxLoadingDistanceInParcels)
@@ -90,6 +102,14 @@ private void SetSceneLoadRadius(int maxLoadingDistanceInParcels)
realmPartitionSettings.MaxLoadingDistanceInParcels = maxLoadingDistanceInParcels;
}
+ private void SetMaxSimultaneousVideos(int maxSimultaneousVideos)
+ {
+ if(videoPrioritizationSettings == null)
+ return;
+
+ videoPrioritizationSettings.MaximumSimultaneousVideos = maxSimultaneousVideos;
+ }
+
private void SetLodThreshold(int lodThreshold, int index)
{
if (lodSettingsAsset == null)
diff --git a/Explorer/Assets/DCL/Quality/Runtime/QualityRuntimeFactory.cs b/Explorer/Assets/DCL/Quality/Runtime/QualityRuntimeFactory.cs
index 12a4946a7b..523386d6ea 100644
--- a/Explorer/Assets/DCL/Quality/Runtime/QualityRuntimeFactory.cs
+++ b/Explorer/Assets/DCL/Quality/Runtime/QualityRuntimeFactory.cs
@@ -1,5 +1,6 @@
using DCL.Landscape.Settings;
using DCL.LOD;
+using DCL.SDKComponents.MediaStream.Settings;
using ECS.Prioritization;
using System;
using System.Collections.Generic;
@@ -17,6 +18,7 @@ public static IQualityLevelController Create(
IRendererFeaturesCache rendererFeaturesCache,
QualitySettingsAsset settingsAsset,
RealmPartitionSettingsAsset? realmPartitionSettings = null,
+ VideoPrioritizationSettings? videoPrioritizationSettings = null,
ILODSettingsAsset? lodSettingsAsset = null,
LandscapeData? landscapeData = null)
{
@@ -25,7 +27,7 @@ public static IQualityLevelController Create(
runtimes.Add(CreateFogRuntime());
runtimes.Add(CreateLensFlareRuntime());
runtimes.Add(CreateGlobalVolume());
- runtimes.Add(CreateEnvironmentRuntime(realmPartitionSettings, lodSettingsAsset, landscapeData));
+ runtimes.Add(CreateEnvironmentRuntime(realmPartitionSettings, videoPrioritizationSettings, lodSettingsAsset, landscapeData));
CreateRendererFeaturesRuntimes(rendererFeaturesCache, settingsAsset, runtimes);
return new QualityLevelController(runtimes, settingsAsset.customSettings);
@@ -39,9 +41,10 @@ private static IQualitySettingRuntime CreateFogRuntime() =>
private static IQualitySettingRuntime CreateEnvironmentRuntime(
RealmPartitionSettingsAsset? realmPartitionSettings,
+ VideoPrioritizationSettings? videoPrioritizationSettings,
ILODSettingsAsset? lodSettingsAsset,
LandscapeData? landscapeData) =>
- new EnvironmentSettingsRuntime(realmPartitionSettings, lodSettingsAsset, landscapeData);
+ new EnvironmentSettingsRuntime(realmPartitionSettings, videoPrioritizationSettings, lodSettingsAsset, landscapeData);
///
/// Create a separate class for every renderer feature type possibly available
diff --git a/Explorer/Assets/DCL/Quality/Settings/EnvironmentSettings.cs b/Explorer/Assets/DCL/Quality/Settings/EnvironmentSettings.cs
index 2ddb485b61..e549c8a6c8 100644
--- a/Explorer/Assets/DCL/Quality/Settings/EnvironmentSettings.cs
+++ b/Explorer/Assets/DCL/Quality/Settings/EnvironmentSettings.cs
@@ -11,5 +11,6 @@ public class EnvironmentSettings
public float detailDensity;
public float grassDistance;
public float chunkCullDistance;
+ public int maxSimultaneousVideos;
}
}
diff --git a/Explorer/Assets/DCL/Roads/Settings/Editor.meta b/Explorer/Assets/DCL/Roads/Settings/Editor.meta
new file mode 100644
index 0000000000..9a2169520f
--- /dev/null
+++ b/Explorer/Assets/DCL/Roads/Settings/Editor.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: e615bcead634acf43a9d86c2517d5b66
+folderAsset: yes
+DefaultImporter:
+ externalObjects: {}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Explorer/Assets/DCL/Roads/Settings/Editor/DCL.Roads.Settings.Editor.asmdef b/Explorer/Assets/DCL/Roads/Settings/Editor/DCL.Roads.Settings.Editor.asmdef
new file mode 100644
index 0000000000..7507645fb6
--- /dev/null
+++ b/Explorer/Assets/DCL/Roads/Settings/Editor/DCL.Roads.Settings.Editor.asmdef
@@ -0,0 +1,19 @@
+{
+ "name": "DCL.Roads.Settings.Editor",
+ "rootNamespace": "",
+ "references": [
+ "GUID:54cb1906aeb4e4264bc1d2aa3818a43f",
+ "GUID:46c2e553ecab9ff4784aee64075136c9"
+ ],
+ "includePlatforms": [
+ "Editor"
+ ],
+ "excludePlatforms": [],
+ "allowUnsafeCode": false,
+ "overrideReferences": false,
+ "precompiledReferences": [],
+ "autoReferenced": true,
+ "defineConstraints": [],
+ "versionDefines": [],
+ "noEngineReferences": false
+}
\ No newline at end of file
diff --git a/Explorer/Assets/DCL/Roads/Settings/Editor/DCL.Roads.Settings.Editor.asmdef.meta b/Explorer/Assets/DCL/Roads/Settings/Editor/DCL.Roads.Settings.Editor.asmdef.meta
new file mode 100644
index 0000000000..db1425cbb9
--- /dev/null
+++ b/Explorer/Assets/DCL/Roads/Settings/Editor/DCL.Roads.Settings.Editor.asmdef.meta
@@ -0,0 +1,7 @@
+fileFormatVersion: 2
+guid: 05c5e091fc59a804d8f972e6f29b0c85
+AssemblyDefinitionImporter:
+ externalObjects: {}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Explorer/Assets/DCL/Roads/Settings/Editor/RoadSettingsAssetEditor.cs b/Explorer/Assets/DCL/Roads/Settings/Editor/RoadSettingsAssetEditor.cs
new file mode 100644
index 0000000000..6ce555841a
--- /dev/null
+++ b/Explorer/Assets/DCL/Roads/Settings/Editor/RoadSettingsAssetEditor.cs
@@ -0,0 +1,88 @@
+using UnityEditor;
+using UnityEngine;
+
+namespace DCL.Roads.Settings.Editor
+{
+ ///
+ /// A custom inspector that just shows a search box to make finding road descriptions easier.
+ ///
+ [CustomEditor(typeof(RoadSettingsAsset))]
+ internal class RoadSettingsAssetEditor : UnityEditor.Editor
+ {
+ private Vector2Int coordinatesToSearch;
+ private int foundElementIndex = -1;
+ private Vector2Int foundElementCoordinates;
+ private Vector3 foundElementRotation;
+ private string foundElementModel;
+ private bool showNotFoundMessage;
+ private bool showUpdatedMessage;
+
+ public override void OnInspectorGUI()
+ {
+ EditorGUILayout.LabelField("Search for a Road description by its coordinates:");
+
+ using (var scope = new EditorGUI.ChangeCheckScope())
+ {
+ coordinatesToSearch = EditorGUILayout.Vector2IntField(GUIContent.none, coordinatesToSearch);
+
+ if (scope.changed)
+ {
+ foundElementIndex = -1;
+ showUpdatedMessage = false;
+ showNotFoundMessage = false;
+ }
+ }
+
+ RoadSettingsAsset roadSettingsAsset = target as RoadSettingsAsset;
+
+ if (GUILayout.Button("Search"))
+ {
+ for (int i = 0; i < roadSettingsAsset.RoadDescriptions.Count; ++i)
+ {
+ if (roadSettingsAsset.RoadDescriptions[i].RoadCoordinate == coordinatesToSearch)
+ {
+ foundElementIndex = i;
+ foundElementCoordinates = roadSettingsAsset.RoadDescriptions[i].RoadCoordinate;
+ foundElementRotation = roadSettingsAsset.RoadDescriptions[i].Rotation.eulerAngles;
+ foundElementModel = roadSettingsAsset.RoadDescriptions[i].RoadModel;
+ break;
+ }
+ }
+
+ if (foundElementIndex == -1)
+ showNotFoundMessage = true;
+ }
+
+ if (foundElementIndex > -1)
+ {
+ EditorGUILayout.LabelField("Element found at: " + foundElementIndex);
+
+ foundElementCoordinates = EditorGUILayout.Vector2IntField(nameof(RoadDescription.RoadCoordinate), foundElementCoordinates);
+ foundElementRotation = EditorGUILayout.Vector3Field(nameof(RoadDescription.Rotation), foundElementRotation);
+ foundElementModel = EditorGUILayout.TextField(nameof(RoadDescription.RoadModel), foundElementModel);
+
+ if (GUILayout.Button("Update road"))
+ {
+ roadSettingsAsset.RoadDescriptions[foundElementIndex] = new RoadDescription()
+ {
+ RoadModel = foundElementModel,
+ RoadCoordinate = foundElementCoordinates,
+ Rotation = Quaternion.Euler(foundElementRotation.x, foundElementRotation.y, foundElementRotation.z)
+ };
+
+ showUpdatedMessage = true;
+ }
+ }
+
+ if (showNotFoundMessage)
+ EditorGUILayout.HelpBox("There is no element with coordinates " + coordinatesToSearch, MessageType.Error);
+
+ if (showUpdatedMessage)
+ EditorGUILayout.HelpBox("Element updated successfully.", MessageType.Info);
+
+ EditorGUILayout.Separator();
+
+ base.OnInspectorGUI();
+ }
+ }
+}
diff --git a/Explorer/Assets/DCL/Roads/Settings/Editor/RoadSettingsAssetEditor.cs.meta b/Explorer/Assets/DCL/Roads/Settings/Editor/RoadSettingsAssetEditor.cs.meta
new file mode 100644
index 0000000000..7a206c18f7
--- /dev/null
+++ b/Explorer/Assets/DCL/Roads/Settings/Editor/RoadSettingsAssetEditor.cs.meta
@@ -0,0 +1,3 @@
+fileFormatVersion: 2
+guid: 4ea58085f7074da1bddc3bf2fef86c0d
+timeCreated: 1732714667
\ No newline at end of file
diff --git a/Explorer/Assets/DCL/SDKComponents/AvatarShape/Systems/AvatarShapeHandlerSystem.cs b/Explorer/Assets/DCL/SDKComponents/AvatarShape/Systems/AvatarShapeHandlerSystem.cs
index f982a8bc5c..7a151ea00c 100644
--- a/Explorer/Assets/DCL/SDKComponents/AvatarShape/Systems/AvatarShapeHandlerSystem.cs
+++ b/Explorer/Assets/DCL/SDKComponents/AvatarShape/Systems/AvatarShapeHandlerSystem.cs
@@ -2,10 +2,10 @@
using Arch.System;
using Arch.SystemGroups;
using Arch.SystemGroups.Throttling;
+using DCL.Character.Components;
using DCL.Diagnostics;
using DCL.ECSComponents;
using ECS.Abstract;
-using DCL.Utilities;
using ECS.LifeCycle;
using ECS.LifeCycle.Components;
using ECS.Prioritization.Components;
@@ -37,10 +37,10 @@ protected override void Update(float t)
}
[Query]
- [None(typeof(SDKAvatarShapeComponent))]
- private void LoadAvatarShape(in Entity entity, ref PBAvatarShape pbAvatarShape, ref PartitionComponent partitionComponent, ref TransformComponent transformComponent)
+ [None(typeof(SDKAvatarShapeComponent), typeof(DeleteEntityIntention))]
+ private void LoadAvatarShape(Entity entity, ref PBAvatarShape pbAvatarShape, ref PartitionComponent partitionComponent, ref TransformComponent transformComponent)
{
- World.Add(entity, new SDKAvatarShapeComponent(globalWorld.Create(pbAvatarShape, partitionComponent, transformComponent)));
+ World.Add(entity, new SDKAvatarShapeComponent(globalWorld.Create(pbAvatarShape, partitionComponent, new CharacterTransform(transformComponent.Transform))));
}
[Query]
@@ -54,32 +54,38 @@ private void UpdateAvatarShape(ref PBAvatarShape pbAvatarShape, ref SDKAvatarSha
[Query]
[None(typeof(PBAvatarShape), typeof(DeleteEntityIntention))]
- private void HandleComponentRemoval(in Entity entity, ref SDKAvatarShapeComponent sdkAvatarShapeComponent)
+ private void HandleComponentRemoval(Entity entity, ref SDKAvatarShapeComponent sdkAvatarShapeComponent)
{
// If the component is removed at scene-world, the global-world representation should disappear entirely
- globalWorld.Add(sdkAvatarShapeComponent.globalWorldEntity, new DeleteEntityIntention());
+ MarkGlobalWorldEntityForDeletion(sdkAvatarShapeComponent.globalWorldEntity);
World.Remove(entity);
}
[Query]
[All(typeof(DeleteEntityIntention))]
- private void HandleEntityDestruction(in Entity entity, ref SDKAvatarShapeComponent sdkAvatarShapeComponent)
+ private void HandleEntityDestruction(Entity entity, ref SDKAvatarShapeComponent sdkAvatarShapeComponent)
{
+ MarkGlobalWorldEntityForDeletion(sdkAvatarShapeComponent.globalWorldEntity);
World.Remove(entity);
- World.Remove(entity);
- globalWorld.Add(sdkAvatarShapeComponent.globalWorldEntity, new DeleteEntityIntention());
}
[Query]
- public void FinalizeComponents(ref SDKAvatarShapeComponent sdkAvatarShapeComponent)
- {
- globalWorld.Add(sdkAvatarShapeComponent.globalWorldEntity, new DeleteEntityIntention());
- }
+ public void FinalizeComponents(ref SDKAvatarShapeComponent sdkAvatarShapeComponent) =>
+ MarkGlobalWorldEntityForDeletion(sdkAvatarShapeComponent.globalWorldEntity);
- public void FinalizeComponents(in Query query)
- {
+ public void FinalizeComponents(in Query query) =>
FinalizeComponentsQuery(World);
+
+ public void MarkGlobalWorldEntityForDeletion(Entity globalEntity)
+ {
+ // Has to be removed, otherwise scene loading may break after teleportation (no error anywhere to know why)
+ globalWorld.Remove(globalEntity);
+
+ // Has to be deferred because many times it happens that the entity is marked for deletion AFTER the
+ // AvatarCleanUpSystem.Update() and BEFORE the DestroyEntitiesSystem.Update(), probably has to do with
+ // non-synchronicity between global and scene ECS worlds. AvatarCleanUpSystem resets the DeferDeletion.
+ globalWorld.Add(globalEntity, new DeleteEntityIntention() { DeferDeletion = true });
}
}
}
diff --git a/Explorer/Assets/DCL/SDKComponents/AvatarShape/Tests/AvatarShapeHandlerSystemShould.cs b/Explorer/Assets/DCL/SDKComponents/AvatarShape/Tests/AvatarShapeHandlerSystemShould.cs
index 64441c52d8..ad142c8e56 100644
--- a/Explorer/Assets/DCL/SDKComponents/AvatarShape/Tests/AvatarShapeHandlerSystemShould.cs
+++ b/Explorer/Assets/DCL/SDKComponents/AvatarShape/Tests/AvatarShapeHandlerSystemShould.cs
@@ -1,12 +1,12 @@
using Arch.Core;
using DCL.ECSComponents;
-using DCL.Utilities;
using ECS.LifeCycle.Components;
using ECS.Prioritization.Components;
using ECS.TestSuite;
using ECS.Unity.AvatarShape.Components;
using ECS.Unity.AvatarShape.Systems;
using NUnit.Framework;
+using DCL.Character.Components;
namespace ECS.Unity.AvatarShape.Tests
{
@@ -40,7 +40,7 @@ public void ForwardSDKAvatarShapeInstantiationToGlobalWorldSystems()
Assert.AreEqual(1, world.CountEntities(new QueryDescription().WithAll()));
Assert.AreEqual(1, globalWorld.CountEntities(new QueryDescription().WithAll()));
- globalWorld.Query(new QueryDescription().WithAll(), (ref PBAvatarShape comp) => Assert.AreEqual(pbAvatarShapeComponent.Name, comp.Name));
+ globalWorld.Query(new QueryDescription().WithAll(), (ref PBAvatarShape comp) => Assert.AreEqual(pbAvatarShapeComponent.Name, comp.Name));
}
[Test]
diff --git a/Explorer/Assets/DCL/SDKComponents/MediaStream/Components/VideoStateByPriorityComponent.cs b/Explorer/Assets/DCL/SDKComponents/MediaStream/Components/VideoStateByPriorityComponent.cs
new file mode 100644
index 0000000000..fafab8c78f
--- /dev/null
+++ b/Explorer/Assets/DCL/SDKComponents/MediaStream/Components/VideoStateByPriorityComponent.cs
@@ -0,0 +1,58 @@
+using Arch.Core;
+using UnityEngine;
+
+namespace DCL.SDKComponents.MediaStream
+{
+ ///
+ /// Data related to the calculation of the priority of a video and its corresponding state (playing or paused).
+ ///
+ public struct VideoStateByPriorityComponent
+ {
+ ///
+ /// The final score used to determine the priority of the video.
+ ///
+ public float Score;
+
+ ///
+ /// Whether the video should be playing or not, if prioritization mechanism did not exist.
+ ///
+ public bool WantsToPlay;
+
+ ///
+ /// The entity that has the MediaPlayer.
+ ///
+ public readonly Entity Entity;
+
+ ///
+ /// Half of the size of the mesh renderer (or mesh renderer group that consume the same video texture).
+ ///
+ public readonly float HalfSize;
+
+ ///
+ /// Whether the video should be playing according to its priority.
+ ///
+ public bool IsPlaying;
+
+ ///
+ /// The time when the video was played manually.
+ ///
+ public float MediaPlayStartTime;
+
+ ///
+ /// A mesh renderer used for visually debugging the priority of each video.
+ ///
+ public MeshRenderer? DebugPrioritySign;
+
+ public VideoStateByPriorityComponent(Entity entity, float halfSize, bool wantsToPlay)
+ {
+ Entity = entity;
+ HalfSize = halfSize;
+ WantsToPlay = wantsToPlay;
+
+ Score = 0.0f;
+ IsPlaying = false;
+ MediaPlayStartTime = float.MinValue;
+ DebugPrioritySign = null;
+ }
+ }
+}
diff --git a/Explorer/Assets/DCL/SDKComponents/MediaStream/Components/VideoStateByPriorityComponent.cs.meta b/Explorer/Assets/DCL/SDKComponents/MediaStream/Components/VideoStateByPriorityComponent.cs.meta
new file mode 100644
index 0000000000..e95f091374
--- /dev/null
+++ b/Explorer/Assets/DCL/SDKComponents/MediaStream/Components/VideoStateByPriorityComponent.cs.meta
@@ -0,0 +1,3 @@
+fileFormatVersion: 2
+guid: 35cb88511432404db5b33aec0f01f483
+timeCreated: 1730466981
\ No newline at end of file
diff --git a/Explorer/Assets/DCL/SDKComponents/MediaStream/DCL.MediaPlayer.asmdef b/Explorer/Assets/DCL/SDKComponents/MediaStream/DCL.MediaPlayer.asmdef
index eb7ea722e8..6eee3e36c1 100644
--- a/Explorer/Assets/DCL/SDKComponents/MediaStream/DCL.MediaPlayer.asmdef
+++ b/Explorer/Assets/DCL/SDKComponents/MediaStream/DCL.MediaPlayer.asmdef
@@ -1,5 +1,5 @@
{
- "name": "DCL.AudioStream.PluginWrapper",
+ "name": "DCL.MediaPlayer",
"rootNamespace": "",
"references": [
"GUID:275e22790c04e9b47a5085d7b0c4432a",
@@ -21,7 +21,9 @@
"GUID:4a12c0b1b77ec6b418a8d7bd5c925be3",
"GUID:f51ebe6a0ceec4240a699833d6309b23",
"GUID:fa7b3fdbb04d67549916da7bd2af58ab",
- "GUID:1d75b3d8691c845b1a51082e81433dfc"
+ "GUID:1d75b3d8691c845b1a51082e81433dfc",
+ "GUID:4307f53044263cf4b835bd812fc161a4",
+ "GUID:fc37ca6521833154cab08ec51af097d9"
],
"includePlatforms": [],
"excludePlatforms": [],
diff --git a/Explorer/Assets/DCL/SDKComponents/MediaStream/Settings.meta b/Explorer/Assets/DCL/SDKComponents/MediaStream/Settings.meta
new file mode 100644
index 0000000000..eb537894ff
--- /dev/null
+++ b/Explorer/Assets/DCL/SDKComponents/MediaStream/Settings.meta
@@ -0,0 +1,3 @@
+fileFormatVersion: 2
+guid: 6534e056f2aa48dbbb47c8daa99a70d5
+timeCreated: 1730376111
\ No newline at end of file
diff --git a/Explorer/Assets/DCL/SDKComponents/MediaStream/Settings/DCL.MediaPlayer.Settings.asmdef b/Explorer/Assets/DCL/SDKComponents/MediaStream/Settings/DCL.MediaPlayer.Settings.asmdef
new file mode 100644
index 0000000000..58b09c5cb5
--- /dev/null
+++ b/Explorer/Assets/DCL/SDKComponents/MediaStream/Settings/DCL.MediaPlayer.Settings.asmdef
@@ -0,0 +1,3 @@
+{
+ "name": "DCL.MediaPlayer.Settings"
+}
diff --git a/Explorer/Assets/DCL/SDKComponents/MediaStream/Settings/DCL.MediaPlayer.Settings.asmdef.meta b/Explorer/Assets/DCL/SDKComponents/MediaStream/Settings/DCL.MediaPlayer.Settings.asmdef.meta
new file mode 100644
index 0000000000..c84db05663
--- /dev/null
+++ b/Explorer/Assets/DCL/SDKComponents/MediaStream/Settings/DCL.MediaPlayer.Settings.asmdef.meta
@@ -0,0 +1,7 @@
+fileFormatVersion: 2
+guid: fc37ca6521833154cab08ec51af097d9
+AssemblyDefinitionImporter:
+ externalObjects: {}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Explorer/Assets/DCL/SDKComponents/MediaStream/Settings/VideoPrioritizationSettings.asset b/Explorer/Assets/DCL/SDKComponents/MediaStream/Settings/VideoPrioritizationSettings.asset
new file mode 100644
index 0000000000..cfcd25e9a3
--- /dev/null
+++ b/Explorer/Assets/DCL/SDKComponents/MediaStream/Settings/VideoPrioritizationSettings.asset
@@ -0,0 +1,20 @@
+%YAML 1.1
+%TAG !u! tag:unity3d.com,2011:
+--- !u!114 &11400000
+MonoBehaviour:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 0}
+ m_Enabled: 1
+ m_EditorHideFlags: 0
+ m_Script: {fileID: 11500000, guid: fdabaecc89a44639a539486656238701, type: 3}
+ m_Name: VideoPrioritizationSettings
+ m_EditorClassIdentifier:
+ maximumSimultaneousVideos: 21
+ sizeInScreenWeight: 6
+ distanceWeight: 4
+ angleWeight: 10
+ minimumSizeLimit: 0.066
+ maximumDistanceLimit: 80
diff --git a/Explorer/Assets/DCL/SDKComponents/MediaStream/Settings/VideoPrioritizationSettings.asset.meta b/Explorer/Assets/DCL/SDKComponents/MediaStream/Settings/VideoPrioritizationSettings.asset.meta
new file mode 100644
index 0000000000..e32fd22004
--- /dev/null
+++ b/Explorer/Assets/DCL/SDKComponents/MediaStream/Settings/VideoPrioritizationSettings.asset.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: 12f48d0297bd3f746b92a97878478086
+NativeFormatImporter:
+ externalObjects: {}
+ mainObjectFileID: 11400000
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Explorer/Assets/DCL/SDKComponents/MediaStream/Settings/VideoPrioritizationSettings.cs b/Explorer/Assets/DCL/SDKComponents/MediaStream/Settings/VideoPrioritizationSettings.cs
new file mode 100644
index 0000000000..1513f5d89f
--- /dev/null
+++ b/Explorer/Assets/DCL/SDKComponents/MediaStream/Settings/VideoPrioritizationSettings.cs
@@ -0,0 +1,89 @@
+using UnityEngine;
+
+namespace DCL.SDKComponents.MediaStream.Settings
+{
+ ///
+ /// The parameters that define how the video playback prioritization mechanism behaves. They affect how priorities are calculated and which are paused.
+ ///
+ [CreateAssetMenu(fileName = "VideoPrioritizationSettings", menuName = "SO/VideoPrioritizationSettings", order = 0)]
+ public class VideoPrioritizationSettings : ScriptableObject
+ {
+ [Tooltip("The amount of videos that will be playing at the same time, at most, on camera.")]
+ [Range(1, 50.0f)]
+ [SerializeField]
+ private int maximumSimultaneousVideos;
+
+ [Tooltip("The weight of the 'size in screen of the video renderers' factor in the calculation of video priorities.")]
+ [Range(0.0f, 10.0f)]
+ [SerializeField]
+ private float sizeInScreenWeight = 1.0f;
+
+ [Tooltip("The weight of the 'distance from the camera to the video renderers' factor in the calculation of video priorities.")]
+ [Range(0.0f, 10.0f)]
+ [SerializeField]
+ private float distanceWeight = 1.0f;
+
+ [Tooltip("The weight of the 'angle of the camera with respect the video renderers' factor in the calculation of video priorities.")]
+ [Range(0.0f, 10.0f)]
+ [SerializeField]
+ private float angleWeight = 1.0f;
+
+ [Tooltip("A normalized value that determines which videos will be paused, without being prioritized, when their size in screen is below it.")]
+ [Range(0.0001f, 0.9999f)]
+ [SerializeField]
+ private float minimumSizeLimit = 0.1f;
+
+ [Tooltip("A value that determines which videos will be paused, without being prioritized, when their distance to the camera is above it.")]
+ [SerializeField]
+ private float maximumDistanceLimit = 100.0f;
+
+ public delegate void MaximumSimultaneousVideosChangedDelegate(int newValue);
+
+ ///
+ /// Raised when the maximum simultaneous videos property changes.
+ ///
+ public event MaximumSimultaneousVideosChangedDelegate MaximumSimultaneousVideosChanged;
+
+ ///
+ /// Gets or sets the amount of videos that will be playing at the same time, at most, on camera.
+ ///
+ public int MaximumSimultaneousVideos
+ {
+ get => maximumSimultaneousVideos;
+
+ set
+ {
+ if (value != maximumSimultaneousVideos)
+ {
+ maximumSimultaneousVideos = Mathf.Clamp(value, 1, 50);
+ MaximumSimultaneousVideosChanged?.Invoke(value);
+ }
+ }
+ }
+
+ ///
+ /// Gets the weight of the 'size in screen of the video renderers' factor in the calculation of video priorities.
+ ///
+ public float SizeInScreenWeight => sizeInScreenWeight;
+
+ ///
+ /// Gets the weight of the 'distance from the camera to the video renderers' factor in the calculation of video priorities.
+ ///
+ public float DistanceWeight => distanceWeight;
+
+ ///
+ /// Gets the weight of the 'angle of the camera with respect the video renderers' factor in the calculation of video priorities.
+ ///
+ public float AngleWeight => angleWeight;
+
+ ///
+ /// Gets a normalized value that determines which videos will be paused, without being prioritized, when their size in screen is below it.
+ ///
+ public float MinimumSizeLimit => minimumSizeLimit;
+
+ ///
+ /// Gets a value that determines which videos will be paused, without being prioritized, when their distance to the camera is above it.
+ ///
+ public float MaximumDistanceLimit => maximumDistanceLimit;
+ }
+}
diff --git a/Explorer/Assets/DCL/SDKComponents/MediaStream/Settings/VideoPrioritizationSettings.cs.meta b/Explorer/Assets/DCL/SDKComponents/MediaStream/Settings/VideoPrioritizationSettings.cs.meta
new file mode 100644
index 0000000000..96a43075d7
--- /dev/null
+++ b/Explorer/Assets/DCL/SDKComponents/MediaStream/Settings/VideoPrioritizationSettings.cs.meta
@@ -0,0 +1,3 @@
+fileFormatVersion: 2
+guid: fdabaecc89a44639a539486656238701
+timeCreated: 1730376170
\ No newline at end of file
diff --git a/Explorer/Assets/DCL/SDKComponents/MediaStream/Systems/CleanUpMediaPlayerSystem.cs b/Explorer/Assets/DCL/SDKComponents/MediaStream/Systems/CleanUpMediaPlayerSystem.cs
index 786db3679c..875a683c46 100644
--- a/Explorer/Assets/DCL/SDKComponents/MediaStream/Systems/CleanUpMediaPlayerSystem.cs
+++ b/Explorer/Assets/DCL/SDKComponents/MediaStream/Systems/CleanUpMediaPlayerSystem.cs
@@ -54,6 +54,7 @@ private void HandleSdkVideoPlayerComponentRemoval(Entity entity, ref VideoTextur
CleanUpVideoTexture(ref textureConsumer);
CleanUpMediaPlayer(ref mediaPlayer);
World.Remove(entity);
+ World.Remove(entity);
}
///
@@ -69,6 +70,7 @@ private void HandleVideoPlayerWithoutConsumers(Entity entity, ref VideoTextureCo
CleanUpVideoTexture(ref textureConsumer);
CleanUpMediaPlayer(ref mediaPlayerComponent);
World.Remove(entity);
+ World.Remove(entity);
}
}
diff --git a/Explorer/Assets/DCL/SDKComponents/MediaStream/Systems/CreateMediaPlayerSystem.cs b/Explorer/Assets/DCL/SDKComponents/MediaStream/Systems/CreateMediaPlayerSystem.cs
index 6ce346e1a3..3416d37fdd 100644
--- a/Explorer/Assets/DCL/SDKComponents/MediaStream/Systems/CreateMediaPlayerSystem.cs
+++ b/Explorer/Assets/DCL/SDKComponents/MediaStream/Systems/CreateMediaPlayerSystem.cs
@@ -13,9 +13,11 @@
using ECS.Abstract;
using ECS.Unity.Groups;
using ECS.Unity.Textures.Components;
+using ECS.Unity.Transforms.Components;
using RenderHeads.Media.AVProVideo;
using SceneRunner.Scene;
using System.Threading;
+using UnityEngine;
namespace DCL.SDKComponents.MediaStream
{
@@ -72,6 +74,11 @@ private void CreateMediaPlayer(Entity entity, string url, bool hasVolume, float
if (component.State != VideoState.VsError)
component.OpenMediaPromise.UrlReachabilityResolveAsync(webRequestController, component.URL, GetReportData(), component.Cts.Token).SuppressCancellationThrow().Forget();
+ // There is no way to set this from the scene code, at the moment
+ // If the player has no transform, it will appear at 0,0,0 and nobody will hear it if it is in 3D
+ if (component.MediaPlayer.TryGetComponent(out AudioSource mediaPlayerAudio))
+ mediaPlayerAudio.spatialBlend = World.Has(entity) ? 1.0f : 0.0f;
+
World.Add(entity, component);
}
diff --git a/Explorer/Assets/DCL/SDKComponents/MediaStream/Systems/UpdateMediaPlayerPrioritizationSystem.cs b/Explorer/Assets/DCL/SDKComponents/MediaStream/Systems/UpdateMediaPlayerPrioritizationSystem.cs
new file mode 100644
index 0000000000..cc1e8a652d
--- /dev/null
+++ b/Explorer/Assets/DCL/SDKComponents/MediaStream/Systems/UpdateMediaPlayerPrioritizationSystem.cs
@@ -0,0 +1,324 @@
+//#define DEBUG_VIDEO_PRIORITIES
+// When the definition is enabled, a colored cube will be created next to each video's mesh renderer. Its color corresponds to the current priority of the video.
+// Green means higher priority, red means lower priority. Blue means that it was prioritized but it is not allowed to play due to the maximum limit.
+// Black means it has been discarded from prioritization.
+
+using Arch.Core;
+using Arch.System;
+using Arch.SystemGroups;
+using Arch.SystemGroups.Throttling;
+using DCL.CharacterCamera;
+using DCL.Diagnostics;
+using DCL.ECSComponents;
+using DCL.SDKComponents.MediaStream.Settings;
+using ECS.Abstract;
+using ECS.Groups;
+using ECS.Unity.Textures.Components;
+using System.Collections.Generic;
+using UnityEngine;
+
+namespace DCL.SDKComponents.MediaStream
+{
+ ///
+ /// A system that limits the amount of video streams that can be playing at the same time on camera.
+ /// Videos are streamed using MediaPlayers. MediaPlayers can be played or paused manually outside this system. Those that are played manually will be
+ /// prioritized. Depending on the position and priority of the renderer every the video, it will keep playing or will be "culled", which means paused
+ /// until its priority/position allows it to resume the stream at the current time (not at the time it was paused, as if it was never paused at all).
+ ///
+ [UpdateInGroup(typeof(SyncedPresentationSystemGroup))]
+ [UpdateAfter(typeof(UpdateMediaPlayerSystem))]
+ [LogCategory(ReportCategory.MEDIA_STREAM)]
+ [ThrottlingEnabled]
+ public partial class UpdateMediaPlayerPrioritizationSystem : BaseUnityLoopSystem
+ {
+ private readonly IExposedCameraData exposedCameraData;
+ private readonly VideoPrioritizationSettings videoPrioritizationSettings;
+
+ private readonly List sortedVideoPriorities = new ();
+
+ // Note: it was necessary to cache this in order to avoid a change in FOV when the character runs that ruins the computation of priorities
+ private float cachedCameraVerticalFOV;
+ private float cachedCameraHorizontalFOV;
+ private float cachedCameraTanValue; // A pre-calculated value of the tangent of half the FOV, used to calculate the size on screen
+
+ public UpdateMediaPlayerPrioritizationSystem(World world, IExposedCameraData exposedCameraData, VideoPrioritizationSettings videoPrioritizationSettings) : base(world)
+ {
+ this.videoPrioritizationSettings = videoPrioritizationSettings;
+ this.exposedCameraData = exposedCameraData;
+ }
+
+ public override void Initialize()
+ {
+ base.Initialize();
+
+ if (exposedCameraData.CinemachineBrain != null)
+ {
+ cachedCameraVerticalFOV = exposedCameraData.CinemachineBrain!.OutputCamera.fieldOfView;
+ cachedCameraHorizontalFOV = Camera.VerticalToHorizontalFieldOfView(exposedCameraData.CinemachineBrain.OutputCamera.fieldOfView, exposedCameraData.CinemachineBrain.OutputCamera.aspect);
+ float cameraHalfFov = cachedCameraVerticalFOV * 0.5f * Mathf.Deg2Rad;
+ cachedCameraTanValue = Mathf.Tan(cameraHalfFov);
+ }
+ else
+ {
+ ReportHub.LogError(GetReportData(), "Missing cinemachine brain while initializing UpdateMediaPlayerPrioritizationSystem!");
+ }
+ }
+
+ protected override void Update(float t)
+ {
+ sortedVideoPriorities.Clear();
+ AddVideoStatesByPriorityQuery(World);
+ UpdateVideoPrioritiesQuery(World, cachedCameraVerticalFOV, cachedCameraHorizontalFOV, exposedCameraData.WorldPosition.Value, exposedCameraData.WorldRotation.Value);
+ UpdateVideoStateDependingOnPriorityQuery(World, videoPrioritizationSettings.MaximumSimultaneousVideos);
+
+#if DEBUG_VIDEO_PRIORITIES
+
+ ReportHub.Log(GetReportData(), "" + sortedVideoPriorities.Count + "");
+
+ float maximumPlayingVideos = Mathf.Min(sortedVideoPriorities.Count, videoPrioritizationSettings.MaximumSimultaneousVideos);
+
+ for (int i = 0; i < sortedVideoPriorities.Count; ++i)
+ {
+ sortedVideoPriorities[i].DebugPrioritySign.material.color = (i >= maximumPlayingVideos) ? Color.blue :
+ new Color(i / maximumPlayingVideos, 1.0f - i / maximumPlayingVideos, 0.0f, 1.0f);
+ }
+#endif
+ }
+
+ ///
+ /// Adds the VideoStateByPriorityComponent to all entities streaming a video with a MediaPlayer.
+ ///
+ [Query]
+ [All(typeof(PBVideoPlayer))]
+ [None(typeof(VideoStateByPriorityComponent))]
+ private void AddVideoStatesByPriority(Entity entity, in MediaPlayerComponent mediaPlayer, in VideoTextureConsumer videoTextureConsumer)
+ {
+ // Using the diagonal of the box instead of the height, meshes that occupy "the same" area on screen should have the same priority
+ float videoMeshLocalSize = (videoTextureConsumer.BoundsMax - videoTextureConsumer.BoundsMin).magnitude;
+
+ VideoStateByPriorityComponent newVideoStateByPriority = new VideoStateByPriorityComponent(
+ entity,
+ videoMeshLocalSize * 0.5f,
+ mediaPlayer.IsPlaying);
+
+#if DEBUG_VIDEO_PRIORITIES
+ // Adds a colored cube to a corner of the video mesh renderer which shows the priority of the video
+ GameObject prioritySign = CreateDebugPrioritySign();
+ prioritySign.transform.position = videoTextureConsumer.BoundsMax;
+ newVideoStateByPriority.DebugPrioritySign = prioritySign.GetComponent();
+#endif
+
+ World.Add(entity, newVideoStateByPriority);
+ }
+
+ ///
+ /// Calculates the priority of each video.
+ /// First, videos whose renderer's position is not on camera (imagine a cone in the XZ plane) will be culled; in the same way, those that are too far
+ /// from the camera will also be culled. The rest of the videos will be prioritized calculating a score that depends on their positions and sizes.
+ /// The formula of the score is: S * w0 + D * w1 + A * w2, were S, D and A are values in [0, 1] and wX are arbitrary multipliers.
+ /// S = The size of the video mesh renderer relative to the screen.
+ /// D = The distance from the camera to the video mesh renderer, with a maximum.
+ /// A = The angle of the camera with respect to the video mesh renderer (the nearer to the center of the screen, the higher).
+ /// The first M videos with the highest score will resume / keep playing (were M is the maximum amount of videos allowed), the rest will be culled.
+ /// Every video is stored in a list sorted by score.
+ ///
+ [Query]
+ private void UpdateVideoPriorities([Data] float cameraFov, [Data] float cameraHorizontalFov,
+ [Data] Vector3 cameraWorldPosition, [Data] Quaternion cameraWorldRotation,
+ in MediaPlayerComponent mediaPlayer,
+ ref VideoStateByPriorityComponent videoStateByPriority,
+ ref VideoTextureConsumer videoTextureConsumer)
+ {
+
+#if DEBUG_VIDEO_PRIORITIES
+ videoStateByPriority.DebugPrioritySign.transform.position = videoTextureConsumer.BoundsMax;
+ videoStateByPriority.DebugPrioritySign.material.color = Color.black;
+#endif
+ // If the state of the video was changed manually...
+ if (videoStateByPriority.IsPlaying != mediaPlayer.MediaPlayer.Control.IsPlaying())
+ {
+ if (mediaPlayer.MediaPlayer.Control.IsPlaying())
+ {
+ videoStateByPriority.WantsToPlay = true;
+ videoStateByPriority.MediaPlayStartTime = Time.realtimeSinceStartup;
+
+#if DEBUG_VIDEO_PRIORITIES
+ ReportHub.Log(GetReportData(),"Video: PLAYED MANUALLY");
+#endif
+ }
+ else
+ {
+ videoStateByPriority.WantsToPlay = false;
+
+#if DEBUG_VIDEO_PRIORITIES
+ ReportHub.Log(GetReportData(),"Video: PAUSED MANUALLY");
+#endif
+ }
+ }
+
+ // If the video should be playing according to external state changes...
+ if (videoStateByPriority.WantsToPlay)
+ {
+ Vector3 boundsMin = videoTextureConsumer.BoundsMin;
+ Vector3 boundsMax = videoTextureConsumer.BoundsMax;
+ Vector3 videoCenterPosition = (boundsMax + boundsMin) * 0.5f;
+
+ bool isCameraInVideoBoundingBox = cameraWorldPosition.x >= boundsMin.x && cameraWorldPosition.y >= boundsMin.y && cameraWorldPosition.z >= boundsMin.z &&
+ cameraWorldPosition.x <= boundsMax.x && cameraWorldPosition.y <= boundsMax.y && cameraWorldPosition.z <= boundsMax.z;
+
+ Vector3 cameraToVideo = (videoCenterPosition - cameraWorldPosition).normalized;
+ Vector3 cameraDirection = cameraWorldRotation * Vector3.forward;
+ bool isVideoInCameraFrustum = false;
+
+ if (!isCameraInVideoBoundingBox) // If the camera is inside the BB, it's not necessary to calculate anything else, the video is considered in camera
+ {
+ // Note: It was necessary to calculate a flattened version of the dot product to prevent some videos from pausing when they were big and
+ // the character was too close, so the height of the center of the screen did not affect the result
+ Vector3 cameraToVideoFlattened = new Vector3(cameraToVideo.x, 0.0f, cameraToVideo.z).normalized;
+ Vector3 cameraDirectionFlattened = new Vector3(cameraDirection.x, 0.0f, cameraDirection.z).normalized;
+
+ float dotProductInXZ = Vector3.Dot(cameraToVideoFlattened, cameraDirectionFlattened);
+ isVideoInCameraFrustum = Mathf.Acos(dotProductInXZ) * Mathf.Rad2Deg <= cameraHorizontalFov * 0.5f;
+ }
+
+ // Skips videos that are out of the camera frustum in XZ
+ if (isCameraInVideoBoundingBox || isVideoInCameraFrustum)
+ {
+ float distance = (videoCenterPosition - cameraWorldPosition).magnitude;
+
+ // Skips videos that are too far
+ if (distance <= videoPrioritizationSettings.MaximumDistanceLimit)
+ {
+ float screenSize = Mathf.Clamp01(CalculateObjectHeightRelativeToScreenHeight(videoStateByPriority.HalfSize, distance));
+
+ // Skips videos that are too small on screen
+ if (screenSize >= videoPrioritizationSettings.MinimumSizeLimit)
+ {
+ float dotProduct = Vector3.Dot(cameraToVideo, cameraDirection);
+
+ // Final score
+ videoStateByPriority.Score = (videoPrioritizationSettings.MaximumDistanceLimit - distance) / videoPrioritizationSettings.MaximumDistanceLimit * videoPrioritizationSettings.DistanceWeight +
+ screenSize * videoPrioritizationSettings.SizeInScreenWeight +
+ dotProduct * videoPrioritizationSettings.AngleWeight;
+
+#if DEBUG_VIDEO_PRIORITIES
+ ReportHub.Log(GetReportData(),$"VIDEO ENTITY[{videoStateByPriority.Entity.Id}] Dist: {distance} HSize:{videoStateByPriority.HalfSize} / {CalculateObjectHeightRelativeToScreenHeight(videoStateByPriority.HalfSize, distance)} Dot:{dotProduct} SCORE:{videoStateByPriority.Score}");
+#endif
+
+ // Sorts the playing video list by score, on insertion
+ int i = 0;
+
+ for (; i < sortedVideoPriorities.Count; ++i)
+ if (sortedVideoPriorities[i].Score <= videoStateByPriority.Score)
+ break;
+
+ if (i <= sortedVideoPriorities.Count)
+ sortedVideoPriorities.Insert(i, videoStateByPriority);
+ }
+ }
+ }
+ }
+ }
+
+ ///
+ /// Resumes or pauses every video depending on its priority.
+ ///
+ [Query]
+ private void UpdateVideoStateDependingOnPriority([Data] int maxSimultaneousVideos, ref VideoStateByPriorityComponent videoStateByPriority, ref MediaPlayerComponent mediaPlayer)
+ {
+ bool mustPlay = false;
+ int playingVideoCount = Mathf.Min(maxSimultaneousVideos, sortedVideoPriorities.Count);
+ double pauseDuration = 0.0f;
+
+ // Is the current video player in the list of playing video players? And is it in the first N elements that are allowed to play at maximum? And should it be playing?
+ for (int i = 0; i < playingVideoCount; ++i)
+ {
+ if (sortedVideoPriorities[i].Entity == videoStateByPriority.Entity &&
+ sortedVideoPriorities[i].WantsToPlay)
+ {
+ mustPlay = true;
+ pauseDuration = Time.realtimeSinceStartup - videoStateByPriority.MediaPlayStartTime;
+
+ break;
+ }
+ }
+
+ if (mustPlay && !videoStateByPriority.IsPlaying)
+ {
+ double seekTime = pauseDuration % mediaPlayer.Duration;
+
+ if (!mediaPlayer.MediaPlayer.Control.IsPlaying())
+ {
+ // Videos are resumed at the current time, not at the time it was paused
+ mediaPlayer.MediaPlayer.Control.Play();
+ mediaPlayer.MediaPlayer.Control.Seek(seekTime);
+ }
+
+ videoStateByPriority.IsPlaying = true;
+
+#if DEBUG_VIDEO_PRIORITIES
+ ReportHub.Log(GetReportData(),"VIDEO RESUMED BY PRIORITY: " + videoStateByPriority.Entity.Id + " t:" + seekTime);
+#endif
+ }
+ else if(!mustPlay && (videoStateByPriority.IsPlaying || mediaPlayer.MediaPlayer.Control.IsPlaying()))
+ {
+ if (mediaPlayer.MediaPlayer.Control.IsPlaying())
+ {
+ mediaPlayer.MediaPlayer.Control.Pause();
+ }
+
+ videoStateByPriority.IsPlaying = false;
+
+#if DEBUG_VIDEO_PRIORITIES
+ ReportHub.Log(GetReportData(),"VIDEO CULLED BY PRIORITY: " + videoStateByPriority.Entity.Id);
+#endif
+ }
+ }
+
+ ///
+ /// Given the height of an object, it calculates how much screen it covers in vertical.
+ ///
+ /// A half of the height of the object.
+ /// The distance from the camera to the object.
+ /// The amount of screen covered in vertical, from 0 to 1 (total coverage).
+ private float CalculateObjectHeightRelativeToScreenHeight(float halfHeight, float distance)
+ {
+ return halfHeight / ((distance + halfHeight) * cachedCameraTanValue);
+ }
+
+ // Called when the scene is unloaded
+ public override void Dispose()
+ {
+#if DEBUG_VIDEO_PRIORITIES
+ DestroyAllDebuggingSignsQuery(World);
+#endif
+ base.Dispose();
+ }
+
+ [Query]
+ private void DestroyAllDebuggingSigns(in VideoStateByPriorityComponent videoStateByPriorityComponent)
+ {
+ GameObject.Destroy(videoStateByPriorityComponent.DebugPrioritySign?.gameObject);
+ }
+
+#if DEBUG_VIDEO_PRIORITIES
+
+ private static GameObject CreateDebugPrioritySign()
+ {
+ GameObject plane = GameObject.CreatePrimitive(PrimitiveType.Cube);
+ plane.transform.localScale = Vector3.one * 0.5f;
+ plane.name = "DebugPrioritySign";
+
+ Material cubeMaterial = new Material(Shader.Find("DCL/Unlit"));
+ cubeMaterial.color = Color.white;
+ plane.GetComponent().material = cubeMaterial;
+
+ GameObject.Destroy(plane.GetComponent());
+
+ return plane;
+ }
+
+#endif
+
+ }
+}
diff --git a/Explorer/Assets/DCL/SDKComponents/MediaStream/Systems/UpdateMediaPlayerPrioritizationSystem.cs.meta b/Explorer/Assets/DCL/SDKComponents/MediaStream/Systems/UpdateMediaPlayerPrioritizationSystem.cs.meta
new file mode 100644
index 0000000000..1ee205ddaf
--- /dev/null
+++ b/Explorer/Assets/DCL/SDKComponents/MediaStream/Systems/UpdateMediaPlayerPrioritizationSystem.cs.meta
@@ -0,0 +1,3 @@
+fileFormatVersion: 2
+guid: 3165107914b74b9e9e589bc0528765a0
+timeCreated: 1730560564
\ No newline at end of file
diff --git a/Explorer/Assets/DCL/SDKComponents/MediaStream/Systems/UpdateMediaPlayerSystem.cs b/Explorer/Assets/DCL/SDKComponents/MediaStream/Systems/UpdateMediaPlayerSystem.cs
index b39f161104..98d7756af2 100644
--- a/Explorer/Assets/DCL/SDKComponents/MediaStream/Systems/UpdateMediaPlayerSystem.cs
+++ b/Explorer/Assets/DCL/SDKComponents/MediaStream/Systems/UpdateMediaPlayerSystem.cs
@@ -1,4 +1,4 @@
-using Arch.Core;
+using Arch.Core;
using Arch.System;
using Arch.SystemGroups;
using Arch.SystemGroups.Throttling;
@@ -13,6 +13,7 @@
using ECS.Abstract;
using ECS.Groups;
using ECS.Unity.Textures.Components;
+using ECS.Unity.Transforms.Components;
using RenderHeads.Media.AVProVideo;
using SceneRunner.Scene;
using System;
@@ -73,12 +74,20 @@ private void OnMasterVolumeChanged(float volume)
protected override void Update(float t)
{
+ UpdateMediaPlayerPositionQuery(World);
UpdateAudioStreamQuery(World);
UpdateVideoStreamQuery(World);
UpdateVideoTextureQuery(World);
}
+ [Query]
+ private void UpdateMediaPlayerPosition(ref MediaPlayerComponent mediaPlayer, ref TransformComponent transformComponent)
+ {
+ // Needed for positional sound
+ mediaPlayer.MediaPlayer.transform.position = transformComponent.Transform.position;
+ }
+
[Query]
private void UpdateAudioStream(ref MediaPlayerComponent component, PBAudioStream sdkComponent)
{
diff --git a/Explorer/Assets/DCL/SDKComponents/MediaStream/Wrapper/DCL.MediaPlayer.PluginWrapper.asmdef b/Explorer/Assets/DCL/SDKComponents/MediaStream/Wrapper/DCL.MediaPlayer.PluginWrapper.asmdef
index 77a58b13be..c8d23311a7 100644
--- a/Explorer/Assets/DCL/SDKComponents/MediaStream/Wrapper/DCL.MediaPlayer.PluginWrapper.asmdef
+++ b/Explorer/Assets/DCL/SDKComponents/MediaStream/Wrapper/DCL.MediaPlayer.PluginWrapper.asmdef
@@ -1,5 +1,5 @@
{
- "name": "DCL.VideoPlayer.PluginWrapper",
+ "name": "DCL.MediaPlayer.PluginWrapper",
"rootNamespace": "",
"references": [
"GUID:1b8e1e1bd01505f478f0369c04a4fb2f",
@@ -18,7 +18,9 @@
"GUID:46c2e553ecab9ff4784aee64075136c9",
"GUID:4a12c0b1b77ec6b418a8d7bd5c925be3",
"GUID:543b8f091a5947a3880b7f2bca2358bd",
- "GUID:1d75b3d8691c845b1a51082e81433dfc"
+ "GUID:1d75b3d8691c845b1a51082e81433dfc",
+ "GUID:fa7b3fdbb04d67549916da7bd2af58ab",
+ "GUID:fc37ca6521833154cab08ec51af097d9"
],
"includePlatforms": [],
"excludePlatforms": [],
diff --git a/Explorer/Assets/DCL/SDKComponents/MediaStream/Wrapper/MediaPlayerPluginWrapper.cs b/Explorer/Assets/DCL/SDKComponents/MediaStream/Wrapper/MediaPlayerPluginWrapper.cs
index de6159a680..a4eb05dee5 100644
--- a/Explorer/Assets/DCL/SDKComponents/MediaStream/Wrapper/MediaPlayerPluginWrapper.cs
+++ b/Explorer/Assets/DCL/SDKComponents/MediaStream/Wrapper/MediaPlayerPluginWrapper.cs
@@ -1,17 +1,18 @@
-using Arch.Core;
+using Arch.Core;
using Arch.SystemGroups;
using CrdtEcsBridge.ECSToCRDTWriter;
+using DCL.CharacterCamera;
using DCL.Optimization.PerformanceBudgeting;
using DCL.Optimization.Pools;
using DCL.ResourcesUnloading;
using DCL.WebRequests;
-using ECS.ComponentsPooling.Systems;
using ECS.LifeCycle;
using SceneRunner.Scene;
using System.Collections.Generic;
using UnityEngine;
using RenderHeads.Media.AVProVideo;
using DCL.ECSComponents;
+using DCL.SDKComponents.MediaStream.Settings;
using DCL.Settings;
namespace DCL.SDKComponents.MediaStream.Wrapper
@@ -24,6 +25,8 @@ public class MediaPlayerPluginWrapper
private readonly IPerformanceBudget frameTimeBudget;
private readonly GameObjectPool mediaPlayerPool;
private readonly WorldVolumeMacBus worldVolumeMacBus;
+ private readonly IExposedCameraData exposedCameraData;
+ private readonly VideoPrioritizationSettings videoPrioritizationSettings;
public MediaPlayerPluginWrapper(
IComponentPoolsRegistry componentPoolsRegistry,
@@ -32,8 +35,13 @@ public MediaPlayerPluginWrapper(
IExtendedObjectPool videoTexturePool,
IPerformanceBudget frameTimeBudget,
MediaPlayer mediaPlayerPrefab,
- WorldVolumeMacBus worldVolumeMacBus)
+ WorldVolumeMacBus worldVolumeMacBus,
+ IExposedCameraData exposedCameraData,
+ VideoPrioritizationSettings videoPrioritizationSettings)
{
+ this.exposedCameraData = exposedCameraData;
+ this.videoPrioritizationSettings = videoPrioritizationSettings;
+
#if AV_PRO_PRESENT && !UNITY_EDITOR_LINUX && !UNITY_STANDALONE_LINUX
this.componentPoolsRegistry = componentPoolsRegistry;
this.webRequestController = webRequestController;
@@ -73,6 +81,7 @@ public void InjectToWorld(ref ArchSystemsWorldBuilder builder, ISceneData
CreateMediaPlayerSystem.InjectToWorld(ref builder, webRequestController, sceneData, mediaPlayerPool, sceneStateProvider, frameTimeBudget);
UpdateMediaPlayerSystem.InjectToWorld(ref builder, webRequestController, sceneData, sceneStateProvider, frameTimeBudget, worldVolumeMacBus);
+ UpdateMediaPlayerPrioritizationSystem.InjectToWorld(ref builder, exposedCameraData, videoPrioritizationSettings);
VideoEventsSystem.InjectToWorld(ref builder, ecsToCrdtWriter, sceneStateProvider, frameTimeBudget);
finalizeWorldSystems.Add(CleanUpMediaPlayerSystem.InjectToWorld(ref builder, mediaPlayerPool, videoTexturePool));
diff --git a/Explorer/Assets/DCL/Settings/Configuration/DropdownModuleBinding.cs b/Explorer/Assets/DCL/Settings/Configuration/DropdownModuleBinding.cs
index ddc0535092..74c5691ada 100644
--- a/Explorer/Assets/DCL/Settings/Configuration/DropdownModuleBinding.cs
+++ b/Explorer/Assets/DCL/Settings/Configuration/DropdownModuleBinding.cs
@@ -1,6 +1,7 @@
using DCL.Landscape.Settings;
using DCL.Optimization.PerformanceBudgeting;
using DCL.Quality;
+using DCL.SDKComponents.MediaStream.Settings;
using DCL.Settings.ModuleControllers;
using DCL.Settings.ModuleViews;
using DCL.Settings.Settings;
@@ -29,6 +30,7 @@ public enum DropdownFeatures
public override SettingsFeatureController CreateModule(
Transform parent,
RealmPartitionSettingsAsset realmPartitionSettingsAsset,
+ VideoPrioritizationSettings videoPrioritizationSettings,
LandscapeData landscapeData,
AudioMixer generalAudioMixer,
QualitySettingsAsset qualitySettingsAsset,
diff --git a/Explorer/Assets/DCL/Settings/Configuration/SettingsModuleBindings.cs b/Explorer/Assets/DCL/Settings/Configuration/SettingsModuleBindings.cs
index c437130cba..25c0632fcb 100644
--- a/Explorer/Assets/DCL/Settings/Configuration/SettingsModuleBindings.cs
+++ b/Explorer/Assets/DCL/Settings/Configuration/SettingsModuleBindings.cs
@@ -1,6 +1,7 @@
using DCL.Landscape.Settings;
using DCL.Optimization.PerformanceBudgeting;
using DCL.Quality;
+using DCL.SDKComponents.MediaStream.Settings;
using DCL.Settings.ModuleControllers;
using DCL.Settings.ModuleViews;
using DCL.Settings.Settings;
@@ -20,6 +21,7 @@ public abstract class SettingsModuleBindingBase
public abstract SettingsFeatureController CreateModule(
Transform parent,
RealmPartitionSettingsAsset realmPartitionSettingsAsset,
+ VideoPrioritizationSettings videoPrioritizationSettings,
LandscapeData landscapeData,
AudioMixer generalAudioMixer,
QualitySettingsAsset qualitySettingsAsset,
diff --git a/Explorer/Assets/DCL/Settings/Configuration/SliderModuleBinding.cs b/Explorer/Assets/DCL/Settings/Configuration/SliderModuleBinding.cs
index f3c599a6c5..3187f92515 100644
--- a/Explorer/Assets/DCL/Settings/Configuration/SliderModuleBinding.cs
+++ b/Explorer/Assets/DCL/Settings/Configuration/SliderModuleBinding.cs
@@ -1,6 +1,7 @@
using DCL.Landscape.Settings;
using DCL.Optimization.PerformanceBudgeting;
using DCL.Quality;
+using DCL.SDKComponents.MediaStream.Settings;
using DCL.Settings.ModuleControllers;
using DCL.Settings.ModuleViews;
using DCL.Settings.Settings;
@@ -31,6 +32,7 @@ public enum SliderFeatures
public override SettingsFeatureController CreateModule(
Transform parent,
RealmPartitionSettingsAsset realmPartitionSettingsAsset,
+ VideoPrioritizationSettings videoPrioritizationSettings,
LandscapeData landscapeData,
AudioMixer generalAudioMixer,
QualitySettingsAsset qualitySettingsAsset,
diff --git a/Explorer/Assets/DCL/Settings/Configuration/ToggleModuleBinding.cs b/Explorer/Assets/DCL/Settings/Configuration/ToggleModuleBinding.cs
index 086bca7cc7..421e13c46e 100644
--- a/Explorer/Assets/DCL/Settings/Configuration/ToggleModuleBinding.cs
+++ b/Explorer/Assets/DCL/Settings/Configuration/ToggleModuleBinding.cs
@@ -1,6 +1,7 @@
using DCL.Landscape.Settings;
using DCL.Optimization.PerformanceBudgeting;
using DCL.Quality;
+using DCL.SDKComponents.MediaStream.Settings;
using DCL.Settings.ModuleControllers;
using DCL.Settings.ModuleViews;
using DCL.Settings.Settings;
@@ -24,6 +25,7 @@ public enum ToggleFeatures
public override SettingsFeatureController CreateModule(
Transform parent,
RealmPartitionSettingsAsset realmPartitionSettingsAsset,
+ VideoPrioritizationSettings videoPrioritizationSettings,
LandscapeData landscapeData,
AudioMixer generalAudioMixer,
QualitySettingsAsset qualitySettingsAsset,
diff --git a/Explorer/Assets/DCL/Settings/Settings.asmdef b/Explorer/Assets/DCL/Settings/Settings.asmdef
index 5fea4efadd..e17bf24756 100644
--- a/Explorer/Assets/DCL/Settings/Settings.asmdef
+++ b/Explorer/Assets/DCL/Settings/Settings.asmdef
@@ -11,7 +11,8 @@
"GUID:21c2e77c042a2d34d8cfbf58f8217053",
"GUID:f51ebe6a0ceec4240a699833d6309b23",
"GUID:ba2f4073aea205344b1f48bb5111ff3b",
- "GUID:3640f3c0b42946b0b8794a1ed8e06ca5"
+ "GUID:3640f3c0b42946b0b8794a1ed8e06ca5",
+ "GUID:fc37ca6521833154cab08ec51af097d9"
],
"includePlatforms": [],
"excludePlatforms": [],
diff --git a/Explorer/Assets/DCL/Settings/SettingsController.cs b/Explorer/Assets/DCL/Settings/SettingsController.cs
index 2aabd10af6..5211b05612 100644
--- a/Explorer/Assets/DCL/Settings/SettingsController.cs
+++ b/Explorer/Assets/DCL/Settings/SettingsController.cs
@@ -2,6 +2,7 @@
using DCL.Landscape.Settings;
using DCL.Optimization.PerformanceBudgeting;
using DCL.Quality;
+using DCL.SDKComponents.MediaStream.Settings;
using DCL.Settings.Configuration;
using DCL.Settings.ModuleControllers;
using DCL.Settings.Settings;
@@ -21,6 +22,7 @@ public class SettingsController : ISection, IDisposable
private readonly SettingsMenuConfiguration settingsMenuConfiguration;
private readonly AudioMixer generalAudioMixer;
private readonly RealmPartitionSettingsAsset realmPartitionSettingsAsset;
+ private readonly VideoPrioritizationSettings videoPrioritizationSettings;
private readonly LandscapeData landscapeData;
private readonly QualitySettingsAsset qualitySettingsAsset;
private readonly ISystemMemoryCap memoryCap;
@@ -34,6 +36,7 @@ public SettingsController(
SettingsMenuConfiguration settingsMenuConfiguration,
AudioMixer generalAudioMixer,
RealmPartitionSettingsAsset realmPartitionSettingsAsset,
+ VideoPrioritizationSettings videoPrioritizationSettings,
LandscapeData landscapeData,
QualitySettingsAsset qualitySettingsAsset,
ControlsSettingsAsset controlsSettingsAsset,
@@ -49,6 +52,7 @@ public SettingsController(
this.memoryCap = memoryCap;
this.worldVolumeMacBus = worldVolumeMacBus;
this.controlsSettingsAsset = controlsSettingsAsset;
+ this.videoPrioritizationSettings = videoPrioritizationSettings;
rectTransform = view.transform.parent.GetComponent();
@@ -114,7 +118,7 @@ private void GenerateSettingsSection(SettingsSectionConfig sectionConfig, Transf
generalGroupView.GroupTitle.text = group.GroupTitle;
foreach (SettingsModuleBindingBase module in group.Modules)
- controllers.Add(module?.CreateModule(generalGroupView.ModulesContainer, realmPartitionSettingsAsset, landscapeData, generalAudioMixer, qualitySettingsAsset, controlsSettingsAsset, memoryCap, worldVolumeMacBus));
+ controllers.Add(module?.CreateModule(generalGroupView.ModulesContainer, realmPartitionSettingsAsset, videoPrioritizationSettings, landscapeData, generalAudioMixer, qualitySettingsAsset, controlsSettingsAsset, memoryCap, worldVolumeMacBus));
}
}
diff --git a/Explorer/Assets/Scripts/ECS/Unity/Materials/ReleaseMaterial.cs b/Explorer/Assets/Scripts/ECS/Unity/Materials/ReleaseMaterial.cs
index 39d4a77c8d..ec06b36a88 100644
--- a/Explorer/Assets/Scripts/ECS/Unity/Materials/ReleaseMaterial.cs
+++ b/Explorer/Assets/Scripts/ECS/Unity/Materials/ReleaseMaterial.cs
@@ -4,6 +4,7 @@
using ECS.Unity.Materials.Components;
using ECS.Unity.PrimitiveRenderer.Components;
using ECS.Unity.Textures.Components;
+using ECS.Unity.Textures.Utils;
using UnityEngine;
using Utility.Primitives;
using Promise = ECS.StreamableLoading.Common.AssetPromise;
@@ -25,7 +26,7 @@ public static void TryReleaseDefault(ref PrimitiveMeshRendererComponent primitiv
primitiveMeshRendererComponent.DefaultMaterialIsUsed = false;
}
- public static void Execute(World world, ref MaterialComponent materialComponent, DestroyMaterial destroyMaterial)
+ public static void Execute(Entity entity, World world, ref MaterialComponent materialComponent, DestroyMaterial destroyMaterial)
{
switch (materialComponent.Status)
{
@@ -43,14 +44,14 @@ public static void Execute(World world, ref MaterialComponent materialComponent,
void ReleaseTextures(ref MaterialComponent mat, bool forgetLoading)
{
- ReleaseIntention(world, ref mat.AlbedoTexPromise, forgetLoading);
- ReleaseIntention(world, ref mat.EmissiveTexPromise, forgetLoading);
- ReleaseIntention(world, ref mat.AlphaTexPromise, forgetLoading);
- ReleaseIntention(world, ref mat.BumpTexPromise, forgetLoading);
+ ReleaseIntention(entity, world, ref mat.AlbedoTexPromise, forgetLoading);
+ ReleaseIntention(entity, world, ref mat.EmissiveTexPromise, forgetLoading);
+ ReleaseIntention(entity, world, ref mat.AlphaTexPromise, forgetLoading);
+ ReleaseIntention(entity, world, ref mat.BumpTexPromise, forgetLoading);
}
}
- internal static void ReleaseIntention(World world, ref Promise? promise, bool forgetLoading)
+ internal static void ReleaseIntention(Entity entity, World world, ref Promise? promise, bool forgetLoading)
{
if (promise == null)
return;
@@ -60,6 +61,19 @@ internal static void ReleaseIntention(World world, ref Promise? promise, bool fo
if (forgetLoading)
promiseValue.ForgetLoading(world);
+ if (promiseValue.LoadingIntention.IsVideoTexture)
+ {
+ ref VideoTextureConsumer consumer = ref world.TryGetRef(entity, out bool hasConsumer);
+
+ if (hasConsumer)
+ {
+ ref PrimitiveMeshRendererComponent meshRenderer = ref world.TryGetRef(entity, out bool hasMesh);
+
+ if(hasMesh)
+ consumer.RemoveConsumerMeshRenderer(meshRenderer.MeshRenderer);
+ }
+ }
+
promiseValue.TryDereference(world);
// Nullify the entity reference
diff --git a/Explorer/Assets/Scripts/ECS/Unity/Materials/Systems/CleanUpMaterialsSystem.cs b/Explorer/Assets/Scripts/ECS/Unity/Materials/Systems/CleanUpMaterialsSystem.cs
index 7d21e3aa1b..e62052eb5b 100644
--- a/Explorer/Assets/Scripts/ECS/Unity/Materials/Systems/CleanUpMaterialsSystem.cs
+++ b/Explorer/Assets/Scripts/ECS/Unity/Materials/Systems/CleanUpMaterialsSystem.cs
@@ -32,15 +32,15 @@ protected override void Update(float t)
[Query]
[All(typeof(DeleteEntityIntention))]
- private void TryRelease(ref MaterialComponent materialComponent)
+ private void TryRelease(Entity entity, ref MaterialComponent materialComponent)
{
- ReleaseMaterial.Execute(World, ref materialComponent, destroyMaterial);
+ ReleaseMaterial.Execute(entity, World, ref materialComponent, destroyMaterial);
}
[Query]
- private void ReleaseUnconditionally(ref MaterialComponent materialComponent)
+ private void ReleaseUnconditionally(Entity entity, ref MaterialComponent materialComponent)
{
- ReleaseMaterial.Execute(World, ref materialComponent, destroyMaterial);
+ ReleaseMaterial.Execute(entity, World, ref materialComponent, destroyMaterial);
}
public void FinalizeComponents(in Query query)
diff --git a/Explorer/Assets/Scripts/ECS/Unity/Materials/Systems/ResetMaterialSystem.cs b/Explorer/Assets/Scripts/ECS/Unity/Materials/Systems/ResetMaterialSystem.cs
index 5a26b49e35..e5c809574e 100644
--- a/Explorer/Assets/Scripts/ECS/Unity/Materials/Systems/ResetMaterialSystem.cs
+++ b/Explorer/Assets/Scripts/ECS/Unity/Materials/Systems/ResetMaterialSystem.cs
@@ -37,10 +37,10 @@ protected override void Update(float t)
[Query]
[None(typeof(PBMaterial))]
- private void Reset(ref PrimitiveMeshRendererComponent meshRendererComponent, ref MaterialComponent materialComponent)
+ private void Reset(Entity entity, ref PrimitiveMeshRendererComponent meshRendererComponent, ref MaterialComponent materialComponent)
{
meshRendererComponent.SetDefaultMaterial(sceneData.Geometry.CircumscribedPlanes, sceneData.Geometry.Height);
- ReleaseMaterial.Execute(World, ref materialComponent, destroyMaterial);
+ ReleaseMaterial.Execute(entity, World, ref materialComponent, destroyMaterial);
}
}
}
diff --git a/Explorer/Assets/Scripts/ECS/Unity/Materials/Systems/StartMaterialsLoadingSystem.cs b/Explorer/Assets/Scripts/ECS/Unity/Materials/Systems/StartMaterialsLoadingSystem.cs
index 3cefb86d95..d034a212a7 100644
--- a/Explorer/Assets/Scripts/ECS/Unity/Materials/Systems/StartMaterialsLoadingSystem.cs
+++ b/Explorer/Assets/Scripts/ECS/Unity/Materials/Systems/StartMaterialsLoadingSystem.cs
@@ -70,29 +70,29 @@ private void InvalidateMaterialComponent(Entity entity, ref PBMaterial material,
if (MaterialDataEqualityComparer.Equals(in materialComponent.Data, in materialData))
return;
- InvalidatePrbInequality(ref materialComponent, ref materialData);
+ InvalidatePrbInequality(entity, ref materialComponent, ref materialData);
MaterialData.TexturesData prevTextureData = materialComponent.Data.Textures;
materialComponent.Data = materialData;
materialComponent.Status = StreamableLoading.LifeCycle.LoadingInProgress;
- World.Set(entity, StartNewMaterialLoad(materialComponent, in prevTextureData, partitionComponent));
+ World.Set(entity, StartNewMaterialLoad(entity, materialComponent, in prevTextureData, partitionComponent));
World.AddOrGet(entity, new ShouldInstanceMaterialComponent());
}
- private void InvalidatePrbInequality(ref MaterialComponent materialComponent, ref MaterialData materialData)
+ private void InvalidatePrbInequality(Entity entity, ref MaterialComponent materialComponent, ref MaterialData materialData)
{
// If isPbr is the same right the same material is reused
if (materialComponent.Data.IsPbrMaterial != materialData.IsPbrMaterial)
{
- ReleaseMaterial.Execute(World!, ref materialComponent, destroyMaterial);
+ ReleaseMaterial.Execute(entity, World!, ref materialComponent, destroyMaterial);
materialComponent.Result = null;
}
}
- private MaterialComponent StartNewMaterialLoad(MaterialComponent materialComponent, in MaterialData.TexturesData prevTexturesData, PartitionComponent partitionComponent)
+ private MaterialComponent StartNewMaterialLoad(Entity entity, MaterialComponent materialComponent, in MaterialData.TexturesData prevTexturesData, PartitionComponent partitionComponent)
{
- CreateGetTexturePromises(ref materialComponent, prevTexturesData, partitionComponent);
+ CreateGetTexturePromises(entity, ref materialComponent, prevTexturesData, partitionComponent);
return materialComponent;
}
@@ -105,7 +105,7 @@ private void CreateMaterialComponent(Entity entity, ref PBMaterial material, ref
return;
var materialComponent = new MaterialComponent(CreateMaterialData(in material));
- CreateGetTexturePromises(ref materialComponent, null, partitionComponent);
+ CreateGetTexturePromises(entity, ref materialComponent, null, partitionComponent);
materialComponent.Status = StreamableLoading.LifeCycle.LoadingInProgress;
World.Add(entity, materialComponent);
@@ -148,35 +148,35 @@ private static MaterialData CreatePBRMaterialData(
pbMaterial.GetEmissiveIntensity(),
pbMaterial.GetDirectIntensity());
- private void CreateGetTexturePromises(ref MaterialComponent materialComponent,
+ private void CreateGetTexturePromises(Entity entity, ref MaterialComponent materialComponent,
in MaterialData.TexturesData? oldTexturesData,
PartitionComponent partitionComponent)
{
- TryCreateGetTexturePromise(in materialComponent.Data.Textures.AlbedoTexture, oldTexturesData?.AlbedoTexture, ref materialComponent.AlbedoTexPromise, partitionComponent);
+ TryCreateGetTexturePromise(entity, in materialComponent.Data.Textures.AlbedoTexture, oldTexturesData?.AlbedoTexture, ref materialComponent.AlbedoTexPromise, partitionComponent);
if (materialComponent.Data.IsPbrMaterial)
{
- TryCreateGetTexturePromise(in materialComponent.Data.Textures.AlphaTexture, oldTexturesData?.AlphaTexture, ref materialComponent.AlphaTexPromise, partitionComponent);
- TryCreateGetTexturePromise(in materialComponent.Data.Textures.EmissiveTexture, oldTexturesData?.EmissiveTexture, ref materialComponent.EmissiveTexPromise, partitionComponent);
- TryCreateGetTexturePromise(in materialComponent.Data.Textures.BumpTexture, oldTexturesData?.BumpTexture, ref materialComponent.BumpTexPromise, partitionComponent);
+ TryCreateGetTexturePromise(entity, in materialComponent.Data.Textures.AlphaTexture, oldTexturesData?.AlphaTexture, ref materialComponent.AlphaTexPromise, partitionComponent);
+ TryCreateGetTexturePromise(entity, in materialComponent.Data.Textures.EmissiveTexture, oldTexturesData?.EmissiveTexture, ref materialComponent.EmissiveTexPromise, partitionComponent);
+ TryCreateGetTexturePromise(entity, in materialComponent.Data.Textures.BumpTexture, oldTexturesData?.BumpTexture, ref materialComponent.BumpTexPromise, partitionComponent);
}
else
{
- TryCreateGetTexturePromise(in materialComponent.Data.Textures.AlphaTexture, oldTexturesData?.AlphaTexture, ref materialComponent.AlphaTexPromise, partitionComponent);
+ TryCreateGetTexturePromise(entity, in materialComponent.Data.Textures.AlphaTexture, oldTexturesData?.AlphaTexture, ref materialComponent.AlphaTexPromise, partitionComponent);
}
}
private static MaterialData CreateBasicMaterialData(in PBMaterial pbMaterial, in TextureComponent? albedoTexture, in TextureComponent? alphaTexture) =>
MaterialData.CreateBasicMaterial(albedoTexture, alphaTexture, pbMaterial.GetAlphaTest(), pbMaterial.GetDiffuseColor(), pbMaterial.GetCastShadows());
- private bool TryCreateGetTexturePromise(in TextureComponent? textureComponent,
+ private bool TryCreateGetTexturePromise(Entity entity, in TextureComponent? textureComponent,
in TextureComponent? oldTextureComponent,
ref Promise? promise, PartitionComponent partitionComponent)
{
if (textureComponent == null)
{
// If component is being reused forget the previous promise
- ReleaseMaterial.ReleaseIntention(World, ref promise, true);
+ ReleaseMaterial.ReleaseIntention(entity, World, ref promise, true);
return false;
}
@@ -188,7 +188,7 @@ private bool TryCreateGetTexturePromise(in TextureComponent? textureComponent,
return false;
// If component is being reused forget the previous promise
- ReleaseMaterial.ReleaseIntention(World, ref promise, true);
+ ReleaseMaterial.ReleaseIntention(entity, World, ref promise, true);
// TODO this code must be unified to be able to load video textures in a common way
if (textureComponentValue.IsVideoTexture)
@@ -196,7 +196,7 @@ private bool TryCreateGetTexturePromise(in TextureComponent? textureComponent,
var intention = new GetTextureIntention(textureComponentValue.VideoPlayerEntity);
promise = Promise.CreateFinalized(intention,
- textureComponentValue.TryAddConsumer(entitiesMap, videoTexturesPool, World, out Texture2DData? tex)
+ textureComponentValue.TryAddConsumer(entity, entitiesMap, videoTexturesPool, World, out Texture2DData? tex)
? new StreamableLoadingResult(tex!)
: new StreamableLoadingResult(GetReportCategory(), CreateException(new EcsEntityNotFoundException(textureComponentValue.VideoPlayerEntity, $"Entity {textureComponentValue.VideoPlayerEntity} not found!. VideoTexture will not be created."))));
}
diff --git a/Explorer/Assets/Scripts/ECS/Unity/Tests/ECS.Unity.Tests.asmdef b/Explorer/Assets/Scripts/ECS/Unity/Tests/ECS.Unity.Tests.asmdef
index 40b51062a3..c36c6e768e 100644
--- a/Explorer/Assets/Scripts/ECS/Unity/Tests/ECS.Unity.Tests.asmdef
+++ b/Explorer/Assets/Scripts/ECS/Unity/Tests/ECS.Unity.Tests.asmdef
@@ -1,53 +1,49 @@
{
- "name": "ECS.Unity.Tests",
- "rootNamespace": "",
- "references": [
- "GUID:27619889b8ba8c24980f49ee34dbb44a",
- "GUID:0acc523941302664db1f4e527237feb3",
- "GUID:3c7b57a14671040bd8c549056adc04f5",
- "GUID:a3c61f15599a43ae9de508c9c4dd5530",
- "GUID:4794e238ed0f65142a4aea5848b513e5",
- "GUID:1b8e1e1bd01505f478f0369c04a4fb2f",
- "GUID:c2b7e3e0e95f4eb588516c8ae12e919b",
- "GUID:6e2b4bed29ad1c549ab19b744f36f388",
- "GUID:0f4c0f120707fb74497f5d581b9858f8",
- "GUID:d414ef88f3b15f746a4b97636b50dfb4",
- "GUID:286980af24684da6acc1caa413039811",
- "GUID:fa7b3fdbb04d67549916da7bd2af58ab",
- "GUID:f51ebe6a0ceec4240a699833d6309b23",
- "GUID:101b8b6ebaf64668909b49c4b7a1420d",
- "GUID:fa0cb088e184452c8a89ecdeff7c731d",
- "GUID:9e24947de15b9834991c9d8411ea37cf",
- "GUID:84651a3751eca9349aac36a66bba901b",
- "GUID:9e314663ce958b746873cb22d57ede55",
- "GUID:8322ea9340a544c59ddc56d4793eac74",
- "GUID:3640f3c0b42946b0b8794a1ed8e06ca5",
- "GUID:275e22790c04e9b47a5085d7b0c4432a",
- "GUID:78e0b5197588c4841a6544409324031c",
- "GUID:4505fcf99e744d9bba6c6de3568145fd",
- "GUID:166b65e6dfc848bb9fb075f53c293a38",
- "GUID:54660b0fae444b4cbfdafa9d68108f04",
- "GUID:fc4fd35fb877e904d8cedee73b2256f6",
- "GUID:4a12c0b1b77ec6b418a8d7bd5c925be3"
- ],
- "includePlatforms": [
- "Editor"
- ],
- "excludePlatforms": [],
- "allowUnsafeCode": false,
- "overrideReferences": true,
- "precompiledReferences": [
- "nunit.framework.dll",
- "Arch.System.dll",
- "Arch.dll",
- "Arch.SystemGroups.dll",
- "NSubstitute.dll",
- "Google.Protobuf.dll"
- ],
- "autoReferenced": false,
- "defineConstraints": [
- "UNITY_INCLUDE_TESTS"
- ],
- "versionDefines": [],
- "noEngineReferences": false
+ "name": "ECS.Unity.Tests",
+ "rootNamespace": "",
+ "references": [
+ "GUID:27619889b8ba8c24980f49ee34dbb44a",
+ "GUID:0acc523941302664db1f4e527237feb3",
+ "GUID:3c7b57a14671040bd8c549056adc04f5",
+ "GUID:a3c61f15599a43ae9de508c9c4dd5530",
+ "GUID:4794e238ed0f65142a4aea5848b513e5",
+ "GUID:1b8e1e1bd01505f478f0369c04a4fb2f",
+ "GUID:0f4c0f120707fb74497f5d581b9858f8",
+ "GUID:d414ef88f3b15f746a4b97636b50dfb4",
+ "GUID:286980af24684da6acc1caa413039811",
+ "GUID:fa7b3fdbb04d67549916da7bd2af58ab",
+ "GUID:f51ebe6a0ceec4240a699833d6309b23",
+ "GUID:9e24947de15b9834991c9d8411ea37cf",
+ "GUID:84651a3751eca9349aac36a66bba901b",
+ "GUID:9e314663ce958b746873cb22d57ede55",
+ "GUID:8322ea9340a544c59ddc56d4793eac74",
+ "GUID:3640f3c0b42946b0b8794a1ed8e06ca5",
+ "GUID:275e22790c04e9b47a5085d7b0c4432a",
+ "GUID:78e0b5197588c4841a6544409324031c",
+ "GUID:166b65e6dfc848bb9fb075f53c293a38",
+ "GUID:54660b0fae444b4cbfdafa9d68108f04",
+ "GUID:fc4fd35fb877e904d8cedee73b2256f6",
+ "GUID:4a12c0b1b77ec6b418a8d7bd5c925be3",
+ "GUID:c80c82a8f4e04453b85fbab973d6774a"
+ ],
+ "includePlatforms": [
+ "Editor"
+ ],
+ "excludePlatforms": [],
+ "allowUnsafeCode": false,
+ "overrideReferences": true,
+ "precompiledReferences": [
+ "nunit.framework.dll",
+ "Arch.System.dll",
+ "Arch.dll",
+ "Arch.SystemGroups.dll",
+ "NSubstitute.dll",
+ "Google.Protobuf.dll"
+ ],
+ "autoReferenced": false,
+ "defineConstraints": [
+ "UNITY_INCLUDE_TESTS"
+ ],
+ "versionDefines": [],
+ "noEngineReferences": false
}
\ No newline at end of file
diff --git a/Explorer/Assets/Scripts/ECS/Unity/Textures/Components/VideoTextureConsumer.cs b/Explorer/Assets/Scripts/ECS/Unity/Textures/Components/VideoTextureConsumer.cs
index 106fc2eba2..274ade1652 100644
--- a/Explorer/Assets/Scripts/ECS/Unity/Textures/Components/VideoTextureConsumer.cs
+++ b/Explorer/Assets/Scripts/ECS/Unity/Textures/Components/VideoTextureConsumer.cs
@@ -1,11 +1,53 @@
using ECS.StreamableLoading.Textures;
using System;
+using System.Collections.Generic;
using UnityEngine;
namespace ECS.Unity.Textures.Components
{
public struct VideoTextureConsumer : IDisposable
{
+ ///
+ /// Gets the current world position of the maximum corner of the bounding box that contains all the mesh renderers used by video consumers of one texture.
+ ///
+ public Vector3 BoundsMax
+ {
+ get
+ {
+ Vector3 boundsMax = Vector3.one * float.MinValue;
+
+ for (int i = 0; i < renderers.Count; ++i)
+ {
+ Vector3 inputBoundsMax = renderers[i].bounds.max;
+ boundsMax = new Vector3(Mathf.Max(inputBoundsMax.x, boundsMax.x), Mathf.Max(inputBoundsMax.y, boundsMax.y), Mathf.Max(inputBoundsMax.z, boundsMax.z));
+ }
+
+ return boundsMax;
+ }
+ }
+
+ ///
+ /// Gets the current world position of the minimum corner of the bounding box that contains all the mesh renderers used by video consumers of one texture.
+ ///
+ public Vector3 BoundsMin
+ {
+ get
+ {
+ Vector3 boundsMin = Vector3.one * float.MaxValue;
+
+ for (int i = 0; i < renderers.Count; ++i)
+ {
+ Vector3 inputBoundsMin = renderers[i].bounds.min;
+ boundsMin = new Vector3(Mathf.Min(inputBoundsMin.x, boundsMin.x), Mathf.Min(inputBoundsMin.y, boundsMin.y), Mathf.Min(inputBoundsMin.z, boundsMin.z));
+ }
+
+ return boundsMin;
+ }
+ }
+
+ // All the renderers that use the video texture
+ private readonly List renderers;
+
///
/// The single copy kept for the single Entity with VideoPlayer,
/// we don't use the original texture from AVPro
@@ -17,12 +59,32 @@ public struct VideoTextureConsumer : IDisposable
public VideoTextureConsumer(Texture2D texture)
{
Texture = new Texture2DData(texture);
+ renderers = new List();
}
public void Dispose()
{
// On Dispose video textures are dereferenced by material that acquired it
Texture = null!;
+ renderers.Clear();
+ }
+
+ ///
+ /// Stores a reference to a renderer that consumes the same texture.
+ ///
+ /// The renderer using the video texture.
+ public void AddConsumerMeshRenderer(MeshRenderer renderer)
+ {
+ renderers.Add(renderer);
+ }
+
+ ///
+ /// Removes a reference to a renderer that was consuming the same texture.
+ ///
+ /// The renderer to stop referencing to.
+ public void RemoveConsumerMeshRenderer(MeshRenderer renderer)
+ {
+ renderers.Remove(renderer);
}
}
}
diff --git a/Explorer/Assets/Scripts/ECS/Unity/Textures/Utils/VideoTextureUtils.cs b/Explorer/Assets/Scripts/ECS/Unity/Textures/Utils/VideoTextureUtils.cs
index 8e36d25ae6..d3dd9b0e9d 100644
--- a/Explorer/Assets/Scripts/ECS/Unity/Textures/Utils/VideoTextureUtils.cs
+++ b/Explorer/Assets/Scripts/ECS/Unity/Textures/Utils/VideoTextureUtils.cs
@@ -1,6 +1,7 @@
using Arch.Core;
using CRDT;
using ECS.StreamableLoading.Textures;
+using ECS.Unity.PrimitiveRenderer.Components;
using ECS.Unity.Textures.Components;
using System.Collections.Generic;
using UnityEngine;
@@ -12,6 +13,7 @@ public static class VideoTextureUtils
{
public static bool TryAddConsumer(
this in TextureComponent textureComponent,
+ Entity entity,
IReadOnlyDictionary entitiesMap,
IObjectPool videoTexturesPool,
World world,
@@ -27,9 +29,14 @@ public static bool TryAddConsumer(
consumer = ref world.Get(videoPlayerEntity);
}
-
texture = consumer.Texture;
texture.AddReference();
+
+ ref PrimitiveMeshRendererComponent meshRenderer = ref world.TryGetRef(entity, out bool hasMesh);
+
+ if (hasMesh)
+ consumer.AddConsumerMeshRenderer(meshRenderer.MeshRenderer);
+
return true;
}
diff --git a/Explorer/Assets/Scripts/Global/StaticContainer.cs b/Explorer/Assets/Scripts/Global/StaticContainer.cs
index f6bc7691e8..e3e627d4bf 100644
--- a/Explorer/Assets/Scripts/Global/StaticContainer.cs
+++ b/Explorer/Assets/Scripts/Global/StaticContainer.cs
@@ -1,4 +1,4 @@
-using Arch.Core;
+using Arch.Core;
using CrdtEcsBridge.Components;
using Cysharp.Threading.Tasks;
using DCL.AssetsProvision;
@@ -229,7 +229,7 @@ await UniTask.WhenAll(
container.CharacterContainer.CreateWorldPlugin(componentsContainer.ComponentPoolsRegistry),
new AnimatorPlugin(),
new TweenPlugin(),
- new MediaPlayerPlugin(sharedDependencies, videoTexturePool, sharedDependencies.FrameTimeBudget, container.assetsProvisioner, container.WebRequestsContainer.WebRequestController, container.CacheCleaner, worldVolumeMacBus),
+ new MediaPlayerPlugin(sharedDependencies, videoTexturePool, sharedDependencies.FrameTimeBudget, container.assetsProvisioner, container.WebRequestsContainer.WebRequestController, container.CacheCleaner, worldVolumeMacBus, exposedGlobalDataContainer.ExposedCameraData),
new CharacterTriggerAreaPlugin(globalWorld, container.MainPlayerAvatarBaseProxy, exposedGlobalDataContainer.ExposedCameraData.CameraEntityProxy, container.CharacterContainer.CharacterObject, componentsContainer.ComponentPoolsRegistry, container.assetsProvisioner, container.CacheCleaner, exposedGlobalDataContainer.ExposedCameraData, container.SceneRestrictionBusController, web3IdentityProvider),
new InteractionsAudioPlugin(container.assetsProvisioner),
new MapPinPlugin(globalWorld, container.FeatureFlagsCache),
diff --git a/Explorer/Assets/Scripts/Global/Tests/PlayMode/Integration Tests Global Container.asset b/Explorer/Assets/Scripts/Global/Tests/PlayMode/Integration Tests Global Container.asset
index 94800bf986..b3a0c2c17a 100644
--- a/Explorer/Assets/Scripts/Global/Tests/PlayMode/Integration Tests Global Container.asset
+++ b/Explorer/Assets/Scripts/Global/Tests/PlayMode/Integration Tests Global Container.asset
@@ -51,6 +51,11 @@ MonoBehaviour:
m_SubObjectName:
m_SubObjectType:
m_EditorAssetChanged: 0
+ k__BackingField:
+ m_AssetGUID: 12f48d0297bd3f746b92a97878478086
+ m_SubObjectName:
+ m_SubObjectType:
+ m_EditorAssetChanged: 0
k__BackingField:
m_AssetGUID: 0703f7736b8c9b244953ae7c6ff9a037
m_SubObjectName:
@@ -64,16 +69,6 @@ MonoBehaviour:
- rid: 6784895265395441664
type: {class: StaticSettings, ns: DCL.PluginSystem.Global, asm: DCL.Plugins}
data:
- k__BackingField:
- m_AssetGUID: 0dd75559898ca8d4db9fc8ab99ac2269
- m_SubObjectName:
- m_SubObjectType:
- m_EditorAssetChanged: 0
- k__BackingField:
- m_AssetGUID: 6c1c35a66af59874a8373ebcd51572a4
- m_SubObjectName:
- m_SubObjectType:
- m_EditorAssetChanged: 0
k__BackingField:
m_AssetGUID: 8d266ff458e71f2439f9c30bd7e68d4a
m_SubObjectName:
@@ -84,9 +79,11 @@ MonoBehaviour:
m_SubObjectName:
m_SubObjectType:
m_EditorAssetChanged: 0
- k__BackingField: 33
+ frameTimeCap: 33
+ frameTimeCapDeepProfiler: 300
k__BackingField: 100
k__BackingField: 50
+ k__BackingField: 20
- rid: 6784895265412481024
type: {class: CharacterCameraSettings, ns: DCL.PluginSystem.Global, asm: DCL.Plugins}
data:
@@ -100,6 +97,11 @@ MonoBehaviour:
m_SubObjectName:
m_SubObjectType:
m_EditorAssetChanged: 0
+ k__BackingField:
+ m_AssetGUID:
+ m_SubObjectName:
+ m_SubObjectType:
+ m_EditorAssetChanged: 0
- rid: 6784895265412481025
type: {class: CharacterMotionSettings, ns: DCL.PluginSystem.Global, asm: DCL.Plugins}
data:
diff --git a/Explorer/Assets/Scripts/Global/Tests/PlayMode/Integration Tests World Container.asset b/Explorer/Assets/Scripts/Global/Tests/PlayMode/Integration Tests World Container.asset
index 33b7dcd92c..c45f98717d 100644
--- a/Explorer/Assets/Scripts/Global/Tests/PlayMode/Integration Tests World Container.asset
+++ b/Explorer/Assets/Scripts/Global/Tests/PlayMode/Integration Tests World Container.asset
@@ -34,6 +34,11 @@ MonoBehaviour:
m_SubObjectName:
m_SubObjectType:
m_EditorAssetChanged: 0
+ VideoPrioritizationSettings:
+ m_AssetGUID: 12f48d0297bd3f746b92a97878478086
+ m_SubObjectName:
+ m_SubObjectType:
+ m_EditorAssetChanged: 0
- rid: 758312634468794373
type: {class: AudioSourcesPlugin/AudioSourcesPluginSettings, ns: DCL.PluginSystem.World, asm: DCL.Plugins}
data:
diff --git a/Explorer/ProjectSettings/QualitySettings.asset b/Explorer/ProjectSettings/QualitySettings.asset
index d60851f79e..34673fac21 100644
--- a/Explorer/ProjectSettings/QualitySettings.asset
+++ b/Explorer/ProjectSettings/QualitySettings.asset
@@ -4,7 +4,7 @@
QualitySettings:
m_ObjectHideFlags: 0
serializedVersion: 5
- m_CurrentQuality: 0
+ m_CurrentQuality: 2
m_QualitySettings:
- serializedVersion: 3
name: Low
@@ -30,7 +30,7 @@ QualitySettings:
useLegacyDetailDistribution: 0
vSyncCount: 0
realtimeGICPUUsage: 25
- lodBias: 0.75
+ lodBias: 1
maximumLODLevel: 0
enableLODCrossFade: 1
streamingMipmapsActive: 1
@@ -47,9 +47,9 @@ QualitySettings:
customRenderPipeline: {fileID: 11400000, guid: 362b7d6d8bc7d8a4caba9aa7515a5f6d, type: 2}
terrainQualityOverrides: 12
terrainPixelError: 1
- terrainDetailDensityScale: 0.3
+ terrainDetailDensityScale: 0.7
terrainBasemapDistance: 1000
- terrainDetailDistance: 75
+ terrainDetailDistance: 150
terrainTreeDistance: 5000
terrainBillboardStart: 50
terrainFadeLength: 5
@@ -79,7 +79,7 @@ QualitySettings:
useLegacyDetailDistribution: 1
vSyncCount: 0
realtimeGICPUUsage: 25
- lodBias: 1.25
+ lodBias: 1
maximumLODLevel: 0
enableLODCrossFade: 1
streamingMipmapsActive: 1
@@ -96,9 +96,9 @@ QualitySettings:
customRenderPipeline: {fileID: 11400000, guid: c7655666771b41447aa2994cf82e2fc7, type: 2}
terrainQualityOverrides: 0
terrainPixelError: 1
- terrainDetailDensityScale: 1
+ terrainDetailDensityScale: 0.7
terrainBasemapDistance: 1000
- terrainDetailDistance: 300
+ terrainDetailDistance: 150
terrainTreeDistance: 5000
terrainBillboardStart: 50
terrainFadeLength: 5