FocusEntity icon indicating copy to clipboard operation
FocusEntity copied to clipboard

isEnabled is not defined in the class

Open Andrew-Chen-Wang opened this issue 2 years ago • 1 comments

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

Andrew-Chen-Wang avatar Mar 12 '22 19:03 Andrew-Chen-Wang

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:

  1. 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.

  2. Wrap the entire "ARViewContainer" struct code in the macro.

  3. 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.

mike-piazza avatar Mar 27 '22 13:03 mike-piazza

Should be fixed in 2.3.0

maxxfrazer avatar Oct 31 '22 12:10 maxxfrazer

Value of type 'FocusEntity' has no member 'isEnabled' same issue again

kharabe avatar Nov 14 '23 04:11 kharabe

are you building for the device or simulator?

maxxfrazer avatar Nov 14 '23 07:11 maxxfrazer

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

}

kharabe avatar Nov 18 '23 16:11 kharabe