how do you make rocket jumping in godot - godot

I have been having some problems in making rocket jumping in Godot using GDscript I cannot add any code here as everything i try to do always fails

Since you are asking about rocket jumping, I'll assume you already have a projectile weapon working, and you already have a character controller working.
The next step is to make an explosion. Go ahead and make an explosion scene. When the projectile collides with the scenario or another character, you will spawn the explosion scene, and queue_free the projectile.
For the explosion scene, you probably want to set up a particle system, let it play for a predetermined time, and then queue_free the explosion scene too. But that is not the part that is relevant for rocket jumping.
What you need is an Area in the explosion scene, that represent the blast radius. The idea is that everything inside the Area (everything that triggers "body_entered" on the Area) can take damage and can be pushed away. You can further refine using a RayCast if you want allow characters to take cover. But again, that is not relevant for rocket jumping, so I suggest get it working without the RayCast and you can add it later if you want.
Alright, so you got a body in the "body_entered" signal of the Area that represents the blast radius of the explosion spawned by the projectile when it collided. Then what?
You want a vector that goes from the explosion to that body. That would be like this:
var vector := body.global_transform.origin - global_transform.origin
I remind you, this goes in the function for the "body_entered" signal.
In fact, we want the unit vector:
var vector := body.global_transform.origin - global_transform.origin
var direction := vector.normalized()
And the distance:
var vector := body.global_transform.origin - global_transform.origin
var direction := vector.normalized()
var distance := vector.length()
Squared:
var vector := body.global_transform.origin - global_transform.origin
var direction := vector.normalized()
var distance_squared := vector.length_squared()
Now, the idea is that you will apply to the body a velocity proportional to the inverse of the distance squared. You want the velocity to be configurable, and tweak it for the needs of your game, so add a export variable on the top of the script:
var export speed := 10.0
And we compute the velocity:
var vector := body.global_transform.origin - global_transform.origin
var direction := vector.normalized()
var distance_squared := vector.length_squared()
var velocity := direction * speed/distance_squared
I'm trying to mimic the inverse square law. But, it is your game, if you find that using the distance instead of distance_squared works better, or you want to make the velocity decay differently, or not at all, go ahead and change it.
If the body is a RigidBody we can apply an impulse or set the linear velocity. And you probably should do that anyway, so the explosion can knock down other objects. But your player character probably is a KinematicBody, right?
Now, I don't know how the code for your player character looks like (you haven't added your code to the question), so I don't know you would apply a velocity to it.
However, most tutorials for player character will have you set a velocity vector, and the idea is that we will add the velocity we computed to it. Assuming yours is similar, that should be something like this:
body.velocity += velocity
But, of course, that should only be for your characters. So you should filter for that. If they have a class_name you probably can do this (assuming here that they are class_name Character):
if body is Character:
body.velocity += velocity
By the way, this will push everything with the same velocity. It probably should push lighter object more and heavier objects less. For the RigidBody, you would apply a force instead of an impulse. So you could declare a mass in your characters and take into account for computing the velocity. But, again, get the simple version working first.

Related

Get velocity or deviation of hand, during manipulation on Hololens2 with MRTK2.5

What I'm trying to do:
I am using MRTK2.5.1 / Hololens2 and the OnlineMaps asset in Unity. I want to use my hand (by either touching map, or pointer from distance) to scroll the map. i.e. tap/grip the map, then drag hand around x/z plane.
What I've done previously:
With holotoolkit/hololens1, this was easily done with a listener for manipulation events.
The OnManipulationChanged event provided me with a CumulativeDelta value of how the hand position had changed since the start of the manipulation.
What I've tried in MRTK2.5:
I started off with ManipulationHandler, which gives me the pointer in eventdata. The pointer->controller has a velocity value, but that's always 0,0,0. I couldn't see anything else obvious relating to velocity or delta position of the thing (hand) triggering the manipulation.
The PointerHandler script has an OnPointerDragged event, but again has no property that looks like a velocity or delta position of hand.
Do i need to be using Gestures?
Not looking for code, just a brief explanation of the correct approach to get the hand velocity or deviation of hand, once the hand has tapped/clicked on the map.
Actually, ManipulationHandler component is deprecated and ObjectManipulator component is a replacement for manipulation behavior. So it is recommended you start with the Object Manipulator component to makes your map movable.
For your question about how to scroll the map around x/z plane, Constraint is aimed at limiting manipulation in some way. Once constraint enabled on your ObjectManipulator component, transform changes will be processed by constraints registered to the selected constraint manager. In your case, MoveAxisConstraint can meet your need, you can add MoveAxisConstraint to game object from Constraint Manager component and set the Constraint On Movement property of Move Axis Constraint component to Y Axis. For more information about MoveAxisConstraint please refer to: https://microsoft.github.io/MixedRealityToolkit-Unity/Documentation/README_ConstraintManager.html#moveaxisconstraint

