RealityKit - 如何为ModelEntity实体动态调整不透明度?

8
通过将ModelEntitymodel属性上的材料颜色设置,可以改变物体的不透明度/透明度。但是如何实现动画效果呢?我的目标是使物体从完全不透明的状态开始动画,然后淡出到设定的透明度,例如50%。

使用SceneKitSCNNodeSCNAction.fadeOpacity就特别容易了。
let fade = SCNAction.fadeOpacity(by: 0.5, duration: 0.5)
node.runAction(fade)

一个 Entity 符合 HasTransform,但这只允许你对缩放、位置和方向进行动画处理,与像淡入淡出等材质的动画处理无关。如果在 RealityComposer 中为动画隐藏或显示创建行为,则该效果存在,但似乎没有类似于 HasTransform 的内容可提供透明度动画处理的功能。
我已经查看了所有文档,我的下一个想法就是创建自定义动画以替换此行为,但似乎应该是可用的,只是我没有找到它。
4个回答

2
我使用了不同的技术进行测试,并得出了令人沮丧的结论:在RealityKit框架中无法动画化材质的不透明度,因为现在(希望未来会有)RealityKit材质不支持运行时动画。让我们等待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
        })
    }
}

请使用以下代码片段以确保动画无法正常工作(仅进行值分配,没有动画过程):
```html

并使用此代码片段以确保动画不正常工作

(没有动画过程,只有值分配):

```
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)
        })
    }
}

2
2023年了,还没有合适的方法来解决这个问题吗? - dqualias

2
如@AndyFedo所说,目前没有办法对实体的不透明度或透明度进行动画处理。
即使在运行时更改SimpleMaterial也会导致闪烁。
虽然如此,我仍然能够对SimpleMaterials颜色的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) 尽管目前只能在非常有限的范围内实现,但它在一定程度上是可行的(因此,可以适合生产)。

0

你也可以在Reality Composer中创建淡入体验,并在Xcode中触发.rcproject文件。我还没有测试.rcproject的其他交互,但至少我知道它可以加载一个模型以淡入到场景中。


0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接