Skip to content

Instantly share code, notes, and snippets.

@LukasKastern
Created August 29, 2020 00:23
Show Gist options
  • Save LukasKastern/27f215b1244ebd5390ffd899b70f54ff to your computer and use it in GitHub Desktop.
Save LukasKastern/27f215b1244ebd5390ffd899b70f54ff to your computer and use it in GitHub Desktop.
Simple NavMeshAgent with a rolling movement
using UnityEngine;
using UnityEngine.AI;
[RequireComponent(typeof(NavMeshAgent))]
public class RollBehavior : MonoBehaviour
{
/// <summary>
/// Distance the agent will elapse when rolling per second.
/// </summary>
public float rollSpeed;
/// <summary>
/// Max Distance the agent will role
/// </summary>
public float maxRollDistance;
public LayerMask cameraCastMask;
private NavMeshAgent m_agent;
private Camera m_cameraToRaycastFrom;
private bool m_isRolling;
private float m_remainingRoleDuration;
private Vector3 m_rollDirection;
private void Awake( )
{
m_agent = GetComponent<NavMeshAgent>( );
if ( m_cameraToRaycastFrom == null )
m_cameraToRaycastFrom = Camera.main;
}
private void Update( )
{
var doMoveToPosition = Input.GetKeyDown( KeyCode.Mouse0 );
var doRoll = Input.GetKeyDown( KeyCode.LeftControl );
if ( m_isRolling )
{
m_remainingRoleDuration -= Time.deltaTime;
if ( m_remainingRoleDuration < 0 )
{
m_isRolling = false;
m_agent.velocity = Vector3.zero;
}
else
{
m_agent.velocity = m_rollDirection * rollSpeed;
m_agent.ResetPath( );
return;
}
}
if ( !doMoveToPosition && !doRoll )
return;
var ray = m_cameraToRaycastFrom.ScreenPointToRay( Input.mousePosition );
var didCameraCastDetectGround = Physics.Raycast( ray, out var rayHit, 150, cameraCastMask.value );
if ( !didCameraCastDetectGround ) return;
//Find closest point on NavMesh
NavMesh.SamplePosition( rayHit.point, out var navMeshHit, 100, -1 );
if ( !navMeshHit.hit ) return; //Point is not on NavMesh, ignore input
var closestPointOnNavMesh = navMeshHit.position;
if ( doMoveToPosition )
{
m_agent.SetDestination( closestPointOnNavMesh );
}
else
{
var heading = closestPointOnNavMesh - transform.position;
var roleTargetPosition = Vector3.ClampMagnitude( heading, maxRollDistance );
m_rollDirection = Vector3.Normalize( heading );
m_remainingRoleDuration = Vector3.Magnitude( roleTargetPosition ) / rollSpeed; //How long will it take for the Agent to roll to the target position?
m_isRolling = true;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment