using Unity.BossRoom.Gameplay.Actions; using Unity.BossRoom.Gameplay.GameplayObjects.Character; using Unity.Netcode; using UnityEngine; [CreateAssetMenu(menuName = "BossRoom/Actions/Swap Action")] public class SwapAction : Action { private ServerCharacter m_TargetCharacter; // The character to swap with private Vector3 m_TargetOriginalPosition; // Target's original position private Vector3 m_ServerCharacterOriginalPosition; // Server character's original position private bool m_MovementStarted = false; // Ensures movement commands are sent only once public override bool OnStart(ServerCharacter serverCharacter) { // Validate the target if (Data.TargetIds == null || Data.TargetIds.Length == 0) { Debug.LogError("SwapAction failed: No target specified!"); return false; // End the action immediately } // Retrieve the target character if (!NetworkManager.Singleton.SpawnManager.SpawnedObjects.TryGetValue(Data.TargetIds[0], out var targetObject) || !targetObject.TryGetComponent(out m_TargetCharacter)) { Debug.LogError("SwapAction failed: Target is invalid or missing!"); return false; // End the action immediately } // Store original positions m_ServerCharacterOriginalPosition = serverCharacter.physicsWrapper.Transform.position; m_TargetOriginalPosition = m_TargetCharacter.physicsWrapper.Transform.position; // Command both characters to move to each other's original positions serverCharacter.ServerSendCharacterInputRpc(m_TargetOriginalPosition); m_TargetCharacter.ServerSendCharacterInputRpc(m_ServerCharacterOriginalPosition); Debug.Log("SwapAction: Movement commands sent to both players."); m_MovementStarted = true; return true; // Keep the action active } public override bool OnUpdate(ServerCharacter serverCharacter) { if (!m_MovementStarted) { Debug.LogError("SwapAction OnUpdate called without movement initialization!"); return false; // Fail-safe: End the action } // Check if both characters have reached their destinations bool serverCharacterReached = Vector3.Distance(serverCharacter.physicsWrapper.Transform.position, m_TargetOriginalPosition) < 0.1f; bool targetCharacterReached = Vector3.Distance(m_TargetCharacter.physicsWrapper.Transform.position, m_ServerCharacterOriginalPosition) < 0.1f; if (serverCharacterReached && targetCharacterReached) { Debug.Log("SwapAction: Both players have swapped positions successfully."); return false; // End the action } return true; // Continue the action until both characters reach their destinations } public override void Reset() { base.Reset(); m_TargetCharacter = null; m_TargetOriginalPosition = Vector3.zero; m_ServerCharacterOriginalPosition = Vector3.zero; m_MovementStarted = false; } }