微信小程序框架内置了一些环境数据资源。
| 资源id | 描述 | 预览 |
|---|---|---|
| xr-frame-team-workspace-day | xr-frame团队工作地,白天 | ![]() |
| xr-frame-team-workspace-night | xr-frame团队工作地,夜晚 | ![]() |
| xr-frame-team-workspace-day2 | xr-frame团队工作地2,白天 | ![]() |
| gz-haixinsha | 广州海心沙,下午 | ![]() |
微信小程序框架内置了一些环境数据资源。
| 资源id | 描述 | 预览 |
|---|---|---|
| xr-frame-team-workspace-day | xr-frame团队工作地,白天 | ![]() |
| xr-frame-team-workspace-night | xr-frame团队工作地,夜晚 | ![]() |
| xr-frame-team-workspace-day2 | xr-frame团队工作地2,白天 | ![]() |
| gz-haixinsha | 广州海心沙,下午 | ![]() |
在基础库版本v3.1.1之后,分享系统提供了如下方式来录制:
// 录制配置,以下是默认值
// 这里建议根据实际情况,等比缩放`width`和`height`,防止丢帧
const options: XrFrame.IShareRecordOptions = {
fps: 30,
width: scene.width,
height: scene.height,
videoBitsPerSecond: 1000
};
// 启动录制
await scene.share.recordStart(options);
// 暂停录制
await scene.share.recordPause(options);
// 唤醒录制
await scene.share.recordResume(options);
// 停止录制,并保存到临时文件
const tempFilePath = await scene.share.recordFinishToTempFile(options);
// 停止录制,直接保存到相册
await scene.share.recordFinishToAlbum(options);
// 可以获取录制状态,来做用户提示
if (scene.share.recordState === xrFrameSystem.EShareRecordState.Recording) {
......
}
分享系统提供了三种方式来截图:
// 判断当前客户端是否支持分享系统
const supported = scene.share.supported;
// 截取配置,可选`type`为`jpg`或`png`,在为`jpg`时,可配置`0~1`的`quality`
// 以下是默认值
const options: XrFrame.IShareCaptureOptions = {
type: 'jpg',
quality: 0.8
};
// 在鸿蒙上有BUG,已弃用,请使用下方异步接口!
const base64 = scene.share.captureToDataURL(options);
// 基础库`3.0.2`以上新增的异步接口,获取原始的`base64`字符串
const base64 = await scene.share.captureToDataURLAsync(options);
// 在鸿蒙上有BUG,已弃用,请使用异步接口!
const buffer = scene.share.captureToArrayBuffer(options);
// 基础库`3.0.2`以上新增的异步接口,直接获取转换后的`ArrayBuffer`
const buffer = await scene.share.captureToArrayBufferAsync(options);
// 获取本地路径的分享图片
// 第一个方法来处理本地路径,结束后释放文件
// 此回调在`2.27.3`基础库以及之前时是异步,之后兼容同步和异步
// 在基础库`3.0.2`之后,为异步接口
await scene.share.captureToLocalPath(options, fp => {});
// 直接唤起分享图片给好友
// 在基础库`3.0.2`之后,为异步接口
await scene.share.captureToFriends(options);
唤起分享给好友的结果如下:

