首页 > 其他分享 >2d物理引擎学习 - 斜坡上下滑的物体

2d物理引擎学习 - 斜坡上下滑的物体

时间:2024-01-13 16:11:07浏览次数:30  
标签:rigidbodyA Vector2 float 2d 引擎 ra rb 斜坡 rigidbodyB

效果

 

代码只是在之前的基础上增加了重力和摩擦力,重力的实现就是给物体加一个持续的力(即:Fg = m * g),摩擦力就是切线方向加一个修正冲量。

 

代码和之前的主要区别

1) 刚体MyRigidbody增加一个Friction,摩擦系数属性

2) MyRigidbody.PostSeperation中增加切线方向的冲量

private void PostSeperation(float dt, CollisionPair collisionPair)
{
    var rigidbodyA = collisionPair.m_RigidbodyA;
    var rigidbodyB = collisionPair.m_RigidbodyB;
    float mergeFriction = Mathf.Sqrt(rigidbodyA.Friction * rigidbodyB.Friction);

    for (int i = 0; i < collisionPair.m_NumContacts; ++i)
    {
        var contact = collisionPair.m_Contacts[i];
        Vector2 ra = contact.m_Point - rigidbodyA.Position;
        Vector2 rb = contact.m_Point - rigidbodyB.Position;
        var relativeV = rigidbodyB.GetPointVelocity(rb) - rigidbodyA.GetPointVelocity(ra);

        var normal = contact.m_Normal;
        float relativeVN = Vector2.Dot(relativeV, normal); //投影到法向量
        //if (relativeVN > 0) //相对速度>0时, 表明没有碰撞趋势了
        //    return;

        float kMassNormal = rigidbodyA.InvMass + rigidbodyB.InvMass;
        float raN = Vector2.Dot(ra, normal);
        float rbN = Vector2.Dot(rb, normal);
        kMassNormal += rigidbodyA.InvInertia * (Vector2.Dot(ra, ra) - raN * raN) + rigidbodyB.InvInertia * (Vector2.Dot(rb, rb) - rbN * rbN);
        float massEffectiveT = 1 / kMassNormal;
        //Δp = (1 + e) * (v2 - v1) / kMass
        float deltaPN = (1 + m_Elasticity) * relativeVN * massEffectiveT;
        deltaPN = -deltaPN; //对Δp取反, 主要是为了让累加冲量是正值
        deltaPN = Mathf.Max(deltaPN, 0); //冲量为负, 碰撞后就加速了, 这样不对
        
        Vector2 impulseN = deltaPN * normal; //转为矢量
        rigidbodyA.ApplyImpulse(-impulseN);
        rigidbodyA.ApplyTorqueImpulse(ra, -impulseN);

        rigidbodyB.ApplyImpulse(impulseN);
        rigidbodyB.ApplyTorqueImpulse(rb, impulseN);

        //摩擦力(切线方向)
        relativeV = rigidbodyB.GetPointVelocity(rb) - rigidbodyA.GetPointVelocity(ra); //上面的冲量生效后, 再计算相对速度

        var tangent = new Vector2(normal.y, -normal.x); //切线(顺时针)
        float relativeVT = Vector2.Dot(relativeV, tangent); //投影到切线方向
        relativeVT = -relativeVT; //取反让值为正(与运动方向相同)

        float kMassTangent = rigidbodyA.InvMass + rigidbodyB.InvMass;
        float raT = Vector2.Dot(ra, tangent);
        float rbT = Vector2.Dot(rb, tangent);
        kMassTangent += rigidbodyA.InvInertia * (Vector2.Dot(ra, ra) - raT * raT) + rigidbodyB.InvInertia * (Vector2.Dot(rb, rb) - rbT * rbT);
        float massEffectiveT = 1 / kMassTangent;
        float deltaPT = relativeVT * massEffectiveT;
        float maxDeltaPt = mergeFriction * deltaPN;
        deltaPT = Mathf.Clamp(deltaPT, -maxDeltaPt, maxDeltaPt);
            
        Vector2 impulseT = deltaPT * tangent;
        rigidbodyA.ApplyImpulse(-impulseT); //摩擦力与运动(趋势)方向相反
        rigidbodyA.ApplyTorqueImpulse(ra, -impulseT);

        rigidbodyB.ApplyImpulse(impulseT);
        rigidbodyB.ApplyTorqueImpulse(rb, impulseT);
    }

}

其他相同的代码就不贴了

 

标签:rigidbodyA,Vector2,float,2d,引擎,ra,rb,斜坡,rigidbodyB
From: https://www.cnblogs.com/sailJs/p/17962466

