Hey @Brian_Trotter @bixarrio and other friends
Currently I’m working on an “Off-the-NavMesh” AI Controller, something to essentially allow NPCs, like patrolling boats for my particular example, or maybe flying planes even, to essentially move off the NavMesh in patrolling states. Problem is, I’m facing a lot of challenges with the code as our code relies heavily on NavMeshAgents, so I seek some help here today. Here’s my current ‘BoatPatrollingState.cs’ script, which I’m currently trying to develop:
using System.Collections;
using System.Collections.Generic;
using RPG.Control;
using UnityEditor.Experimental.GraphView;
using UnityEngine;
public class BoatPatrolState : BoatBaseState
{
private const string NextPatrolPointIndexKey = "NextPatrolPointIndex";
public BoatPatrolState(BoatStateMachine stateMachine) : base(stateMachine) {}
private float movementSpeed = 0.5f;
private float acceptanceRadius = 3f;
private float dwellTime = 2f;
private Vector3 targetPatrolPoint;
public override void Enter()
{
if (stateMachine.GetBoatLastAttacker() != null && !stateMachine.CooldownTokenManager.HasCooldown("BoatAggro"))
{
stateMachine.ClearLastBoatAttacker();
}
if (stateMachine.PatrolPath == null)
{
stateMachine.SwitchState(new BoatIdleState(stateMachine));
return;
}
int index;
if (stateMachine.Blackboard.ContainsKey(NextPatrolPointIndexKey))
{
index = stateMachine.Blackboard.GetValueAsInt(NextPatrolPointIndexKey);
}
else
{
index = stateMachine.PatrolPath.GetNearestIndex(stateMachine.transform.position);
}
targetPatrolPoint = stateMachine.PatrolPath.GetWaypoint(index);
PatrolPoint patrolPoint = stateMachine.PatrolPath.GetPatrolPoint(index);
if (patrolPoint)
{
movementSpeed = stateMachine.MovementSpeed * patrolPoint.SpeedModifier;
acceptanceRadius = patrolPoint.AcceptanceRadius;
dwellTime = patrolPoint.DwellTime;
}
else
{
movementSpeed = stateMachine.MovementSpeed;
}
acceptanceRadius *= acceptanceRadius;
stateMachine.Blackboard[NextPatrolPointIndexKey] = stateMachine.PatrolPath.GetNextIndex(index);
}
public override void Tick(float deltaTime)
{
if (IsAggrevated())
{
stateMachine.Blackboard.Remove(NextPatrolPointIndexKey);
stateMachine.SwitchState(new BoatChasingState(stateMachine));
return;
}
if (IsInAcceptanceRange())
{
stateMachine.SwitchState(new BoatDwellState(stateMachine));
return;
}
Vector3 lastPosition = stateMachine.transform.position;
MoveToWayPoint(deltaTime);
Vector3 deltaMovement = lastPosition - stateMachine.transform.position;
float deltaMagnitude = deltaMovement.magnitude;
// Find a way to get the direction without using the NavMeshAgent
if (deltaMagnitude > 0)
{
// Find a way to face the movement direction, without using the direction that relies on the NavMeshAgent's desired velocity
}
else
{
// Find a way to face the movement direction, without using the direction that relies on the NavMeshAgent's desired velocity
}
}
public override void Exit()
{
// Without a NavMeshAgent, there's not much to write here
}
private bool IsInAcceptanceRange()
{
return (stateMachine.transform.position - targetPatrolPoint).sqrMagnitude < acceptanceRadius;
}
private void MoveToWayPoint(float deltaTime)
{
// You'll need to find a way here to get the direction, without using the NavMeshAgent
}
// Face Movement Direction here, but without the NavMeshAgent
// Work on a Boat Dismounting State in here, something to invoke in 'PlayerBoatDrivingState.Exit()'
}
As you can see, it’s missing a few things here and there. Any idea what modifications will need to be done to get patrol paths that are independent of the NavMeshAgent to work? Thanks in advance
Also does it make sense to have a Character Controller on a ship?