1

I have my entity which has also physics I check for it with the if let syntax:

if let scoot = scooter as? HasPhysics { ... }

this works as charm I am able to get the user tap by using UITapGestureRecognizer this is just the first iteration I would like to use the swipe or pan gestures ideally.

// I can get the location of the tap in the arView
let location =  sender.location(in: arView)

// I can use this three approaches both of them returns me the Entity not sure which to use though
let hittest = arView.hitTest(location)
let results = arView.raycast(from: location, allowing: .existingPlaneInfinite, alignment: .any)
let entity = arView.entity(at: location)

At this stage I am in need of applying the force at the point of the Tap impact. Since I am in this iteration using tap, the force is always the same (in the next iteration I want to count with the velocity/vector of the impact and push my object with greater force on greater velocity gesture).

I just want to make sure the object is behaving the right way. Is this possible?

Andy Jazz
  • 49,178
  • 17
  • 136
  • 220
Csabi
  • 3,097
  • 17
  • 59
  • 107

1 Answers1

2

I think you need the following approach.

First of all, apply generateCollisionShapes(...) instance method that activates collisions for given entities.

func generateCollisionShapes(recursive: Bool)

Secondly, use ray(...) method returning an optional tuple:

@MainActor func ray(through screenPoint: CGPoint) -> (origin: SIMD3<Float>, 
                                                   direction: SIMD3<Float>)?

Thirdly, use arView.scene.raycast(...) method that returns CollisionCastHit collection:

       func raycast(origin: SIMD3<Float>, 
                 direction: SIMD3<Float>, 
                    length: Float = 100, 
                     query: CollisionCastQueryType = .all, 
                      mask: CollisionGroup = .all, 
relativeTo referenceEntity: Entity? = nil) -> [CollisionCastHit]

Instance of CollisionCastHit can give you 4 subproperties:

CollisionCastHit().position
CollisionCastHit().entity
CollisionCastHit().distance
CollisionCastHit().normal

And at last, you already know the vector of force...

entity.physicsMotion?.linearVelocity = SIMD3<Float>()

Optionally, you might use an angular velocity of the body around the center of its mass.

entity.physicsMotion?.angularVelocity = SIMD3<Float>()
Andy Jazz
  • 49,178
  • 17
  • 136
  • 220
  • 1
    thank you and let me try it out, one quick question I have not used this `entity.physicsMotion?.linearVelocity` but something like this : ``` entity.clearForcesAndTorques() entity.addForce([0.0,-0.01,0.0], at:CollisionCastHit().position, relativeTo: nil) ``` will try out your approach and let you know. thank you! – Csabi Feb 09 '22 at 09:58
  • 1
    There are always multiple solutions for the same task. )) – Andy Jazz Feb 09 '22 at 10:13
  • 1
    let me try the angular velocity as well : this kind of works for me it is a bit of a mesh : `scoot.addForce([CollisionCastHit().normal.x, -2.0 * CollisionCastHit().normal.y, CollisionCastHit().normal.z], at:CollisionCastHit().position, relativeTo: nil)` – Csabi Feb 09 '22 at 11:21