在应用中启用动画的概览

配置 build

若要在应用中配置 build 以启用动画,您需要修改 build.gradle 文件并将动画导入项目中。

  1. 通过添加 Sceneform 动画依赖项,更新应用build.gradle 以支持导入的动画模型可渲染对象:

     dependencies {
         …
         // Support for animated model renderables.
         implementation "com.google.ar.sceneform:animation:1.15.0"
         }
    
  2. 导入并预览 *.fbx 动画文件以获取包含导入的模型的 *.sfb 文件。

在运行时使用动画

使用运行时操作可以:

创建可渲染动画

在运行时,使用 ModelRenderable.Builder 加载 *.sfb 并将其附加到场景中的节点,如同处理任何 ModelRenderable 一样:

  // Create the ModelRenderable.
  ModelRenderable.builder()
      .setSource(this, R.raw.andy)
      .build()
      .thenAccept(renderable -> andyRenderable = renderable)
      .exceptionally(
          throwable -> {
          Log.e(TAG, "Unable to load Renderable.", throwable);
          return null;
      });

  // Attach the ModelRenderable to the node in the scene.
  Node andyNode = new Node();
  andyNode.setParent(arFragment.getArSceneView().getScene());
  andyNode.setRenderable(andyRenderable);

获取动画数据

// Get the animation data called "andy_dance" from the `andyRenderable`.
AnimationData danceData = andyRenderable.getAnimationData("andy_dance");

访问基于不同元数据的动画

     // Get the animation name.
     danceData.getName();

如需检索动画数据的实例,请使用 ModelRenderable.getAnimationData() 方法:

     // Access animations by index.
     numAnimations = andyRenderable.getAnimationDataCount();
     danceData = andyRenderable.getAnimationData(0);

控制播放

创建 ModelAnimator 以控制播放。

ModelAnimator andyAnimator = new ModelAnimator(danceData, andyRenderable);

使用 start() 播放动画。该应用在结束时会自动停止。

andyAnimator.start();

如需循环播放动画,请使用 setRepeatCount()

andyAnimator.setRepeatCount(<number of repeats>)

(可选)添加属性动画操作

ModelAnimator 扩展了 Android Animator 类,该类允许进行更丰富的互动,例如循环播放、响应事件和非线性插值器。

使用 SkeletonNode 识别模型并将其附加到骨头上

使用包含骨头的可渲染对象时,请使用 SkeletonNode 类通过将节点连接到骨头访问骨架的各个骨头。这样,您就可以将对象“附加”到架构上或控制它们的位置。

在播放动画时,附加节点的位置、缩放比例和方向由每帧的 SkeletonNode 更新。设置附加节点的位置、缩放或旋转会替换骨头,直到动画下次更新骨头。

动画示例中,这是将含有一顶帽子型号的 Node 附加到骨头上以指示 Andy 的头部来实现这一点。当 Andy 添加动画效果后,帽子会留在他的头上。

访问骨头信息

如需访问 ModelRenderable 中架构的相关信息,请使用 getBoneCount()getBoneName()getBoneParent() 方法:

// Get the number of bones in the model’s skeleton.
andyRenderable.getBoneCount();

// Get the names of the bones in the model’s skeleton.
andyRenderable.getBoneName();

// Get the hierarchy of the bones in the model’s skeleton.
andyRenderable.getBoneParent();

使用 SkeletonNode

SkeletonNode 类公开了模型的框架,以将节点附加到特定架构。

如需使用 SkeletonNode,请为其创建新的实例化,并将可渲染对象设置为包含具有框架的模型的可渲染对象。

 andyWithSkeleton = new SkeletonNode();
 andyWithSkeleton.setRenderable(andyRenderable);
 andyWithSkeleton.setParent(scene);

要将可渲染对象附加到特定骨头,请先创建一个新节点并将其附加到骨头。添加包含可渲染对象的节点作为第一个节点的子级。为确保骨架的缩放和旋转不用于设置节点的相对转换,请务必重置第二个节点的缩放和位置。

 hatNode = new Node();
 Node boneNode = new Node();
 boneNode.setParent(andy);
 andy.setBoneAttachment(HAT_BONE_NAME, boneNode);
 hatNode.setRenderable(hatRenderable);
 hatNode.setParent(boneNode);
 hatNode.setWorldScale(Vector3.one());
 hatNode.setWorldRotation(Quaternion.identity());
 Vector3 pos = hatNode.getWorldPosition();