首页 > 其他分享 >重构物理Entity架构,支持更多的形状

重构物理Entity架构,支持更多的形状

时间:2023-11-01 10:13:44浏览次数:36  
标签:重构 架构 phyEntity Entity PhyBaseEntity Fix64 形状 物理

上一节实战如何编译BEPUphysicsint源码到自己的项目, 如何整合物理引擎与Unity图形渲染。本节来从新调整设计,让物理的Entity基本操作与物理的形状分离,支持更多的物理形状,支持物理entity与Unity物体位移与旋转同步。主要分成以下3个部分:

PhyBaseEntity 设计

上一节课我们设计的PhyBoxEntity主要包含了两个部分,一个是Entity的物理形状的创建(这个与具体的形状有关),一个是物理Entity的基本功能,如位置,旋转同步,給Entity线性速度等。而且其它的形状的物理Entity,除了形状创建会不一样,其它基本一样,所以我们调整一下设计,把PhyBoxEntity与物理形状相关的代码放到PhyBoxEntity里面,与形状无关的物理Entity的基本功能,我们放到PhyBaseEntity里面,然后让具体的形状在扩展的时候继承PhyBaseEntity即可。合计架构如图所示:

 

接下来我们把上一节课的PhyBoxEntity与形状无关的数据与功能提取到PhyBaseEntity,PhyBoxEntity只保留形状相关的代码。与形状无关的数据部分:

public class PhyBaseEntity : MonoBehaviour {
    protected BEPUphysics.Entities.Entity phyEntity = null;
    protected Vector3 center = Vector3.zero;
    [SerializeField]
    protected float mass = 1;

    protected bool isTrigger = false;
    protected PhysicMaterial phyMat = null;
    
    [SerializeField]
    protected bool isStatic = false;
}

phyEntity: 用的是所有Entity形状的基类,这样可以指向不同子类的具体实例,其它数据都是物理Entity通用的,都写道PhyBaseEntity里面。

同步物理Entity与Unity节点的位移与旋转

同时PhyBaseEntity实现了物理Entity与Unity节点同步的功能增加了位置+旋转。如代码所示:

public void AddSelfToPhyWorld() { 
        if(this.phyEntity == null) {
            return;
        }

        BEPUPhyMgr.Instance.space.Add(this.phyEntity);
    }

    public void SyncPhyTransformWithUnityTransform() {
        if (this.phyEntity == null) {
            return;
        }


        // 位置
        Vector3 unityPos = this.transform.position;
        unityPos += this.center;
        this.phyEntity.position = ConversionHelper.MathConverter.Convert(unityPos);
        // end

        // 旋转
        Quaternion rot = this.transform.rotation;
        this.phyEntity.orientation = ConversionHelper.MathConverter.Convert(rot);
        // end
    }

    public void SyncUnityTransformWithPhyTransform() {
        if (this.phyEntity == null) {
            return;
        }

        // 位置
        BEPUutilities.Vector3 pos = this.phyEntity.position;
        Vector3 unityPosition = ConversionHelper.MathConverter.Convert(pos);
        unityPosition -= this.center;
        this.transform.position = unityPosition;
        // end 

        // 旋转
        BEPUutilities.Quaternion rot = this.phyEntity.orientation;
        Quaternion r = ConversionHelper.MathConverter.Convert(rot);
        this.transform.rotation = r;
        // end
    }

    // 同步物理entity的位置到transform;
    void LateUpdate() {
        if (this.phyEntity == null || this.isStatic) {
            return;
        }

        this.SyncUnityTransformWithPhyTransform();
    }

接口SyncUnityTransformWithPhyTransform: 从物理Entity同步到Unity节点

接口SyncPhyTransformWithUnityTransform: 从Unity节点同步到物理Entity

 

再来看调整后的PhyBoxEntity,就很简单了:

[RequireComponent(typeof(BoxCollider))]
public class PhyBoxEntity : PhyBaseEntity {
    
    void Start() {
        BoxCollider box = this.gameObject.GetComponent<BoxCollider>();
        float width = box.size.x;
        float height = box.size.y;
        float length = box.size.z;
        
        this.center = box.center;
        this.phyMat = box.material;
        this.isTrigger = box.isTrigger;


        if (this.isStatic) {
            this.phyEntity = new BEPUphysics.Entities.Prefabs.Box(BEPUutilities.Vector3.Zero, (FixMath.NET.Fix64)width, (FixMath.NET.Fix64)height, (FixMath.NET.Fix64)length);
        }
        else {
            this.phyEntity = new BEPUphysics.Entities.Prefabs.Box(BEPUutilities.Vector3.Zero, (FixMath.NET.Fix64)width, (FixMath.NET.Fix64)height, (FixMath.NET.Fix64)length, (FixMath.NET.Fix64)this.mass);
        }

        this.AddSelfToPhyWorld();
        this.SyncPhyTransformWithUnityTransform();
    }

   
}

根据BoxCollider的数据创建Box的物理Entity, 同步到Unity节点的位置与旋转,并加入到物理世界。

 

编写其它形状的物理Entity

经过上面的调整以后,我们就很快的编写其它的形状,比如实现PhySphereEntity,

