VisionOS Simulator DragGestures

Hello, Right now I am learning some RealityKit for VisionOS. I do not receive any errors in my code so it seems okay. But I can't drag my object around. Does the SIM supports gestures in general?

//
//  ImmersiveView.swift
//  NewDimensionn
//
//  Created by Patrick Schnitzer on 18.07.23.
//

import SwiftUI
import RealityKit
import RealityKitContent

struct ImmersiveView: View {

    var earth: Entity = Entity()
    var moon: Entity = Entity()


    var body: some View {
        RealityView { content in
            async let earth = ModelEntity(named: "EarthScene", in: realityKitContentBundle)
            async let moon = ModelEntity(named: "MoonScene", in: realityKitContentBundle)

            if let earth = try? await earth, let moon = try? await moon {
                content.add(earth)
                content.add(moon)

            }
        } .gesture(DragGesture()
            .targetedToEntity(earth)
            .onChanged{ value in
                earth.position = value.convert(value.location3D, from: .local, to: earth.parent!)
            }
        )
    }
}

#Preview {
    ImmersiveView()
        .previewLayout(.sizeThatFits)
}```


Accepted Reply

Hello,

Simulator does support DragGesture.

Here is a minimal example that should work for you:

import SwiftUI
import RealityKit

struct ImmersiveView: View {
    var body: some View {
        RealityView { content in
            
            let sphere = ModelEntity(mesh: .generateSphere(radius: 0.1))
            
            // A name for identifying this entity.
            sphere.name = "sphere"

            // Generates collision shapes for the sphere based on its geometry.
            sphere.generateCollisionShapes(recursive: false)
            
            // Give the sphere an InputTargetComponent.
            sphere.components.set(InputTargetComponent())
            
            // Set the initial position.
            sphere.position = .init(0, 1, -0.5)
            
            content.add(sphere)
        }
        .gesture(dragGesture)
    }
    
    var dragGesture: some Gesture {
        
        DragGesture()
            .targetedToAnyEntity()
            .onChanged { value in
                print(value.entity.name)
            }
    }
}

As for why your code isn't working, it looks like you have multiple "earth" entities. The "earth" that you added to your scene is not the same as the "earth" that you are targeting that DragGesture to.

Replies

Do you need to add a collision component to the model entity for the gestures to “contact” it? That was required in pre-Vision RealityKit

Hello thank you for your comment! I have already added the components to the scenes.

  • Input Target
  • Collision

Hello,

Simulator does support DragGesture.

Here is a minimal example that should work for you:

import SwiftUI
import RealityKit

struct ImmersiveView: View {
    var body: some View {
        RealityView { content in
            
            let sphere = ModelEntity(mesh: .generateSphere(radius: 0.1))
            
            // A name for identifying this entity.
            sphere.name = "sphere"

            // Generates collision shapes for the sphere based on its geometry.
            sphere.generateCollisionShapes(recursive: false)
            
            // Give the sphere an InputTargetComponent.
            sphere.components.set(InputTargetComponent())
            
            // Set the initial position.
            sphere.position = .init(0, 1, -0.5)
            
            content.add(sphere)
        }
        .gesture(dragGesture)
    }
    
    var dragGesture: some Gesture {
        
        DragGesture()
            .targetedToAnyEntity()
            .onChanged { value in
                print(value.entity.name)
            }
    }
}

As for why your code isn't working, it looks like you have multiple "earth" entities. The "earth" that you added to your scene is not the same as the "earth" that you are targeting that DragGesture to.

Hello, now it works with following code:

//  ImmersiveView.swift
//  NewDimensionn
//
//  Created by Patrick Schnitzer on 18.07.23.
//

import SwiftUI
import RealityKit
import RealityKitContent


struct ImmersiveView: View {
    var body: some View {
        RealityView { content in

            async let sphere = ModelEntity(named: "EarthScene", in: realityKitContentBundle)
            if let sphere = try? await sphere {
                    // A name for identifying this entity.
                sphere.name = "sphere"

                    // Generates collision shapes for the sphere based on its geometry.
                sphere.generateCollisionShapes(recursive: false)

                    // Give the sphere an InputTargetComponent.
                sphere.components.set(InputTargetComponent())

                    // Set the initial position.
                sphere.position = .init(0, 1, -0.5)

                content.add(sphere)

            }
        }
        .gesture(dragGesture)
    }

    var dragGesture: some Gesture {

        DragGesture()
            .targetedToAnyEntity()
            .onChanged { value in
                print(value.entity.name)
                value.entity.position = value.convert(value.location3D, from: .local, to: value.entity.parent!)

            }
    }
}

#Preview {
    ImmersiveView()
        .previewLayout(.sizeThatFits)
}

Thank you very much ;)