|
|
|
|
using Fusion;
|
|
|
|
|
using UnityEngine;
|
|
|
|
|
|
|
|
|
|
namespace Projectiles
|
|
|
|
|
{
|
|
|
|
|
public struct HitscanData : INetworkStruct
|
|
|
|
|
{
|
|
|
|
|
public byte PrefabIndex;
|
|
|
|
|
public byte BarrelIndex;
|
|
|
|
|
public Vector3Compressed FirePosition;
|
|
|
|
|
public Vector3Compressed FireDirection;
|
|
|
|
|
public Vector3Compressed ImpactPosition;
|
|
|
|
|
public Vector3Compressed ImpactNormal;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Projectile data buffer for hitscan projectiles.
|
|
|
|
|
/// </summary>
|
|
|
|
|
public class HitscanProjectileBuffer : NetworkDataBuffer<HitscanData, HitscanProjectile>
|
|
|
|
|
{
|
|
|
|
|
// PRIVATE MEMBERS
|
|
|
|
|
|
|
|
|
|
[SerializeField]
|
|
|
|
|
private HitscanProjectile[] _projectilePrefabs;
|
|
|
|
|
|
|
|
|
|
private ProjectileContext _context;
|
|
|
|
|
|
|
|
|
|
// PUBLIC METHODS
|
|
|
|
|
|
|
|
|
|
public void AddProjectile(HitscanProjectile projectilePrefab, Vector3 firePosition, Vector3 direction, byte barrelIndex = 0)
|
|
|
|
|
{
|
|
|
|
|
int prefabIndex = _projectilePrefabs.IndexOf(projectilePrefab);
|
|
|
|
|
|
|
|
|
|
if (prefabIndex < 0)
|
|
|
|
|
{
|
|
|
|
|
Debug.LogError($"Projectile {projectilePrefab} not found. Add it in HitscanProjectiles prefab array.");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Temporarily assign correct context in case it will be needed in GetFireData
|
|
|
|
|
projectilePrefab.Context = _context;
|
|
|
|
|
var data = projectilePrefab.GetFireData(firePosition, direction);
|
|
|
|
|
projectilePrefab.Context = null;
|
|
|
|
|
|
|
|
|
|
data.PrefabIndex = (byte)prefabIndex;
|
|
|
|
|
data.BarrelIndex = barrelIndex;
|
|
|
|
|
|
|
|
|
|
AddData(data);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void UpdateBarrelTransforms(Transform[] barrelTransforms)
|
|
|
|
|
{
|
|
|
|
|
_context.BarrelTransforms = barrelTransforms;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// NetworkDataBuffer INTERFACE
|
|
|
|
|
|
|
|
|
|
[Networked, Capacity(32)]
|
|
|
|
|
protected override NetworkArray<HitscanData> DataBuffer { get; }
|
|
|
|
|
|
|
|
|
|
protected override HitscanProjectile GetView(HitscanData data)
|
|
|
|
|
{
|
|
|
|
|
var projectile = Context.ObjectCache.Get(_projectilePrefabs[data.PrefabIndex]);
|
|
|
|
|
|
|
|
|
|
Runner.MoveToRunnerScene(projectile);
|
|
|
|
|
if (Runner.Config.PeerMode == NetworkProjectConfig.PeerModes.Multiple)
|
|
|
|
|
{
|
|
|
|
|
Runner.AddVisibilityNodes(projectile.gameObject);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
projectile.Context = _context;
|
|
|
|
|
projectile.Activate(ref data);
|
|
|
|
|
|
|
|
|
|
return projectile;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
protected override void ReturnView(HitscanProjectile projectile, bool misprediction)
|
|
|
|
|
{
|
|
|
|
|
if (projectile == null)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
projectile.Deactivate();
|
|
|
|
|
|
|
|
|
|
Context.ObjectCache.Return(projectile);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public override void Spawned()
|
|
|
|
|
{
|
|
|
|
|
base.Spawned();
|
|
|
|
|
|
|
|
|
|
_context.Runner = Runner;
|
|
|
|
|
_context.Cache = Context.ObjectCache;
|
|
|
|
|
_context.Owner = Object.InputAuthority;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// MONOBEHAVIOUR
|
|
|
|
|
|
|
|
|
|
protected void Awake()
|
|
|
|
|
{
|
|
|
|
|
_context = new ProjectileContext();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|