З вихідного коду
Рішення про сходи в коді: кожна сходинка - куб зі знятим колайдером, а під ними одна прихована повернута плита, на якій насправді стоять гравець і NavMesh. Два з трьох коментарів дописані для цієї сторінки, решта - дослівно.
public static void Stairs(Transform parent, string name, Vector3 start, Vector3 direction, float run,
float rise, float width, int steps, Material material)
{
var root = Empty(name, parent, Vector3.zero).transform;
Vector3 dir = new Vector3(direction.x, 0f, direction.z).normalized;
Vector3 side = Vector3.Cross(Vector3.up, dir);
float stepRun = run / steps;
float stepRise = rise / steps;
for (int i = 0; i < steps; i++)
{
float top = start.y + stepRise * (i + 1);
Vector3 centre = start + dir * (stepRun * (i + 0.5f));
centre.y = top - stepRise * 0.5f;
var go = GameObject.CreatePrimitive(PrimitiveType.Cube);
go.name = "Step";
go.transform.SetParent(root, false);
go.transform.localPosition = centre;
go.transform.localRotation = Quaternion.LookRotation(dir, Vector3.up);
go.transform.localScale = new Vector3(width, stepRise, stepRun);
go.GetComponent<MeshRenderer>().sharedMaterial = material;
Object.DestroyImmediate(go.GetComponent<Collider>()); // the eye gets steps
}
BuildRamp(root, start, dir, side, run, rise, width); // the feet get a slope
}
private static void BuildRamp(Transform parent, Vector3 start, Vector3 dir, Vector3 side,
float run, float rise, float width)
{
const float thickness = 0.4f;
float slope = Mathf.Sqrt(run * run + rise * rise);
Vector3 alongSlope = (dir * run + Vector3.up * rise).normalized;
Quaternion rotation = Quaternion.LookRotation(alongSlope, Vector3.Cross(alongSlope, side).normalized);
// Sit the ramp so its top face passes through the step noses.
Vector3 topMid = start + dir * (run * 0.5f) + Vector3.up * (rise * 0.5f);
Vector3 centre = topMid - rotation * Vector3.up * (thickness * 0.5f);
var go = GameObject.CreatePrimitive(PrimitiveType.Cube);
go.name = "RampCollider";
go.transform.SetParent(parent, false);
go.transform.localPosition = centre;
go.transform.localRotation = rotation;
go.transform.localScale = new Vector3(width, thickness, slope);
go.GetComponent<MeshRenderer>().enabled = false; // never drawn, always walked on
}