How do I rotate an object so that it's always facing the mouse position?

I'm using ggez to make a game with some friends, and I'm trying to have our character rotate to face the pointer at all times. I know so far that I need to get an angle value (f32) in radians, and I think I can use atan2 to get this (?) However, I just don't get the behavior that I want.
This is the code I have: (btw, move_data is a struct holding our player character's values, such as position, velocity, angle and rotation speed).
let m = mouse::position(ctx);
move_data.angle = ((m.y - move_data.position.y).atan2(move_data.position.x - m.x)) * (consts::PI / 2.0) as f32;
I think that I'm close, as I'm already able with this to rotate the character, but only in a sort of 'incomplete' way. The player character (pc) can mostly only face to the upper left corner, when I move the mouse there. Otherwise, if the pointer is to the right and/or below the pc, it rotates in a very slow and minor way, and stops facing the pointer. I don't know if this description makes sense.
I think the problem is that I'm not entirely sure what atan2 is doing in the first place (I only remember some basic trigonometry), and I am also not sure if I'm using it correctly, so I don't exactly know what my code is doing. (Here is the documentation I used for atan2: https://doc.rust-lang.org/std/primitive.f64.html#method.atan2)
I've gotten only so far after much trial and error, Googling as much as I can (mostly Unity tutorial results showed up when looking for algorithms to base my code off of) and I've also asked in the unofficial Rust community Discord server, but nothing so far has worked.
I also had this code earlier, but couldn't find how to make it work either.
let m = mouse::position(ctx); // Type Point2
let mouse_pos = Vector2::new(m.x, m.y); // Transformed to Vector2 to be read by Matrix
move_data.angle = Matrix::angle(&mouse_pos, &move_data.position);

Adjusting initial bullet angle to match user set distance(scope zero) (for math gods)

So my question is pretty specific, which means it was pretty hard to find anything that could help me on google or stackoverflow.
I want to give users the ability to set the distance/range on their guns. I have almost everything I need to make this happen, I just don't have the angle that I need to add on to the direction angle at which the bullet comes from. I don't know what equation/formula I would need to get this. I am not looking for anything code-specific, just an idea of what/how to do this.
Since I do not know what formula to use, I just started messing around with some numbers with this formula I found:
(This formula applies to actual sniper)
Range = 1000 * ActualTargetHeight/TargetHeightInMils(on the scope)
BulletDrop = BulletDropSpeed*Range^2/2*VelocityOfTheBullet
MilsToRaiseScope = 1000 * BulletDrop * RangeToTarget
I just replaced Range with the whatever zero the user is on.
I have a feeling I would just toss the MilsToRaiseScope into a trigonometry function. But I'm not sure.
If anyone is confused as to what I'm talking about, you can find an example of what I want in Battlefield 4 or any of the Arma games. With snipers, you can zero in the scope on to whatever distance you need so you won't have to adjust for bullet drop on the scope.
Sorry for the long question, just want to make sure everyone understands! :)
Mils corresponds to (military) angular measurement unit of 1/1000 of radian, so it is ready-to-use angle
Second formula looks strange. Height loss depends on time of flight:
dH = g*t^2/2 = g * (Range / VelocityOfTheBullet)^2 / 2
where g is 9.81 m/sec^2
I am using a 2D table look up for this.
I generate the table by doing a whole bunch of test firings at different angles, and record the path of the bullet for each angle.
To analytically determine this, it can get quite complex if aerodynamic drag is involved.
It is also discussed on this game-specific question.
For inspiration, this animated gif is great.

Haskell IdleCallback too slow

I just started designing some graphics in haskell. I want to create an animated picture with a rotating sphere, so I created an IdleCallback function to constantly update the angle value:
idle :: IORef GLfloat -> IdleCallback
idle angle = do
a <- get angle
angle $= a+1
postRedisplay Nothing
I'm adding 1 each time to the angle because I want to make my sphere smoothly rotate, rather than just jump from here to there. The problem is that now it rotates TOO slow. Is there a way to keep the rotation smooth and make it faster??
Thanks a lot!
There's not a lot to go on here. I don't see an explicit delay anywhere, so I'm guessing it's slow just because of how long it takes to update?
It also doesn't look explicitly recursive, so it seems like the problem is outside the scope of this snippet.
Also I don't know which libraries you may be using.
In general, though, that IORef makes me feel unhappy.
While it may be common in other languages to have global variables, IORefs in Haskell have their place, but are often a bad sign.
Even in another language, I don't think I'd do this with a global variable.
If you want to do time-updating things in Haskell, one "common" approach is to use a Functional Reactive Programming library.
They are built to have chains of functions that trigger off of a signal coming from outside, modifying the state of something, which eventually renders an output.
I've used them in the past for (simple) games, and in your case you could construct a system that is fed a clock signal 24 times per second, or whatever, and uses that to update the counter and yield a new image to blit.
My answer is kind of vague, but the question is a little vague too, so hopefully I've at least given you something to look into.

