如何在 SparkAR 中监控物体位置?

How to monitor object position in SparkAR?

我在 SparkAR 中编写脚本,只是试图不断检查某些对象的世界(非本地)位置。

到目前为止,我已经尝试过:

Promise.all([

    Scene.root.findFirst('plane4'),

]).then(function (results) {

    const plane4 = results[0];

    // Get the timer ready
    reset();
    start();

    function reset() {

        Patches.inputs.setPulse('SendReset', Reactive.once());
    }

    function start() {


    plane4.monitor({ fireOnInitialValue: true }).subscribe(function (p) {
        Diagnostics.log(p.position.x.newValue);
    })

还尝试了取下 newValue、取下 x 等。如何检查对象随时间的位置?

  1. 要访问世界变换位置,您必须使用路径 plane4.worldTransform
  2. 您可以订阅更改 Spark ar 中的任何信号。 例如:您可以订阅 plane4.worldTransform.x 的更改,因为这是 ScalarSignal。但是您不能订阅 plane4plane4.worldTransform,因为它们不是信号,而只是被视为场景的对象。

您可以在此处找到有关每种类型 Spark 的更多信息 https://sparkar.facebook.com/ar-studio/learn/developer/reference/scripting/summary

下面是订阅 plane4 的世界 X 坐标的工作示例代码

plane4.worldTransform.x.monitor().subscribe(function (posX) {
    Diagnostics.log(posX.newValue);
});

UPD: 添加了检查多个对象位置的示例

Spark AR引擎的开发者建议尽量少使用信号订阅,因为订阅对性能影响很大,所以需要熟练使用Reactive模块,订阅复杂的复合信号。在示例中,我使用了 2 个对象,而不是 9 个。另外,我没有使用纯 0,而是有一些小偏差。

注意代码中的注释

const Scene = require('Scene');
const Reactive = require('Reactive');
const Diagnostics = require('Diagnostics');

const planes = [];
const objectsCount = 2;

Promise.all([
    Scene.root.findFirst('plane0'),
    Scene.root.findFirst('plane1'),
]).then(function(result)
{
    for(let i = 0; i < objectsCount; ++i)
    {
        planes.push(result[i]);
    }

    /*
    The case when it is important to you which of the objects is in the position {0,0}
    can be dispensed with using N subscriptions. Where N is the number of objects.

    For example, a game where a character collects coins when he touches them and
     you need to know which coin you need to hide from the screen.
    */
    // Case 1 begin
    for(let i = 0; i < objectsCount; ++i)
    {
        Reactive.and(
            Reactive.and(
                planes[i].worldTransform.x.le(0.01),
                planes[i].worldTransform.x.ge(-0.01)
            ),
            Reactive.and(
                planes[i].worldTransform.y.le(0.01),
                planes[i].worldTransform.y.ge(-0.01)
            )
        )
        .monitor().subscribe(function(isPosZero)
        {
            if(isPosZero.newValue)
            {
                Diagnostics.log("plane" + i.toString() + " pos is zero");
            }
        });
    }
    // Case 1 end
    
    
    /*
    The case when it does not matter to you which particular object is in the position {0,0}.
    Here you can get by with just one subscription.
    
    For example, a game where a player dies when he touches the spikes, 
    no matter which spike he touches, it is important that you kill the character.
    */
    // Case 2 begin
    let myOrList = [];
    
    for (let i = 0; i < objectsCount; ++i)
    {
        myOrList.push(
            Reactive.and(
                Reactive.and(
                    planes[i].worldTransform.x.le(0.01),
                    planes[i].worldTransform.x.ge(-0.01)
                ),
                Reactive.and(
                    planes[i].worldTransform.y.le(0.01),
                    planes[i].worldTransform.y.ge(-0.01)
                )
            )
        );
    }

    Reactive.orList(
        myOrList
    ).monitor().subscribe(function(isPosZero)
    {
        Diagnostics.log('the position of one of the objects is {0,0}');
    });
    // Case 2 end
});