Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enhacement: Show scene limits through debug panel (#1873) #2023

Merged
merged 10 commits into from
Sep 12, 2024
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ public static class Categories
public const string ROOM_SCENE = "Room: Scene";
public const string PERFORMANCE = "Performance";
public const string MEMORY = "Memory";
public const string CURRENT_SCENE = "Current scene";
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,6 @@ MonoBehaviour:
Severity: 0
- Category: ARCHIPELAGO_REQUEST
Severity: 0
- Category: ASSET_BUNDLES
Severity: 0
- Category: ASSETS_PROVISION
Severity: 0
- Category: AUDIO
Expand Down Expand Up @@ -168,8 +166,6 @@ MonoBehaviour:
Severity: 4
- Category: ARCHIPELAGO_REQUEST
Severity: 4
- Category: ASSET_BUNDLES
Severity: 4
- Category: ASSETS_PROVISION
Severity: 4
- Category: AUDIO
Expand Down Expand Up @@ -298,6 +294,10 @@ MonoBehaviour:
Severity: 4
- Category: UNSPECIFIED
Severity: 3
- Category: ASSET_BUNDLES
Severity: 0
- Category: ASSET_BUNDLES
Severity: 4
sentryMatrix:
entries: []
debounceEnabled: 1
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
using Arch.Core;
using Arch.SystemGroups;
using DCL.Character.Components;
using DCL.DebugUtilities;
using DCL.DebugUtilities.UIBindings;
using ECS.Abstract;
using ECS.SceneLifeCycle.CurrentScene;
using UnityEngine;
using UnityEngine.Rendering;
using Utility;

namespace ECS.SceneLifeCycle.Systems
Expand All @@ -23,14 +26,31 @@ public partial class UpdateCurrentSceneSystem : BaseUnityLoopSystem

private readonly SceneAssetLock sceneAssetLock;

internal UpdateCurrentSceneSystem(World world, IRealmData realmData, IScenesCache scenesCache, CurrentSceneInfo currentSceneInfo, Entity playerEntity, SceneAssetLock sceneAssetLock) : base(world)
private IDebugContainerBuilder debugBuilder;
private ElementBinding<string> sceneNameBinding;
private ElementBinding<string> sceneParcelsBinding;
private ElementBinding<string> sceneHeightBinding;
private DebugWidgetVisibilityBinding debugInfoVisibilityBinding;
private bool showDebugCube;
private GameObject sceneBoundsCube;

internal UpdateCurrentSceneSystem(World world, IRealmData realmData, IScenesCache scenesCache, CurrentSceneInfo currentSceneInfo,
Entity playerEntity, SceneAssetLock sceneAssetLock, IDebugContainerBuilder debugBuilder) : base(world)
{
this.realmData = realmData;
this.scenesCache = scenesCache;
this.currentSceneInfo = currentSceneInfo;
this.playerEntity = playerEntity;
this.sceneAssetLock = sceneAssetLock;
ResetProcessedParcel();

debugBuilder.TryAddWidget(IDebugContainerBuilder.Categories.CURRENT_SCENE)?
.SetVisibilityBinding(debugInfoVisibilityBinding = new DebugWidgetVisibilityBinding(true))
.AddCustomMarker("Name:", sceneNameBinding = new ElementBinding<string>(string.Empty))
.AddCustomMarker("Parcels:", sceneParcelsBinding = new ElementBinding<string>(string.Empty))
.AddCustomMarker("Height (m):", sceneHeightBinding = new ElementBinding<string>(string .Empty))
.AddToggleField("Show scene bounds:", (state) => { showDebugCube = state.newValue; }, false);
this.debugBuilder = debugBuilder;
}

private void ResetProcessedParcel()
Expand All @@ -51,6 +71,16 @@ protected override void Update(float t)
UpdateSceneReadiness(parcel);
UpdateCurrentScene(parcel);
UpdateCurrentSceneInfo(parcel);

if (debugBuilder.IsVisible && debugInfoVisibilityBinding.IsExpanded)
RefreshSceneDebugInfo();
}

public override void Dispose()
{
base.Dispose();

GameObject.Destroy(sceneBoundsCube);
}

private void UpdateSceneReadiness(Vector2Int parcel)
Expand All @@ -59,14 +89,14 @@ private void UpdateSceneReadiness(Vector2Int parcel)
return;

sceneAssetLock.TryLock(currentScene);

if (!currentScene.SceneStateProvider.IsCurrent)
currentScene.SetIsCurrent(true);
}

private void UpdateCurrentScene(Vector2Int parcel)
{
if (lastParcelProcessed == parcel) return;

scenesCache.TryGetByParcel(lastParcelProcessed, out var lastProcessedScene);
scenesCache.TryGetByParcel(parcel, out var currentScene);

Expand All @@ -85,5 +115,71 @@ private void UpdateCurrentSceneInfo(Vector2Int parcel)
currentSceneInfo.Update(currentScene);
scenesCache.SetCurrentScene(currentScene);
}

private void RefreshSceneDebugInfo()
{
if (scenesCache.CurrentScene != null)
{
sceneBoundsCube?.SetActive(showDebugCube);

if (sceneNameBinding.Value != scenesCache.CurrentScene.Info.Name)
{
sceneNameBinding.Value = scenesCache.CurrentScene.Info.Name;

if (scenesCache.CurrentScene.SceneData.Parcels != null)
{
sceneParcelsBinding.Value = scenesCache.CurrentScene.SceneData.Parcels.Count.ToString();
}

sceneHeightBinding.Value = scenesCache.CurrentScene.SceneData.Geometry.Height.ToString();

if (sceneBoundsCube == null)
{
sceneBoundsCube = CreateDebugCube();
}

UpdateDebugCube(scenesCache.CurrentScene.SceneData.Geometry, sceneBoundsCube);
}
}
else
{
sceneNameBinding.Value = "<No data>";
sceneParcelsBinding.Value = "<No data>";
sceneHeightBinding.Value = "<No data>";
sceneBoundsCube?.SetActive(false);
}
}

private static GameObject CreateDebugCube()
{
GameObject cube = GameObject.CreatePrimitive(PrimitiveType.Cube);
cube.name = "DebugSceneBoundsCube";

Material cubeMaterial = new Material(Shader.Find("DCL/Scene"));
cubeMaterial.color = new Color(1.0f, 0.0f, 0.0f, 0.8f);
cubeMaterial.SetFloat("_SrcBlend", (int)BlendMode.One);
cubeMaterial.SetFloat("_DstBlend", (int)BlendMode.OneMinusSrcAlpha);
cubeMaterial.SetFloat("_Cull", (int)CullMode.Off);
cubeMaterial.SetFloat("_Surface", 1.0f); // 1 means transparent
cubeMaterial.renderQueue = (int)RenderQueue.Transparent;
cube.GetComponent<MeshRenderer>().material = cubeMaterial;

GameObject.Destroy(cube.GetComponent<Collider>());

cube.SetActive(false);
return cube;
}

private static void UpdateDebugCube(ParcelMathHelper.SceneGeometry sceneGeometry, GameObject cube)
{
// Makes the cube fit the scene bounds
Vector3 cubeSize = new Vector3(sceneGeometry.CircumscribedPlanes.MaxX - sceneGeometry.CircumscribedPlanes.MinX,
sceneGeometry.Height,
sceneGeometry.CircumscribedPlanes.MaxZ - sceneGeometry.CircumscribedPlanes.MinZ);
cube.transform.position = new Vector3(sceneGeometry.CircumscribedPlanes.MinX + cubeSize.x * 0.5f,
cubeSize.y * 0.5f,
sceneGeometry.CircumscribedPlanes.MinZ + cubeSize.z * 0.5f);
cube.transform.localScale = cubeSize;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,7 @@ public GlobalWorld Create(ISceneFactory sceneFactory, V8ActiveEngines v8ActiveEn

OwnAvatarLoaderFromDebugMenuSystem.InjectToWorld(ref builder, playerEntity, debugContainerBuilder, realmData);

UpdateCurrentSceneSystem.InjectToWorld(ref builder, realmData, scenesCache, currentSceneInfo, playerEntity, staticContainer.SingletonSharedDependencies.SceneAssetLock);
UpdateCurrentSceneSystem.InjectToWorld(ref builder, realmData, scenesCache, currentSceneInfo, playerEntity, staticContainer.SingletonSharedDependencies.SceneAssetLock, debugContainerBuilder);

var pluginArgs = new GlobalPluginArguments(playerEntity, v8ActiveEngines);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ public interface ISceneFacade : IUniTaskAsyncDisposable, IDisposable
ISceneStateProvider SceneStateProvider { get; }
SceneEcsExecutor EcsExecutor { get; }
PersistentEntities PersistentEntities { get; }
bool IsEmpty { get; }
ISceneData SceneData { get; }
bool IsEmpty { get; }

void Initialize();

Expand Down
Loading