如何给Unity HingeJoint添加摩擦力?

问题描述 投票:0回答:3

我在 Unity 中将刚体附加到 HingeJoint。

它安装在关节锚点的中心。

为了阻止它掉落,我设置了

Use Motor = true
Target Velocity = 0
并向电机施加一些力。

但是,这并没有帮助,请看视频:

http://g.recordit.co/JJ0cmfT1Mb.gif

这是示例项目:https://drive.google.com/open?id=0B8QGeF3SuAgTNnozX05wTVJGZHc

重现问题的屏幕(没有代码): enter image description here

如何对关节施加摩擦力以阻止刚体移动?

设置带有阻尼器的弹簧或施加限制对我来说不是一个选择,因为当我向电机施加足够的扭矩(力)时,我需要正确旋转刚体。
如果我打开和关闭阻尼器/限制器,刚体沿下降方向旋转时移动速度会更快,而沿相反方向旋转时移动速度会更慢。

unity-game-engine game-physics physx
3个回答
2
投票

我已经组合了一种在铰链关节上施加摩擦力的行为。在这里:

using UnityEngine;

public class JointFriction : MonoBehaviour {

  [Tooltip("mulitiplier for the angular velocity for the torque to apply.")]
  public float Friction = 0.4f;

  private HingeJoint _hinge;
  private Rigidbody _thisBody;
  private Rigidbody _connectedBody;
  private Vector3 _axis;  //local space

  // Use this for initialization
  void Start () {
    _hinge = GetComponent<HingeJoint>();
    _connectedBody = _hinge.connectedBody;
    _axis = _hinge.axis;

    _thisBody = GetComponent<Rigidbody>();
  }

  // Update is called once per frame
  void FixedUpdate () {
    var angularV = _hinge.velocity;
    //Debug.Log("angularV " + angularV);
    var worldAxis = transform.TransformVector(_axis);
    var worldTorque = Friction * angularV * worldAxis;

    _thisBody.AddTorque(-worldTorque);
    _connectedBody.AddTorque(worldTorque);
  }
}

这回答了您问题的标题,这就是我找到它时正在寻找的内容。然而,这可能无法满足您从更详细的描述中获得的需求。

这会施加与角速度成正比的摩擦力,如果没有角速度,则不会施加力。这意味着在恒定的力(例如示例中的重力)下,它将始终以某种降低的速度移动。实际上,材料的缺陷和其他现实世界的混乱意味着对关节施加摩擦可以使它们在恒定扭矩下保持静止,但在游戏引擎中,您将需要一些其他扭矩来抵消恒定力。


0
投票

听起来你不需要重力。您可以在刚体的检查器中关闭重力。


0
投票

这是 2D 游戏的解决方案:

using UnityEngine;

public class HingeJointFriction2D : MonoBehaviour {
    [Tooltip("Multiplier for the angular velocity for the torque to apply.")]
    public float Friction = 0.4f;

    private HingeJoint2D _hinge;
    private Rigidbody2D _thisBody;
    private Rigidbody2D _connectedBody;

    void Start() {
        _hinge = GetComponent<HingeJoint2D>();
        _thisBody = GetComponent<Rigidbody2D>();
        _connectedBody = _hinge.connectedBody;
    }

    void FixedUpdate() {
        float angularV = _thisBody.angularVelocity - (_connectedBody ? _connectedBody.angularVelocity : 0);

        float torque = Friction * angularV;

        _thisBody.AddTorque(-torque);
        if (_connectedBody != null) {
            _connectedBody.AddTorque(torque);
        }
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.