enemy ai
This commit is contained in:
216
Game/Scripts/Networking/SteamNetworkTransform.cs
Normal file
216
Game/Scripts/Networking/SteamNetworkTransform.cs
Normal file
@@ -0,0 +1,216 @@
|
||||
using Steamworks;
|
||||
using UnityEngine;
|
||||
|
||||
namespace MegaKoop.Game.Networking
|
||||
{
|
||||
/// <summary>
|
||||
/// Host-authoritative transform replication that mirrors state to all peers via Steam P2P messages.
|
||||
/// </summary>
|
||||
[DisallowMultipleComponent]
|
||||
public class SteamNetworkTransform : MonoBehaviour
|
||||
{
|
||||
[Header("References")]
|
||||
[SerializeField] private Transform targetTransform;
|
||||
[SerializeField] private NetworkIdentity identity;
|
||||
[SerializeField] private Rigidbody trackedRigidbody;
|
||||
[SerializeField] private UnityEngine.AI.NavMeshAgent trackedNavMeshAgent;
|
||||
|
||||
[Header("Authority")]
|
||||
[SerializeField] private bool authorityIsHost = true;
|
||||
[SerializeField] private bool simulateWhenDisconnected = true;
|
||||
|
||||
[Header("Synchronization")]
|
||||
[SerializeField] private float broadcastInterval = 0.05f;
|
||||
[SerializeField] private float remoteLerpSpeed = 12f;
|
||||
[SerializeField] private float teleportThreshold = 4f;
|
||||
|
||||
private SteamCoopNetworkManager networkManager;
|
||||
private float broadcastTimer;
|
||||
private bool isRegistered;
|
||||
private Vector3 remoteTargetPosition;
|
||||
private Quaternion remoteTargetRotation;
|
||||
private Vector3 remoteTargetVelocity;
|
||||
private bool haveRemoteState;
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
if (targetTransform == null)
|
||||
{
|
||||
targetTransform = transform;
|
||||
}
|
||||
|
||||
if (identity == null)
|
||||
{
|
||||
identity = GetComponent<NetworkIdentity>();
|
||||
}
|
||||
|
||||
if (trackedRigidbody == null)
|
||||
{
|
||||
trackedRigidbody = GetComponent<Rigidbody>();
|
||||
}
|
||||
|
||||
if (trackedNavMeshAgent == null)
|
||||
{
|
||||
trackedNavMeshAgent = GetComponent<UnityEngine.AI.NavMeshAgent>();
|
||||
}
|
||||
|
||||
remoteTargetPosition = targetTransform.position;
|
||||
remoteTargetRotation = targetTransform.rotation;
|
||||
remoteTargetVelocity = Vector3.zero;
|
||||
broadcastTimer = Random.Range(0f, Mathf.Max(0.01f, broadcastInterval));
|
||||
}
|
||||
|
||||
private void OnEnable()
|
||||
{
|
||||
EnsureNetworkManager();
|
||||
RegisterHandlers();
|
||||
}
|
||||
|
||||
private void OnDisable()
|
||||
{
|
||||
UnregisterHandlers();
|
||||
}
|
||||
|
||||
private void Update()
|
||||
{
|
||||
RefreshNetworkManager();
|
||||
|
||||
if (HasAuthority())
|
||||
{
|
||||
broadcastTimer -= Time.deltaTime;
|
||||
if (broadcastTimer <= 0f)
|
||||
{
|
||||
BroadcastState();
|
||||
broadcastTimer = Mathf.Max(0.01f, broadcastInterval);
|
||||
}
|
||||
}
|
||||
else if (haveRemoteState)
|
||||
{
|
||||
float lerpFactor = Mathf.Clamp01(remoteLerpSpeed * Time.deltaTime);
|
||||
Vector3 currentPosition = targetTransform.position;
|
||||
float sqrDistance = (remoteTargetPosition - currentPosition).sqrMagnitude;
|
||||
if (sqrDistance >= teleportThreshold * teleportThreshold)
|
||||
{
|
||||
targetTransform.SetPositionAndRotation(remoteTargetPosition, remoteTargetRotation);
|
||||
}
|
||||
else
|
||||
{
|
||||
targetTransform.position = Vector3.Lerp(currentPosition, remoteTargetPosition, lerpFactor);
|
||||
targetTransform.rotation = Quaternion.Slerp(targetTransform.rotation, remoteTargetRotation, lerpFactor);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void RefreshNetworkManager()
|
||||
{
|
||||
if (networkManager == null)
|
||||
{
|
||||
networkManager = SteamCoopNetworkManager.Instance;
|
||||
if (networkManager != null && isActiveAndEnabled)
|
||||
{
|
||||
RegisterHandlers();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void EnsureNetworkManager()
|
||||
{
|
||||
RefreshNetworkManager();
|
||||
}
|
||||
|
||||
private bool HasAuthority()
|
||||
{
|
||||
if (!authorityIsHost)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (networkManager == null)
|
||||
{
|
||||
return simulateWhenDisconnected;
|
||||
}
|
||||
|
||||
if (!networkManager.IsConnected)
|
||||
{
|
||||
return simulateWhenDisconnected;
|
||||
}
|
||||
|
||||
return networkManager.IsHost;
|
||||
}
|
||||
|
||||
private void BroadcastState()
|
||||
{
|
||||
if (identity == null || targetTransform == null || networkManager == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Vector3 velocity = Vector3.zero;
|
||||
if (trackedNavMeshAgent != null && trackedNavMeshAgent.enabled)
|
||||
{
|
||||
velocity = trackedNavMeshAgent.velocity;
|
||||
}
|
||||
else if (trackedRigidbody != null)
|
||||
{
|
||||
velocity = trackedRigidbody.linearVelocity;
|
||||
}
|
||||
|
||||
var message = new CharacterTransformMessage(identity.NetworkId, targetTransform.position, targetTransform.rotation, velocity);
|
||||
byte[] payload = CharacterTransformMessage.Serialize(message);
|
||||
networkManager.SendToAll(NetworkMessageType.CharacterTransform, payload, EP2PSend.k_EP2PSendUnreliableNoDelay);
|
||||
}
|
||||
|
||||
private void RegisterHandlers()
|
||||
{
|
||||
if (isRegistered || networkManager == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
networkManager.RegisterHandler(NetworkMessageType.CharacterTransform, HandleTransformMessage);
|
||||
isRegistered = true;
|
||||
}
|
||||
|
||||
private void UnregisterHandlers()
|
||||
{
|
||||
if (!isRegistered || networkManager == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
networkManager.UnregisterHandler(NetworkMessageType.CharacterTransform, HandleTransformMessage);
|
||||
isRegistered = false;
|
||||
}
|
||||
|
||||
private void HandleTransformMessage(NetworkMessage message)
|
||||
{
|
||||
if (identity == null || targetTransform == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (HasAuthority())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
CharacterTransformMessage transformMessage = CharacterTransformMessage.Deserialize(message.Payload);
|
||||
if (transformMessage.NetworkId != identity.NetworkId)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
remoteTargetPosition = transformMessage.Position;
|
||||
remoteTargetRotation = transformMessage.Rotation;
|
||||
remoteTargetVelocity = transformMessage.Velocity;
|
||||
haveRemoteState = true;
|
||||
}
|
||||
|
||||
private void OnValidate()
|
||||
{
|
||||
broadcastInterval = Mathf.Max(0.01f, broadcastInterval);
|
||||
remoteLerpSpeed = Mathf.Max(0f, remoteLerpSpeed);
|
||||
teleportThreshold = Mathf.Max(0.01f, teleportThreshold);
|
||||
}
|
||||
}
|
||||
}
|
||||
2
Game/Scripts/Networking/SteamNetworkTransform.cs.meta
Normal file
2
Game/Scripts/Networking/SteamNetworkTransform.cs.meta
Normal file
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 88efaaed4187a0ee8ad63b619f65e970
|
||||
Reference in New Issue
Block a user