FocusEntity
FocusEntity copied to clipboard
isEnabled is not defined in the class
Describe the bug
Preview compilation issue. When setting focusEntity isEnabled, because there is no member, Swift raises an exception.
error: value of type 'FocusEntity' has no member 'isEnabled'
arView.focusEntity?.isEnabled = false
~~~~~~~~~~~~~~~~~~~ ^~~~~~~~
To Reproduce
arView.focusEntity?.isEnabled = false
Where this was set:
class CustomARView: ARView {
required init(frame frameRect: CGRect, sessionSettings: SessionSettings, modelDeletionManager: ModelDeletionManager) {
super.init(frame: frameRect)
self.focusEntity = FocusEntity(on: self, focus: .classic)
In Xcode: Value of type 'FocusEntity' has no member 'isEnabled'
I see that RealityKit's Entity has isEnabled
:
/// Indicates whether the entity is active, ignoring parent's active state.
public var isEnabled: Bool
but I'm not sure why FocusEntity is not inheriting that.
Interestingly, the app does compile and run. I bumped into this problem when compiling the app and it disappeared. This is now happening when I preview...
Expected behavior
A member variable called isEnabled that can also be set on a public interface.
Environment:
- iOS Version 15
- Device Information actual device iPhone 13 Pro
- macOS Version 12.2.1
- Xcode Version 13.2.1
Additional context
In FocusEntity.swift, the following macro determines which FocusEntity class will be used:
#if canImport(ARKit) && !targetEnvironment(simulator)
Since PreviewProvider uses the simulator targetEnvironment, the second FocusEntity class is used which does not inherit from Entity:
open class FocusEntity {
One quick workaround is to comment out all structs inheriting from PreviewProvider, which breaks the canvas preview.
Another workaround is to put all incompatible code inside this macro:
#if !targetEnvironment(simulator)
...
#endif
Using the Reality School (Ryan Kopinsky) tutorial for ModelPickerApp:
-
In the body of ContentView, wrap "ARViewContainer(modelConfirmedForPlacement: $modelConfirmedForPlacement)" Note: using
#else
macro to wrap "Rectangle().foreground(.white)" creates a placeholder for the ARViewContainer that looks similar to the ARViewContainer in the canvas preview. -
Wrap the entire "ARViewContainer" struct code in the macro.
-
Wrap the entire "CustomARView" class in the macro (this class contains the FocusEntity code).
With the macros in place, previews work in the canvas, and AR functionality works on a real device.
Should be fixed in 2.3.0
Value of type 'FocusEntity' has no member 'isEnabled' same issue again
are you building for the device or simulator?
are you building for the device or simulator?
Value of type 'FocusEntity' has no member 'isEnabled' same issue again
import Foundation import RealityKit import SwiftUI
struct ARViewRepresentable: UIViewRepresentable {
@EnvironmentObject var placementSettings: PlacementSettings
@EnvironmentObject var sessionSettings: SessionSettings
func makeUIView(context: Context) -> CustomARView {
let arView = CustomARView(frame: .zero, sessionSettings: sessionSettings)
placementSettings.sceneObserver = arView.scene.subscribe(to: SceneEvents.Update.self, { event in
updateScene(for: arView)
})
return arView
}
func updateUIView(_ uiView: CustomARView, context: Context) {
}
private func updateScene(for arView: CustomARView?) {
guard let arView = arView else { return }
if let confirmedModel = placementSettings.confirmedModel, let modelEntity = confirmedModel.modelEntity {
place(modelEntity, in: arView)
placementSettings.confirmedModel = nil
}
}
private func place(_ modelEntity: ModelEntity, in arView: ARView) {
let clonedEntity = modelEntity.clone(recursive: true)
clonedEntity.generateCollisionShapes(recursive: true)
arView.installGestures([.translation, .rotation], for: clonedEntity)
if let raycastResult = arView.raycast(from: arView.center, allowing: .existingPlaneGeometry, alignment: .horizontal).first {
let anchorEntity = AnchorEntity(world: raycastResult.worldTransform)
anchorEntity.addChild(clonedEntity)
arView.scene.addAnchor(anchorEntity)
}
}
}