Added leveler
This commit is contained in:
@@ -1,16 +1,23 @@
|
||||
using System.Collections.Generic;
|
||||
using Unity.Netcode;
|
||||
using Unity.Netcode.Components;
|
||||
using UnityEngine;
|
||||
|
||||
[RequireComponent(typeof(Rigidbody), typeof(NetworkRigidbody))]
|
||||
public abstract class NetworkHeldInteractable : NetworkInteractable
|
||||
{
|
||||
protected const ulong NoHolder = ulong.MaxValue;
|
||||
private static readonly HashSet<NetworkHeldInteractable> SpawnedHeldObjects = new();
|
||||
|
||||
[Header("Physics")]
|
||||
[SerializeField] private Rigidbody physicsBody;
|
||||
[SerializeField] private Collider[] objectColliders;
|
||||
[SerializeField, Min(0.05f)] private float collisionRefreshInterval = 0.25f;
|
||||
|
||||
[Header("Throw")]
|
||||
[SerializeField, Min(0f)] private float throwForce = 6f;
|
||||
[SerializeField, Min(0f)] private float throwUpwardForce = 0.5f;
|
||||
|
||||
private readonly NetworkVariable<ulong> holderClientId = new(
|
||||
NoHolder,
|
||||
NetworkVariableReadPermission.Everyone,
|
||||
@@ -22,9 +29,10 @@ public abstract class NetworkHeldInteractable : NetworkInteractable
|
||||
protected abstract Vector3 HoldingOffset { get; }
|
||||
protected abstract string DropPrompt { get; }
|
||||
|
||||
private bool IsHeld => holderClientId.Value != NoHolder;
|
||||
private bool IsHeldByLocalPlayer =>
|
||||
public bool IsHeld => holderClientId.Value != NoHolder;
|
||||
public bool IsHeldByLocalPlayer =>
|
||||
NetworkManager != null && holderClientId.Value == NetworkManager.LocalClientId;
|
||||
public string HeldObjectName => InteractionLabel;
|
||||
|
||||
public override string InteractionPrompt => !IsHeld
|
||||
? InteractionLabel
|
||||
@@ -46,6 +54,7 @@ public abstract class NetworkHeldInteractable : NetworkInteractable
|
||||
|
||||
public override void OnNetworkSpawn()
|
||||
{
|
||||
SpawnedHeldObjects.Add(this);
|
||||
holderClientId.OnValueChanged += HandleHolderChanged;
|
||||
ApplyHoldingState(IsHeld);
|
||||
}
|
||||
@@ -53,6 +62,7 @@ public abstract class NetworkHeldInteractable : NetworkInteractable
|
||||
public override void OnNetworkDespawn()
|
||||
{
|
||||
holderClientId.OnValueChanged -= HandleHolderChanged;
|
||||
SpawnedHeldObjects.Remove(this);
|
||||
ApplyHoldingState(false);
|
||||
}
|
||||
|
||||
@@ -69,9 +79,10 @@ public abstract class NetworkHeldInteractable : NetworkInteractable
|
||||
return;
|
||||
}
|
||||
|
||||
Transform anchor = ResolveHoldingAnchor(holder);
|
||||
transform.SetPositionAndRotation(
|
||||
holder.transform.TransformPoint(HoldingOffset),
|
||||
holder.transform.rotation);
|
||||
anchor.TransformPoint(HoldingOffset),
|
||||
anchor.rotation);
|
||||
|
||||
if (Time.time >= nextCollisionRefreshTime)
|
||||
{
|
||||
@@ -80,8 +91,38 @@ public abstract class NetworkHeldInteractable : NetworkInteractable
|
||||
}
|
||||
}
|
||||
|
||||
protected override bool CanInteractOnServer(ulong senderClientId) =>
|
||||
!IsHeld || holderClientId.Value == senderClientId;
|
||||
public void RequestThrow()
|
||||
{
|
||||
if (IsSpawned && IsHeldByLocalPlayer)
|
||||
RequestThrowServerRpc();
|
||||
}
|
||||
|
||||
public static bool TryGetHeldObject(
|
||||
ulong clientId,
|
||||
out NetworkHeldInteractable heldObject)
|
||||
{
|
||||
foreach (NetworkHeldInteractable candidate in SpawnedHeldObjects)
|
||||
{
|
||||
if (candidate != null && candidate.holderClientId.Value == clientId)
|
||||
{
|
||||
heldObject = candidate;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
heldObject = null;
|
||||
return false;
|
||||
}
|
||||
|
||||
protected override bool CanInteractOnServer(ulong senderClientId)
|
||||
{
|
||||
if (holderClientId.Value == senderClientId)
|
||||
return true;
|
||||
|
||||
return !IsHeld &&
|
||||
!TryGetHeldObject(senderClientId, out _) &&
|
||||
!NetworkHandItemInteractable.TryGetHeldItem(senderClientId, out _);
|
||||
}
|
||||
|
||||
protected override void InteractOnServer(ulong senderClientId, NetworkObject playerObject)
|
||||
{
|
||||
@@ -91,6 +132,30 @@ public abstract class NetworkHeldInteractable : NetworkInteractable
|
||||
StartHolding(senderClientId);
|
||||
}
|
||||
|
||||
[Rpc(SendTo.Server, InvokePermission = RpcInvokePermission.Everyone)]
|
||||
private void RequestThrowServerRpc(RpcParams rpcParams = default)
|
||||
{
|
||||
ulong senderClientId = rpcParams.Receive.SenderClientId;
|
||||
if (holderClientId.Value != senderClientId ||
|
||||
!TryGetPlayerObject(senderClientId, out NetworkObject playerObject))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
FirstPersonCameraController cameraController =
|
||||
playerObject.GetComponent<FirstPersonCameraController>();
|
||||
Vector3 throwDirection = cameraController != null
|
||||
? cameraController.AimForward
|
||||
: playerObject.transform.forward;
|
||||
Vector3 throwVelocity = throwDirection * throwForce +
|
||||
Vector3.up * throwUpwardForce;
|
||||
|
||||
StopHolding();
|
||||
|
||||
if (physicsBody != null)
|
||||
physicsBody.linearVelocity = throwVelocity;
|
||||
}
|
||||
|
||||
private void StartHolding(ulong clientId)
|
||||
{
|
||||
holderClientId.Value = clientId;
|
||||
@@ -103,6 +168,13 @@ public abstract class NetworkHeldInteractable : NetworkInteractable
|
||||
ApplyHoldingState(false);
|
||||
}
|
||||
|
||||
private Transform ResolveHoldingAnchor(NetworkObject holder)
|
||||
{
|
||||
FirstPersonCameraController cameraController =
|
||||
holder.GetComponent<FirstPersonCameraController>();
|
||||
return cameraController != null ? cameraController.AimTransform : holder.transform;
|
||||
}
|
||||
|
||||
private void HandleHolderChanged(ulong _, ulong currentHolder) =>
|
||||
ApplyHoldingState(currentHolder != NoHolder);
|
||||
|
||||
@@ -110,9 +182,9 @@ public abstract class NetworkHeldInteractable : NetworkInteractable
|
||||
{
|
||||
if (physicsBody != null)
|
||||
{
|
||||
physicsBody.isKinematic = isHeld;
|
||||
if (!isHeld)
|
||||
physicsBody.linearVelocity = Vector3.zero;
|
||||
physicsBody.isKinematic = isHeld || !IsServer;
|
||||
physicsBody.linearVelocity = Vector3.zero;
|
||||
physicsBody.angularVelocity = Vector3.zero;
|
||||
}
|
||||
|
||||
if (isHeld)
|
||||
@@ -129,10 +201,8 @@ public abstract class NetworkHeldInteractable : NetworkInteractable
|
||||
{
|
||||
foreach (Collider objectCollider in objectColliders)
|
||||
{
|
||||
if (objectCollider == null || playerCollider == null)
|
||||
continue;
|
||||
|
||||
Physics.IgnoreCollision(objectCollider, playerCollider, true);
|
||||
if (objectCollider != null && playerCollider != null)
|
||||
Physics.IgnoreCollision(objectCollider, playerCollider, true);
|
||||
}
|
||||
|
||||
ignoredPlayerColliders.Add(playerCollider);
|
||||
|
||||
Reference in New Issue
Block a user