This script allows characters to slow down when moving on slopes. It works by comparing the angle of the floor they're on with a graph set by the user in its Inspector.
Note that this script will override the "Walk speed scale" and "Run speed scale" values set in the regular Player / NPC Inspectors.
To use it:
- Create a new C# script named SlopeSpeedControl, and paste in the code below
- Attach the Slope Speed Control component to your Player or NPC
- Set its "Flat Walk Speed" and "Flat Run Speed" Inspector values to match the character's "Walk speed scale" and "Run speed scale" values respectively
- Tweak the "Slope Curve" graph to suit. The x-axis represents the floor's slope angle (negative values equates to a downward slope), and the y-axis represents the multiplier to apply to the character's regular speed
SlopeSpeedControl.cs:
using UnityEngine;
using System.Collections;
namespace AC
{
public class SlopeSpeedControl : MonoBehaviour
{
[SerializeField] private AnimationCurve slopeCurve = new AnimationCurve (new Keyframe(-45f, 0.7f), new Keyframe(0f, 1f), new Keyframe (45f, 0.7f));
[SerializeField] private float flatWalkSpeed = 2f;
[SerializeField] private float flatRunSpeed = 6f;
[SerializeField] private bool showDebug = false;
private Char character;
private RaycastHit hit = new RaycastHit ();
private void Awake ()
{
character = GetComponent <Char>();
}
private void Update ()
{
if (character != null)
{
Vector3 rayStart = character.transform.position + new Vector3 (0f, 0.1f, 0f);
Ray floorRay = new Ray (rayStart, Vector3.down);
if (showDebug)
{
Debug.DrawRay (rayStart, -Vector3.up);
}
if (Physics.Raycast (floorRay, out hit, 1f, character.groundCheckLayerMask))
{
float slopeAngle = ((Vector3.Angle (hit.normal, character.TransformForward)) - 90);
float speedFactor = slopeCurve.Evaluate (slopeAngle);
if (showDebug)
{
Debug.Log ("Character: " + character.GetName () +", Slope angle: " + slopeAngle + ", Speed factor: " + speedFactor);
}
character.walkSpeedScale = flatWalkSpeed * speedFactor;
character.runSpeedScale = flatRunSpeed * speedFactor;
}
}
}
}
}