Added many other things and processings

This commit is contained in:
2026-08-13 17:55:05 +03:00
parent 36ecac038a
commit 3c490bdae8
625 changed files with 929224 additions and 151067 deletions
@@ -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();