Added RocketAssemblyStation and ReadyRocket
This commit is contained in:
@@ -16,13 +16,12 @@ public abstract class NetworkHeldInteractable : NetworkInteractable, IWorkstatio
|
||||
|
||||
[Header("Holding Follow")]
|
||||
[SerializeField, Min(0.1f)] private float maximumFollowSpeed = 12f;
|
||||
[SerializeField, Min(0.1f)] private float followResponsiveness = 10f;
|
||||
[SerializeField, Min(0.1f)] private float maximumFollowAcceleration = 80f;
|
||||
[SerializeField, Min(0.5f)] private float maximumHoldDistance = 4.5f;
|
||||
[SerializeField, Min(0.1f)] private float rotationFollowSpeed = 14f;
|
||||
|
||||
[Header("Local Presentation")]
|
||||
[Tooltip("Removes the server round-trip delay for the player currently carrying the item.")]
|
||||
[SerializeField] private bool correctLocalHolderPresentation = true;
|
||||
[SerializeField, Min(0.1f)] private float maximumLocalCorrectionDistance = 2f;
|
||||
[SerializeField, Min(0.1f)] private float rotationResponsiveness = 10f;
|
||||
[SerializeField, Min(0.1f)] private float maximumAngularAcceleration = 80f;
|
||||
|
||||
[Header("Throw")]
|
||||
[SerializeField, Min(0f)] private float throwForce = 6f;
|
||||
@@ -41,10 +40,10 @@ public abstract class NetworkHeldInteractable : NetworkInteractable, IWorkstatio
|
||||
private readonly HashSet<Collider> ignoredPlayerColliders = new();
|
||||
private readonly HashSet<Collider> desiredIgnoredColliders = new();
|
||||
private readonly List<Collider> collidersToRestore = new();
|
||||
private readonly RaycastHit[] localCorrectionHits = new RaycastHit[24];
|
||||
private float nextCollisionRefreshTime;
|
||||
private bool initialUseGravity;
|
||||
private CollisionDetectionMode initialCollisionDetectionMode;
|
||||
private NetworkTransform networkTransform;
|
||||
|
||||
protected abstract Vector3 HoldingOffset { get; }
|
||||
protected abstract string DropPrompt { get; }
|
||||
@@ -80,6 +79,8 @@ public abstract class NetworkHeldInteractable : NetworkInteractable, IWorkstatio
|
||||
initialUseGravity = physicsBody.useGravity;
|
||||
initialCollisionDetectionMode = physicsBody.collisionDetectionMode;
|
||||
}
|
||||
|
||||
networkTransform = GetComponent<NetworkTransform>();
|
||||
}
|
||||
|
||||
public override void OnNetworkSpawn()
|
||||
@@ -87,6 +88,12 @@ public abstract class NetworkHeldInteractable : NetworkInteractable, IWorkstatio
|
||||
SpawnedHeldObjects.Add(this);
|
||||
holderClientId.OnValueChanged += HandleHolderChanged;
|
||||
isExternallyControlled.OnValueChanged += HandleExternalControlChanged;
|
||||
if (networkTransform != null)
|
||||
{
|
||||
networkTransform.Interpolate = true;
|
||||
networkTransform.UseUnreliableDeltas = true;
|
||||
}
|
||||
|
||||
ApplyHoldingState();
|
||||
}
|
||||
|
||||
@@ -129,28 +136,6 @@ public abstract class NetworkHeldInteractable : NetworkInteractable, IWorkstatio
|
||||
|
||||
}
|
||||
|
||||
private void LateUpdate()
|
||||
{
|
||||
if (!correctLocalHolderPresentation || IsServer || !IsSpawned ||
|
||||
!IsHeldByLocalPlayer || IsExternallyControlled || physicsBody == null ||
|
||||
!TryGetPlayerObject(holderClientId.Value, out NetworkObject holder))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Transform anchor = ResolveHoldingAnchor(holder);
|
||||
Vector3 targetPosition = anchor.TransformPoint(HoldingOffset);
|
||||
Vector3 targetDelta = targetPosition - physicsBody.position;
|
||||
if (targetDelta.sqrMagnitude >
|
||||
maximumLocalCorrectionDistance * maximumLocalCorrectionDistance ||
|
||||
HasBlockingColliderForLocalCorrection(targetDelta))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
transform.SetPositionAndRotation(targetPosition, anchor.rotation);
|
||||
}
|
||||
|
||||
public void RequestThrow()
|
||||
{
|
||||
if (IsSpawned && IsHeldByLocalPlayer)
|
||||
@@ -292,10 +277,14 @@ public abstract class NetworkHeldInteractable : NetworkInteractable, IWorkstatio
|
||||
return false;
|
||||
}
|
||||
|
||||
Vector3 targetVelocity = targetDelta / Mathf.Max(Time.fixedDeltaTime, 0.001f);
|
||||
physicsBody.linearVelocity = Vector3.ClampMagnitude(
|
||||
targetVelocity,
|
||||
float fixedDeltaTime = Mathf.Max(Time.fixedDeltaTime, 0.001f);
|
||||
Vector3 targetVelocity = Vector3.ClampMagnitude(
|
||||
targetDelta * followResponsiveness,
|
||||
maximumFollowSpeed);
|
||||
physicsBody.linearVelocity = Vector3.MoveTowards(
|
||||
physicsBody.linearVelocity,
|
||||
targetVelocity,
|
||||
maximumFollowAcceleration * fixedDeltaTime);
|
||||
|
||||
DriveRotation(anchor.rotation);
|
||||
return true;
|
||||
@@ -306,57 +295,25 @@ public abstract class NetworkHeldInteractable : NetworkInteractable, IWorkstatio
|
||||
Quaternion rotationDelta = targetRotation * Quaternion.Inverse(physicsBody.rotation);
|
||||
rotationDelta.ToAngleAxis(out float angle, out Vector3 axis);
|
||||
if (axis.sqrMagnitude < 0.0001f || float.IsNaN(axis.x))
|
||||
{
|
||||
physicsBody.angularVelocity = Vector3.MoveTowards(
|
||||
physicsBody.angularVelocity,
|
||||
Vector3.zero,
|
||||
maximumAngularAcceleration * Mathf.Max(Time.fixedDeltaTime, 0.001f));
|
||||
return;
|
||||
}
|
||||
|
||||
if (angle > 180f)
|
||||
angle -= 360f;
|
||||
|
||||
Vector3 targetAngularVelocity = axis.normalized *
|
||||
(angle * Mathf.Deg2Rad / Mathf.Max(Time.fixedDeltaTime, 0.001f));
|
||||
physicsBody.angularVelocity = Vector3.ClampMagnitude(
|
||||
targetAngularVelocity,
|
||||
float fixedDeltaTime = Mathf.Max(Time.fixedDeltaTime, 0.001f);
|
||||
Vector3 targetAngularVelocity = Vector3.ClampMagnitude(
|
||||
axis.normalized * angle * Mathf.Deg2Rad * rotationResponsiveness,
|
||||
rotationFollowSpeed);
|
||||
}
|
||||
|
||||
private bool HasBlockingColliderForLocalCorrection(Vector3 targetDelta)
|
||||
{
|
||||
float distance = targetDelta.magnitude;
|
||||
if (distance <= 0.0001f)
|
||||
return false;
|
||||
|
||||
int hitCount = Physics.RaycastNonAlloc(
|
||||
physicsBody.position,
|
||||
targetDelta / distance,
|
||||
localCorrectionHits,
|
||||
distance,
|
||||
~0,
|
||||
QueryTriggerInteraction.Ignore);
|
||||
|
||||
for (int hitIndex = 0; hitIndex < hitCount; hitIndex++)
|
||||
{
|
||||
Collider hitCollider = localCorrectionHits[hitIndex].collider;
|
||||
if (hitCollider == null ||
|
||||
ignoredPlayerColliders.Contains(hitCollider) ||
|
||||
IsObjectCollider(hitCollider))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private bool IsObjectCollider(Collider candidate)
|
||||
{
|
||||
foreach (Collider objectCollider in objectColliders)
|
||||
{
|
||||
if (objectCollider == candidate)
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
physicsBody.angularVelocity = Vector3.MoveTowards(
|
||||
physicsBody.angularVelocity,
|
||||
targetAngularVelocity,
|
||||
maximumAngularAcceleration * fixedDeltaTime);
|
||||
}
|
||||
|
||||
private void HandleHolderChanged(ulong _, ulong __) => ApplyHoldingState();
|
||||
@@ -369,6 +326,9 @@ public abstract class NetworkHeldInteractable : NetworkInteractable, IWorkstatio
|
||||
{
|
||||
bool isPhysicallyHeld = IsHeld && !IsExternallyControlled;
|
||||
bool shouldBeKinematic = IsExternallyControlled || !IsServer;
|
||||
physicsBody.interpolation = IsServer
|
||||
? RigidbodyInterpolation.Interpolate
|
||||
: RigidbodyInterpolation.None;
|
||||
|
||||
if (shouldBeKinematic)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user