You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
126 lines
4.5 KiB
C#
126 lines
4.5 KiB
C#
3 weeks ago
|
using System;
|
||
|
using Unity.BossRoom.Gameplay.GameplayObjects.Character;
|
||
|
using Unity.Netcode;
|
||
|
using UnityEngine;
|
||
|
|
||
|
namespace Unity.BossRoom.Gameplay.Actions
|
||
|
{
|
||
|
[CreateAssetMenu(menuName = "BossRoom/Actions/Chase Action")]
|
||
|
public class ChaseAction : Action
|
||
|
{
|
||
|
private NetworkObject m_Target;
|
||
|
|
||
|
Transform m_TargetTransform;
|
||
|
|
||
|
/// <summary>
|
||
|
/// Called when the Action starts actually playing (which may be after it is created, because of queueing).
|
||
|
/// </summary>
|
||
|
/// <returns>false if the action decided it doesn't want to run after all, true otherwise. </returns>
|
||
|
public override bool OnStart(ServerCharacter serverCharacter)
|
||
|
{
|
||
|
if (!HasValidTarget())
|
||
|
{
|
||
|
Debug.Log("Failed to start ChaseAction. The target entity wasn't submitted or doesn't exist anymore");
|
||
|
return ActionConclusion.Stop;
|
||
|
}
|
||
|
|
||
|
m_Target = NetworkManager.Singleton.SpawnManager.SpawnedObjects[m_Data.TargetIds[0]];
|
||
|
|
||
|
if (PhysicsWrapper.TryGetPhysicsWrapper(m_Data.TargetIds[0], out var physicsWrapper))
|
||
|
{
|
||
|
m_TargetTransform = physicsWrapper.Transform;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
m_TargetTransform = m_Target.transform;
|
||
|
}
|
||
|
|
||
|
Vector3 currentTargetPos = m_TargetTransform.position;
|
||
|
|
||
|
if (StopIfDone(serverCharacter))
|
||
|
{
|
||
|
serverCharacter.physicsWrapper.Transform.LookAt(currentTargetPos); //even if we didn't move, snap to face the target!
|
||
|
return ActionConclusion.Stop;
|
||
|
}
|
||
|
|
||
|
if (!serverCharacter.Movement.IsPerformingForcedMovement())
|
||
|
{
|
||
|
serverCharacter.Movement.FollowTransform(m_TargetTransform);
|
||
|
}
|
||
|
return ActionConclusion.Continue;
|
||
|
}
|
||
|
|
||
|
public override void Reset()
|
||
|
{
|
||
|
base.Reset();
|
||
|
m_Target = null;
|
||
|
m_TargetTransform = null;
|
||
|
}
|
||
|
|
||
|
/// <summary>
|
||
|
/// Returns true if our ActionRequestData came with a valid target. For the ChaseAction, this is pretty liberal (could be friend or foe, could be
|
||
|
/// dead or alive--just needs to be present).
|
||
|
/// </summary>
|
||
|
private bool HasValidTarget()
|
||
|
{
|
||
|
return m_Data.TargetIds != null &&
|
||
|
m_Data.TargetIds.Length > 0 &&
|
||
|
NetworkManager.Singleton.SpawnManager.SpawnedObjects.ContainsKey(m_Data.TargetIds[0]);
|
||
|
}
|
||
|
|
||
|
/// <summary>
|
||
|
/// Tests to see if we've reached our target. Returns true if we've reached our target, false otherwise (in which case it also stops our movement).
|
||
|
/// </summary>
|
||
|
private bool StopIfDone(ServerCharacter parent)
|
||
|
{
|
||
|
if (m_TargetTransform == null)
|
||
|
{
|
||
|
//if the target disappeared on us, then just stop.
|
||
|
Cancel(parent);
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
float distToTarget2 = (parent.physicsWrapper.Transform.position - m_TargetTransform.position).sqrMagnitude;
|
||
|
if ((m_Data.Amount * m_Data.Amount) > distToTarget2)
|
||
|
{
|
||
|
//we made it! we're done.
|
||
|
Cancel(parent);
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
/// <summary>
|
||
|
/// Called each frame while the action is running.
|
||
|
/// </summary>
|
||
|
/// <returns>true to keep running, false to stop. The Action will stop by default when its duration expires, if it has a duration set. </returns>
|
||
|
public override bool OnUpdate(ServerCharacter clientCharacter)
|
||
|
{
|
||
|
if (StopIfDone(clientCharacter)) { return ActionConclusion.Stop; }
|
||
|
|
||
|
// Keep re-assigning our chase target whenever possible.
|
||
|
// This way, if we get Knocked Back mid-chase, we pick right back up and continue the chase.
|
||
|
if (!clientCharacter.Movement.IsPerformingForcedMovement())
|
||
|
{
|
||
|
clientCharacter.Movement.FollowTransform(m_TargetTransform);
|
||
|
}
|
||
|
|
||
|
return ActionConclusion.Continue;
|
||
|
}
|
||
|
|
||
|
public override void Cancel(ServerCharacter serverCharacter)
|
||
|
{
|
||
|
if (serverCharacter.Movement && !serverCharacter.Movement.IsPerformingForcedMovement())
|
||
|
{
|
||
|
serverCharacter.Movement.CancelMove();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public override bool OnUpdateClient(ClientCharacter clientCharacter)
|
||
|
{
|
||
|
return ActionConclusion.Continue;
|
||
|
}
|
||
|
}
|
||
|
}
|