Keep live entity transforms body-owned
This commit is contained in:
parent
8d0789ba0d
commit
e5556c3194
4 changed files with 65 additions and 6 deletions
|
|
@ -23,14 +23,17 @@ namespace GameCult.Eve.UnityScene
|
|||
{
|
||||
private readonly IEveUnityPlayableWorldSceneSink _sceneSink;
|
||||
private readonly IEveUnityPlayableWorldAssetResolver _assetResolver;
|
||||
private readonly bool _liveEntityBodyOwner;
|
||||
private readonly HashSet<string> _knownEntityIds = new HashSet<string>(StringComparer.Ordinal);
|
||||
|
||||
public EveUnityPlayableWorldPresenter(
|
||||
IEveUnityPlayableWorldSceneSink sceneSink,
|
||||
IEveUnityPlayableWorldAssetResolver assetResolver)
|
||||
IEveUnityPlayableWorldAssetResolver assetResolver,
|
||||
bool liveEntityBodyOwner = false)
|
||||
{
|
||||
_sceneSink = sceneSink ?? throw new ArgumentNullException(nameof(sceneSink));
|
||||
_assetResolver = assetResolver ?? throw new ArgumentNullException(nameof(assetResolver));
|
||||
_liveEntityBodyOwner = liveEntityBodyOwner;
|
||||
}
|
||||
|
||||
public EveUnityPlayableWorldPresentation Apply(EveUnitySceneProjection projection)
|
||||
|
|
@ -46,9 +49,26 @@ namespace GameCult.Eve.UnityScene
|
|||
{
|
||||
if (world == null) throw new ArgumentNullException(nameof(world));
|
||||
|
||||
var nextEntityIds = new HashSet<string>(StringComparer.Ordinal);
|
||||
_sceneSink.ConfigureWorld(world);
|
||||
|
||||
// A world that advertises a live entity body has one transform and
|
||||
// membership owner: the SoA generation presenter. The durable Eve
|
||||
// surface remains configuration/topology and must not periodically
|
||||
// overwrite realtime body state.
|
||||
if (_liveEntityBodyOwner &&
|
||||
(!string.IsNullOrWhiteSpace(world.EntityViewPointerId) ||
|
||||
!string.IsNullOrWhiteSpace(world.EntityBodyId)))
|
||||
return new EveUnityPlayableWorldPresentation(
|
||||
world.WorldRootId,
|
||||
world.PlayerEntityId,
|
||||
world.InputProfile,
|
||||
world.CameraRig,
|
||||
0,
|
||||
0,
|
||||
_knownEntityIds.Count);
|
||||
|
||||
var nextEntityIds = new HashSet<string>(StringComparer.Ordinal);
|
||||
|
||||
var upserted = 0;
|
||||
foreach (var entity in world.Entities)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -41,7 +41,10 @@ namespace GameCult.Eve.UnityScene
|
|||
_connection = new EveUnitySceneProviderConnection(_surfaceSource, commandSink);
|
||||
_client = new EveUnityPlayableWorldLiveClient(
|
||||
_connection,
|
||||
new EveUnityPlayableWorldPresenter(sceneSink, assetResolver ?? new EveUnityAssetRefResolver()),
|
||||
new EveUnityPlayableWorldPresenter(
|
||||
sceneSink,
|
||||
assetResolver ?? new EveUnityAssetRefResolver(),
|
||||
liveEntityBodyOwner: _entityViews != null),
|
||||
receiptSource);
|
||||
|
||||
if (assetManifestDocuments != null)
|
||||
|
|
|
|||
|
|
@ -1856,7 +1856,7 @@ namespace GameCult.Eve.UnityScene.Tests
|
|||
var presenter = new EveUnityPlayableWorldPresenter(sink, new EveUnityAssetRefResolver());
|
||||
|
||||
var firstProjection = lowerer.Lower(PlayableArpgDocument(), Advertisement("aetheria.daemon.game"));
|
||||
var firstPresentation = presenter.Apply(firstProjection);
|
||||
var firstPresentation = presenter.Apply(SnapshotWorld(firstProjection.PlayableWorld!));
|
||||
|
||||
Assert.That(firstPresentation.WorldRootId, Is.EqualTo("aetheria.daemon.game.playable"));
|
||||
Assert.That(firstPresentation.PlayerEntityId, Is.EqualTo("player-vanguard"));
|
||||
|
|
@ -1875,7 +1875,7 @@ namespace GameCult.Eve.UnityScene.Tests
|
|||
var secondProjection = lowerer.Lower(
|
||||
PlayableArpgDocument(includeRaider: false, playerPosition: "5,0,2"),
|
||||
Advertisement("aetheria.daemon.game"));
|
||||
var secondPresentation = presenter.Apply(secondProjection);
|
||||
var secondPresentation = presenter.Apply(SnapshotWorld(secondProjection.PlayableWorld!));
|
||||
|
||||
Assert.That(secondPresentation.UpsertedEntities, Is.EqualTo(2));
|
||||
Assert.That(secondPresentation.RemovedEntities, Is.EqualTo(1));
|
||||
|
|
@ -1888,6 +1888,27 @@ namespace GameCult.Eve.UnityScene.Tests
|
|||
Assert.That(sink.Upserts[3].entity.PositionZ, Is.EqualTo(2f));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void PlayableWorldSurfaceCannotOverwriteLiveBodyEntities()
|
||||
{
|
||||
var projection = new EveUnitySceneSurfaceLowerer()
|
||||
.Lower(PlayableArpgDocument(), Advertisement("aetheria.daemon.game"));
|
||||
var sink = new FakePlayableWorldSceneSink();
|
||||
var presenter = new EveUnityPlayableWorldPresenter(
|
||||
sink,
|
||||
new EveUnityAssetRefResolver(),
|
||||
liveEntityBodyOwner: true);
|
||||
|
||||
var presentation = presenter.Apply(projection);
|
||||
|
||||
Assert.That(projection.PlayableWorld!.EntityBodyId, Is.Not.Empty);
|
||||
Assert.That(sink.ConfiguredWorlds.Count, Is.EqualTo(1));
|
||||
Assert.That(sink.Upserts, Is.Empty);
|
||||
Assert.That(sink.RemovedEntityIds, Is.Empty);
|
||||
Assert.That(presentation.UpsertedEntities, Is.Zero);
|
||||
Assert.That(presentation.RemovedEntities, Is.Zero);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void LivePlayableWorldClientPresentsProviderSnapshotsAndKeepsCommandsProviderOwned()
|
||||
{
|
||||
|
|
@ -2950,6 +2971,21 @@ namespace GameCult.Eve.UnityScene.Tests
|
|||
}
|
||||
}
|
||||
|
||||
private static EveUnityPlayableWorldProjection SnapshotWorld(EveUnityPlayableWorldProjection source) =>
|
||||
new EveUnityPlayableWorldProjection(
|
||||
source.WorldRootId,
|
||||
source.StatePointerId,
|
||||
source.AssetManifest,
|
||||
source.InputProfile,
|
||||
source.CameraRig,
|
||||
source.ViewId,
|
||||
source.PlayerEntityId,
|
||||
source.MovementCommand,
|
||||
source.FocusCommand,
|
||||
source.TargetCommand,
|
||||
source.ActionCommand,
|
||||
source.Entities);
|
||||
|
||||
private static EveUnityPlayableWorldEntity PlayableEntityModel(
|
||||
string entityId,
|
||||
string assetRef,
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"name": "org.gamecult.eve.unity-scene",
|
||||
"displayName": "Eve Unity Scene Lowering",
|
||||
"version": "0.3.103",
|
||||
"version": "0.3.104",
|
||||
"unity": "6000.0",
|
||||
"description": "Provider-agnostic Unity scene shell for gamecult.eve.surface.v1 interactive world surfaces.",
|
||||
"dependencies": {
|
||||
|
|
|
|||
Reference in a new issue