Added many other things and processings
This commit is contained in:
@@ -12,9 +12,10 @@ public enum DraggableMovementMode
|
||||
}
|
||||
|
||||
[RequireComponent(typeof(Rigidbody), typeof(NetworkRigidbody))]
|
||||
public sealed class NetworkDraggableInteractable : NetworkInteractable
|
||||
public sealed class NetworkDraggableInteractable : NetworkInteractable, IWorkstationItemControl
|
||||
{
|
||||
private const ulong NoDragger = ulong.MaxValue;
|
||||
private static readonly HashSet<NetworkDraggableInteractable> SpawnedDraggables = new();
|
||||
|
||||
[Header("Weight")]
|
||||
[SerializeField, Min(0.1f)] private float weight = 35f;
|
||||
@@ -59,6 +60,11 @@ public sealed class NetworkDraggableInteractable : NetworkInteractable
|
||||
NetworkVariableReadPermission.Everyone,
|
||||
NetworkVariableWritePermission.Server);
|
||||
|
||||
private readonly NetworkVariable<bool> isExternallyControlled = new(
|
||||
false,
|
||||
NetworkVariableReadPermission.Everyone,
|
||||
NetworkVariableWritePermission.Server);
|
||||
|
||||
private readonly HashSet<Collider> ignoredPlayerColliders = new();
|
||||
private readonly RaycastHit[] groundHits = new RaycastHit[16];
|
||||
private float nextCollisionRefreshTime;
|
||||
@@ -79,6 +85,7 @@ public sealed class NetworkDraggableInteractable : NetworkInteractable
|
||||
}
|
||||
public int RequiredDraggerCount => Mathf.Max(1, Mathf.CeilToInt(weight / pullStrengthPerPlayer));
|
||||
public bool HasEnoughPullStrength => ActiveDraggerCount >= RequiredDraggerCount;
|
||||
public bool IsExternallyControlled => isExternallyControlled.Value;
|
||||
|
||||
private bool HasAnyDragger => ActiveDraggerCount > 0;
|
||||
private bool IsDraggedByLocalPlayer =>
|
||||
@@ -88,6 +95,9 @@ public sealed class NetworkDraggableInteractable : NetworkInteractable
|
||||
{
|
||||
get
|
||||
{
|
||||
if (IsExternallyControlled)
|
||||
return "In machine";
|
||||
|
||||
if (IsDraggedByLocalPlayer)
|
||||
return "Release";
|
||||
|
||||
@@ -105,7 +115,11 @@ public sealed class NetworkDraggableInteractable : NetworkInteractable
|
||||
}
|
||||
|
||||
public override bool IsInteractionAvailable => base.IsInteractionAvailable &&
|
||||
(IsDraggedByLocalPlayer || ActiveDraggerCount < maximumDraggers);
|
||||
!IsExternallyControlled &&
|
||||
(IsDraggedByLocalPlayer ||
|
||||
(ActiveDraggerCount < maximumDraggers &&
|
||||
(NetworkManager == null ||
|
||||
!TryGetDraggedObject(NetworkManager.LocalClientId, this, out _))));
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
@@ -121,15 +135,19 @@ public sealed class NetworkDraggableInteractable : NetworkInteractable
|
||||
|
||||
public override void OnNetworkSpawn()
|
||||
{
|
||||
SpawnedDraggables.Add(this);
|
||||
firstDraggerClientId.OnValueChanged += HandleDraggerChanged;
|
||||
secondDraggerClientId.OnValueChanged += HandleDraggerChanged;
|
||||
isExternallyControlled.OnValueChanged += HandleExternalControlChanged;
|
||||
ApplyDraggingState();
|
||||
}
|
||||
|
||||
public override void OnNetworkDespawn()
|
||||
{
|
||||
SpawnedDraggables.Remove(this);
|
||||
firstDraggerClientId.OnValueChanged -= HandleDraggerChanged;
|
||||
secondDraggerClientId.OnValueChanged -= HandleDraggerChanged;
|
||||
isExternallyControlled.OnValueChanged -= HandleExternalControlChanged;
|
||||
RestorePlayerCollisions();
|
||||
}
|
||||
|
||||
@@ -144,7 +162,7 @@ public sealed class NetworkDraggableInteractable : NetworkInteractable
|
||||
|
||||
private void FixedUpdate()
|
||||
{
|
||||
if (!IsServer || !IsSpawned || physicsBody == null)
|
||||
if (!IsServer || !IsSpawned || physicsBody == null || IsExternallyControlled)
|
||||
return;
|
||||
|
||||
RemoveInvalidDraggers();
|
||||
@@ -177,9 +195,17 @@ public sealed class NetworkDraggableInteractable : NetworkInteractable
|
||||
}
|
||||
}
|
||||
|
||||
protected override bool CanInteractOnServer(ulong senderClientId) =>
|
||||
IsDragger(senderClientId) ||
|
||||
ActiveDraggerCount < maximumDraggers;
|
||||
protected override bool CanInteractOnServer(ulong senderClientId)
|
||||
{
|
||||
if (IsExternallyControlled)
|
||||
return false;
|
||||
|
||||
if (IsDragger(senderClientId))
|
||||
return true;
|
||||
|
||||
return ActiveDraggerCount < maximumDraggers &&
|
||||
!TryGetDraggedObject(senderClientId, this, out _);
|
||||
}
|
||||
|
||||
protected override void InteractOnServer(ulong senderClientId, NetworkObject playerObject)
|
||||
{
|
||||
@@ -191,6 +217,9 @@ public sealed class NetworkDraggableInteractable : NetworkInteractable
|
||||
|
||||
private void AddDragger(ulong clientId)
|
||||
{
|
||||
if (IsExternallyControlled || TryGetDraggedObject(clientId, this, out _))
|
||||
return;
|
||||
|
||||
if (firstDraggerClientId.Value == NoDragger)
|
||||
firstDraggerClientId.Value = clientId;
|
||||
else if (maximumDraggers > 1 && secondDraggerClientId.Value == NoDragger)
|
||||
@@ -265,19 +294,78 @@ public sealed class NetworkDraggableInteractable : NetworkInteractable
|
||||
if (clientId == NoDragger || !TryGetPlayerObject(clientId, out NetworkObject playerObject))
|
||||
return;
|
||||
|
||||
Transform dragAnchor = ResolveDragAnchor(playerObject);
|
||||
target += dragAnchor.TransformPoint(dragOffset);
|
||||
forward += dragAnchor.forward;
|
||||
FirstPersonCameraController cameraController =
|
||||
playerObject.GetComponent<FirstPersonCameraController>();
|
||||
Vector3 aimForward = cameraController != null
|
||||
? cameraController.AimForward
|
||||
: playerObject.transform.forward;
|
||||
|
||||
target += playerObject.transform.position +
|
||||
playerObject.transform.right * dragOffset.x +
|
||||
Vector3.up * dragOffset.y +
|
||||
aimForward * dragOffset.z;
|
||||
forward += aimForward;
|
||||
validTargets++;
|
||||
}
|
||||
|
||||
private static Transform ResolveDragAnchor(NetworkObject playerObject)
|
||||
private static bool TryGetDraggedObject(
|
||||
ulong clientId,
|
||||
NetworkDraggableInteractable except,
|
||||
out NetworkDraggableInteractable draggedObject)
|
||||
{
|
||||
FirstPersonCameraController cameraController =
|
||||
playerObject.GetComponent<FirstPersonCameraController>();
|
||||
return cameraController != null
|
||||
? cameraController.AimTransform
|
||||
: playerObject.transform;
|
||||
foreach (NetworkDraggableInteractable candidate in SpawnedDraggables)
|
||||
{
|
||||
if (candidate != null && candidate != except && candidate.IsDragger(clientId))
|
||||
{
|
||||
draggedObject = candidate;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
draggedObject = null;
|
||||
return false;
|
||||
}
|
||||
|
||||
public static bool TryGetDraggedObject(
|
||||
ulong clientId,
|
||||
out NetworkDraggableInteractable draggedObject) =>
|
||||
TryGetDraggedObject(clientId, null, out draggedObject);
|
||||
|
||||
public void RequestRelease()
|
||||
{
|
||||
if (IsSpawned && IsDraggedByLocalPlayer)
|
||||
RequestReleaseRpc();
|
||||
}
|
||||
|
||||
public bool TryAcquireExternalControl()
|
||||
{
|
||||
if (!IsServer || !IsSpawned || IsExternallyControlled)
|
||||
return false;
|
||||
|
||||
isExternallyControlled.Value = true;
|
||||
|
||||
firstDraggerClientId.Value = NoDragger;
|
||||
secondDraggerClientId.Value = NoDragger;
|
||||
ApplyDraggingState();
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool TryReleaseExternalControl()
|
||||
{
|
||||
if (!IsServer || !IsSpawned || !IsExternallyControlled)
|
||||
return false;
|
||||
|
||||
isExternallyControlled.Value = false;
|
||||
ApplyDraggingState();
|
||||
return true;
|
||||
}
|
||||
|
||||
[Rpc(SendTo.Server, InvokePermission = RpcInvokePermission.Everyone)]
|
||||
private void RequestReleaseRpc(RpcParams rpcParams = default)
|
||||
{
|
||||
ulong senderClientId = rpcParams.Receive.SenderClientId;
|
||||
if (!IsExternallyControlled && IsDragger(senderClientId))
|
||||
RemoveDragger(senderClientId);
|
||||
}
|
||||
|
||||
private bool IsDragger(ulong clientId) =>
|
||||
@@ -285,11 +373,13 @@ public sealed class NetworkDraggableInteractable : NetworkInteractable
|
||||
|
||||
private void HandleDraggerChanged(ulong _, ulong __) => ApplyDraggingState();
|
||||
|
||||
private void HandleExternalControlChanged(bool _, bool __) => ApplyDraggingState();
|
||||
|
||||
private void ApplyDraggingState()
|
||||
{
|
||||
if (physicsBody != null)
|
||||
{
|
||||
bool shouldBeKinematic = HasAnyDragger || !IsServer;
|
||||
bool shouldBeKinematic = HasAnyDragger || IsExternallyControlled || !IsServer;
|
||||
|
||||
if (physicsBody.isKinematic && !shouldBeKinematic)
|
||||
physicsBody.isKinematic = false;
|
||||
@@ -303,7 +393,7 @@ public sealed class NetworkDraggableInteractable : NetworkInteractable
|
||||
physicsBody.isKinematic = shouldBeKinematic;
|
||||
}
|
||||
|
||||
if (HasAnyDragger)
|
||||
if (HasAnyDragger || IsExternallyControlled)
|
||||
{
|
||||
dragVelocity = Vector3.zero;
|
||||
CacheGroundContactPoint();
|
||||
|
||||
Reference in New Issue
Block a user