RealityKit-对ModelEntity的不透明度进行动画处理?

时间:2020-01-16 08:04:24

标签: swift augmented-reality arkit realitykit reality-composer

通过在model的{​​{1}}属性上设置材料的颜色,我可以更改对象的不透明度/ alpha。但是,如何为它设置动画?我的目标是为具有完全不透明度的对象设置动画,然后使它们淡化为设置的不透明度,例如50%。

ModelEntity中的SCNAction.fadeOpacity上放置SCNNode时,这特别容易。

SceneKit

let fade = SCNAction.fadeOpacity(by: 0.5, duration: 0.5) node.runAction(fade) 符合Entity,但这仅允许您设置比例,位置和方向的动画。与将材质淡入或淡出之类的动画无关。如果您创建用于隐藏或显示动画的行为,则效果在RealityComposer中,但是似乎没有与HasTransform类似的东西来提供用于动画不透明度的功能。

我到处都是文档,一直在寻找东西,我的下一个想法实质上是创建一个自定义动画来替代此行为,但似乎应该可以使用,而我只是找不到它。

4 个答案:

答案 0 :(得分:1)

我使用不同的技术对其进行了测试,得出一个可悲的结论:您无法在RealityKit框架中为材质的不透明度设置动画,因为RealityKit materials don't support animation at runtime(现在希望如此)。让我们等待RealityKit的主要更新。

这是可用于测试的代码

arView.alpha属性就可以使用):

import UIKit
import RealityKit

class ViewController: UIViewController {

    @IBOutlet var arView: ARView!

    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)

        arView.alpha = 1.0 
        opacityAnimation()
    }

    func opacityAnimation() {

        UIView.animate(withDuration: 5.0,
                         animations: {

            self.arView.alpha = 0.0
        })
    }
}

并使用此代码段以确保动画无法正常运行

(没有动画处理,只有值分配):

import UIKit
import RealityKit

class ViewController: UIViewController {

    @IBOutlet var arView: ARView!
    let tetheringAnchor = AnchorEntity(world: [0,0,0])
    var material = SimpleMaterial()
    let mesh: MeshResource = .generateSphere(radius: 0.5)
    var sphereComponent: ModelComponent? = nil

    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)

        material.metallic = .float(1.0)
        material.roughness = .float(0.0)
        material.baseColor = .color(.red)

        sphereComponent = ModelComponent(mesh: mesh,
                                    materials: [material])

        tetheringAnchor.components.set(sphereComponent!)
        arView.scene.anchors.append(tetheringAnchor)

        opacityAnimation()
    }

    func opacityAnimation() {

        UIView.animate(withDuration: 5.0,
                         animations: {

            self.material.metallic = .float(1.0)
            self.material.roughness = .float(0.0)
            self.material.baseColor = .color(.green)

            self.sphereComponent = ModelComponent(mesh: self.mesh,
                                             materials: [self.material])

            self.tetheringAnchor.components.set(self.sphereComponent!)
            self.arView.scene.anchors.append(self.tetheringAnchor)
        })
    }
}

答案 1 :(得分:1)

正如@AndyFedo所说,目前无法为Entity的不透明度和Alpha设置动画。

即使在运行时更改SimpleMaterial,当前也会导致闪烁。

我已经说过,我能够为SimpleMaterials Color的Alpha设置动画,但是基于测试,它绝不是最佳选择,也不建议这样做。

但是,以防万一,您想尝试进一步尝试使用此方法,请参阅随附的示例,该示例假定您只有一个SimpleMaterial

class CustomBox: Entity, HasModel, HasAnchoring {

  var timer: Timer?
  var baseColour: UIColor!

  //MARK:- Initialization

  /// Initializes The Box With The Desired Colour
  /// - Parameter color: UIColor
  required init(color: UIColor) {
    self.baseColour = color
    super.init()
    self.components[ModelComponent] = ModelComponent(mesh: .generateBox(size: [0.2, 0.2, 0.2]),
                                                     materials:  [SimpleMaterial (color:  baseColour, isMetallic: false)]
    )
  }

  required init() { super.init() }

  //MARK:- Example Fading

  /// Fades The Colour Of The Entities Current Material
  func fadeOut() {

    var alpha: CGFloat = 1.0
    timer = Timer.scheduledTimer(withTimeInterval: 0.05, repeats: true) { timer in

      if alpha == 0 {
        timer.invalidate()
        return
      }

      var material = SimpleMaterial()
      alpha -= 0.01
      material.baseColor = MaterialColorParameter.color(self.baseColour.withAlphaComponent(alpha))
      material.metallic = .float(Float(alpha))
      material.roughness = .float(Float(alpha))
      DispatchQueue.main.async {
        self.model?.materials = [material]

      }
    }
  }
}

就这样进行测试,您可以创建然后调用该函数,如下所示:

let box = CustomBox(color: .green)
box.position = [0,0,-0.5]
arView.scene.anchors.append(box)
box.fadeOut()

我还要礼貌地问一下,这个答案不会被否决,因为我只是在反复这样一个事实,即(a)当前没有任何内置方法,(b)尽管可以部分实现在非常有限的程度上(因此,目前;以某种方式适合生产)。

答案 2 :(得分:0)

我不知道它是否适合您的用例。但是您应该考虑视频材料。 如您在此WWDC会话中看到的(2分45秒)。具有复杂的脉动不透明度的实体。

https://developer.apple.com/videos/play/wwdc2020/10612/

答案 3 :(得分:0)

您还可以在 Reality Composer 中创建淡入淡出体验并在 Xcode 中触发 .rcproject 文件。尚未测试与 .rcproject 的其他交互,但我知道至少这可以加载模型以淡入场景。