Lower authoritative pilot aim in generic worlds
This commit is contained in:
parent
4b1f0be605
commit
3075f71ece
15 changed files with 405 additions and 3 deletions
|
|
@ -0,0 +1,49 @@
|
|||
using System;
|
||||
using System.Globalization;
|
||||
|
||||
#nullable enable
|
||||
|
||||
namespace GameCult.Eve.UnityScene
|
||||
{
|
||||
public sealed class EveUnityAimPresentation
|
||||
{
|
||||
public EveUnityAimPresentation(EveUnitySceneNode node)
|
||||
{
|
||||
if (node == null) throw new ArgumentNullException(nameof(node));
|
||||
ControlledEntityId = Get(node, "controlledEntityId");
|
||||
ConvergenceTargetEntityId = Get(node, "convergenceTargetEntityId");
|
||||
ViewDotRole = Get(node, "viewDotRole");
|
||||
MinimumConvergenceDistance = Math.Max(0.01f, Number(node, "minimumConvergenceDistance", 50f));
|
||||
ViewDotRadius = Math.Max(0.01f, Number(node, "viewDotRadius", 0.8f));
|
||||
}
|
||||
|
||||
public string ControlledEntityId { get; }
|
||||
public string ConvergenceTargetEntityId { get; }
|
||||
public string ViewDotRole { get; }
|
||||
public float MinimumConvergenceDistance { get; }
|
||||
public float ViewDotRadius { get; }
|
||||
|
||||
public static EveUnityAimPresentation? Find(EveUnitySceneProjection? projection) =>
|
||||
projection == null ? null : Find(projection.Root);
|
||||
|
||||
private static EveUnityAimPresentation? Find(EveUnitySceneNode node)
|
||||
{
|
||||
if (string.Equals(node.ComponentKind, "aim.presentation", StringComparison.Ordinal))
|
||||
return new EveUnityAimPresentation(node);
|
||||
foreach (var child in node.Children)
|
||||
{
|
||||
var found = Find(child);
|
||||
if (found != null) return found;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static string Get(EveUnitySceneNode node, string key) =>
|
||||
node.Props.TryGetValue(key, out var value) ? value ?? "" : "";
|
||||
|
||||
private static float Number(EveUnitySceneNode node, string key, float fallback) =>
|
||||
float.TryParse(Get(node, key), NumberStyles.Float, CultureInfo.InvariantCulture, out var value)
|
||||
? value
|
||||
: fallback;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
fileFormatVersion: 2
|
||||
guid: f859926d39664cefa5aa96ed3c2d8903
|
||||
|
|
@ -0,0 +1,136 @@
|
|||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
#nullable enable
|
||||
|
||||
namespace GameCult.Eve.UnityScene
|
||||
{
|
||||
public sealed class EveUnityAimPresentationRenderer : MonoBehaviour
|
||||
{
|
||||
[SerializeField] private Color viewDotColor = new Color(0.35f, 0.95f, 1f, 0.95f);
|
||||
[SerializeField] private float width = 0.1f;
|
||||
|
||||
private EveUnityPlayableWorldClientHost? _host;
|
||||
private LineRenderer? _ring;
|
||||
private LineRenderer? _horizontal;
|
||||
private LineRenderer? _vertical;
|
||||
private Material? _material;
|
||||
|
||||
public EveUnityAimPresentation? Current { get; private set; }
|
||||
public bool ViewDotVisible => _ring != null && _ring.enabled;
|
||||
public Vector3 ViewDotPosition { get; private set; }
|
||||
|
||||
public void Bind(EveUnityPlayableWorldClientHost host)
|
||||
{
|
||||
_host = host != null ? host : throw new ArgumentNullException(nameof(host));
|
||||
}
|
||||
|
||||
public void RefreshNow()
|
||||
{
|
||||
Current = EveUnityAimPresentation.Find(_host?.ActiveProjection);
|
||||
if (Current == null || string.IsNullOrWhiteSpace(Current.ControlledEntityId))
|
||||
{
|
||||
SetVisible(false);
|
||||
return;
|
||||
}
|
||||
|
||||
var controlled = FindMarker(Current.ControlledEntityId);
|
||||
if (controlled == null)
|
||||
{
|
||||
SetVisible(false);
|
||||
return;
|
||||
}
|
||||
|
||||
var distance = Current.MinimumConvergenceDistance;
|
||||
var target = FindMarker(Current.ConvergenceTargetEntityId);
|
||||
if (target != null)
|
||||
distance = Mathf.Max(distance, Vector3.Distance(controlled.transform.position, target.transform.position));
|
||||
var forward = controlled.transform.forward;
|
||||
forward.y = 0f;
|
||||
if (forward.sqrMagnitude <= 0.0001f) forward = Vector3.forward;
|
||||
forward.Normalize();
|
||||
ViewDotPosition = controlled.transform.position + forward * distance;
|
||||
|
||||
EnsureVisuals();
|
||||
var camera = Camera.main;
|
||||
var right = camera == null ? Vector3.right : camera.transform.right;
|
||||
var up = camera == null ? Vector3.up : camera.transform.up;
|
||||
var center = ViewDotPosition + (camera == null ? Vector3.zero : -camera.transform.forward * 0.1f);
|
||||
Ring(_ring!, center, right, up, Current.ViewDotRadius);
|
||||
Segment(_horizontal!, center, right, Current.ViewDotRadius * 1.6f);
|
||||
Segment(_vertical!, center, up, Current.ViewDotRadius * 1.6f);
|
||||
SetVisible(true);
|
||||
}
|
||||
|
||||
private void LateUpdate() => RefreshNow();
|
||||
|
||||
private EveUnityPlayableWorldEntityMarker? FindMarker(string entityId)
|
||||
{
|
||||
if (_host == null || string.IsNullOrWhiteSpace(entityId)) return null;
|
||||
foreach (var marker in _host.SceneRoot.GetComponentsInChildren<EveUnityPlayableWorldEntityMarker>(true))
|
||||
if (string.Equals(marker.EntityId, entityId, StringComparison.Ordinal)) return marker;
|
||||
return null;
|
||||
}
|
||||
|
||||
private void EnsureVisuals()
|
||||
{
|
||||
if (_ring != null) return;
|
||||
var root = new GameObject("Eve aim presentation");
|
||||
root.transform.SetParent(transform, false);
|
||||
_ring = Line(root.transform, "View direction ring");
|
||||
_horizontal = Line(root.transform, "View direction horizontal");
|
||||
_vertical = Line(root.transform, "View direction vertical");
|
||||
}
|
||||
|
||||
private LineRenderer Line(Transform parent, string name)
|
||||
{
|
||||
var child = new GameObject(name);
|
||||
child.transform.SetParent(parent, false);
|
||||
var line = child.AddComponent<LineRenderer>();
|
||||
line.useWorldSpace = true;
|
||||
line.material = SharedMaterial();
|
||||
line.startColor = line.endColor = viewDotColor;
|
||||
line.startWidth = line.endWidth = Mathf.Max(0.01f, width);
|
||||
line.numCapVertices = 2;
|
||||
return line;
|
||||
}
|
||||
|
||||
private Material SharedMaterial()
|
||||
{
|
||||
if (_material != null) return _material;
|
||||
var shader = Shader.Find("Sprites/Default") ?? Shader.Find("Universal Render Pipeline/Unlit");
|
||||
if (shader == null) throw new InvalidOperationException("EveUnity requires an unlit shader for aim presentation.");
|
||||
return _material = new Material(shader) { name = "EveUnity aim presentation" };
|
||||
}
|
||||
|
||||
private static void Ring(LineRenderer line, Vector3 center, Vector3 right, Vector3 up, float radius)
|
||||
{
|
||||
const int segments = 33;
|
||||
line.positionCount = segments;
|
||||
for (var index = 0; index < segments; index++)
|
||||
{
|
||||
var angle = index / (float)(segments - 1) * Mathf.PI * 2f;
|
||||
line.SetPosition(index, center + right * (Mathf.Cos(angle) * radius) + up * (Mathf.Sin(angle) * radius));
|
||||
}
|
||||
}
|
||||
|
||||
private static void Segment(LineRenderer line, Vector3 center, Vector3 axis, float radius)
|
||||
{
|
||||
line.positionCount = 2;
|
||||
line.SetPosition(0, center - axis * radius);
|
||||
line.SetPosition(1, center + axis * radius);
|
||||
}
|
||||
|
||||
private void SetVisible(bool visible)
|
||||
{
|
||||
if (_ring != null) _ring.enabled = visible;
|
||||
if (_horizontal != null) _horizontal.enabled = visible;
|
||||
if (_vertical != null) _vertical.enabled = visible;
|
||||
}
|
||||
|
||||
private void OnDestroy()
|
||||
{
|
||||
if (_material != null) Destroy(_material);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 97c7b809756a4350a6e61c67bba69b82
|
||||
|
|
@ -95,6 +95,9 @@ namespace GameCult.Eve.UnityScene
|
|||
var combatPresentation = GetComponent<EveUnityCombatPresentationRenderer>();
|
||||
if (combatPresentation == null) combatPresentation = gameObject.AddComponent<EveUnityCombatPresentationRenderer>();
|
||||
combatPresentation.Bind(this);
|
||||
var aimPresentation = GetComponent<EveUnityAimPresentationRenderer>();
|
||||
if (aimPresentation == null) aimPresentation = gameObject.AddComponent<EveUnityAimPresentationRenderer>();
|
||||
aimPresentation.Bind(this);
|
||||
var thermal = GetComponent<EveUnityThermalPresenter>();
|
||||
var thermalHud = GetComponent<EveUnityThermalHudSink>();
|
||||
if (thermalHud == null) thermalHud = gameObject.AddComponent<EveUnityThermalHudSink>();
|
||||
|
|
@ -135,6 +138,16 @@ namespace GameCult.Eve.UnityScene
|
|||
return RequireRuntime().SubmitMoveVectorIntent(entityId, directionX, directionY, scalarValue, issuedAt);
|
||||
}
|
||||
|
||||
public EveSurfaceCommandRequest SubmitLookDirectionIntent(
|
||||
string entityId,
|
||||
float directionX,
|
||||
float directionY,
|
||||
float directionZ,
|
||||
DateTimeOffset? issuedAt = null)
|
||||
{
|
||||
return RequireRuntime().SubmitLookDirectionIntent(entityId, directionX, directionY, directionZ, issuedAt);
|
||||
}
|
||||
|
||||
public EveSurfaceCommandRequest SubmitFocusIntent(
|
||||
string entityId,
|
||||
DateTimeOffset? issuedAt = null)
|
||||
|
|
|
|||
|
|
@ -20,12 +20,16 @@ namespace GameCult.Eve.UnityScene
|
|||
[SerializeField] private string horizontalAxis = "Horizontal";
|
||||
[SerializeField] private string verticalAxis = "Vertical";
|
||||
[SerializeField] private string actionButton = "Fire1";
|
||||
[SerializeField] private string lookHorizontalAxis = "Mouse X";
|
||||
[SerializeField] private float defaultLookSensitivityRadians = 0.001f;
|
||||
[SerializeField] private float deadZone = 0.01f;
|
||||
[SerializeField] private float commandIntervalSeconds = 0.05f;
|
||||
[SerializeField] private bool submitZeroOnRelease = true;
|
||||
|
||||
private float _nextCommandAt;
|
||||
private bool _wasMoving;
|
||||
private float _lookYawRadians;
|
||||
private bool _hasLookYaw;
|
||||
|
||||
public EveUnityPlayableWorldClientHost? Host
|
||||
{
|
||||
|
|
@ -94,6 +98,34 @@ namespace GameCult.Eve.UnityScene
|
|||
resolvedActionId);
|
||||
}
|
||||
|
||||
public EveSurfaceCommandRequest? SubmitLookInput(
|
||||
float horizontalDelta,
|
||||
DateTimeOffset? issuedAt = null)
|
||||
{
|
||||
var resolvedHost = ResolveHost();
|
||||
var world = resolvedHost?.ActiveWorld;
|
||||
if (world == null || string.IsNullOrWhiteSpace(world.LookCommand) ||
|
||||
Mathf.Abs(horizontalDelta) <= 0.0001f)
|
||||
return null;
|
||||
|
||||
if (!_hasLookYaw)
|
||||
{
|
||||
_lookYawRadians = ResolveControlledYawRadians(resolvedHost!, world.PlayerEntityId);
|
||||
_hasLookYaw = true;
|
||||
}
|
||||
var sensitivity = Mathf.Abs(world.LookSensitivityRadians) > 0.000001f
|
||||
? world.LookSensitivityRadians
|
||||
: defaultLookSensitivityRadians;
|
||||
_lookYawRadians += horizontalDelta * sensitivity;
|
||||
var direction = EveUnityPlayableWorldLookDirection.FromPlanarYaw(_lookYawRadians);
|
||||
return resolvedHost!.SubmitLookDirectionIntent(
|
||||
world.PlayerEntityId,
|
||||
direction.DirectionX,
|
||||
0f,
|
||||
direction.DirectionZ,
|
||||
issuedAt);
|
||||
}
|
||||
|
||||
public static string ResolvePrimaryActionId(EveInputCapabilityDocument? capability)
|
||||
{
|
||||
if (capability == null)
|
||||
|
|
@ -121,6 +153,8 @@ namespace GameCult.Eve.UnityScene
|
|||
|
||||
_nextCommandAt = Time.unscaledTime + Math.Max(0.01f, commandIntervalSeconds);
|
||||
SubmitMoveVectorInput(Input.GetAxisRaw(horizontalAxis), Input.GetAxisRaw(verticalAxis));
|
||||
if (!string.IsNullOrWhiteSpace(lookHorizontalAxis))
|
||||
SubmitLookInput(Input.GetAxisRaw(lookHorizontalAxis));
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(actionButton) && Input.GetButtonDown(actionButton))
|
||||
SubmitPrimaryAction();
|
||||
|
|
@ -134,6 +168,29 @@ namespace GameCult.Eve.UnityScene
|
|||
host = GetComponent<EveUnityPlayableWorldClientHost>();
|
||||
return host;
|
||||
}
|
||||
|
||||
private static float ResolveControlledYawRadians(EveUnityPlayableWorldClientHost host, string entityId)
|
||||
{
|
||||
foreach (var marker in host.SceneRoot.GetComponentsInChildren<EveUnityPlayableWorldEntityMarker>(true))
|
||||
if (string.Equals(marker.EntityId, entityId, StringComparison.Ordinal))
|
||||
return marker.transform.eulerAngles.y * Mathf.Deg2Rad;
|
||||
return 0f;
|
||||
}
|
||||
}
|
||||
|
||||
public readonly struct EveUnityPlayableWorldLookDirection
|
||||
{
|
||||
public EveUnityPlayableWorldLookDirection(float directionX, float directionZ)
|
||||
{
|
||||
DirectionX = directionX;
|
||||
DirectionZ = directionZ;
|
||||
}
|
||||
|
||||
public float DirectionX { get; }
|
||||
public float DirectionZ { get; }
|
||||
|
||||
public static EveUnityPlayableWorldLookDirection FromPlanarYaw(float yawRadians) =>
|
||||
new EveUnityPlayableWorldLookDirection(Mathf.Sin(yawRadians), Mathf.Cos(yawRadians));
|
||||
}
|
||||
|
||||
public readonly struct EveUnityPlayableWorldMoveVector
|
||||
|
|
|
|||
|
|
@ -88,6 +88,16 @@ namespace GameCult.Eve.UnityScene
|
|||
return _connection.SubmitMoveVectorIntent(entityId, directionX, directionY, scalarValue, issuedAt);
|
||||
}
|
||||
|
||||
public EveSurfaceCommandRequest SubmitLookDirectionIntent(
|
||||
string entityId,
|
||||
float directionX,
|
||||
float directionY,
|
||||
float directionZ,
|
||||
DateTimeOffset? issuedAt = null)
|
||||
{
|
||||
return _connection.SubmitLookDirectionIntent(entityId, directionX, directionY, directionZ, issuedAt);
|
||||
}
|
||||
|
||||
public EveSurfaceCommandRequest SubmitFocusIntent(
|
||||
string entityId,
|
||||
DateTimeOffset? issuedAt = null)
|
||||
|
|
|
|||
|
|
@ -143,6 +143,16 @@ namespace GameCult.Eve.UnityScene
|
|||
return _client.SubmitMoveVectorIntent(entityId, directionX, directionY, scalarValue, issuedAt);
|
||||
}
|
||||
|
||||
public EveSurfaceCommandRequest SubmitLookDirectionIntent(
|
||||
string entityId,
|
||||
float directionX,
|
||||
float directionY,
|
||||
float directionZ,
|
||||
DateTimeOffset? issuedAt = null)
|
||||
{
|
||||
return _client.SubmitLookDirectionIntent(entityId, directionX, directionY, directionZ, issuedAt);
|
||||
}
|
||||
|
||||
public EveSurfaceCommandRequest SubmitFocusIntent(
|
||||
string entityId,
|
||||
DateTimeOffset? issuedAt = null)
|
||||
|
|
|
|||
|
|
@ -83,6 +83,26 @@ namespace GameCult.Eve.UnityScene
|
|||
issuedAt);
|
||||
}
|
||||
|
||||
public EveSurfaceCommandRequest CreateLookDirectionIntent(
|
||||
string entityId,
|
||||
float directionX,
|
||||
float directionY,
|
||||
float directionZ,
|
||||
DateTimeOffset? issuedAt = null)
|
||||
{
|
||||
var playableWorld = RequirePlayableWorld();
|
||||
return CreatePlayableWorldIntent(
|
||||
playableWorld.LookCommand,
|
||||
new Dictionary<string, string>(StringComparer.Ordinal)
|
||||
{
|
||||
["entityId"] = entityId ?? "",
|
||||
["directionX"] = FormatFloat(directionX),
|
||||
["directionY"] = FormatFloat(directionY),
|
||||
["directionZ"] = FormatFloat(directionZ)
|
||||
},
|
||||
issuedAt);
|
||||
}
|
||||
|
||||
public EveSurfaceCommandRequest CreateFocusIntent(
|
||||
string entityId,
|
||||
DateTimeOffset? issuedAt = null)
|
||||
|
|
|
|||
|
|
@ -221,6 +221,16 @@ namespace GameCult.Eve.UnityScene
|
|||
return Submit(_session.CreateMoveVectorIntent(entityId, directionX, directionY, scalarValue, issuedAt));
|
||||
}
|
||||
|
||||
public EveSurfaceCommandRequest SubmitLookDirectionIntent(
|
||||
string entityId,
|
||||
float directionX,
|
||||
float directionY,
|
||||
float directionZ,
|
||||
DateTimeOffset? issuedAt = null)
|
||||
{
|
||||
return Submit(_session.CreateLookDirectionIntent(entityId, directionX, directionY, directionZ, issuedAt));
|
||||
}
|
||||
|
||||
public EveSurfaceCommandRequest SubmitFocusIntent(
|
||||
string entityId,
|
||||
DateTimeOffset? issuedAt = null)
|
||||
|
|
|
|||
|
|
@ -136,7 +136,9 @@ namespace GameCult.Eve.UnityScene
|
|||
ParseVector3(worldRoot.GetProp("ambientLightColor")),
|
||||
ParseFloat(worldRoot.GetProp("ambientLightIntensity"), 1f),
|
||||
ParseFloat(worldRoot.GetProp("cameraNearClipPlane"), 0f),
|
||||
ParseFloat(worldRoot.GetProp("cameraFarClipPlane"), 0f));
|
||||
ParseFloat(worldRoot.GetProp("cameraFarClipPlane"), 0f),
|
||||
worldRoot.GetProp("lookCommand"),
|
||||
ParseFloat(worldRoot.GetProp("lookSensitivityRadians"), 0f));
|
||||
}
|
||||
|
||||
private static EveUnityPlayableWorldEntity BuildPlayableEntity(EveSurfaceComponent component)
|
||||
|
|
@ -357,7 +359,9 @@ namespace GameCult.Eve.UnityScene
|
|||
(float r, float g, float b) ambientLightColor = default,
|
||||
float ambientLightIntensity = 1f,
|
||||
float cameraNearClipPlane = 0f,
|
||||
float cameraFarClipPlane = 0f)
|
||||
float cameraFarClipPlane = 0f,
|
||||
string lookCommand = "",
|
||||
float lookSensitivityRadians = 0f)
|
||||
{
|
||||
WorldRootId = worldRootId ?? "";
|
||||
StatePointerId = statePointerId ?? "";
|
||||
|
|
@ -388,6 +392,8 @@ namespace GameCult.Eve.UnityScene
|
|||
AmbientLightIntensity = ambientLightIntensity;
|
||||
CameraNearClipPlane = cameraNearClipPlane;
|
||||
CameraFarClipPlane = cameraFarClipPlane;
|
||||
LookCommand = lookCommand ?? "";
|
||||
LookSensitivityRadians = lookSensitivityRadians;
|
||||
}
|
||||
|
||||
public string WorldRootId { get; }
|
||||
|
|
@ -438,6 +444,10 @@ namespace GameCult.Eve.UnityScene
|
|||
|
||||
public string MovementCommand { get; }
|
||||
|
||||
public string LookCommand { get; }
|
||||
|
||||
public float LookSensitivityRadians { get; }
|
||||
|
||||
public string FocusCommand { get; }
|
||||
|
||||
public string TargetCommand { get; }
|
||||
|
|
|
|||
|
|
@ -0,0 +1,57 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using NUnit.Framework;
|
||||
using UnityEngine;
|
||||
|
||||
#nullable enable
|
||||
|
||||
namespace GameCult.Eve.UnityScene.Tests
|
||||
{
|
||||
public sealed class EveUnityAimPresentationTests
|
||||
{
|
||||
[Test]
|
||||
public void ProjectionPreservesProviderAimConvergenceSemantic()
|
||||
{
|
||||
var projection = new EveUnitySceneProjection(
|
||||
"provider", "surface", "world", "commands", "receipt", "provider", null,
|
||||
Node("root", "surface", Node("aim", "aim.presentation", new Dictionary<string, string>
|
||||
{
|
||||
["controlledEntityId"] = "run.zone.0.entity.4",
|
||||
["convergenceTargetEntityId"] = "run.zone.0.entity.9",
|
||||
["viewDotRole"] = "aim.marker.view-direction",
|
||||
["minimumConvergenceDistance"] = "50",
|
||||
["viewDotRadius"] = "0.8"
|
||||
})));
|
||||
|
||||
var aim = EveUnityAimPresentation.Find(projection);
|
||||
|
||||
Assert.That(aim, Is.Not.Null);
|
||||
Assert.That(aim!.ControlledEntityId, Is.EqualTo("run.zone.0.entity.4"));
|
||||
Assert.That(aim.ConvergenceTargetEntityId, Is.EqualTo("run.zone.0.entity.9"));
|
||||
Assert.That(aim.MinimumConvergenceDistance, Is.EqualTo(50f));
|
||||
Assert.That(aim.ViewDotRadius, Is.EqualTo(0.8f));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void PlanarYawProducesPortableUnitLookDirection()
|
||||
{
|
||||
var forward = EveUnityPlayableWorldLookDirection.FromPlanarYaw(0f);
|
||||
var right = EveUnityPlayableWorldLookDirection.FromPlanarYaw(Mathf.PI * 0.5f);
|
||||
|
||||
Assert.That(forward.DirectionX, Is.EqualTo(0f).Within(0.0001f));
|
||||
Assert.That(forward.DirectionZ, Is.EqualTo(1f).Within(0.0001f));
|
||||
Assert.That(right.DirectionX, Is.EqualTo(1f).Within(0.0001f));
|
||||
Assert.That(right.DirectionZ, Is.EqualTo(0f).Within(0.0001f));
|
||||
}
|
||||
|
||||
private static EveUnitySceneNode Node(string id, string kind, params EveUnitySceneNode[] children) =>
|
||||
Node(id, kind, Empty(), children);
|
||||
|
||||
private static EveUnitySceneNode Node(string id, string kind, IReadOnlyDictionary<string, string> props, params EveUnitySceneNode[] children) =>
|
||||
new EveUnitySceneNode(id, kind, "scene-node", props, Empty(), Empty(), 0, 0,
|
||||
Array.Empty<EveUnitySceneEmbeddedDocumentSlot>(), null, children);
|
||||
|
||||
private static IReadOnlyDictionary<string, string> Empty() =>
|
||||
new Dictionary<string, string>(StringComparer.Ordinal);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 2bcc030e48554a49accc4efc105c36b4
|
||||
|
|
@ -512,6 +512,18 @@ namespace GameCult.Eve.UnityScene.Tests
|
|||
Assert.That(moveVectorIntent.Payload.GetString("directionX"), Is.EqualTo("0.25"));
|
||||
Assert.That(moveVectorIntent.Payload.GetString("directionY"), Is.EqualTo("0.75"));
|
||||
Assert.That(moveVectorIntent.Payload.GetString("scalarValue"), Is.EqualTo("0.8"));
|
||||
|
||||
var lookIntent = session.CreateLookDirectionIntent(
|
||||
"player-vanguard",
|
||||
0.6f,
|
||||
0f,
|
||||
0.8f,
|
||||
DateTimeOffset.Parse("2026-07-09T00:00:02Z"));
|
||||
Assert.That(lookIntent.Payload.GetString("commandId"), Is.EqualTo("aetheria.daemon.look_intent"));
|
||||
Assert.That(lookIntent.Payload.GetString("entityId"), Is.EqualTo("player-vanguard"));
|
||||
Assert.That(lookIntent.Payload.GetString("directionX"), Is.EqualTo("0.6"));
|
||||
Assert.That(lookIntent.Payload.GetString("directionY"), Is.EqualTo("0"));
|
||||
Assert.That(lookIntent.Payload.GetString("directionZ"), Is.EqualTo("0.8"));
|
||||
}
|
||||
|
||||
[Test]
|
||||
|
|
@ -978,6 +990,16 @@ namespace GameCult.Eve.UnityScene.Tests
|
|||
Assert.That(request.Payload.GetDouble("directionY", 0), Is.EqualTo(0f).Within(0.0001f));
|
||||
Assert.That(request.Payload.GetDouble("scalarValue", 0), Is.EqualTo(1f).Within(0.0001f));
|
||||
|
||||
var controlledYaw = rootObject.GetComponentsInChildren<EveUnityPlayableWorldEntityMarker>(true)
|
||||
.Single(marker => marker.EntityId == "player-vanguard")
|
||||
.transform.eulerAngles.y * Mathf.Deg2Rad;
|
||||
var look = driver.SubmitLookInput(1000f);
|
||||
Assert.That(look, Is.Not.Null);
|
||||
Assert.That(provider.Submitted.Count, Is.EqualTo(2));
|
||||
Assert.That(look!.Payload.GetString("commandId"), Is.EqualTo("aetheria.daemon.look_intent"));
|
||||
Assert.That(look.Payload.GetDouble("directionX", 0), Is.EqualTo(Mathf.Sin(controlledYaw - 1f)).Within(0.0001f));
|
||||
Assert.That(look.Payload.GetDouble("directionZ", 0), Is.EqualTo(Mathf.Cos(controlledYaw - 1f)).Within(0.0001f));
|
||||
|
||||
var movement = EveUnityPlayableWorldMoveVector.FromCameraRelativeInput(1f, 1f, null);
|
||||
Assert.That(movement.HasInput, Is.True);
|
||||
Assert.That(movement.ScalarValue, Is.EqualTo(1f).Within(0.0001f));
|
||||
|
|
@ -1752,6 +1774,8 @@ namespace GameCult.Eve.UnityScene.Tests
|
|||
["excludedRenderChannels"] = "map",
|
||||
["playerEntityId"] = "player-vanguard",
|
||||
["movementCommand"] = "aetheria.daemon.move_intent",
|
||||
["lookCommand"] = "aetheria.daemon.look_intent",
|
||||
["lookSensitivityRadians"] = "-0.001",
|
||||
["focusCommand"] = "aetheria.daemon.focus",
|
||||
["targetCommand"] = "aetheria.daemon.target",
|
||||
["actionCommand"] = "aetheria.daemon.use_equipment"
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"name": "org.gamecult.eve.unity-scene",
|
||||
"displayName": "Eve Unity Scene Lowering",
|
||||
"version": "0.3.23",
|
||||
"version": "0.3.24",
|
||||
"unity": "2021.3",
|
||||
"description": "Provider-agnostic Unity scene shell for gamecult.eve.surface.v1 interactive world surfaces.",
|
||||
"dependencies": {
|
||||
|
|
|
|||
Reference in a new issue