Unity检测地面坡度丨人物上坡检测
前言
此功能为,人物在爬坡等功能时可以检测地面坡度从而完成向某个方向给力或者完成其他操作
使用
其中我们创建了脚本GradeCalculation,把脚本挂载到人物上即可,或者有其他的使用方式,可自行拆分使用,注:其中需要修改地形的layer层级或者使用默认的就不用修改了。
代码
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
public class GradeCalculation : MonoBehaviour
{
private Vector3 mLastPosition; // 上一帧的位置
private Vector3 mForward; // 当前方向
public float NeedleDistance = 1.0f; // 针尖距离
public float NeedleHeightOffset = 1.0f; // 针尖高度偏移
// Start is called before the first frame update
void Start()
{
// 在这里进行初始化
}
// Update is called once per frame
void Update()
{
// 在每一帧更新时输出坡度的读数
Debug.Log("坡度的读数" + speedctr());
}
// 计算坡度的方法
private float speedctr()
{
if (mLastPosition == null)
{
mLastPosition = transform.position;
}
// 计算当前方向
Vector3 forward = (transform.position - mLastPosition);
mLastPosition = transform.position;
mForward = forward.normalized;
// 计算针尖位置
Vector3 pos = transform.position + (mForward * NeedleDistance);
pos.y += NeedleHeightOffset;
float steepness = 0.0f; // 坡度值初始化
// 创建射线以检测地面
Ray ray = new Ray(transform.position + new Vector3(0, NeedleHeightOffset, 0), Vector3.down);
RaycastHit hitCur;
// 如果射线与地面碰撞
if (Physics.Raycast(ray, out hitCur, 100.0f, LayerMask.GetMask("Default")))//“Default”是你的地面Layer层级名字
{
ray = new Ray(pos, Vector3.down);
// 沿着当前方向发射射线,按距离排序
var hitsForward = Physics.RaycastAll(ray, 100.0f, LayerMask.GetMask("Default")).OrderBy(h => h.distance).ToArray();
if (hitsForward.Count() == 0)
steepness = 0f; // 如果没有碰到地面,坡度为0
else
{
// 计算坡度
float deltaH = hitsForward[0].point.y - hitCur.point.y;
float dist = (hitsForward[0].point - hitCur.point).magnitude;
if (dist != 0)
{
steepness = Mathf.Asin(deltaH / dist) / Mathf.PI * 180.0f;
}
}
}
return steepness; // 返回坡度值
}
}