thibaud-d
1/15/2017 - 4:42 PM

Script allowing a physics enabled character to hop over small steps/fences

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;
		}

	}

}