FANDOM


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:

  1. Create a new C# script named SlopeSpeedControl, and paste in the code below
  2. Attach the Slope Speed Control component to your Player or NPC
  3. 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
  4. 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;
                }
            }
        }
        
    }

}
Community content is available under CC-BY-SA unless otherwise noted.