Problem with rigid body on instanced object

Hello

So basically, I’m trying to reproduce the bow and arrow example you have, and I’m having a problem where when I try to use rigidbody.applyImpulse(), it doesn’t work. In the console, it tells me “rigidbody doesn’t exist, cannot apply impulse”. I even saw that in your code you have a comment about this:

// workaround Rigidbody not yet created in the physics engine (it gets created in onEnable)
await delayForFrames(1);

But it still doesn’t work. I also tried using an arrow from the Unity Store, and I have the same problem. I tried changing the insantiate objetct to a cube, and it works perfectly fine .

Hi, please provide more information about your scene setup (which materials, please show the hierarchy in Unity etc) and how you reference the Rigidbody. Otherwise it’s not possible to help you.

Make sure your object is actually included in the export (e.g. not tagged with EditorOnly)

Hi marcel ! So this is my hierarchy and the arrow prefab

and this is how im reference the rigidBody

const instance = await this.arrowPrefab.instantiate({ parent: this.context.scene }); 
const rigidbody = instance.getComponent(Rigidbody)!;

if(!rigidbody) return;
if (rigidbody) {
    rigidbody.isKinematic = false;
    rigidbody.autoMass = false;
    rigidbody.mass = .05;
  

    // workaround Rigidbody not yet created in the physics engine (it gets created in onEnable)
    await delayForFrames(1);
    
    rigidbody.applyImpulse(dir.multiplyScalar(force), true);
}

When I try to do it with a cube instead of the arrow, it works without any problem

Hi, thanks. And how do you reference the arrow prefab in Unity + in code? I don’t see this in your screenshots.

And can you show where the rigidbody doesn’t exist log is coming from exactly?

this is in unity

image

and this is in code

@serializable(AssetReference)
arrowPrefab?: AssetReference;

and this is the console

and this is the code when i call the function

onUpdateXR(args: NeedleXREventArgs): void {
   if (this.grabbable?.istryAttach) {
       if (
           this.grabbable?.leftController?.getButton("xr-standard-squeeze")?.value === 1 &&
           this.grabbable?.rightController?.gamepad?.buttons.value === 1
       ) {
           this._isAiming = true;
           this.createArrow();
       }

       if (
           this.grabbable?.leftController?.getButton("xr-standard-squeeze")?.value === 1 &&
           this.grabbable?.rightController?.gamepad?.buttons.value === 0 &&
           this._isAiming
       ) {
           console.log('intentando disparar ');

           if (!this._isAiming) return;
           this._isAiming = false;

           const point = this.grabbable.leftController.gripWorldPosition;
           if (point) {
               const dir = point.clone().sub(this.grabbable.rightController.gripWorldPosition);
               let dist = this.grabbable.rightController.object.worldPosition.distanceTo(this.grabbable.leftController.object.worldPosition);
               dist -= this.drawMinPhysicalDistance;
               const t = Mathf.clamp01(dist / this.drawMaxPhysicalDistance);
               const power = 1.5;

               dir.normalize().multiplyScalar(t * power);

               this.shoot(point, dir);

           }

           this._isAiming = false;
 
       }
   }
}

For debugging you can spawn an instance in awake.

Is it possible that your arrow prefab is disabled / inactive in Unity so it gets instantiated but “visible” is still false? Or some part of the child hierarchy?

Is the arrow a real “prefab” in Unity or is it part of your scene?

So right now I have it active in the scene and is both is a real prefab en unity and that prefab is part of my scene . i can see the arrow it gets instantited but the rigidbody.aplyImpulse doenst work the arrow stay in the scene . I’m debugging, and it shows that the rigid body exists

typescript

async awake() {
    if (this.arrowPrefab?.asset) {
        this.arrowPrefab.asset.visible = false;
    }
    if (this.bowObject) {
        this._initRot.copy(this.bowObject.quaternion);
    }
    
    this.grabbable = GameObject.getComponent(this.gameObject,Grabbable)

    const instance = await this.arrowPrefab!.instantiate({ parent: this.arrowSpawnSpot });

    const rigidbody = instance!.getComponent(Rigidbody)!;

    if(rigidbody) {
        console.log("rigidbody exists")

        await delayForFrames(1);
    
        rigidbody.applyImpulse(this.gameObject.position, true);
    }
}

Is it possible that it doesnt work because you don’t have a collider in your arrow?

Omg that was the problem :laughing:! Thank you so much Marcel!

Ok great, good to know - I’ll see if we can add a proper warning for that :slight_smile: thanks for reporting

1 Like