Further Tests & Progress
This commit is contained in:
@@ -38,7 +38,10 @@ namespace ProjectM.Client
|
||||
float3 _lastKbmGroundPoint; // last valid cursor ground point (held when the projection misses)
|
||||
bool _haveKbmPoint; // true after the first valid KBM ground hit
|
||||
bool _cursorHidden; // tracks the applied Cursor.visible state (avoid per-frame churn)
|
||||
bool _cursorTouched; // we changed the OS cursor at least once -> restore on destroy
|
||||
bool _cursorTouched;
|
||||
GameObject _tether;
|
||||
LineRenderer _tetherLine;
|
||||
Material _tetherMat; // we changed the OS cursor at least once -> restore on destroy
|
||||
|
||||
protected override void OnStartRunning()
|
||||
{
|
||||
@@ -52,9 +55,12 @@ namespace ProjectM.Client
|
||||
|
||||
bool haveTarget = false;
|
||||
float3 ringPos = default;
|
||||
float3 lpPos = default;
|
||||
float2 lpFacing = default;
|
||||
|
||||
EntityManager.CompleteDependencyBeforeRO<LocalTransform>();
|
||||
EntityManager.CompleteDependencyBeforeRO<PlayerFacing>();
|
||||
EntityManager.CompleteDependencyBeforeRO<Health>();
|
||||
foreach (var (xform, facing) in
|
||||
SystemAPI.Query<RefRO<LocalTransform>, RefRO<PlayerFacing>>()
|
||||
.WithAll<GhostOwnerIsLocal, PlayerTag>())
|
||||
@@ -87,6 +93,8 @@ namespace ProjectM.Client
|
||||
}
|
||||
|
||||
ringPos.y += ReticleLiftY;
|
||||
lpPos = playerPos;
|
||||
lpFacing = facing.ValueRO.Direction;
|
||||
haveTarget = true;
|
||||
break;
|
||||
}
|
||||
@@ -97,6 +105,43 @@ namespace ProjectM.Client
|
||||
if (_reticle.activeSelf != haveTarget) _reticle.SetActive(haveTarget);
|
||||
}
|
||||
|
||||
// Lock-on tether (cosmetic aim HINT - the client computes nearest enemy itself; the server's actual
|
||||
// gamepad auto-target cone may differ, so divergence is acceptable, not a bug).
|
||||
bool tetherShown = false;
|
||||
if (_tetherLine != null && haveTarget && FeelConfig.LockOnEnabled
|
||||
&& (!FeelConfig.LockOnGamepadOnly || scheme == InputSchemeId.Gamepad))
|
||||
{
|
||||
float2 fdir = lpFacing;
|
||||
if (math.lengthsq(fdir) < 1e-6f) fdir = new float2(0f, 1f);
|
||||
fdir = math.normalize(fdir);
|
||||
float rangeSq = FeelConfig.LockOnRange * FeelConfig.LockOnRange;
|
||||
float cone = math.cos(math.radians(FeelConfig.LockOnArcDegrees));
|
||||
float bestSq = float.MaxValue;
|
||||
float3 bestPos = default;
|
||||
bool found = false;
|
||||
foreach (var (hx, hh) in
|
||||
SystemAPI.Query<RefRO<LocalTransform>, RefRO<Health>>().WithAll<EnemyTag>())
|
||||
{
|
||||
if (hh.ValueRO.Current <= 0f) continue;
|
||||
float3 hp = hx.ValueRO.Position;
|
||||
float2 to = hp.xz - lpPos.xz;
|
||||
float sq = math.lengthsq(to);
|
||||
if (sq > rangeSq || sq < 1e-6f) continue;
|
||||
if (math.dot(fdir, math.normalize(to)) < cone) continue;
|
||||
if (sq < bestSq) { bestSq = sq; bestPos = hp; found = true; }
|
||||
}
|
||||
if (found)
|
||||
{
|
||||
_tetherLine.startColor = FeelConfig.LockOnLineColor;
|
||||
_tetherLine.endColor = FeelConfig.LockOnLineColor;
|
||||
_tetherLine.widthMultiplier = FeelConfig.LockOnLineWidth;
|
||||
_tetherLine.SetPosition(0, (Vector3)ringPos);
|
||||
_tetherLine.SetPosition(1, new Vector3(bestPos.x, ringPos.y, bestPos.z));
|
||||
tetherShown = true;
|
||||
}
|
||||
}
|
||||
if (_tether != null && _tether.activeSelf != tetherShown) _tether.SetActive(tetherShown);
|
||||
|
||||
// Hide the OS cursor only while aiming AND focused; restore otherwise (focus loss / pre-spawn) so an
|
||||
// unfocused editor or a windowed session is never stranded with an invisible pointer.
|
||||
bool wantHidden = haveTarget && Application.isFocused;
|
||||
@@ -131,6 +176,8 @@ namespace ProjectM.Client
|
||||
if (_reticle != null) Object.Destroy(_reticle);
|
||||
if (_reticleMat != null) Object.Destroy(_reticleMat);
|
||||
if (_ringTex != null) Object.Destroy(_ringTex);
|
||||
if (_tether != null) Object.Destroy(_tether);
|
||||
if (_tetherMat != null) Object.Destroy(_tetherMat);
|
||||
}
|
||||
|
||||
void BuildReticle()
|
||||
@@ -154,6 +201,25 @@ namespace ProjectM.Client
|
||||
_reticle.transform.rotation = Quaternion.Euler(90f, 0f, 0f); // lay flat on the ground
|
||||
_reticle.transform.localScale = new Vector3(ReticleSize, ReticleSize, 1f);
|
||||
_reticle.SetActive(false);
|
||||
|
||||
// Lock-on tether line (persistent; built once, GC-clean). Own material so the ring texture doesn't tint it.
|
||||
var lineShader = Shader.Find("Sprites/Default");
|
||||
if (lineShader == null) lineShader = Shader.Find("Universal Render Pipeline/Particles/Unlit");
|
||||
_tetherMat = new Material(lineShader) { color = Color.white };
|
||||
_tether = new GameObject("~AimTether");
|
||||
_tetherLine = _tether.AddComponent<LineRenderer>();
|
||||
_tetherLine.material = _tetherMat;
|
||||
_tetherLine.positionCount = 2;
|
||||
_tetherLine.useWorldSpace = true;
|
||||
_tetherLine.numCapVertices = 2;
|
||||
_tetherLine.alignment = LineAlignment.View;
|
||||
_tetherLine.textureMode = LineTextureMode.Stretch;
|
||||
_tetherLine.shadowCastingMode = UnityEngine.Rendering.ShadowCastingMode.Off;
|
||||
_tetherLine.receiveShadows = false;
|
||||
_tetherLine.startColor = FeelConfig.LockOnLineColor;
|
||||
_tetherLine.endColor = FeelConfig.LockOnLineColor;
|
||||
_tetherLine.widthMultiplier = FeelConfig.LockOnLineWidth;
|
||||
_tether.SetActive(false);
|
||||
}
|
||||
|
||||
// ---- procedural ring texture (asset-free, like HudSystem's code-built uGUI) ----
|
||||
|
||||
Reference in New Issue
Block a user