Unity ecs physics collision

本文详细介绍了Unity Physics中的碰撞(Collision)机制,通过实例展示了如何在DOTS架构下创建小球并设置碰撞规则,包括设置Collider、PhysicsShape、CollisionFilter和PhysicsBody。同时讲解了如何使用PhysicsEventsJob处理小球间的碰撞并调整运动方向。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Unity DOTS中的物理系统即Unity.Physics,这里使用一个简单的demo(小球相撞效果),来说明一下 碰撞 Collision。
1、创建两个sphere(注意,要去掉ShpereCollider),添加Physics Shape,ShapeType 选择 Sphere,PhysicsShape 选择Collide Raise Collision Events。新建CollisionFilter类型Sphere和Plane,然后设置 BelongsTo = Sphere,设置CollidesWith = Sphere, Plane;添加 Physics Body。
在这里插入图片描述
2、创建三个plane(注意,要去掉MeshCollider),添加Physics Shape,ShapeType 选择 Plane,PhysicsShape 选择Collide。然后设置 CollisionFilter, BelongsTo = Plane,设置CollidesWith = Sphere;添加 Physics Body,MotionType设为Kinematic。
在这里插入图片描述
3、小球碰撞,触发逻辑

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Unity.Entities;
using Unity.Mathematics;
using Unity.Transforms;
using Unity.Physics;
using Unity.Collections;
using Unity.Physics.Systems;

public class PhysicalSystem : SystemBase
{
    private BuildPhysicsWorld buildPhysicsWorld;//物理系统的准备工作,将TriggerCollisionEvents传递给Job
    private StepPhysicsWorld stepPhysicsWorld;//物理系统的准备工作,将TriggerCollisionEvents传递给Job

    protected override void OnCreate()
    {
        buildPhysicsWorld = World.GetOrCreateSystem<BuildPhysicsWorld>();
        stepPhysicsWorld = World.GetOrCreateSystem<StepPhysicsWorld>();
    }

    protected override void OnUpdate()
    {
        ColliderJob colliderJob = new ColliderJob()
        {
            velocitys = GetComponentDataFromEntity<PhysicsVelocity>()
        };
        Dependency = colliderJob.Schedule(stepPhysicsWorld.Simulation, ref buildPhysicsWorld.PhysicsWorld, Dependency);
    }
}


public struct ColliderJob : ICollisionEventsJob
{
    public ComponentDataFromEntity<PhysicsVelocity> velocitys;

    public void Execute(CollisionEvent collisionEvent)
    {
        if (velocitys.HasComponent(collisionEvent.EntityA) && IsSphere(collisionEvent.EntityA, "Sphere"))
        {
            if (velocitys.HasComponent(collisionEvent.EntityB) && IsSphere(collisionEvent.EntityB, "Sphere"))
            {
                var velocityA = velocitys[collisionEvent.EntityA];
                var dirA = -math.sign(velocityA.Linear.x);
                //Debug.Log("dirA = " + dirA);
                velocityA.Linear.x = dirA * 20;
                velocitys[collisionEvent.EntityA] = velocityA;

                var velocityB = velocitys[collisionEvent.EntityB];
                var dirB = -math.sign(velocityB.Linear.x);
                //Debug.Log("dirB = " + dirB);
                velocityB.Linear.x = dirB * 20;
                velocitys[collisionEvent.EntityB] = velocityB;
            }
        }
    }

    public bool IsSphere(Entity entity, string name)
    {
        return World.DefaultGameObjectInjectionWorld.EntityManager.GetName(entity) == name;
    }
}
### UniApp 使用高德地图 API 实现点击地图添加标记点 #### 准备工作 为了在 UniApp 中集成高德地图并实现点击地图添加标记点功能,需先完成以下准备工作: - 注册高德开放平台账号,并创建应用获取 Key[^1]。 #### 创建项目结构 确保项目的 `pages.json` 文件中已配置好页面路径。接着,在相应页面目录下新建 HTML 文件用于承载地图实例化逻辑。 #### 页面布局设计 编辑 `.vue` 组件文件中的模板部分,定义 WebView 容器来加载外部 HTML 文档: ```html <template> <view class="container"> <!-- 使用 web-view 来嵌入自定义 html --> <web-view :src="&#39;./path/to/map.html&#39;"></web-view> </view> </template> <script> export default { data() { return {}; } }; </script> ``` #### 编写地图HTML代码 在上述提到的 `map.html` 文件内编写如下 JavaScript 和 HTML 结构以初始化地图对象并与之交互: ```html <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Map Page</title> <style type="text/css"> * { margin: 0; padding: 0; } #container { width: 100vw; height: calc(100vh - 20px); } </style> <script src="//webapi.amap.com/maps?v=2.0&key=您的KEY"></script> </head> <body> <div id="container"></div> <button onclick="clearMarkers()">清除所有标注</button> <script type="text/javascript"> var map, markerArr = []; function initMap() { // 初始化地图对象 设置中心点坐标以及缩放级别 map = new AMap.Map(&#39;container&#39;, { zoom: 10, center: [116.397428, 39.90923], resizeEnable: true }); addClickEvent(); } function addMarker(lnglat) { let lngLatObj = typeof lnglat === &#39;string&#39; ? lnglat.split(&#39;,&#39;) : lnglat; const marker = new AMap.Marker({ position: new AMap.LngLat(...lngLatObj), title: "新增位置" }); marker.setMap(map); // 将 Marker 添加至 Map 上显示出来 markerArr.push(marker); console.log(`Added marker at ${lngLatObj}`); } function clearMarkers(){ while (markerArr.length){ markerArr.pop().setMap(null); } } function addClickEvent(){ map.on(&#39;click&#39;,(e)=>{ addMarker([e.lnglat.getLng(), e.lnglat.getLat()]); }) } window.onload = initMap; </script> </body> </html> ``` 此段脚本实现了当用户单击地图任意处时自动于该地点放置一个新的标记点;同时提供了一个按钮用来清空当前所有的标记点[^2]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值