相关文章

  • 2d物理引擎学习 - 基于约束的公式解决接触稳定性问题
    先看下直接用弹性碰撞的公式,会出现的问题:Box落在地面上后,没有停在地面上,而是还在不断的下沉。弹性碰撞公式处理碰撞后弹开没有大问题,但是处理物体碰撞后的接触存在不稳定问题。 如何解决?目前物理引擎最主流的解决方法是:基于约束来组织物理公式,而不是直接套用物理公式。什......
  • 读元宇宙改变一切笔记06_虚拟世界引擎
    1. 一棵虚拟的树在虚拟森林里倒下了!1.1. 它们都是数据和代码1.2. 数据可以描述虚拟对象的属性1.2.1. 尺寸或颜色1.3. 为了让我们的树由CPU处理并由GPU渲染,这些数据需要通过代码运行1.4. 该代码必须是运行虚拟世界的更广泛代码框架的一部分2. 现实世界2.1. 现实世......
  • 读元宇宙改变一切笔记06_虚拟世界引擎
    1. 一棵虚拟的树在虚拟森林里倒下了1.1. 它们都是数据和代码1.2. 数据可以描述虚拟对象的属性1.2.1. 尺寸或颜色1.3. 为了让我们的树由CPU处理并由GPU渲染,这些数据需要通过代码运行1.4. 该代码必须是运行虚拟世界的更广泛代码框架的一部分2. 现实世界2.1. 现实世......
  • 智能导诊AI引擎,智慧医院智能导诊系统源码,以智能问答的人机对话形式精准推荐科室
    什么是智能导诊?智能导诊系统是在医liao中使用的引导患者自助就诊挂号,在就诊的过程中有许多患者不知道需要挂什么号,要看什么病,通过智慧导诊系统,可输入自身疾病的症状表现,或选择身体部位,在经由智慧导诊系统多维度计算,准确推荐科室,引导患者挂号就诊,实现科学就诊,不用担心挂错号。在日常......
  • Cocos Creator 3.8 开发2D水面波纹Shader
     使用cocosCreator3.8做了一个游戏开中常用的2D的波浪水面,把技术点给记录一下,并提供完整的Shader代码。先上效果:   2D波浪的基本技术原理 2D水面波纹的主要原理就是给定一个正选波的边界,在范围内的片元uv就显示,在范围外的片元uv就不显示。同时利用正弦波表达式:......
  • 24-调度引擎:Kubernete 如何高效调度 Pod?
    我们已经学会如何部署业务,发布Pod。但是Pod创建好以后,Kubernetes又如何调度这些Pod呢?如果我们希望把一个Pod跑在我们期望的节点上,该如何操作呢?如果我们希望把某些关联性强的Pod跑在特定的节点上,或者同一个节点上,又该怎么操作呢?今天我们就来揭晓。Kubernetes调度器工......
  • JVS逻辑引擎调用规则引擎:深入剖析工作原理与应用场景
    在当今的数字化时代,业务逻辑和规则的复杂性不断增加,这使得逻辑引擎和规则引擎在处理业务需求时显得尤为重要。逻辑引擎和规则引擎通过定义、解析和管理业务逻辑和规则,能够帮助企业提高工作效率、降低运营成本,并增强决策的科学性和准确性。本文将详细解释JVS逻辑引擎调用规则引擎的......
  • DOTS Unity.Physics物理引擎碰撞查询核心分析
    最近DOTS发布了正式的版本,同时基于DOTS的理念实现了一套高性能的物理引擎,今天我们给大家分享和介绍一下这个物理引擎的碰撞查询以及核心相关概念。Unity.Physics碰撞查询概述 碰撞查询(CollisonQurey)是Unity.Physics物理引擎中的一个很重要的功能。很多游戏逻辑都需要基于碰......
  • Unity DOTS物理引擎的核心分析与详解
    最近DOTS发布了正式的版本,同时基于DOTS的理念实现了一套高性能的物理引擎,今天我们来给大家分享和介绍一下这个物理引擎的使用。Unity.Physics的设计哲学 Unity.Physics是基于DOTS设计思想的一个高性能C#物理引擎的实现,  包含了物理刚体的迭代计算与碰撞检测等查询。Unity.P......
  • 重新认识Elasticsearch-一体化矢量搜索引擎
    前言2023哪个网络词最热?我投“生成式人工智能”一票。过去一年大家都在拥抱大模型,所有的行业都在做自己的大模型。就像冬日里不来件美拉德色系的服饰就会跟不上时代一样。这不前段时间接入JES,用上好久为碰的RestHighLevelClient包。心血来潮再次访问Elasticsearch官网,发现风格又变......