Script allowing a physics enabled character to hop over small steps/fences
using UnityEngine;
public class Hop : MonoBehaviour {
public float low=0.14f; // min hopping height
public float high=0.6f; // max hopping height
public float distance=1.0f; // distance to hop
public float cooldown = 0.5f; // min. time between hops
public float strength=2.5f; // impulse in Newtons/kg
public float minSpeed = 0.3f; // min speed to hop
[Header("Debug")]
public float countdown = 1f; // initial countdown
public float speed = 0f; // current speed
void Update () {
if (countdown > 0f) {
countdown -= Time.deltaTime;
countdown = countdown < 0f ? 0f : countdown;
return;
}
Rigidbody body = GetComponentInChildren<Rigidbody> ();
Vector3 u = body.velocity;
u.y = 0.0f;
speed = u.magnitude;
// Too slow to hop
// This also avoids false positive, for example
// hopping when the player stop right after dropping down from
// a step, which can cause slight backtracking depending on
// locomotion method
if (speed<minSpeed) return;
Vector3 P = transform.position;
u.Normalize ();
Vector3 up = Vector3.up;
Vector3 A0 = P + up * low;
Vector3 B0 = A0 + distance * u;
Vector3 A1 = P + up * high;
Vector3 B1 = A1 + distance * u;
Debug.DrawLine (A0, B0, Color.cyan);
Debug.DrawLine (A1, B1, Color.red);
RaycastHit hit1;
RaycastHit hit2;
bool didHit1=Physics.Raycast (A0, u, out hit1, distance);
bool didHit2=Physics.Raycast (A1, u, out hit2, distance);
// Too high to hop
if (didHit2) return;
// Let's hop
if (didHit1) {
body.AddForce (up*body.mass*strength, ForceMode.Impulse);
countdown = cooldown;
}
}
}