Skip to content
This repository has been archived by the owner on Jun 10, 2022. It is now read-only.

Rigidbody Addforce or Velocity no longer working? #742

Open
AlecGamble opened this issue Mar 23, 2021 · 1 comment
Open

Rigidbody Addforce or Velocity no longer working? #742

AlecGamble opened this issue Mar 23, 2021 · 1 comment

Comments

@AlecGamble
Copy link

Hi,

I've recently been developing a minigolf SDK and as of the update this week my Rigidbody physics which I was applying to the ball no longer works. I can no longer AddForce or set the velocity as I was doing before. logging the rigidbody's velocity length after using AddForce prints 0s as if it hasn't been applied and setting the velocity manually returns the length of the vector it has been set to so it has been applied but has no visible effect in-game. I've tried creating a new project to isolate this behaviour but I'm still having no luck applying a force to it. This is a behaviour I had working before and initially I thought it might have been that because I was updating my kit objects last week it was using a cached version and the new version had something different but having tried to isolate the behaviour in the following script I think it might be a bug.

export default class App {
    private assets: MRE.AssetContainer;
    private ball: MRE.Actor;
    private speedCheckTimer: NodeJS.Timer;

    constructor(private context: MRE.Context) 
    {
        this.context.onStarted(() => this.Initialise());
    }

    private Initialise() 
    {
        this.assets = new MRE.AssetContainer(this.context);
        this.ball = MRE.Actor.CreatePrimitive(this.assets, {
            definition: {
                shape: MRE.PrimitiveShape.Sphere,
                dimensions: { x: 0.2, y: 0.2, z: 0.2 }
            },
            addCollider: true,
            actor: {
                name: 'ball prim',
                transform: { local: { position: { x: 0, y: 0, z: 0 } } },
                rigidBody: {
                    useGravity:true,
                    mass: 0.2,
                    // velocity: MRE.Vector3.Forward().scale(50000) // <--------
                },
                subscriptions: ['transform', 'rigidbody', 'rigidbody-velocity'],

            }
        });
        this.ball.collider.layer = MRE.CollisionLayer.Navigation;
        // this.ball.rigidBody.velocity = MRE.Vector3.Forward().scale(50000); // <--------
        // this.ball.rigidBody.addForce(MRE.Vector3.Forward().scale(50000)); // <--------
        this.CheckBallSpeed();
    }

    private CheckBallSpeed()
    {
        let x = 0;
        this.speedCheckTimer = setInterval(() => {
            let currentVelocity = this.ball.rigidBody.velocity;
            console.log(currentVelocity.length());
            x++;
            if(x > 5) clearInterval(this.speedCheckTimer);
        }, 120);
    }
}

Thanks in advance for your help!

@norybiak
Copy link
Contributor

norybiak commented Mar 24, 2021

An actor needs to have an owner when using rigidBodies, otherwise the client side portion of the SDK will not add the actor to the physics bridge, or perform any action such as addForce().

I discovered that when actors are created immediately after the onStarted() event, the SDK fails to properly update each actor's owner once the authoritative user joins. The _rigidBodyDefaultOwner is still undefined at this point.

Actors with rigidBodies for physics simulation require a different method of instantiation than how the sample apps are doing it (e.g. creating actors after onStarted()). This isn't known since there is a lack of documentation on the matter.

The below is an example of a pattern that can be used to assist with getting around the issue mentioned above.

private actorsWithPhysicsCreated = false;

constructor(private context: MRE.Context) 
{
    this.context.onStarted(() => this.createStaticActors());
    this.context.onUserJoined((user) => {

        if (!actorsWithPhysicsCreated) 
            this.initActorsWithPhysics();

        this.userJoined(user);

    });
}

private createStaticActors() {

}

private initActorsWithPhysics() {

    this.actorsWithPhysicsCreated = true;
}

private userJoined(use: MRE.User) {
    
}

For the SDK devs: A better pattern would be for the onStarted() event to fire once the authoritative user is known and the _rigidBodyDefaultOwner property has been defined.

If an actor is intended to be exclusive, it's best to set the the owner manually.

MRE.Actor.Create(this.app.context, {
	actor: {
		exclusiveToUser: user.id,
		owner: user.id,
	}
});

Edit:

"I discovered that when actors are created immediately after the onStarted() event, the SDK fails to properly update each actor's owner once the authoritative user joins. The _rigidBodyDefaultOwner is still undefined at this point."

I found a fix that ensures actors created without owners properly receive the default owner when created within this.context.onStarted(() => .... See the referenced PRs.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants