Spark AR —— 使用脚本创建效果(二)【脚本】

458 阅读5分钟

Spark AR 是 Facebook 免费创作 AR 作品的平台,使用户能够为 Facebook 和 Instagram 创建交互式增强现实体验,超过 40 万名创作者,190个国家/地区,使用 Spark AR 来创作自己的AR作品

由于该软件无需任何编码知识即可使用,因此任何人现在都可以在 AR 世界中几乎没有经验地制作下一个疯狂式传播的 Instagram AR 特效,引领世界潮流。

专门的 AR 滤镜设计师单价甚至可达到 1000 美元到 3 万美元不等。

录音机的基对象动画

我们要应用的第一个动画是录音机的基对象(缩放)动画。我们想要通过播放的音频给录音机带来脉冲的效果。

加载场景模块

我们需要加载场景模块,这样我们就可以访问场景中的录音机的基对象。

下面的代码将加载场景模块并将其存储在一个变量中,以便以后可以使用它来访问场景中的对象。

脚本代码

 const Scene = require('Scene');

require() 方法告诉脚本我们正在寻找一个模块,我们传入模块的名称作为参数来指定我们想要加载的模块。

Scene 变量现在包含了对 Scene 模块的引用,可以用它来访问模块的属性、方法、类和枚举。

访问基对象

在我们可以访问脚本中的基础对象之前,我们需要知道它在场景面板中被称为什么。

通过点击箭头展开 boombox_animated 对象,在场景面板中显示完整的对象树。

image.png

boombox 的基部由 base_jnt 对象表示。这个基础对象,以及它下面的扬声器,只是在 3D 模型中进行变换。

场景对象的名称已知后,我们现在可以在脚本中使用它来访问它。

下面的代码在场景中找到 base_jnt 对象,并将其存储在一个变量中,我们将在后面使用它来制作动画。

脚本代码

 Scene.root.findFirst('base_jnt')
          .then(function(base) {});

scene 模块的根(root)属性允许我们访问 Scene Panel 树的根,SceneObjectBase (由根属性返回)的 findFirst() 方法允许我们搜索树中的对象。

找到的对象 base 将在 Promise 回调中返回。

脚本代码

 const Scene = require('Scene');
 Scene.root.findFirst('base_jnt')
          .then(function(base) {});

加载动画模块

我们需要加载动画模块,这样我们就可以在场景中为基对象和扬声器添加动画。

该模块的加载方式与场景模块相同,将单词'scene'替换为 'Animation'。

脚本代码

在场景模块上面的一行中添加加载动画模块的代码:

 const Animation = require('Animation');
 const Scene = require('Scene'); // Existing code

完整代码如下

 const Animation = require('Animation');
 const Scene = require('Scene');
 Scene.root.findFirst('base_jnt')
          .then(function(base) {});

创建基动画

在 Spark AR Studio 中创建动画包含3个步骤:

  1. 创建一个驱动器(driver)。
  2. 创建一个取样器(sampler)。
  3. 结合驱动器和采样器来创建动画。

创建一个驱动器

在 Spark AR Studio 中有两种类型的驱动器:

  • 时间驱动器(Time driver) ——— 允许你为动画指定一个以毫秒为单位的持续时间,以及用于循环镜像的可选参数。
  • 值驱动程序器(Value driver) —— 允许你指定一个ScalarSignal,它的值将控制动画,阶段到给定的最小值和最大值。

对于这个项目中的动画,我们将使用时间驱动器。

下面的代码使用预先创建的一组参数创建一个时间驱动器:

脚本代码

const baseDriverParameters = {
   durationMilliseconds: 400,
  loopCount: Infinity,
  mirror: true
 };

 const baseDriver = Animation.timeDriver(baseDriverParameters);

baseDriverParameters 对象指定:

  • durationMilliseconds - 动画将持续0.4秒。
  • loopCount —— 动画将无限循环。
  • mirror —— 当动画完成一个循环时,动画将返回到它的初始值。

然后使用 Animation ModuletimeDriver() 方法使用这些参数创建一个时间驱动器。

时间驱动器也需要指示才能启动。

如下创建时间驱动器

脚本代码

const baseDriver = Animation.timeDriver(baseDriverParameters); // Existing code
 baseDriver.start();

在脚本中此时启动驱动器不会产生效果,直到我们稍后创建动画,目前我们只是将驱动器代码保存在一起。

脚本代码

const Animation = require('Animation');
 const Scene = require('Scene');
 Scene.root.findFirst('base_jnt')
  .then(function(base) {
    const baseDriverParameters = {
        durationMilliseconds: 400,
        loopCount: Infinity,
        mirror: true
    };

    const baseDriver = Animation.timeDriver(baseDriverParameters);
    baseDriver.start();
 });

创建采样器

采样器允许您指定动画的开始值和结束值,以及应用于它的 easing (缓动)函数,从而改变变化率。

下面的代码创建了一个采样器。

脚本代码

const baseSampler = Animation.samplers.easeInQuint(0.9,1);

动画模块的 sampler 属性使我们可以访问 SamplerFactory 类,我们用它来通过 easeInQuint() 方法设置 easing 函数。我们将 0.9 和 1 传递给该方法,以指定动画的开始和结束值。

脚本代码

const Animation = require('Animation');
 const Scene = require('Scene');
 Scene.root.findFirst('base_jnt')
  .then(function(base) {
    const baseDriverParameters = {
        durationMilliseconds: 400,
        loopCount: Infinity,
        mirror: true
    };

    const baseDriver = Animation.timeDriver(baseDriverParameters);
    baseDriver.start();
    const baseSampler = Animation.samplers.easeInQuint(0.9,1);
 });

创建动画

动画是由驱动器和采样器组合而成的。

脚本代码

const baseAnimation = Animation.animate(baseDriver,baseSampler);

animation 模块的 animate() 方法返回一个 ScalarSignal ,根据所使用的 easing 函数,该信号每 0.4 秒在 0.9 到 1 之间变化。

脚本代码

const Animation = require('Animation');
 const Scene = require('Scene');
 Scene.root.findFirst('base_jnt')
  .then(function(base) {
    const baseDriverParameters = {
        durationMilliseconds: 400,
        loopCount: Infinity,
        mirror: true
    };

    const baseDriver = Animation.timeDriver(baseDriverParameters);
    baseDriver.start();
    const baseSampler = Animation.samplers.easeInQuint(0.9,1);
    const baseAnimation = Animation.animate(baseDriver,baseSampler);
 });

随着动画创建,我们现在可以将它应用到 boombox 的基础对象,我们将使用它来改变比例。

录音机的基础对象只是代表了整个 3D 模型。将动画应用到基础对象将意味着我们正在动画整个对象。

获得基础变换

要访问基础的缩放,我们需要首先访问变换(Transform)。变换表示对象在其局部坐标系中的变换(位置、缩放和旋转)。

脚本代码

const baseTransform = base.transform;

SceneObjectBase 类(基础对象是该类的实例)的 transform 属性返回一个 TransformSignal

绑定动画

通过访问基础的变换,我们现在可以将动画绑定到它的缩放属性,对模型进行动画。

脚本代码

baseTransform.scaleX = baseAnimation;
 baseTransform.scaleY = baseAnimation;
 baseTransform.scaleZ = baseAnimation;

TransformSignalscaleX/Y/Z() 方法允许我们将动画输出的 baseAnimation ScalarSignal 绑定到 base 对象的缩放上。

脚本代码

const Animation = require('Animation');
 const Scene = require('Scene');
 Scene.root.findFirst('base_jnt')
  .then(function(base) {
    const baseDriverParameters = {
        durationMilliseconds: 400,
        loopCount: Infinity,
        mirror: true
    };

    const baseDriver = Animation.timeDriver(baseDriverParameters);
    baseDriver.start();
          
    const baseSampler = Animation.samplers.easeInQuint(0.9,1);
    const baseAnimation = Animation.animate(baseDriver, baseSampler);
    
    baseTransform.scaleX = baseAnimation;
    baseTransform.scaleY = baseAnimation;
    baseTransform.scaleZ = baseAnimation;      
 });

保存脚本并返回 Spark AR Studio

录音机模型现在将在场景中动画化。

69528694_1079588018903892_8484091505311481856_n.gif