commit428243f4a6Author: AsanoRema <asanorema2036@gmail.com> Date: Sat Aug 29 13:43:13 2026 +0300 Squashed commit of the following: commit68e78fa464Author: AsanoRema <asanorema2036@gmail.com> Date: Sat Aug 29 13:41:49 2026 +0300 Updated .gitignore commit9f87122a34Author: AsanoRema <asanorema2036@gmail.com> Date: Sat Aug 29 13:34:57 2026 +0300 Added Dohya commitf6a7547e84Author: AsanoRema <asanorema2036@gmail.com> Date: Fri Aug 21 17:59:13 2026 +0300 Fixed commitb98901c366Author: AsanoRema <asanorema2036@gmail.com> Date: Tue Aug 18 17:37:22 2026 +0300 Added new particle Package commitbb2f4a3b16Author: AsanoRema <asanorema2036@gmail.com> Date: Tue Aug 18 17:17:48 2026 +0300 Map mehanic ready to multiplayer commitc01ff800f6Author: AsanoRema <asanorema2036@gmail.com> Date: Tue Aug 18 16:16:19 2026 +0300 Squashed commit of the following: commit173bbb165cAuthor: henjkey <henjkey@gmail.com> Date: Fri Aug 14 18:51:23 2026 +0500 Mappp commitd559ab338aAuthor: henjkey <henjkey@gmail.com> Date: Thu Aug 13 18:42:41 2026 +0500 Map Controller Coordinates Target System Crosshair System Radar System
127 lines
3.9 KiB
C#
127 lines
3.9 KiB
C#
using System.Collections.Generic;
|
|
using Unity.Netcode;
|
|
using UnityEngine;
|
|
using UnityEngine.Events;
|
|
|
|
[DisallowMultipleComponent]
|
|
public sealed class NetworkShockwaveEmitter : NetworkBehaviour
|
|
{
|
|
private const int MaximumOverlaps = 256;
|
|
|
|
[SerializeField] private ShockwaveProfile profile;
|
|
[SerializeField] private Transform origin;
|
|
[SerializeField] private LayerMask physicsLayers = ~0;
|
|
[SerializeField] private UnityEvent shockwaveEmitted;
|
|
|
|
private readonly NetworkVariable<uint> sequence = new(
|
|
0,
|
|
NetworkVariableReadPermission.Everyone,
|
|
NetworkVariableWritePermission.Server);
|
|
|
|
private readonly Collider[] overlapBuffer = new Collider[MaximumOverlaps];
|
|
private readonly HashSet<Rigidbody> affectedBodies = new();
|
|
|
|
public ShockwaveProfile Profile => profile;
|
|
public Vector3 Origin => origin != null ? origin.position : transform.position;
|
|
public uint Sequence => sequence.Value;
|
|
|
|
public event System.Action Emitted;
|
|
|
|
public override void OnNetworkSpawn()
|
|
{
|
|
sequence.OnValueChanged += HandleSequenceChanged;
|
|
}
|
|
|
|
public override void OnNetworkDespawn()
|
|
{
|
|
sequence.OnValueChanged -= HandleSequenceChanged;
|
|
}
|
|
|
|
public bool EmitShockwave() => EmitShockwave(Origin);
|
|
|
|
public bool EmitShockwave(Vector3 worldOrigin)
|
|
{
|
|
if (!IsServer || !IsSpawned || profile == null)
|
|
return false;
|
|
|
|
ApplyToPlayers(worldOrigin);
|
|
ApplyToPhysics(worldOrigin);
|
|
sequence.Value++;
|
|
return true;
|
|
}
|
|
|
|
[ContextMenu("Debug/Emit Shockwave (Server Play Mode)")]
|
|
private void EmitFromContextMenu()
|
|
{
|
|
if (Application.isPlaying)
|
|
EmitShockwave();
|
|
}
|
|
|
|
private void ApplyToPlayers(Vector3 worldOrigin)
|
|
{
|
|
foreach (PlayerImpactController player in
|
|
FindObjectsByType<PlayerImpactController>(FindObjectsSortMode.None))
|
|
{
|
|
if (!player.IsSpawned)
|
|
continue;
|
|
|
|
Vector3 offset = player.transform.position - worldOrigin;
|
|
float distance = offset.magnitude;
|
|
if (!profile.TryEvaluate(distance, out ShockwaveZone zone))
|
|
continue;
|
|
|
|
Vector3 direction = CreateDirection(offset, zone.UpwardBias);
|
|
player.ApplyImpactOnServer(direction * zone.PlayerImpulse, zone);
|
|
}
|
|
}
|
|
|
|
private void ApplyToPhysics(Vector3 worldOrigin)
|
|
{
|
|
int count = Physics.OverlapSphereNonAlloc(
|
|
worldOrigin,
|
|
profile.MaximumRadius,
|
|
overlapBuffer,
|
|
physicsLayers,
|
|
QueryTriggerInteraction.Ignore);
|
|
|
|
affectedBodies.Clear();
|
|
for (int index = 0; index < count; index++)
|
|
{
|
|
Collider hit = overlapBuffer[index];
|
|
Rigidbody body = hit != null ? hit.attachedRigidbody : null;
|
|
if (body == null || body.isKinematic || !affectedBodies.Add(body) ||
|
|
body.GetComponentInParent<PlayerImpactController>() != null)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
Vector3 offset = body.worldCenterOfMass - worldOrigin;
|
|
if (!profile.TryEvaluate(offset.magnitude, out ShockwaveZone zone) ||
|
|
zone.RigidbodyImpulse <= 0f)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
body.AddForce(
|
|
CreateDirection(offset, zone.UpwardBias) * zone.RigidbodyImpulse,
|
|
ForceMode.Impulse);
|
|
}
|
|
}
|
|
|
|
private static Vector3 CreateDirection(Vector3 offset, float upwardBias)
|
|
{
|
|
if (offset.sqrMagnitude < 0.0001f)
|
|
offset = Vector3.up;
|
|
offset.Normalize();
|
|
return (offset + Vector3.up * Mathf.Clamp01(upwardBias)).normalized;
|
|
}
|
|
|
|
private void HandleSequenceChanged(uint previous, uint current)
|
|
{
|
|
if (current == previous)
|
|
return;
|
|
Emitted?.Invoke();
|
|
shockwaveEmitted?.Invoke();
|
|
}
|
|
}
|