Re-positioning a Rigid Body in Bullet Physics

I am writing a character animation rendering engine that uses Bullet Physics as a physics simulation engine.
A sequence will start out with no model on the screen, then an animation will be assigned to that model, the model will be moved to frame 0 of the animation, and the engine will begin rendering the model with the animation.
What is the correct way to re-position the rigid bodies on the character model when it is initialized at frame 0?
Currently I am using this code, which is called immediately after the animation is assigned to the model and the bones are moved to the frame 0 position:
_world->removeRigidBody(_body);
bool k = (_type == Kinematics);
_body->setCollisionFlags(_body->getCollisionFlags() & ~btCollisionObject::CF_NO_CONTACT_RESPONSE);
btTransform tr = BulletPhysics::ConvertD3DXMatrix(&(_bone->getCombinedTrans()));
tr *= _trans;
_body->setCenterOfMassTransform(tr);
_body->clearForces();
_body->setLinearVelocity(btVector3(0,0,0));
_body->setAngularVelocity(btVector3(0,0,0));
_world->addRigidBody(_body, _groupID, _groupMask);
The issue is that sometimes this works, and other times not. For an example, take a skirt of a model. Sometimes it will show up in the natural position, other times slightly misaligned and it will fall into place, and other times it shows up completely clipped through the body, as if collision was turned off and some force pushed it in that direction. This does make sense most of the time, because in the test animation I am using the model's initial position is in the center of the screen, but the animation starts off the left side of the screen. Does anyone know how to solve this?
I know the bones on the skirt are not the problem, because I turned off physics and forced it to manually update the bone positions each frame, and everything was in the correct positions throughout the entire animation.
EDIT: I also have constraints, might that be what's causing this?
Here is my reposition method that does exactly this.
void LimbBt::reposition(btVector3 position,btVector3 orientation) {
btTransform initialTransform;
initialTransform.setOrigin(position);
initialTransform.setRotation(orientation);
mBody->setWorldTransform(initialTransform);
mMotionState->setWorldTransform(initialTransform);
}
The motion state mMotionState is the motion state you created for the btRigidBody in the beginning. Just add your clearForces() and velocities to it to stop the body from moving on from the new position as if it went through a portal. That should do it. It works nicely with me here.
Edit: The constraints will adapt if you reposition all rigidbodies correctly. For that purpose, it is easy to calculate the relative position and reposition the whole constrained rigidbody construct according to that. If you do it incorrectly, you will get severe twitching, as the constraints will try to adjust you construct numerically, causing high forces if the constraint gaps are large.
Edit2: Another issue is that if you need deterministic behavior (every time you reset your bodies, they should fall exactly the same), then you will have to kill your old dynamicsWorld, recreate it and add all the bodies again. The world stores some information about the bodies that just can not be cleared for now. This might change in the future as bullet4 is going to support deterministic resets. But for now, if you do experiments with deterministic resets, you need to drop the world and recreate it.
source: discussion with Erwin Coumans, the developer of Bullet Physics.
I can't tell you what causes the unusual outcome when moving rigid bodies but I can definitely sympathize!
There are three things you'll need to do in order to solve this:
Convert your rigid bodies to kinematic ones
Adjust the World Transform of the bodies motion state and NOT the rigid body
Convert the kinematic body back to a rigid body
A short tested code snippet effectively teleporting a rigid body by updating its motion state to its new position and orientation, plus nullifying all velocities and forces acting upon it.
void teleport(btVector3 position, btQuaternion& orientation) const {
btTransform transform;
transform.setIdentity();
transform.setOrigin(position);
transform.setRotation(orientation);
m_rigidBodyVehicle->setWorldTransform(transform);
m_rigidBodyVehicle->getMotionState()->setWorldTransform(transform);
m_rigidBodyVehicle->setLinearVelocity(btVector3(0.0f, 0.0f, 0.0f));
m_rigidBodyVehicle->setAngularVelocity(btVector3(0.0f, 0.0f, 0.0f));
m_rigidBodyVehicle->clearForces();
}

Resources