[RequireComponent(typeof(SphereCollider))]
public class PhySphereEntity : PhyBaseEntity
{
    // Start is called before the first frame update
    void Start() {
        SphereCollider sphere = this.gameObject.GetComponent<SphereCollider>();

        float radius = sphere.radius;

        this.center = sphere.center;
        this.phyMat = sphere.material;
        this.isTrigger = sphere.isTrigger;

        if (this.isStatic) {
            this.phyEntity = new BEPUphysics.Entities.Prefabs.Sphere(BEPUutilities.Vector3.Zero, (FixMath.NET.Fix64)radius);
        }
        else {
            this.phyEntity = new BEPUphysics.Entities.Prefabs.Sphere(BEPUutilities.Vector3.Zero, (FixMath.NET.Fix64)radius, (FixMath.NET.Fix64)this.mass);
        }

        this.AddSelfToPhyWorld();
        this.SyncPhyTransformWithUnityTransform();
    }
}

继承自PhyBaseEntity,同时根据SphereCollider组件来创建形状。

后续我们要給物理Entity线性速度,角速度都把接口写到PhyBaseEntity里面。

 

今天的物理Entity的设计调整就到这里了,关注我们,可以获取Unity BEPUphysint3D实战源码。

标签:重构,架构,phyEntity,Entity,PhyBaseEntity,Fix64,形状,物理
From: https://www.cnblogs.com/bycw/p/17802398.html

相关文章

  • BEPU物理引擎碰撞系统的架构与设计
    前面我们讲解了如何监听物理引擎的碰撞事件,在物理引擎内核中如何架构与设计碰撞规则,使得物理Entity与周围的物理环境产生碰撞时,如何灵活的控制物理碰撞,本节給大家详细的讲解BEPUphysicsint物理引擎内部是如何管理与控制碰撞规则的。本文主要讲解3个部分:(1)物理引擎碰撞计算......
  • prometheus几种高可用架构介绍及联邦架构部署
    **问题背景:**单个prometheus性能到达瓶颈问题、多个prometheus-server数据汇总问题等**prometheus监控数据持久化**首先大家都知道prometheus是自带数据存储功能的。优点是简单易用,基本无需配置缺点是:1、存在数据无法长久保存(尤其是频繁变更的监控对象,监控对象变化,短时间内监控......
  • 华为云中虚拟机及容器的架构
    虚拟机现实中我们用的计算机看到的都是物理机,而虚拟机,顾名思义就是虚拟的机子,它把磁盘文件和描述文件封装在同一文件夹然后存放在底层存储提供的文件系统中,相较于物理机他的特点有:资源分区封装(操作系统与应用)独立(不同服务器之间的传递)隔离(每台虚拟机拥有一个独立的OS)容器......
  • 第十章、web前端架构师
    目录二十二、大型项目的编译,部署以及性能优化1、前言二十二、大型项目的编译,部署以及性能优化1、前言......
  • 百度AICA首席AI架构师培养计划第七期毕业,大模型深入产业见成果
    10月28日,由深度学习技术及应用国家工程研究中心与百度联合创办的AICA首席AI架构师培养计划,迎来第7期毕业典礼,88位学员获得AI架构师认证。截至目前,AICA已累计为业界培养了410位产业AI领军人才。同时,AICA第7期毕业学员约有三分之一聚焦大模型产业应用课题并取得先期成果。百度文心......
  • Redis部署架构
    部署架构单节点(Single)优点架构简单,部署方便高性价比:缓存使用时无需备用节点(单实例可用性可以用supervisor或crontab保证),当然为了满足业务的高可用性,也可以牺牲一个备用节点,但同时刻只有一个实例对外提供服务高性能缺点不保证数据的可靠性在缓存使用,进......
  • 揭秘:为什么80%的Android码农都做不了架构师?
    前言一般来说技术团队的金字塔顶尖往往是技术最牛的人做架构师(或TL)。所以架构师在广大码农中的占比大概平均不到20%。然而80%码农干上许多年都是重复以下内容,所以做不了架构师,正在辛苦工作的程序员们,你有没有下面几种感觉?①我的工作就是按时完成领导交给我的任务,至于代码写的怎样......
  • 软件架构设计师需要记住的内容
    第一章系统工程与信息系统基础1软件开发方法(1)结构化开发特点:用户至上,自顶而下,逐步分解,严格区分工作阶段,每阶段都有任务和结果,强调系统开发过程的整体性和全局性,系统开发过程工程化,资料文档标准化。优点:理论基础严密,它的指导思想是在用户需求在系统建立之前就能被充分了解和理......
  • 跑腿小程序开发解析:技术架构、接口设计和前沿趋势
    随着生活节奏的加快和个人需求的增加,跑腿小程序成为了人们生活中不可或缺的一部分。从技术角度来看,一个高效、安全、以及用户友好的跑腿小程序是由多个关键要素构成的,包括技术架构、接口设计和前沿趋势。技术架构1.前端技术选型选择合适的前端框架如ReactNative、Flutter、Vue.j......
  • AMBA总线架构简介
    于是乎,我们想到了总线,用一个统一的接口协议,设计出一个符合要求的总线,然后将ARM核和各种外设模块挂载在总线上,这样,命令和数据似乎便可以在CPU和外设之间自由穿梭。1AMBA总线AMBA,英文全称为AdvancedMicrocontrollerBusArchitecture,即高级微控制器总线架构。AMBA的简易发展历......