diff --git a/Assets/Scripts/Gameplay/ActionGameManager.cs b/Assets/Scripts/Gameplay/ActionGameManager.cs index b79ed017a..068064cbd 100644 --- a/Assets/Scripts/Gameplay/ActionGameManager.cs +++ b/Assets/Scripts/Gameplay/ActionGameManager.cs @@ -1470,17 +1470,19 @@ public class ActionGameManager : MonoBehaviour else if (target.Entity != null) TargetIndicator.Target = DrawAhead.Position(target.Entity, lead).ToUnity(); var distance = length(ViewDot.Target.ToCultMath() - ownDrawn); - var ownField = DrawAhead.Height(CurrentEntity.Zone, ownDrawn.xz, lead); + // The aim's pitch, applied to each barrel's planar bearing: the crosshair sits where the guns point at the view's + // elevation, not on the ship's level plane (which is the horizon). + var aim = CurrentEntity.Aim; + var aimLevel = length(aim.xz); foreach (var (_, barrels, crosshair) in _articulationGroups) { var averagePosition = Vector3.zero; foreach (var barrel in barrels) - averagePosition += barrel.position + barrel.forward * distance; + { + var bearing = new Vector2(barrel.forward.x, barrel.forward.z).normalized; + averagePosition += barrel.position + new Vector3(bearing.x * aimLevel, aim.y, bearing.y * aimLevel) * distance; + } averagePosition /= barrels.Length; - // Shots fly over the field, so the crosshair rides it too: the aim point's own field height, plus the barrels' height - // above the field under the ship. A level projection floats over downhill aim and sinks into uphill aim. - var aimPlanar = float2(averagePosition.x, averagePosition.z); - averagePosition.y += DrawAhead.Height(CurrentEntity.Zone, aimPlanar, lead) - ownField; crosshair.Target = averagePosition; } diff --git a/Assets/Scripts/Gameplay/EntityInstance.cs b/Assets/Scripts/Gameplay/EntityInstance.cs index 281a9db1c..f04094a7b 100644 --- a/Assets/Scripts/Gameplay/EntityInstance.cs +++ b/Assets/Scripts/Gameplay/EntityInstance.cs @@ -405,10 +405,12 @@ public class EntityInstance : MonoBehaviour // The drawn pose first: the camera's LookAt and the barrels read this frame's pose, not the last frame's. var drawn = DrawAhead.Position(Entity, ActionGameManager.Clock.Lead); LocalSpace.localPosition = transform.position = drawn.ToUnity(); - var lead = ActionGameManager.Clock.Lead; var aimDistance = !Entity.Target.Value.IsNone ? max(Entity.TargetRange, Entity.ItemManager.GameplaySettings.ConvergenceMinimumDistance) - : SurfaceDistance(drawn, Entity.Aim, lead); + : 10000; + // The aim's pitch: a planar firing bearing is drawn at the same elevation as the view, so a group aims where the + // player looks, not at the horizon of the ship's plane. + var aimLevel = length(Entity.Aim.xz); LookAtPoint.position = transform.position + Entity.Aim.ToUnity() * aimDistance; foreach (var group in _groupAims) { @@ -416,47 +418,12 @@ public class EntityInstance : MonoBehaviour if (weapon == null) { group.Value.position = LookAtPoint.position; continue; } var barrel = Barrels.TryGetValue(weapon.Item.Hardpoint, out var barrels) ? barrels[0].position : transform.position; var direction = FireControl.Solution(weapon, Entity, Entity.Target.Value).Direction; - var aimAt = barrel + new Vector3(direction.x, 0, direction.y) * aimDistance; - // Shots fly over the field: the group's aim point rides it, at the barrel's height above the field under the ship. - aimAt.y += Entity.RideHeight(float2(aimAt.x, aimAt.z), DrawAhead.Time(Entity.Zone, lead)) - drawn.y; - group.Value.position = aimAt; + group.Value.position = barrel + new Vector3(direction.x * aimLevel, Entity.Aim.y, direction.y * aimLevel) * aimDistance; } if (_influenceInstance) _influenceInstance.position = new Vector3(drawn.x, 0, drawn.z); } - // How far along `aim` from `from` the view ray meets the surface the ship rides, so an untargeted aim lands where the - // player looks on the field. Marches out in growing steps, then bisects the crossing; a ray that never comes down - // (looking level or up) aims at the horizon. - private float SurfaceDistance(CultMath.float3 from, CultMath.float3 aim, float lead) - { - const float horizon = 10000; - var time = DrawAhead.Time(Entity.Zone, lead); - float Above(float t) - { - var p = from + aim * t; - return p.y - Entity.RideHeight(p.xz, time); - } - var near = Entity.ItemManager.GameplaySettings.ConvergenceMinimumDistance; - if (Above(near) <= 0) return near; - var step = max(near, 8f); - for (var t = near; t < horizon; step *= 1.25f) - { - var next = min(t + step, horizon); - if (Above(next) <= 0) - { - for (var i = 0; i < 12; i++) - { - var mid = (t + next) / 2; - if (Above(mid) <= 0) next = mid; else t = mid; - } - return next; - } - t = next; - } - return horizon; - } - public virtual void OnDestroy() { if(_sensor!=null)