namespace HoM.Combat.Actions
[CreateAssetMenu(menuName = "HoM/Game Design/Actions/Movement Action")]
public class MovementAction : CombatAction
protected void RotateTowardsDirection(Vector3 dir)
var angle = 90 - Mathf.Atan2(dir.z, dir.x) * Mathf.Rad2Deg;
var euler = Quaternion.Euler(CombatActor.transform.localEulerAngles);
var newRot = Quaternion.Euler(euler.x, angle, euler.z);
CombatActor.transform.localRotation = Quaternion.Slerp(CombatActor.transform.localRotation, newRot, 0.5f);
protected IEnumerator RotateTowardsDirectionRoutine(Vector3 dir, float duration = 0.1f)
var angle = 90 - Mathf.Atan2(dir.z, dir.x) * Mathf.Rad2Deg;
var euler = Quaternion.Euler(CombatActor.transform.localEulerAngles);
var newRot = Quaternion.Euler(euler.x, angle, euler.z);
for (var i = 0f; i < duration; i += Time.deltaTime)
CombatActor.transform.localRotation =
Quaternion.Slerp(CombatActor.transform.localRotation, newRot, i / duration);
yield return new WaitForEndOfFrame();
protected Vector3 GetRandomPoint(float radius)
var actorPos = CombatActor.transform.position;
var activeRoom = ArenaLevelManager.Instance.currentActiveRoom;
var randomPoint = new Vector3(Random.Range(activeRoom.minimumX, activeRoom.maximumX), actorPos.y,
Random.Range(activeRoom.minimumZ, activeRoom.maximumZ));
var randomDirection = actorPos + (randomPoint - actorPos).normalized * radius;
var walkableMask = CombatActor.AgentType switch
Actor.NavMeshAgentType.Normal => 1 << NavMesh.GetAreaFromName("Walkable"),
Actor.NavMeshAgentType.Flying => 1 << NavMesh.GetAreaFromName("Flying"),
_ => throw new ArgumentOutOfRangeException()
if (NavMesh.SamplePosition(randomDirection, out var hit, radius, CombatActor.Agent.areaMask))
protected Vector3 GetRandomPointFromSpecificPosition(Vector3 position, float radius)
var randomDirection = position + Random.insideUnitSphere * radius;
var walkableMask = CombatActor.AgentType switch
Actor.NavMeshAgentType.Normal => 1 << NavMesh.GetAreaFromName("Walkable"),
Actor.NavMeshAgentType.Flying => 1 << NavMesh.GetAreaFromName("Flying"),
_ => throw new ArgumentOutOfRangeException()
if (NavMesh.SamplePosition(randomDirection, out var hit, radius, CombatActor.Agent.areaMask))
protected bool IsReachable(Vector3 currentDestination, int walkableMask = -1)
var path = new NavMeshPath();
var reachable = NavMesh.CalculatePath(CombatActor.transform.position, currentDestination,