using System ;
using System.Linq ;
using NUnit.Framework ;
using UnityEditor ;
using UnityEngine ;
using UnityEngine.AI ;
private NavMeshAgent m_NavMeshAgent ;
private Rigidbody m_Rigidbody ;
private NetworkCharacterState m_NetworkCharacterState ;
private NavigationSystem m_NavigationSystem ;
private NavMeshPath m_DesiredMovementPath ;
private DynamicNavPath m_NavPath ;
private MovementState m_MovementState ;
private ServerCharacter m_CharLogic ;
// On the server enable navMeshAgent and initialize
m_NavMeshAgent . enabled = true ;
m_NetworkCharacterState . OnReceivedClientInput + = OnReceivedClientInput ;
m_DesiredMovement Path = new NavMesh Path ( ) ;
m_Nav Path = new Dynamic NavPath( m_NavMeshAgent , m_NavigationSystem ) ;
private void OnReceivedClientInput ( Vector3 position )
private void OnReceivedClientInput ( Vector3 position )
{
m_CharLogic . ClearActions ( ) ; //a fresh movement request trumps whatever we were doing before.
SetMovementTarget ( position ) ;
public void SetMovementTarget ( Vector3 position )
{
m_MovementState = MovementState . PathFollowing ;
m_NavPath . SetTargetPosition ( position ) ;
}
// Recalculate navigation path only on target change.
m_NavMeshAgent . CalculatePath ( position , m_DesiredMovementPath ) ;
/// <summary>
/// Follow the given transform until it is reached.
/// </summary>
/// <param name="followTransform">The transform to follow</param>
public void FollowTransform ( Transform followTransform )
{
m_MovementState = MovementState . PathFollowing ;
m_NavPath . FollowTransform ( followTransform ) ;
}
/// <summary>
{
//Luke, is there anything else I should do to clear move state here?
m_NavPath . Clear ( ) ;
m_MovementState = MovementState . Idle ;
}
m_NetworkCharacterState = GetComponent < NetworkCharacterState > ( ) ;
m_CharLogic = GetComponent < ServerCharacter > ( ) ;
m_Rigidbody = GetComponent < Rigidbody > ( ) ;
m_NavigationSystem = GameObject . FindGameObjectWithTag ( NavigationSystem . NavigationSytemTag ) . GetComponent < NavigationSystem > ( ) ;
}
private void FixedUpdate ( )
// Send new position values to the client
m_NetworkCharacterState . NetworkPosition . Value = transform . position ;
m_NetworkCharacterState . NetworkRotationY . Value = transform . rotation . eulerAngles . y ;
m_NetworkCharacterState . NetworkMovementSpeed . Value = m_MovementState = = MovementState . Idle ? 0 : m_MovementSpeed ;
m_NetworkCharacterState . NetworkMovementSpeed . Value =
m_MovementState = = MovementState . Idle ? 0 : m_MovementSpeed ;
private void Movement ( )
private void OnValidate ( )
var corners = m_DesiredMovementPath . corners ;
// If we don't have a movement path stop moving
if ( corners . Length = = 0 )
if ( gameObject . scene . rootCount > 1 ) // Hacky way for checking if this is a scene object or a prefab instance and not a prefab definition.
m_MovementState = MovementState . Idle ;
return ;
Assert . NotNull (
GameObject . FindGameObjectWithTag ( NavigationSystem . NavigationSytemTag ) ? . GetComponent < NavigationSystem > ( ) ,
$"NavigationSystem not found. Is there a NavigationSystem Behaviour in the Scene and does its GameObject have the {NavigationSystem.NavigationSytemTag} tag? {gameObject.scene.name}"
) ;
}
private void OnDestroy ( )
{
m_NavPath . Dispose ( ) ;
}
private void Movement ( )
{
// If there is less distance to move left in the path than our desired amount
if ( Vector3 . SqrMagnitude ( corners [ corners . Length - 1 ] - transform . position ) < ( desiredMovementAmount * desiredMovementAmount ) )
var movementVector = m_NavPath . MoveAlongPath ( desiredMovementAmount ) ;
// If we didn't move stop moving.
if ( movementVector = = Vector3 . zero )
// Set to destination and stop moving
transform . position = corners [ corners . Length - 1 ] ;
// Get the direction to move along based on the calculated path.
var direction = corners . Length > 1
? ( corners [ 1 ] - corners [ 0 ] ) . normalized
: throw new InvalidOperationException ( "Navigation path should have a start and end position" ) ;
var movementVector = direction * desiredMovementAmount ;
//fixme--is this right? If I don't do this the Rigidbody is "left behind", and doesn't move with the GameObject.
//also see ClientCharacterMovement before deleting this comment.
// After moving adjust the position of the dynamic rigidbody.
m_NavMeshAgent . CalculatePath ( corners [ corners . Length - 1 ] , m_DesiredMovementPath ) ;
}
}
}