Created
August 29, 2020 00:23
-
-
Save LukasKastern/27f215b1244ebd5390ffd899b70f54ff to your computer and use it in GitHub Desktop.
Simple NavMeshAgent with a rolling movement
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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