Mount provider-owned Eve UI in playable worlds
This commit is contained in:
parent
4439054977
commit
691c75dfa9
9 changed files with 113 additions and 3 deletions
|
|
@ -5,7 +5,12 @@ interactive worlds.
|
|||
|
||||
Providers implement the surface-document, asset-manifest, command-sink, and
|
||||
receipt-source ports. `EveUnityPlayableWorldClientBootstrap` wires those ports
|
||||
to the generic scene host, input driver, camera rig, and `GameObject` sink.
|
||||
to the generic scene host, input driver, camera rig, `GameObject` sink, and UI
|
||||
Toolkit surface overlay. The overlay lowers provider-owned panes, metrics,
|
||||
progress, inventory, and controls from the same Eve document used by the scene.
|
||||
Stable structures update their native controls in place; only structural
|
||||
changes rebuild the visual tree. Scene, field, and reactive render subtrees are
|
||||
owned by their native lowerers and are not duplicated into empty UI elements.
|
||||
|
||||
`EveUnityCultMeshPlayableWorldProvider` is the runtime composition root for a
|
||||
networked client. Give it one Verse rendezvous endpoint and it discovers an
|
||||
|
|
|
|||
|
|
@ -121,6 +121,9 @@ namespace GameCult.Eve.UnityScene
|
|||
var actionBar = GetComponent<EveUnityInputActionBar>();
|
||||
if (actionBar == null) actionBar = gameObject.AddComponent<EveUnityInputActionBar>();
|
||||
actionBar.Bind(this);
|
||||
var uiOverlay = GetComponent<EveUnityUiToolkitOverlay>();
|
||||
if (uiOverlay == null) uiOverlay = gameObject.AddComponent<EveUnityUiToolkitOverlay>();
|
||||
uiOverlay.Bind(providerSurfaceDocuments!, commandSink!);
|
||||
|
||||
var presentation = Runtime.Connect();
|
||||
ConnectionEpoch++;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,87 @@
|
|||
using System;
|
||||
using GameCult.Eve.UnityUIToolkit;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UIElements;
|
||||
|
||||
#nullable enable
|
||||
|
||||
namespace GameCult.Eve.UnityScene
|
||||
{
|
||||
public sealed class EveUnityUiToolkitOverlay : MonoBehaviour
|
||||
{
|
||||
private IEveUnitySceneProviderSurfaceDocumentSource? _documents;
|
||||
private IEveUnitySceneCommandSink? _commands;
|
||||
private UIDocument? _document;
|
||||
private EveUiToolkitSurfacePresenter? _presenter;
|
||||
private VisualElement? _mountedRoot;
|
||||
|
||||
public VisualElement? Root => _mountedRoot;
|
||||
|
||||
public void Bind(MonoBehaviour documentSource, MonoBehaviour commandSink)
|
||||
{
|
||||
if (documentSource is not IEveUnitySceneProviderSurfaceDocumentSource documents)
|
||||
throw new ArgumentException(
|
||||
$"{nameof(documentSource)} must implement {nameof(IEveUnitySceneProviderSurfaceDocumentSource)}.",
|
||||
nameof(documentSource));
|
||||
if (commandSink is not IEveUnitySceneCommandSink commands)
|
||||
throw new ArgumentException(
|
||||
$"{nameof(commandSink)} must implement {nameof(IEveUnitySceneCommandSink)}.",
|
||||
nameof(commandSink));
|
||||
|
||||
Unsubscribe();
|
||||
_documents = documents;
|
||||
_commands = commands;
|
||||
_documents.DocumentAvailable += OnDocumentAvailable;
|
||||
EnsureDocument();
|
||||
Present(_documents.CurrentDocument);
|
||||
}
|
||||
|
||||
private void OnDestroy() => Unsubscribe();
|
||||
|
||||
private void OnDocumentAvailable(EveUnitySceneProviderSurfaceDocument document) => Present(document);
|
||||
|
||||
private void Present(EveUnitySceneProviderSurfaceDocument document)
|
||||
{
|
||||
if (document == null || _commands == null) return;
|
||||
_presenter ??= new EveUiToolkitSurfacePresenter();
|
||||
var replaced = _presenter.Present(document.SurfaceDocument, _commands.Submit);
|
||||
if (replaced && _presenter.Root != null)
|
||||
{
|
||||
_mountedRoot?.RemoveFromHierarchy();
|
||||
_mountedRoot = _presenter.Root;
|
||||
_mountedRoot.AddToClassList("eve-playable-world-ui-overlay");
|
||||
}
|
||||
AttachToDocument();
|
||||
}
|
||||
|
||||
private void EnsureDocument()
|
||||
{
|
||||
_document = GetComponent<UIDocument>();
|
||||
if (_document != null) return;
|
||||
var panel = ScriptableObject.CreateInstance<PanelSettings>();
|
||||
panel.name = "Eve playable-world surface panel";
|
||||
panel.scaleMode = PanelScaleMode.ScaleWithScreenSize;
|
||||
panel.referenceResolution = new Vector2Int(1920, 1080);
|
||||
panel.match = 0.5f;
|
||||
_document = gameObject.AddComponent<UIDocument>();
|
||||
_document.panelSettings = panel;
|
||||
_document.sortingOrder = 100;
|
||||
}
|
||||
|
||||
private void AttachToDocument()
|
||||
{
|
||||
EnsureDocument();
|
||||
var documentRoot = _document?.rootVisualElement;
|
||||
if (_mountedRoot != null && _mountedRoot.parent == null && documentRoot != null)
|
||||
documentRoot.Add(_mountedRoot);
|
||||
}
|
||||
|
||||
private void Unsubscribe()
|
||||
{
|
||||
if (_documents != null)
|
||||
_documents.DocumentAvailable -= OnDocumentAvailable;
|
||||
_documents = null;
|
||||
_commands = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 843283a94b8a41bab85db52bd84aa59a
|
||||
|
|
@ -4,6 +4,7 @@
|
|||
"references": [
|
||||
"GameCult.Eve.Surface",
|
||||
"GameCult.Eve.PluginFields",
|
||||
"GameCult.Eve.UnityUIToolkit",
|
||||
"Unity.Mathematics",
|
||||
"Unity.RenderPipelines.Core.Runtime",
|
||||
"Unity.RenderPipelines.Universal.Runtime"
|
||||
|
|
|
|||
|
|
@ -1098,6 +1098,8 @@ namespace GameCult.Eve.UnityScene.Tests
|
|||
Assert.That(bootstrap.SceneRoot!.childCount, Is.EqualTo(3));
|
||||
Assert.That(hostObject.GetComponent<EveUnityPlayableWorldInputDriver>(), Is.Not.Null);
|
||||
Assert.That(hostObject.GetComponent<EveUnityPlayableWorldCameraRig>(), Is.Not.Null);
|
||||
Assert.That(hostObject.GetComponent<EveUnityUiToolkitOverlay>(), Is.Not.Null);
|
||||
Assert.That(hostObject.GetComponent<EveUnityUiToolkitOverlay>().Root, Is.Not.Null);
|
||||
Assert.That(bootstrap.CameraTransform, Is.Not.Null);
|
||||
Assert.That(provider.RefreshCount, Is.EqualTo(1));
|
||||
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@
|
|||
"GameCult.Eve.Surface",
|
||||
"GameCult.Eve.UnityScene",
|
||||
"GameCult.Eve.UnityScene.CultMesh",
|
||||
"GameCult.Eve.UnityUIToolkit",
|
||||
"GameCult.Eve.PluginFields",
|
||||
"Unity.RenderPipelines.Core.Runtime",
|
||||
"Unity.RenderPipelines.Universal.Runtime"
|
||||
|
|
|
|||
|
|
@ -113,6 +113,7 @@
|
|||
"packages/org.gamecult.eve.unity-scene/Runtime/EveUnityPlayableWorldLiveClient.cs",
|
||||
"packages/org.gamecult.eve.unity-scene/Runtime/EveUnityPlayableWorldRuntime.cs",
|
||||
"packages/org.gamecult.eve.unity-scene/Runtime/EveUnityPlayableWorldClientHost.cs",
|
||||
"packages/org.gamecult.eve.unity-scene/Runtime/EveUnityUiToolkitOverlay.cs",
|
||||
"packages/org.gamecult.eve.unity-scene/Runtime/EveUnityPlayableWorldClientBootstrap.cs",
|
||||
"packages/org.gamecult.eve.unity-scene/Runtime/EveUnityPlayableWorldInputDriver.cs",
|
||||
"packages/org.gamecult.eve.unity-scene/Runtime/EveUnityPlayableWorldCameraRig.cs",
|
||||
|
|
@ -159,10 +160,17 @@
|
|||
"requiredPackageDependencies": [
|
||||
{
|
||||
"packageName": "org.gamecult.eve.surface",
|
||||
"version": "0.1.0",
|
||||
"version": "0.2.4",
|
||||
"packageManager": "upm",
|
||||
"ownerRepo": "EveUnity",
|
||||
"purpose": "Shared Unity DTOs for gamecult.eve.surface.v1 documents."
|
||||
},
|
||||
{
|
||||
"packageName": "org.gamecult.eve.unity-uitoolkit",
|
||||
"version": "0.1.2",
|
||||
"packageManager": "upm",
|
||||
"ownerRepo": "EveUnity",
|
||||
"purpose": "Generic UI Toolkit lowering for provider-owned Eve panes, metrics, progress, text, and controls."
|
||||
}
|
||||
]
|
||||
},
|
||||
|
|
|
|||
|
|
@ -1,13 +1,14 @@
|
|||
{
|
||||
"name": "org.gamecult.eve.unity-scene",
|
||||
"displayName": "Eve Unity Scene Lowering",
|
||||
"version": "0.3.100",
|
||||
"version": "0.3.101",
|
||||
"unity": "6000.0",
|
||||
"description": "Provider-agnostic Unity scene shell for gamecult.eve.surface.v1 interactive world surfaces.",
|
||||
"dependencies": {
|
||||
"org.gamecult.cultlib": "1.0.43",
|
||||
"org.gamecult.eve.plugin-fields": "0.2.3",
|
||||
"org.gamecult.eve.surface": "0.2.4",
|
||||
"org.gamecult.eve.unity-uitoolkit": "0.1.2",
|
||||
"com.unity.mathematics": "1.3.2",
|
||||
"com.unity.render-pipelines.universal": "17.4.0",
|
||||
"com.unity.modules.particlesystem": "1.0.0"
|
||||
|
|
|
|||
Reference in a new issue