RenderMode不进行设置的前提下,无论相机如何转动,所有粒子永远正对着屏幕。
这里通过render-mode字段进行控制,示例如下:
<xr-particle id="colorGradient" position="2 0 -2" render-mode="off" capacity="20" emit-rate="5" life-time="3" emitter-type="BoxShape"></xr-particle>
| 名称 | 备注 |
|---|---|
| off | 是否启用公告板渲染 |
| default | 默认公告板渲染模式,粒子始终正对屏幕 |
| y | Y轴渲染模式,粒子Y轴将锁定,其它轴的显示正对屏幕 |
| stretched | 拉伸渲染模式,将附带一些旋转,使粒子朝向其运动方向 |
| mesh | 粒子将以指定网格渲染,与粒子系统中的mesh字段搭配 |
可以通过代码调用禁用公告板渲染,粒子将保持它自己的位置,面片的显示不会随着相机旋转而进行调整:
particleComponent.useBillBoard = false
要设定公告板模式,首先要启用useBillBoard,并对billboardMode进行设置,这里以”BILLBOARDMODE_Y”为例:
particleComponent.useBillBoard = true
particleComponent.billboardMode = BillBoardMode.BILLBOARDMODE_Y || 1
粒子系统目前支持基于alpha值,在色彩梯度渐变图上进行采样,从而更改粒子的颜色。要启用此功能,首先将useRampGradients置为true。
通过如下示例,构建自定义色彩取样表:
particleComponent.useRampGradient = true;
particleComponent.addRampGradient(0.0, Vector3.createFromNumber(1, 1, 1));
particleComponent.addRampGradient(0.2, Vector3.createFromNumber(0.8, 0.8, 0.05));
particleComponent.addRampGradient(0.4, Vector3.createFromNumber(0.86, 0.5, 0.05));
particleComponent.addRampGradient(0.6, Vector3.createFromNumber(0.75, 0.18, 0.07));
particleComponent.addRampGradient(0.8, Vector3.createFromNumber(0.45, 0.08, 0.06));
particleComponent.addRampGradient(1, Vector3.createFromNumber(0.05, 0.05, 0.05));
最终粒子将根据自身alpha值,在取样表中采取对应的色彩。
通过如下示例,也可以在生命周期的不同阶段,指定alpha值的变化范围,影响对色彩渐变图的采样。
例如:0.2秒时,因为此时的采样范围为[0.1, 0.8],粒子alpha值小于等于0.1时视为0,当大于等于0.8时视为1,在区间内值映射为(alpha-0.1)/0.8。
particleComponent.addColorRemapGradient(0, 0, 0.1);
particleComponent.addColorRemapGradient(0.2, 0.1, 0.8);
particleComponent.addColorRemapGradient(0.3, 0.2, 0.85);
| 名称 | 类型 | 备注 | 默认值 |
|---|---|---|---|
| useRampGradients | boolean | 是否启用色彩梯度取样 | false |
addRampGradient| 名称 | 类型 | 备注 |
|---|---|---|
| gradient | number | 在指定位置设置对应色彩,该值与(1-粒子alpha值)对应,取值范围[0~1] |
| color | Vector3 | 色彩RGB值 |
addColorRemapGradient| 名称 | 类型 | 备注 |
|---|---|---|
| time | number | 指定粒子生命周期的阶段 |
| min | number | alpha值左区间 |
| max | number | alpha值右区间 |
粒子在运动过程中,可以定制对其大小、颜色、速度的动态变化。
本粒子系统同时内置有关粒子大小的控制方法addSizeGradient,用法如下:
particleComponent.addSizeGradient(0,1);
particleComponent.addSizeGradient(0.5,0.8);
particleComponent.addSizeGradient(0.75,0.3,0.5);
particleComponent.addSizeGradient(1,0);
调用addColorGradient支持带有alpha通道的颜色过渡:
particleComponent.addColorGradient(0, Vector4.createFromNumber(1,1,1,0));
particleComponent.addColorGradient(0.3, Vector4.createFromNumber(0.3,1,1,0.5),Vector4.createFromNumber(0.2,0,0.6,0.5),);
particleComponent.addColorGradient(1, Vector4.createFromNumber(0,1,1,1));
调用addAlphaGradient可以专门调整透明度的过渡:
particleComponent.addAlphaGradient(0,0);
particleComponent.addAlphaGradient(0.3,0.3, 0.5);
particleComponent.addAlphaGradient(1,1);
调用addSpeedScaleGradient动态改变粒子运动过程中的速度大小:
particleComponent.addSpeedScaleGradient(0,0);
particleComponent.addSpeedScaleGradient(0.3,0.5, 1);
particleComponent.addSpeedScaleGradient(1,2);
addSizeGradient| 参数 | 类型 | 描述 |
|---|---|---|
| gradient | number | 指定所处粒子生命周期的阶段 |
| sizeScale | number | 指定粒子大小的左区间 |
| sizeScale2 | number | 指定粒子大小的右区间[可选] |
其中gradient统一取值范围为[0,1]间,表示相对粒子生命周期的占比,如0.1,即指定粒子在0.1 * lifeTime的时刻;sizeScale与sizeScale2值的大小为相对于粒子系统属性中scale配置的值,如sizeScale为2,则粒子体积大小为size * 2。
addColorGradient| 参数 | 类型 | 描述 |
|---|---|---|
| gradient | number | 指定所处粒子生命周期的阶段 |
| color | Vector4 | 指定粒子颜色的左区间 |
| color2 | Vector4 | 指定粒子颜色的右区间[可选] |
addAlphaGradient| 参数 | 类型 | 描述 |
|---|---|---|
| gradient | number | 指定所处粒子生命周期的阶段 |
| alpha | number | 指定粒子颜色透明度的左区间 |
| alpha2 | number | 指定粒子颜色透明度的右区间[可选] |
addSpeedScaleGradient| 参数 | 类型 | 描述 |
|---|---|---|
| gradient | number | 指定所处粒子生命周期的阶段 |
| speed | number | 指定粒子速度的左区间 |
| speed2 | number | 指定粒子速度的右区间[可选] |
speedScale与speedScale2值的大小为相对于粒子系统属性中speed配置的值,如speedScale为2,则粒子速度大小为speed * s2
首先我们需要创建一个图集资源,如实例所示,命名此资源名为”particle-atlas”:
<xr-asset-load type="atlas" asset-id="particle-atlas" src="/path/to/atlas.json" />
<xr-particle capacity="100" size="2" emit-rate="12" life-time="4" angle="0 360" atlas="particle-atlas" atlas-frames="frame-name" atlas-speed="4" atlas-random="true" atlas-loop="true"></xr-particle>
粒子将从图集依次序取出对应纹理样式进行渲染
目前系统支持构建子发射器,可以通过构建子发射器实现类似的烟花绽放的粒子效果。 示例如下,为子发射器构建参数的过程与粒子系统的构建基本一致,可以参考粒子系统的相关参数介绍。
<xr-asset-load type="texture" asset-id="particlePoint" src="xxx" /> <!-- xxx为纹理的url -->
var myData ={}
myData = {
"capacity": 10,
"emitRate": 5,
"size":[0.1],
"startColor":[1,1,0,1],
"endColor":[1,1,0,1],
"emitterType":"SphereShape",
"emitterProps": [["radius","0.1"]],
"stopDuration":3,
"lifeTime":[3],
"texture":"particlePoint", // xxx为纹理的url
"speed":[0.5],
}
const particleSystemElement = xrScene.getElementById("xxxx"); // xxx为粒子系统的id命名
tempSystem = particleSystemElement.getComponent(xrFrameSystem.Particle)
var subEmitter = this.createSubEmitter(myData)
subEmitter.state = 0
//可以规定多个子发射器的阵列
particleComponent.subEmitters = [subEmitter]
如myData的配置所示,调用createSubEmitter创建一个子发射器,具体参数类型参考粒子系统的相关参数介绍:
SubEmitterState
| 参数 | 类型 | 描述 | 默认值 |
|---|---|---|---|
| ATTACH | number | 指定发射器为附加类型 | 0 |
| END | number | 指定发射器为粒子结束时生成 | 1 |
SubEmitterState.ATTACH
当一个粒子产生时,从子发射器阵列中随机选择一种并附加到新粒子上,用于在新粒子上创建拖尾粒子效果。
SubEmitterState.END
当粒子灭亡时,从子发射器阵列中随机选择一种进行克隆并渲染,用于在新粒子上创建收尾特效。
粒子系统目前内置了不同形态的发射器类型,通过对相关参数的调整,满足开发者所需要的粒子效果。
目前支持以下发射器类型:
通过emitter-type指定发射器类型。emitter-props可以配置发射器参数,示例如下:
<xr-particle capacity="20" emit-rate="10" life-time="1.5 2" speed="0.4 0.8" size="0.3 0.5"
emitter-type="SphereShape" emitter-props="radius:1,randomizeDirection:0"></xr-particle>
不同发射器可以指定的相关参数如下:
BoxShapeEmitter 箱形发射器| 参数名称 | 类型 | 备注 | 默认值 |
|---|---|---|---|
| direction | Vector3 | 粒子初始发射方向左区间 | (0, 1.0, 0) |
| direction2 | Vector3 | 粒子初始发射方向右区间 | (0, 1.0, 0) |
| minEmitBox | Vector3 | 粒子初始位置左区间 | (-0.5, -0.5, -0.5) |
| maxEmitBox | Vector3 | 粒子初始位置右区间 | (0.5, 0.5, 0.5) |
CircleShapeEmitter 圆形发射器| 参数名称 | 类型 | 备注 | 默认值 |
|---|---|---|---|
| radius | number | 粒子随机生成圆形区域的半径 | 1 |
| radiusRange | number | 粒子在圆形区域内的覆盖范围 [0-1] | 0 |
| direction | Vector3 | 粒子初始发射方向左区间 | (0, 1.0, 0) |
| direction2 | Vector3 | 粒子初始发射方向右区间 | (0, 1.0, 0) |
| arc | number | 规定粒子生成的扇形区域角度大小 [0-360] | 360 |
ConeShapeEmitter 锥形发射器| 参数名称 | 类型 | 备注 | 默认值 |
|---|---|---|---|
| radius | number | 粒子随机生成锥型区域的半径 | 3 |
| radiusRange | number | 粒子在锥型区域内的覆盖范围 [0-1] | 0 |
| heightRange | number | 粒子在高度方向上的覆盖范围 [0-1] | 1 |
| arc | number | 规定粒子生成的扇形区域角度大小 [0-360] | 360 |
| randomizeDirection | number | 粒子发射方向的扰动程度 [0-1] | 0 |
PointShapeEmitter 点状发射器| 参数名称 | 类型 | 备注 | 默认值 |
|---|---|---|---|
| direction | Vector3 | 粒子初始发射方向左区间 | (0, 1.0, 0) |
| direction2 | Vector3 | 粒子初始发射方向右区间 | (0, 1.0, 0) |
SphereShapeEmitter 球形发射器| 参数名称 | 类型 | 备注 | 默认值 |
|---|---|---|---|
| radius | number | 粒子随机生成球型区域的半径 | 3 |
| radiusRange | number | 粒子在球型区域内的覆盖范围 [0-1] | 0 |
| arc | number | 规定粒子生成的扇形区域角度大小 [0-360] | 360 |
| randomizeDirection | number | 粒子发射方向的扰动程度 [0-1] | 0 |
通过调用stop函数, 可以对当前粒子效果进行暂停。
particleComponent.stop()
通过调用start函数, 播放粒子效果。
particleComponent.start() // 可以设置参数,如: particleComponent.start(2), 延时二秒启动
系统支持通过代码动态创建发射器,这种生成方式可以对发射器的具体参数进行设置, 这里以点型态发射器为例。
首先需要获得元素的实例,详情见element元素, 并获取对应的组件,详情见component组件
particleComponent.createPointEmitter(direction1, direction2)
粒子运作的轨迹由粒子发射器规定的粒子运动矢量direction大小与粒子初始位置position决定,这一运作过程均由粒子系统进行模拟运算。
为了实现特殊的粒子效果,每个发射器中支持定义粒子运作接口processInstance, 这里以粒子复现一副图片效果为例。
// 记录图片数据的二元数组content, 取值范围[0~1]
var content = ..
//设置箱型发射器的发射方向,与粒子初始位置范围
particleComponent.createBoxEmitter(direction1, direction2, minEmitBox, maxEmitBox);
//实现发射器的自定义粒子运作接口, 声明参数instance代表每个粒子实例,deltaTime为根据渲染更新的时间,均由系统自动传入
particleComponent.particleEmitter.processInstance = (instance, deltaTime) => {
var contentTemp = content
var cellNumY = contentTemp.length
var cellNumX = contentTemp[0].length
// 影响画作的大小与粒子疏密程度的因子
var step = 0.02
// 实际渲染出的画作高度
var height = Math.floor(step * content.length)
// 实际渲染出的画作宽度
var width = Math.floor(step * cellNumX)
if(instance.position.x - instance.particleSystem.emitterPosition.x> width){
instance.age = instance.lifeTime;
return;
}
instance.age = 0;
const posX = Math.floor((instance.position.x - instance.particleSystem.emitterPosition.x)/ step);
const posY = Math.floor(instance.position.y/ step);
const speed = contentTemp[cellNumY-1-posY][posX] * 0.97;
instance.position.x += ( 1 - speed * 0.97 ) * 0.03 + Math.random() * 0.007;
instance.color.w = speed * 0.3;
};
这里介绍有关每个粒子实例的相关属性,用户可以在processInstance接口中设计它们的运作规律
| 名称 | 类型 | 备注 |
|---|---|---|
| angle | number | 粒子的偏移角度 |
| color | Vector4 | 粒子颜色 |
| direction | Vector3 | 粒子的运动方向 |
| particleSystem | Particle | 粒子所归属的粒子系统 |
| position | Vector3 | 粒子所处位置 |
| size | number | 粒子大小 |
粒子属性与生命周期过程中的变化效果由系统ParticleSystem管理,其一个版本代理到元素XRParticleSystem,对应在xml中的标签是xr-particle。
首先声明资源节点,导入纹理,用于描绘粒子的基本形态
<xr-asset-load type="texture" asset-id="particle-texture" src="path/to/texture.xxx" />
接下来在xml中通过xr-particle标签声明粒子节点,同时设置粒子系统的基本属性,例如
<xr-particle material="particle-mat" capacity="20" emit-rate="5" life-time="3" emitter-type="BoxShape" textre="particle-texture"></xr-particle>
影响粒子系统生命周期、初始色彩、初始体积等效果的相关属性介绍如下
| 名称 | 类型 | 备注 | 默认值 | 用例 |
|---|---|---|---|---|
| angle | number[] | 粒子的起始角度,”最小值 最大值(可选)” | [0, 0] | angle=”0 0″ |
| angular-speed | number[] | 每秒钟粒子旋转的角度(单位:角度) | [0, 0] | angular-speed=”0 0″ |
| atlas | Atlas | 描绘粒子形态的纹理图集 | atlas=”particle-atlas” | |
| atlas-frames | string[] | 指定纹理图集中的特定帧,以帧名的形式 | atlas-frames=”snow star” | |
| atlas-loop | boolean | 决定纹理图集播放到最后一帧时是否循环 | true | atlas-loop=”false” |
| atlas-random | boolean | 粒子的初始形态是否从纹理集中随机选择 | false | atlas-random=”true” |
| atlas-speed | number | 粒子纹理的变化速度 | 1 | atlas-speed=”2″ |
| burst-count | number | 粒子一次性喷射的粒子数量,大于-1生效 | -1 | burst-count=”5″ |
| capacity | number | 容许同时存在的最多粒子数量 | 1 | capacity=”5″ |
| delay | number | 延时启动粒子的秒数 | 0 | delay=”3″ |
| emit-rate | number | 每秒钟允许生成的最多粒子数量 | 10 | emit-rate=”5″ |
| emitter-type | string | 粒子发射器的类型 | “PointShape” | emitter-type=”SphereShape” |
| emitter-props | map | 粒子发射器的属性,搭配发射器类型使用 | “” | emitter-props=”radius:1.5″ |
| emitter-position | number[] | 粒子发射器的位置 | (0, 0, 0) | emitter-position=”2 0 0″ |
| end-color | number[] | 粒子生命周期结束时的颜色 | [1, 1, 0, 1] | end-color=”1 1 0 1″ |
| gravity | number | 粒子在y轴上每秒的运动距离 | 0 | gravity=”9.8″ |
| life-time | number[] | 粒子的生命周期时长区间,”最小值 最大值(可选)” | [1, 1] | lifeTime=”1 3″ |
| render-mode | string | 粒子的渲染模式,详见billboard模式介绍 | “default” | render-mode=”stretched” |
| size | number[] | 粒子的大小,”最小值 最大值(可选)” | [0.3, 0.3] | size=”1″ |
| speed | number[] | 粒子的速度大小,”最小值 最大值(可选)” | [1, 1] | speed=”1 1″ |
| start-color | number[] | 粒子初始颜色左区间 | [1, 0, 0, 1] | start-color=”1 0 0 1″ |
| start-color2 | number[] | 粒子初始颜色右区间 | start-color2=”1 1 0 1″ | |
| stop-duration | number | 粒子存在的总时长(单位:秒),0表示永远存在 | 0 | stop-duration=”3″ |
| texture | string | 描绘粒子形态的基本纹理 | texture=”particle-texture” | |
| mesh | string | 以特定网格形态渲染粒子 | mesh=”cube” | |
| use-noise | boolean | 是否对粒子运动轨迹启用噪声 | false | use-noise=”true” |
| noise-texture | string | 采样的噪声纹理名(可选),内置柏林噪声 | noise-texture=”noiseTexture” | |
| noise-strength | number[] | 不同轴向上施加噪声干涉运动的力度(可选) | [1, 1, 1] | noise-strength=”2 1 1″ |
注意:这里的属性类型指粒子系统内部对应的数据结构,在xml格式中按照用例的字符串形式输入即可,对应字符串转换规律如data-values中所示。
⚠️ 轮廓间交互功能目前尚在Beta阶段,并且需要2.32.1及之后的基础库才能使用。
碰撞和重叠是不同的概念:
碰撞和重叠是在两个轮廓之间发生的行为,所以在添加交互属性之前,请先确保为物体创建了轮廓。
通过为标签添加shape-interact属性来设置轮廓间交互:
<xr-mesh ... mesh-shape shape-interact>
设置shape-interact属性后会自动为对应元素创建ShapeInteract组件。
| 属性值 | 描述 | 值类型 | 备注 |
|---|---|---|---|
| disabled | 是否禁用交互 | boolean | disable=true的话,效果和不存在shape-interact属性时一致 |
| collide | 是否发生碰撞 | boolean | collide=true的话,发生碰撞,否则发生重叠,默认false |
| bounciness | 弹性系数 | number | 0≤bounciness≤1,仅当collide=true时生效 |
| staticFriction | 静摩擦系数 | number | 0≤staticFriction≤1,仅当collide=true时生效 |
| dynamicFriction | 动摩擦系数 | number | 0≤staticFriction≤1,仅当collide=true时生效 |
⚠️ 只有两个物体的collide都为true,他们之间才能发生碰撞!
在两个轮廓之间发生交互时,会产生交互事件,可以在标签上绑定相关绑定事件回调:
<xr-mesh ... mesh-shape shape-interact bind:overlap-begin="handleOverlapBegin">
事件一共有以下6种:
| 事件名 | 描述 | 事件回调参数 |
|---|---|---|
| collide-begin | 发生碰撞 | ICollideEvent |
| collide-persist | 碰撞持续 | ICollideEvent |
| collide-exit | 碰撞结束 | ICollideEvent |
| overlap-begin | 发生重叠 | IOverlapEvent |
| overlap-persist | 重叠持续 | IOverlapEvent |
| overlap-exit | 重叠结束 | IOverlapEvent |
其中xxx-begin和xxx-exit会成对地出现,从相交的第二帧开始xxx-persist每帧都会生成一次。
⚠️ 刚体物理功能目前尚在Beta阶段,并且需要2.32.1及之后的基础库才能使用。
要让当前的场景成为一个物理世界,需要先在<xr-scene>下配置一个<xr-physics>标签:
<xr-scene>
<xr-physics />
...(场景中的其他标签)
</xr-scene>
⚠️
<xr-physics>标签只能位于<xr-scene>下一级,不能放置在更深的层级中。
可以通过修改在<xr-physics>上的属性来配置全局物理参数(目前仅开放了少数配置项):
| 属性名 | 描述 | 值类型 | 备注 |
|---|---|---|---|
| disabled | 是否禁用物理 | boolean | disable=true的话,效果和不存在<xr-physics>标签时一致。 |
| gravity | 全局重力 | Vector3 | 默认重力(0, -9.8, 0) |
在标签上添加rigidbody属性来使其成为一个刚体:
<xr-mesh ... rigidbody />
添加之后就能观察到物体受重力影响而下落了。
通过为rigidbody属性添加属性值来修改刚体配置:
<xr-mesh ... rigidbody="mass: 5.0" />
| 属性值 | 描述 | 值类型 | 备注 |
|---|---|---|---|
| disabled | 是否禁用刚体 | boolean | disable=true的话,效果和不存在rigidbody属性时一致。 |
| mass | 刚体质量 | number | mass > 0 |
| useGravity | 是否受重力影响 | boolean | |
| constraintsMask | 限制刚体在某个轴上的移动 | number | 具体指参考 @TODO |
标签上的rigidbody属性对应元素上的Rigidbody组件。
使用Rigidbody组件上的方法可以移动刚体或者修改刚体属性:
| 方法名 | 描述 | 备注 |
|---|---|---|
| addForce / addTorque | 对刚体施加力,产生加速度。 | 对刚体施加力,产生加速度。 |
| sleep / wakeUp | 强制刚体睡眠/唤醒 | 正常情况下睡眠状态是由物理引擎自动管理的,如果发现刚体异常静止,可以尝试手动wakeUp。 |
如果想要与场景中的物体进行互动,比如说点击、拖拽物体,那么这个物体得先拥有一个轮廓才行。
轮廓是一个组件。与某个物体互动,实际上是在与这个物体的轮廓进行互动,轮廓让这个物体在物理世界中拥有了一个分身。
创建轮廓非常简单,只要为xml标签添加上xxx-shape的属性即可。
例如以下代码为一个球体创建了一个球状轮廓:
<xr-mesh node-id="mesh-sphere" geometry="sphere" sphere-shape></xr-mesh>
实际上,不需要标签是xr-mesh,任意一个场景标签都可以创建轮廓:
<xr-node node-id="shape-node" sphere-shape></xr-node>
| 名称 | 标签属性名 | 组件数据 | 备注 |
|---|---|---|---|
| 球状轮廓 | sphere-shape | center, radius, autoFit | |
| 胶囊体轮廓 | capsule-shape | center, radius, height, autoFit | |
| 长方体轮廓 | cube-shape | center, size, autoFit | |
| 网格模型轮廓 | mesh-shape | – | 自动适配元素下的Mesh和GLTF模型 |
除了网格模型轮廓之外,其他轮廓均拥有autoFit属性(实际上网格模型轮廓的autoFit常开,所以不能设置)。开启autoFit之后,轮廓会自动寻找当前元素下的Mesh组件和GLTF组件,并使用自身形状去尽量贴合模型。
如果将
GLTF组件和开启了autoFit的轮廓组合使用,那么会为GLTF内部的每个Mesh都创建一个轮廓。 ⚠️ 使用MeshShape的时候,请确保模型顶点数量小于65535个。如果超过了数量限制,推荐使用CubeShape+autoFit来代替。
可以通过为标签绑定事件的方式来与轮廓进行互动,如果尚未了解如何绑定事件,可以参考事件文档。
例如使用以下代码,可以为轮廓绑定一个log事件(需自行完成logFunction函数):
<xr-node node-id="shape-node" cube-shape bind:touch-shape="logFunction"></xr-node>
| 事件名 | 描述 | 事件回调参数 | 备注 |
|---|---|---|---|
| touch-shape | 点击轮廓时触发 | IShapeTouchEvent | 如果有多个物体叠在一起,会点中最上层的。 |
| drag-shape | 点击轮廓后,手指不松开的情况下进行拖拽时触发 | IShapeDragEvent | 只有在先触发touch-shape之后才会触发这个事件,target和touch-shape保持一致。 |
| untouch-shape | 点击轮廓后,手指松开时触发 | IShapeTouchEvent | 只有在先触发touch-shape之后才会触发这个事件。 |
无论有没有绑定事件,其实都会触发事件,只是没有事件回调函数就什么都没发生。
为标签加上shape-gizmo即可将标签上的轮廓用线框绘制出来:
<xr-node node-id="shape-node" cube-shape shape-gizmo></xr-node>
MeshShape不会显示轮廓,因为基本上和渲染出来的模型一致。
xr-frame中的物理系统主要管理场景中的轮廓,以及触发轮廓点击事件。