首页 > 其他分享 >Reality Kit 中的事件系统

Reality Kit 中的事件系统

时间:2024-01-17 12:11:40浏览次数:25  
标签:box 触发 color self 碰撞 Reality let 事件 Kit

    苹果在 2019年推出了一个名为 Combine 的声明性异步事件处理框架,通过采用Combine 框架,可以集成事件处理代码并消除嵌套闭包和基于约定的回调,使代码更易于阅读和维护。Combine 框架 API都是使用类型安全的泛型实现,可以无缝接人已有工程,用于处理各类事件。在 Combine 框架中,最重要的3个组成部分是:Publisher (发布者)、Subscriber(订阅者)和 Operator (操作符)。Combine 事件处理机制是典型的观察者模式(与 RxSwift 中的 Observable、Observer 几平完全一致),Reality Kit 中的事件处理机制完全借用了 Combine,也包括 Publisher、Subscriber、Operator 3个组成部分,并且所有 Publisher 都遵循 Event 协议。目前,RealityKit 所有的事件如表 20所示。

            表20 RealityKit 中的所有事件

 所属事件类型 事件  描述 
 场景   

SceneEvents.AnchoredStateChanged

 

当场景中的 ARAnchor(包括所有遵循 HasAnchoring 协议的实体)状态发生改变时触发

 

SceneEvents.Update

 

该事件每帧都会触发,因此可以执行自定义帧更新逻辑

 动画  

AnimationEvents. PlaybackCompleted

 

当动画播放完毕时触发

 

AnimationEvents. PlaybackLooped

 

当动画循环播放时触发

 

AnimationEvents. Playback Terminated

 

当动画被中止时触发,包括播放完毕或者被中断

 音频  

AudioEvents. PlaybackCompleted

 

当音频播放完毕时触发

 碰撞    

CollisionEvents. Began

 

当两个带碰撞器的对象碰撞开始时触发,每次碰撞只触发一次

 

CollisionEvents. Updated

 

当两个带碰撞器的对象碰撞接触后每帧都会触发

 

CollisionEvents. Ended

 

当两个带碰撞器的对象发生碰撞后脱离接触时触发,每次碰撞只触发一次

 网络同步   

SynchronizationEvents. OwnershipChanged

 

当一个实体对象的所有权属性发生改变时触发

 

SynchronizationEvents. OwnershipRequest

 

当一个网络参与者申请对某个实体对象的所有权时触发

RealityKit 中的所有事件都可以通过 subscribe(to:on:_:)方法订阅监听,并且所有的事件处理遵循相司的步骤与流程,因此只要理解并掌握一种事件处理方法就可以推广到所有其他类型事件的处理中。

     下面以碰撞事件(Collision Events)为例讲解 RealityKit 事件的一般处理方法。通常,在需要处理某类耳件之前需先订阅(subscribe)该事件,在RealityKit 中,我们使用 scene完成订阅操作,典型代码如下

import SwiftUI
import RealityKit
import ARKit
import Combine

struct RealityKitEventView : View {
    var body: some View {
        return ARViewContainer8().edgesIgnoringSafeArea(.all)
    }
}

struct ARViewContainer8: UIViewRepresentable {
    
    func makeUIView(context: Context) -> ARView {
        let arView = ARView(frame: .zero)
        let config = ARWorldTrackingConfiguration()
        config.planeDetection = .horizontal
        arView.session.run(config, options: [])
        arView.setupGestures()
        return arView
    }
    
    func updateUIView(_ uiView: ARView, context: Context) {}
}

extension ARView{
    
    func setupGestures() {
        let tap = UITapGestureRecognizer(target: self, action: #selector(self.handleTap(_:)))
        self.addGestureRecognizer(tap)
    }
    
    @objc func handleTap(_ sender: UITapGestureRecognizer? = nil) {
        guard let touchInView = sender?.location(in: self) else {
            return
        }
        guard let raycastQuery = self.makeRaycastQuery(from: touchInView, allowing: .existingPlaneInfinite,alignment: .horizontal) else {
            return
        }
        guard let result = self.session.raycast(raycastQuery).first else {return}
        let transformation = Transform(matrix: result.worldTransform)
        let box = CustomEntity(color: .yellow,position: transformation.translation)
        self.installGestures(.all, for: box)
        box.addCollisions(scene: self)
        self.scene.addAnchor(box)
    }
}
//自定义实体类
class CustomEntity: Entity, HasModel, HasAnchoring, HasCollision {
    var subscribes: [Cancellable] = []
    required init(color: UIColor) {
        super.init()
        //设置碰撞组件,可以和其他实体发生碰撞
        self.components.set(CollisionComponent(
            shapes: [.generateBox(size: [0.1,0.1,0.1])],
            mode: .default,
            filter: CollisionFilter(group: CollisionGroup(rawValue: 1), mask: CollisionGroup(rawValue: 1))
        ))
        
        //添加组件,定义实体的模型资源
        self.components.set( ModelComponent(
            mesh: .generateBox(size: [0.1,0.1,0.1]),
            materials: [SimpleMaterial(color: color,isMetallic: false)]
        ))
    }
    
