角色坡度行为

时间:2018-04-21 19:08:15

标签: c# unity3d game-physics

我正在开发一款主要针对户外运动的游戏,因此我希望角色控件尽可能地感觉良好。

我目前正在处理的问题是斜坡行为:当站在不太陡峭的斜坡上时,角色不应向下滑动,而在太陡的斜坡上向下滑动。

我通过激活和停用刚体约束来实现这一点,具体取决于玩家在当前的地面角度。

private const RigidbodyConstraints DefaultConstraints = RigidbodyConstraints.FreezeRotation;
private const RigidbodyConstraints StayOnSlope = RigidbodyConstraints.FreezePositionX | RigidbodyConstraints.FreezePositionZ | DefaultConstraints;
private const RigidbodyConstraints SlideDownSlope = DefaultConstraints;

以单独的方法计算地面的角度,以度为单位返回向上向量与地面法线之间的角度。

private float GetGroundAngle()
{
    RaycastHit hit;
    if (Physics.Raycast(transform.position, Vector3.down, out hit, 0.5f))
    {
        return Vector3.Angle(Vector3.up, hit.normal);
    }
    return 0;
}

约束的实际激活和取消激活是在FixedUpdate方法中实现的。此外,玩家的移动速度越来越慢。

private void FixedUpdate()
{
    const float MAX_SLOPE_ANGLE = 45;

    // If the player is grounded, check the ground angle and prevent slope sliding
    float angle = GetGroundAngle();
    // Apply the constraints
    m_rigidbody.constraints = (m_movementVector.magnitude < Vector3.kEpsilon) && angle <= MAX_SLOPE_ANGLE ? StayOnSlope : SlideDownSlope;

    // Calculate the movement coefficient to ensure the player cannot run up slopes
    float slopeCoefficient = Mathf.Cos(angle * Mathf.Deg2Rad);
    // Calculate and apply the movement vector
    Vector3 movement = m_movementVector * slopeCoefficient * Time.fixedDeltaTime;
    m_rigidbody.MovePosition(m_rigidbody.position + movement);

    // ...
}

此功能的问题如下:

  • 当站在斜坡上时,玩家正确停止,但是当向一个太陡的斜坡移动时,玩家向下滑动,但会继续向下滑动,直到移动矢量被改变或根本没有输入。
    预期的结果是,一旦他在一个足够平坦的斜坡上行走,玩家将立即停止滑行,目前情况并非如此。
  • 激活和停用约束似乎有点......太难以在控制器内部使用。

有没有更好的方法来制作坡度运动行为?

1 个答案:

答案 0 :(得分:2)

  

当站在不太陡峭的斜坡上时,角色不应该向下滑动,而是在太陡的斜坡上向下滑动。

我相信CharacterController组件可能对您有用。

请注意,它具有可调节的坡度限制变量。

https://docs.unity3d.com/Manual/class-CharacterController.html

在Unity标准资产中有一个第一人称控制器,可以在Unity内的Unity中找到 - &gt;导入包 - &gt;字符。