RealityKit ARkit : find an anchor (or entity) from raycast - always nil
I finally manage to found a solution :
My ModelEntity
(anchored) had to have a collision shape !
So after adding simply entity.generateCollisionShapes(recursive: true)
.
This is how I generate a simple box :
let box: MeshResource = .generateBox(width: width, height: height, depth: length)
var material = SimpleMaterial()
material.tintColor = color
let entity = ModelEntity(mesh: box, materials: [material])
entity.generateCollisionShapes(recursive: true) // Very important to active collisstion and hittesting !
return entity
and so after that we must tell the arView
to listen to gestures :
arView.installGestures(.all, for: entity)
and finally :
@IBAction func onTap(_ sender: UITapGestureRecognizer){
let tapLocation = sender.location(in: arView)
if let hitEntity = arView.entity(
at: tapLocation
) {
print("touched")
print(hitEntity.name)
// touched !
return ;
}
}
Referencing RealityKit Component
In RealityKit (and RealityFoundation), you have to call a registerComponent()
type method once for every custom component type that you want to use in your app, before you use it.
public static func registerComponent()
You don’t need to call this method for built-in component types, like CollisionComponent
.
ValueComponent.registerComponent()
The same way you have to call registerSystem()
type method to use a System (ECS pattern).
Solution
Seems that type casting to protocols that implement custom components isn't supported. Inexplicably why. Thus, use the following solution.
import UIKit
import RealityKit
protocol HasValueComponent { }
extension HasValueComponent where Self: Entity {
var val: Int {
get { components[ValueComponent.self]?.val ?? .zero }
set { components[ValueComponent.self]?.val = newValue }
}
}
struct ValueComponent: Component {
var val: Int
}
Primitive.swift
class Primitive: Entity, HasModel, HasValueComponent {
required init() {
super.init()
ValueComponent.registerComponent()
self.model = ModelComponent(mesh: .generateSphere(radius: 0.1),
materials: [SimpleMaterial()])
self.name = "model"
self.components.set(ValueComponent(val: 1234))
}
}
ViewController.swift
class ViewController: UIViewController {
var arView = ARView(frame: .zero)
let primitive = Primitive()
override func viewDidLoad() {
super.viewDidLoad()
arView.frame = self.view.frame
self.view.addSubview(arView)
let anchor = AnchorEntity()
anchor.addChild(self.primitive)
arView.scene.addAnchor(anchor)
if let model = arView.scene.findEntity(named: "model") {
print(model.components[ValueComponent.self]!.val) // 1234
print(model.components.has(ValueComponent.self)) // true
}
}
}
Apply a custom texture to Plane entity using RealityKit 2.0
You have to implement brand-new parameters instead of deprecated arguments:
func createBoard() {
let planeMesh = MeshResource.generatePlane(width: 1,
height: 1,
cornerRadius: 0.05)
var material = SimpleMaterial()
material.color = try! .init(tint: .white,
texture: .init(.load(named: "img", in: nil)))
material.metallic = .init(floatLiteral: 1.0)
material.roughness = .init(floatLiteral: 0.5)
let modelEntity = ModelEntity(mesh: planeMesh,
materials: [material])
let anchor = AnchorEntity()
anchor.addChild(modelEntity)
arView.scene.anchors.append(anchor)
}
Also, you can use the following syntax:
var material = SimpleMaterial()
material.color.texture = .init(try! .load(named: "img", in: nil))
If you need mode details, read this post.
Related Topics
Call Function on App Termination in Swift
Protocol Variable Implementing Another Protocol
Swift-Animate Cashapelayer Stroke Color
Swift: Draw a Semi-Sphere in Mkmapview
Automatic Select a Date in Datepicker in Swift Language
Turn Off Touch for Whole Screen, Spritekit, How
How to Bind My Array Controller to My Core Data Model
Allow Line Editing When Reading Input from The Command Line
Firebase Authentication: Linking Multiple Accounts in Swift
How to Get Section of UItableview from Inside a Child UIcollectionview
Place Multiple Scn Objects in Touchesbegan Method
It Is Posible to Load Customise HTML View into Webview in Swift
Return Object for a Method Inside Completion Block
Sending Array Data from One View Controller to Another
Skphysicscontact Not Detecting Categorybitmask Collision
How to Draw Something on a PDF in Swift
Nstimer Scheduledtimerwithtimeinterval and Target Is "Class Level Function"