大多数浏览器和
Developer App 均支持流媒体播放。
-
在 Reality Composer Pro 中编写交互式 3D 内容
探索 Reality Composer Pro 中的“时间线”视图如何栩栩如生地呈现你的 3D 内容。了解如何使用逆向运动分析、形状变形和骨骼位姿打造一个动画故事,让其中的角色和物体能够彼此之间以及与周围环境之间进行交互。我们还将介绍如何使用内置操作和自定操作、为操作排序、应用触发条件,并实现自然动作。
章节
- 0:00 - Introduction
- 2:54 - Introducing timelines
- 18:22 - Inverse kinematics
- 22:55 - Animation actions
- 27:23 - Blend Shapes animation
- 30:35 - Skeletal poses
资源
相关视频
WWDC24
WWDC23
-
下载Array
-
-
20:31 - Setup IKComponent
// Setup IKComponent import RealityKit struct HeroRobotRuntimeComponent: Component { var rig = try? IKRig(for: modelSkeleton) rig.maxIterations = 30 rig.globalFkWeight = 0.02 let hipsJointName = "root/hips" let chestJointName = "root/hips/spine1/spine2/chest" let leftHandJointName = "root/hips/spine1/spine2/chest/…/L_arm3/L_arm4/L_arm5/L_wrist" rig.constraints = [ .parent(named: "hips_constraint", on: hipsJointName, positionWeight: SIMD3(repeating: 90.0), orientationWeight: SIMD3(repeating: 90.0)), .parent(named: "chest_constraint", on: chestJointName, positionWeight: SIMD3(repeating: 120.0), orientationWeight: SIMD3(repeating: 120.0)), .point(named: "left_hand_constraint", on: leftHandJointName, positionWeight: SIMD3(repeating: 10.0)) ] let resource = try? IKResource(rig: rig) modelComponentEntity.components.set(IKComponent(resource: resource)) }
-
21:33 - Update IKComponent
// Update IKComponent import RealityKit struct HeroRobotRuntimeComponent: Component { guard let reachTarget = sceneRoot.findEntity(named: "reachTargetName") else { return } var reachPosition = reachTarget.position(relativeTo: entity) let time = sin(simTime) reachPosition.x += (20.0 + 50.0 * time) reachPosition.y += (40.0 + 30.0 * abs(time)) reachPosition.z += (20.0 + 20.0 * abs(time)) guard let ikComponent = modelComponentEntity.components[IKComponent.self] else { return } var reachPosition = reachTarget.position(relativeTo: entity) ... var leftHandConstraint = ikComponent.solvers.first?.constraints["left_hand_constraint"] leftHandConstraint?.target.translation = reachPosition // A blendValue = 0 means no influence on the constraint. // A blendValue = 1 means full influence on the constraint. var blendValue = isEnabled ? (time / totalBlendTime) : (1.0 - time / totalBlendTime) leftHandConstraint?.animationOverrideWeight.position = blendValue modelComponentEntity.components.set(ikComponent) }
-
24:36 - Sequence and play animation actions
// Play Animation Actions import RealityKit struct HeroRobotRuntimeComponent: Component { let rotateAnimationResource = createRotateAnimationResource() let walkAndMoveAnimationGroup = createWalkAndMoveAnimationGroup() let alignAtHomeActionResource = createAlignAtHomeActionResource() let robotTravelHomeCompleteActionResource = createRobotTravelHomeCompleteAction() // Build a sequence of the rotate, move and align animations/actions to play. let moveHomeSequence = try? AnimationResource.sequence(with: [rotateAnimationResource, walkAndMoveAnimationGroup, alignAtHomeActionResource, robotTravelHomeCompleteActionResource]) // Play the move-to-home sequence. _ = robotEntity.playAnimation(moveHomeSequence) }
-
25:59 - Setup EntityActions
// Setup EntityActions import RealityKit struct HeroRobotRuntimeComponent: Component { struct RobotMoveToHomeComplete: EntityAction { var animatedValueType: (any AnimatableData.Type)? { nil } } let travelCompleteAction = RobotMoveToHomeComplete() let actionResource = try! AnimationResource.makeActionAnimation(for: travelCompleteAction, duration: 0.1) let _ = robotEntity.playAnimation(actionResource) }
-
26:39 - EntityAction subscription
// EntityAction subscription import RealityKit struct HeroRobotRuntimeComponent: Component { // Subscribe to know when the EntityAction has started. RobotMoveToHomeComplete.subscribe(to: .started) { event in if event.playbackController.entity != nil { event.playbackController.stop() } } // Possible states of the robot. public enum HeroRobotState: String, Codable { case available … case arrivedHome } // Subscribe to know when the EntityAction has ended. RobotMoveToHomeComplete.subscribe(to: .ended) { event in if let robotEntity = event.playbackController.entity, var component = robotEntity.components[HeroRobotRuntimeComponent.self] { component.setState(newState:.arrivedHome) } } }
-
29:17 - Setup BlendshapeWeightsComponent
// Setup BlendShapeWeightsComponent import RealityKit struct HeroPlantComponent: Component, Codable { guard let modelComponentEntity = findModelComponentEntity(entity: entity), let modelComponent = modelComponentEntity.components[ModelComponent.self] else { return } let blendShapeWeightsMapping = BlendShapeWeightsMapping(meshResource: modelComponent.mesh) // Create the blend shape weights component. entity.components.set(BlendShapeWeightsComponent(weightsMapping: blendShapeWeightsMapping)) }
-
29:38 - Update BlendshapeWeightsComponent
// Update BlendShapeWeightsComponent struct HeroPlantComponent: Component, Codable { guard let component = entity.components[BlendShapeWeightsComponent.self] else { return } var blendWeightSet = blendShapeComponent.weightSet // Update the weights in the BlendShapeWeightsSet for weightIndex in 0..<blendWeightSet[blendWeightsIndex].weights.count { blendWeightSet[blendWeightsIndex].weights[weightIndex] = 0.0 } // Assign the new weights to the blend shape component. for index in 0..<blendWeightSet.count { component?.weightSet[blendWeightsIndex].weights = blendWeightSet[index].weights } }
-
32:01 - Setup and update Skeletal Poses
// Update Skeletal Poses import RealityKit struct StationaryRobotRuntimeComponent: Component { guard var component = entity.components[SkeletalPosesComponent.self] else { return } let neckRotation = calculateRotation() component.poses.default?.jointTransforms[neckJointIndex].rotation = neckRotation }
-
-
正在查找特定内容?在上方输入一个主题,就能直接跳转到相应的精彩内容。
提交你查询的内容时出现错误。请检查互联网连接,然后再试一次。