using Unity.Netcode;
using UnityEngine;
namespace Unity.Multiplayer.Samples.BossRoom.Server
{
///
/// The "Target" Action is not a skill, but rather the result of a user left-clicking an enemy. This
/// Action runs persistently, and automatically resets the NetworkCharacterState.Target property if the
/// target becomes ineligible (dies or disappears). Note that while Actions in general can have multiple targets,
/// you as a player can only have a single target selected at a time (the character that your target reticule appears under).
///
public class TargetAction : Action
{
public TargetAction(ServerCharacter parent, ref ActionRequestData data) : base(parent, ref data) { }
private ServerCharacterMovement m_Movement;
public override bool Start()
{
//we must always clear the existing target, even if we don't run. This is how targets get cleared--running a TargetAction
//with no target selected.
m_Parent.NetState.TargetId.Value = 0;
//there can only be one TargetAction at a time!
m_Parent.RunningActions.CancelRunningActionsByLogic(ActionLogic.Target, true, this);
if (Data.TargetIds == null || Data.TargetIds.Length == 0) { return false; }
m_Movement = m_Parent.Movement;
m_Parent.NetState.TargetId.Value = TargetId;
FaceTarget(TargetId);
return true;
}
public override bool Update()
{
bool isValid = ActionUtils.IsValidTarget(TargetId);
if (m_Parent.RunningActions.RunningActionCount == 1 && !m_Movement.IsMoving() && isValid)
{
//we're the only action running, and we're not moving, so let's swivel to face our target, just to be cool!
FaceTarget(TargetId);
}
return isValid;
}
public override void Cancel()
{
if (m_Parent.NetState.TargetId.Value == TargetId)
{
m_Parent.NetState.TargetId.Value = 0;
}
}
private ulong TargetId { get { return Data.TargetIds[0]; } }
///
/// Only call this after validating the target via IsValidTarget.
///
///
private void FaceTarget(ulong targetId)
{
if (NetworkManager.Singleton.SpawnManager.SpawnedObjects.TryGetValue(targetId, out var targetObject))
{
Vector3 targetObjectPosition;
if (targetObject.TryGetComponent(out ServerCharacter serverCharacter))
{
targetObjectPosition = serverCharacter.physicsWrapper.Transform.position;
}
else
{
targetObjectPosition = targetObject.transform.position;
}
Vector3 diff = targetObjectPosition - m_Parent.physicsWrapper.Transform.position;
diff.y = 0;
if (diff != Vector3.zero)
{
m_Parent.physicsWrapper.Transform.forward = diff;
}
}
}
}
}