IGrabPresenter.Grab(GrabEvent) only; the binder's Transform and velocity resolvers go. TractorBeam presents a running grab (aims at Started's TargetPosition, emits at Power, dark otherwise). FieldDriver draws its tendril from GrabEvents alone with a real-time phase clock over each event's PhaseDuration and writes no transform and destroys nothing; its grab times move to FieldTester, now the scene's stand-in sim that owns its pickup's timeline and pose. ItemPickup keeps its label lit while held. ImpactPresenterSmoke becomes CapabilityPresentationSmoke with a grab section; its two untracked-ship expectations follow DrawsAt since contact-hud. Builds (Unity 6000.3.24f1 batchmode: smoke ok, scene opens, no missing script). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
51 lines
1.8 KiB
C#
51 lines
1.8 KiB
C#
using System;
|
|
using UnityEngine;
|
|
using CultMath.UnityBridge;
|
|
|
|
// Presents the ship's grab: while the simulation holds an item, the beam looks along the ground-plane vector to the
|
|
// point the item was held from and emits at Power. Zone pulls the held item along the segment from the ship to that
|
|
// point (docs/aetheria-release-map.md L11), which is why GrabEvent.TargetPosition on Started is the exact aim and no
|
|
// pose lookup is needed. Idle, the beam turns with Direction and emits nothing. The simulation decides every grab fact.
|
|
public class TractorBeam : MonoBehaviour, IGrabPresenter
|
|
{
|
|
public ParticleSystem ParticleSystem;
|
|
|
|
public float Power { get; set; }
|
|
public Vector3 Direction { get; set; }
|
|
|
|
private bool _grabbing;
|
|
private Vector3 _heldPoint;
|
|
private Vector3 _heldDirection;
|
|
|
|
// Cancelled can carry no position (a vanished item), so only Started is read for one.
|
|
public void Grab(GrabEvent e)
|
|
{
|
|
switch (e.Phase)
|
|
{
|
|
case GrabPhase.Started:
|
|
_grabbing = true;
|
|
_heldPoint = e.TargetPosition.ToUnity();
|
|
_heldDirection = Direction;
|
|
break;
|
|
case GrabPhase.Completed:
|
|
case GrabPhase.Cancelled:
|
|
_grabbing = false;
|
|
break;
|
|
}
|
|
}
|
|
|
|
public void Update()
|
|
{
|
|
var look = Direction;
|
|
if (_grabbing)
|
|
{
|
|
var toHeld = _heldPoint - transform.position;
|
|
toHeld.y = 0;
|
|
if (toHeld.sqrMagnitude > 1e-6f) _heldDirection = toHeld;
|
|
look = _heldDirection;
|
|
}
|
|
transform.rotation = Quaternion.LookRotation(look);
|
|
var emission = ParticleSystem.emission;
|
|
emission.rateOverTimeMultiplier = _grabbing ? Power : 0;
|
|
}
|
|
}
|