247 lines
5.6 KiB
C#
247 lines
5.6 KiB
C#
using Fusion;
|
|
using Fusion.Addons.Physics;
|
|
using UnityEngine;
|
|
using Plugins.Outline;
|
|
|
|
namespace TPSBR
|
|
{
|
|
public interface IDynamicPickupProvider
|
|
{
|
|
public string Name { get; }
|
|
public string Description { get; }
|
|
public Transform InterpolationTarget { get; }
|
|
public Collider Collider { get; }
|
|
public float DespawnTime { get; }
|
|
|
|
public void Assigned(DynamicPickup pickup);
|
|
public void Unassigned(DynamicPickup pickup);
|
|
}
|
|
|
|
[RequireComponent(typeof(NetworkRigidbody3D))]
|
|
public sealed class DynamicPickup : ContextBehaviour, IPickup
|
|
{
|
|
// PUBLIC MEMBERS
|
|
|
|
public IDynamicPickupProvider Provider { get; private set; }
|
|
|
|
// PRIVATE MEMBERS
|
|
|
|
[SerializeField]
|
|
private float _despawnTime = 60f;
|
|
[SerializeField]
|
|
private float _fullOutlineDistance = 5f;
|
|
[SerializeField]
|
|
private float _noOutlineDistance = 20f;
|
|
|
|
[Networked]
|
|
private NetworkId _dynamicObjectID { get; set; }
|
|
[Networked]
|
|
private TickTimer _despawnCooldown { get; set; }
|
|
|
|
private NetworkObject _dynamicObject;
|
|
|
|
private NetworkRigidbody3D _networkRigidbody;
|
|
|
|
private string _name;
|
|
private string _description;
|
|
|
|
private OutlineBehaviour _outline;
|
|
private Color _defaultOutlineColor;
|
|
private Color _noOutlineColor;
|
|
|
|
// PUBLIC MEMBERS
|
|
|
|
public void AssignObject(NetworkId dynamicObjectID)
|
|
{
|
|
_dynamicObjectID = dynamicObjectID;
|
|
|
|
_dynamicObject = Runner.FindObject(_dynamicObjectID);
|
|
|
|
if (_dynamicObject == null)
|
|
return;
|
|
|
|
_dynamicObject.transform.SetParent(transform, false);
|
|
|
|
NetworkAreaOfInterestProxy aoiProxy = _dynamicObject.GetComponent<NetworkAreaOfInterestProxy>();
|
|
if (aoiProxy != null)
|
|
{
|
|
aoiProxy.SetPositionSource(_networkRigidbody.transform);
|
|
}
|
|
|
|
Provider = _dynamicObject.GetComponent<IDynamicPickupProvider>();
|
|
|
|
_name = Provider.Name;
|
|
_description = Provider.Description;
|
|
|
|
float despawnTime = Provider.DespawnTime > 0f ? Provider.DespawnTime : _despawnTime;
|
|
_despawnCooldown = TickTimer.CreateFromSeconds(Runner, despawnTime);
|
|
|
|
Provider.Collider.enabled = true;
|
|
_networkRigidbody.InterpolationTarget = Provider.InterpolationTarget;
|
|
|
|
Provider.Assigned(this);
|
|
}
|
|
|
|
public void UnassignObject()
|
|
{
|
|
Provider.Unassigned(this);
|
|
|
|
if (_dynamicObject.transform.parent == transform && Runner.IsShutdown == false)
|
|
{
|
|
_dynamicObject.transform.SetParent(null, false);
|
|
|
|
NetworkAreaOfInterestProxy aoiProxy = _dynamicObject.GetComponent<NetworkAreaOfInterestProxy>();
|
|
if (aoiProxy != null)
|
|
{
|
|
aoiProxy.SetPositionSource(null);
|
|
}
|
|
}
|
|
|
|
Provider.Collider.enabled = false;
|
|
|
|
var interpolationTarget = _networkRigidbody.InterpolationTarget;
|
|
if (interpolationTarget != null)
|
|
{
|
|
interpolationTarget.localPosition = Vector3.zero;
|
|
interpolationTarget.localRotation = Quaternion.identity;
|
|
|
|
_networkRigidbody.InterpolationTarget = null;
|
|
}
|
|
|
|
_dynamicObject = null;
|
|
_dynamicObjectID = default;
|
|
Provider = null;
|
|
|
|
_despawnCooldown = TickTimer.CreateFromSeconds(Runner, 1f);
|
|
}
|
|
|
|
// NetworkObject INTERFACE
|
|
|
|
public override void Spawned()
|
|
{
|
|
if (_despawnCooldown.IsRunning == false)
|
|
{
|
|
_despawnCooldown = _despawnTime > 0f ? TickTimer.CreateFromSeconds(Runner, _despawnTime) : default;
|
|
}
|
|
}
|
|
|
|
public override void Despawned(NetworkRunner runner, bool hasState)
|
|
{
|
|
if (_dynamicObject != null)
|
|
{
|
|
var objectToDespawn = _dynamicObjectID.IsValid == true ? _dynamicObject : null;
|
|
|
|
UnassignObject();
|
|
|
|
if (objectToDespawn != null)
|
|
{
|
|
Runner.Despawn(objectToDespawn);
|
|
}
|
|
}
|
|
|
|
_dynamicObjectID = default;
|
|
|
|
#if UNITY_6000_0_OR_NEWER
|
|
_networkRigidbody.Rigidbody.linearVelocity = Vector3.zero;
|
|
#else
|
|
_networkRigidbody.Rigidbody.velocity = Vector3.zero;
|
|
#endif
|
|
_networkRigidbody.Rigidbody.angularVelocity = Vector3.zero;
|
|
}
|
|
|
|
public override void FixedUpdateNetwork()
|
|
{
|
|
if (HasStateAuthority == false)
|
|
return;
|
|
|
|
if (_despawnCooldown.Expired(Runner) == true)
|
|
{
|
|
Runner.Despawn(Object);
|
|
return;
|
|
}
|
|
|
|
UpdateLocalState();
|
|
}
|
|
|
|
public override void Render()
|
|
{
|
|
UpdateLocalState();
|
|
}
|
|
|
|
// MONOBEHAVIOUR
|
|
|
|
private void Awake()
|
|
{
|
|
_networkRigidbody = GetComponent<NetworkRigidbody3D>();
|
|
_outline = GetComponent<OutlineBehaviour>();
|
|
|
|
if (_outline != null)
|
|
{
|
|
_defaultOutlineColor = _outline.Settings.Color;
|
|
_noOutlineColor = _defaultOutlineColor;
|
|
_noOutlineColor.a = 0f;
|
|
}
|
|
}
|
|
|
|
private void Update()
|
|
{
|
|
UpdateOutline();
|
|
}
|
|
|
|
// IPickup INTERFACE
|
|
|
|
string IInteraction.Name => _name;
|
|
string IInteraction.Description => _description;
|
|
Vector3 IInteraction.HUDPosition => transform.position;
|
|
bool IInteraction.IsActive => true;
|
|
|
|
// PRIVATE METHODS
|
|
|
|
private void UpdateLocalState()
|
|
{
|
|
if (_dynamicObjectID.IsValid == true && _dynamicObject == null)
|
|
{
|
|
AssignObject(_dynamicObjectID);
|
|
}
|
|
|
|
if (_dynamicObjectID.IsValid == false && _dynamicObject != null)
|
|
{
|
|
UnassignObject();
|
|
}
|
|
}
|
|
|
|
private void UpdateOutline()
|
|
{
|
|
if (Runner == null)
|
|
return;
|
|
|
|
if (Runner.IsPlayer == false)
|
|
return;
|
|
|
|
if (_outline == null)
|
|
return;
|
|
|
|
if (_dynamicObject == null)
|
|
return;
|
|
|
|
var agent = Context.ObservedAgent;
|
|
if (agent == null)
|
|
return;
|
|
|
|
float sqrDistance = (agent.transform.position - transform.position).sqrMagnitude;
|
|
|
|
if (sqrDistance > _noOutlineDistance * _noOutlineDistance)
|
|
{
|
|
_outline.enabled = false;
|
|
return;
|
|
}
|
|
|
|
float distance = Mathf.Sqrt(sqrDistance);
|
|
float progress = (distance - _fullOutlineDistance) / (_noOutlineDistance - _fullOutlineDistance);
|
|
|
|
_outline.enabled = true;
|
|
_outline.Settings.Color = Color.Lerp(_defaultOutlineColor, _noOutlineColor, progress);
|
|
}
|
|
}
|
|
}
|