    convenience init(color: UIColor, position: SIMD3<Float>) {
        self.init(color: color)
        self.position = position
    }
    
    required init() {
        fatalError("init()没有执行,初始化不成功")
    }
    
    func addCollisions(scene: ARView) {
        subscribes.append(scene.scene.subscribe(to: CollisionEvents.Began.self, on: self) { event in
            guard let box = event.entityA as? CustomEntity else {
                return
            }
            //发生碰撞时把实体变成红色
            box.model?.materials = [SimpleMaterial(color: .red, isMetallic: false)]
            
        })
        subscribes.append(scene.scene.subscribe(to: CollisionEvents.Ended.self, on: self) { event in
            guard let box = event.entityA as? CustomEntity else {
                return
            }
            box.model?.materials = [SimpleMaterial(color: .yellow, isMetallic: false)]
        })
    }
}

 

标签:box,触发,color,self,碰撞,Reality,let,事件,Kit
From: https://www.cnblogs.com/duzhaoquan/p/17969730

相关文章

  • 全志R128 Devkit开发板原理图模块介绍及使用说明
    针对R128模组,百问科技推出了R128DevKit开发板作为快速开发评估工具。板载R128-S2-N16R16模组板载2.4GRF陶瓷天线板载USBTypeCOTG板载UART转USB芯片板载RESET,FEL下载按键板载4颗WS2812RGBLED板载PMU,支持对外供电3.3V1A提供GPIO37个,引出3路MIC,2路......
  • iOS ARKit 中的手势检测
       智能移动设备的手势操作是使用者接受并已习惯的操作方式,在移动端AR应用中,对虚拟物体的操竹也基本通过手势操作完成,需要注意的是,本次所讲中手势检源是指用户在手机屏幕上的手指操作检测,不是指利用图像技术对使用者手部运动的检测。  手势检测是指通过检测使用者在手......
  • asp.net 页面的事件执行顺序(全)
    原文链接:https://www.cnblogs.com/ishibin/archive/2012/08/14/2638054.html默认的aspx页面都是继承自System.Web.UI.Page,Page基类定义了很多需要预执行的事件,这些事件虽没有在aspx页面中显示的定义或提及,但它们仍然会以一定的顺序去执行,这些事件的执行顺序是:1.OnPreInit 2.......
  • iOS ARKit 中的射线检测
    射线检测简介    射线检测 Raycasting,直译为射线投射,通常我们根据它的作用称为射线检测。射线检测是在3D数字世界选择某个特定物体常用的一种技术,如在3D、VR游戏中检测子弹命中敌人情况或者从地上捡起一支枪,这都要用到射线检测,射线检测是在3D数字空间中选择虚拟物体......
  • iOS ARKit 三大类 ARSession ARAnchor ARFrame
    ARSessionARSession(AR会话)是ARKit中最重要的概念之一,其主要的功能是管理AR应用的状态和整个周期,是ARKitAPI的主要人口。ARSession整合了底层的所有技术并为开发者提供程序界面,这些技术包括从设备运动传感器硬件取数据、捕获摄像头图像数据并进行分析、控制虛拟场景摄像机与硬......
  • iOS ARKit 三大基础能力
    ARKit三大基础能力   ARKit整合了SLAM、计算机视觉、机器学习、传感器融合、表面估计、光学校准、特征匹配、非线性优化等大量低层技术,提供给开发者简洁易用的程序界面。ARKit提供的功能总体可以分为3个部分:运动跟踪、场景理解、渲染,1.运动跟踪运动跟踪可以实时跟......
  • iOS ARKit 显示引导示图、添加正方体
    ARKit概述2017年,在WWDC(WorldWideDevelopersConference,苹果全球开发者大会)上,苹果公司了增强现实开发套件ARKit。ARKit一推出即在科技圈引发极大关注,一方面是苹果公司在科技影响力,另一方面更重要的是ARKit在秘动端实现的堪称惊艳的AR效果。ARKit的面世,直接术带到了亿万用......
  • 【scikit-learn基础】--『监督学习』之 层次聚类
    层次聚类算法是机器学习中常用的一种无监督学习算法,它用于将数据分为多个类别或层次。该方法在计算机科学、生物学、社会学等多个领域都有广泛应用。层次聚类算法的历史可以追溯到上世纪60年代,当时它主要被用于社会科学中。随着计算机技术的发展,这种方法在90年代得到了更为广泛的......
  • FreeRTOS--事件组
    示例源码基于FreeRTOSV9.0.0事件组1.概述FreeRTOS事件组,是任务间同步的一种方式。它基于bitmap实现,所谓的事件组,即一个整数。整数中的每一位代表着一个事件,bit为1时表示事件发生,bit为0表示事件未发生;事件触发可以由任务触发,也可以由中断服务触发,触发时将对应bit位置1;当任......
  • 详解Spring事件监听
    第1章:引言大家好,我是小黑。今天咱们来聊下Spring框架中的事件监听。在Java里,事件监听听起来好像很高大上,但其实它就像是我们日常生活中的快递通知:当有快递到了,你会收到一个通知。同样,在程序中,当某些事情发生时(比如用户点击了按钮),系统会发送一个事件,然后监听这个事件的处理器就会......