I'm using mousejoint to drag bodies in box2d, but it causes inertial delay.
Does it exist any way to drag a body instantaneously?
The solution is to tune up properties frequencyHz and dampingRatio in your b2MouseJointDef.
For example:
b2MouseJointDef md;
md.body1 = _groundBody;
md.body2 = body;
md.target = p;
md.maxForce = 10000.0f * body->GetMass();
md.dampingRatio = 0;
md.frequencyHz = 100;
_world->CreateJoint(&md);
I'm trying to implement a pong-style game in Processing/Box2d library and I anticipate having the same problem. One thing that comes to mind is to maintain a hidden object in the Box2d world, one that operates with joints the conventional way, and then draw a virtual object that follows the mouse with no frame delay. This might be adequate to fool the user.
On the other hand, Box2d is not a strict physics simulation and allows for some forgiveness in overlapping objects, so it really seems like there should be a way to do this.
Related
I don't want my player to be able to walk off ledges. I did this by shooting a single raycast downwards in front of the player, and if ground is NOT hit, then ignore input.
However this is jarring, especially if you diagonally walk along an edge you just completely stop, rather than 'slide' along it.
So I thought I could add two raycasts, one per side to detect which side the ledge is, then allow movement (or steer) the player as applicable.
The problem is I'm not sure how to proceed from here. I'm using a character controller for movement, my current code is like:
velocityXZ = velocity;
velocityXZ.y = 0; // we deal with gravity elsewhere
velocityXZ = inputDir * playerSpeed;
if (facingDropLeft || facingDropRight) {
velocityXZ.x = 0;
velocityXZ.z = 0;
}
velocity = new Vector3(velocityXZ.x, velocity.y, velocityXZ.z);
// handle gravity
charController.Move(velocity * Time.deltaTime);
Could anyone offer some insights into what direction to look into, or methods I will need?
I think that if you want to accomplish an enjoyable result you should use invisible walls. I think that probuilder can help you.
This is the approach I would have with this type of problem.
Use boxes to make wall than turn off the mesh renderers this will make invisible walls
I'm going through a few different Unity tutorials and the way a game object is moved around in each is a little different.
What are the pros/cons to each of these methods and which is preferred for a first person RPG?
// Here I use MovePosition function on the rigid body of this component
Rigidbody.MovePosition(m_Rigidbody.position + movement);
//Here I apply force to the rigid body and am able to choose force mode
Rigidbody.AddForce(15 * Time.deltaTime, 0, 0, ForceMode.VelocityChange);
// Here I directly change a transforms position value, in this case the cam
Transform.transform.position = playerTransform.position + cameraOffset;
Thanks!!
EDIT;
Something I have noticed is that the applied force seems to memic wheeled vehicles while the position changes memic walking/running.
RigidBodies and Velocities/Physics
The only time, I personally have used the rigidbodys system was when implementing my own boids (flocking behaviour) as you need to calculate a few separate vectors and apply them all to the unit.
Rigidbody.MovePosition(m_Rigidbody.position + movement);
This calculates a movement vector towards a target for you using the physics system, so the object's velocity and movement can still be affected by drag, angular drag and so on.
This particular function is a wrapper around Rigidbody.AddForce I believe.
Pros :
Good if realistic physical reactions is something you are going for
Cons:
A bit unwieldy to use if all you are trying to achieve is moving a object from point A to point B.
Sometimes an errant setting set too high somewhere (for example: Mass > 10000000) can cause really screwy bugs in behaviour that can be quite a pain to pin down and mitigate.
Notes: Rigidbodies when colliding with another Rigidbody would bounce from each other depending on physics settings.
They are also affected by gravity. Basically they try to mimic real life objects but it can be sometimes difficult to tame the objects and make them do exactly what you want.
And Rigidbody.AddForce is basically the same as above except you calculate the vector yourself.
So for example to get a vector towards a target you would do
Vector3 target = target.position - myPosition;
Rigidbody.AddForce(target * 15 * Time.deltaTime, 0, 0, ForceMode.VelocityChange);
If you don't plan on having any major physics mechanics in your game, I would suggest moving by interpolating the objects position.
As it is far easier to get things to behave how you want, unless of course you are going for physical realism!
Interpolating the units position
Pros :
Perhaps a little strange to understand at first but far simpler to make objects move how you want
Cons:
If you wanted realistic reactions to objects impacting you'd have to do a lot of the work yourself. But sometimes this is preferable to using a physics system then trying, as I've said earlier to tame it.
You would use the technique in say a Pokemon game, you don't stop in Pokemon and wait for ash to stop skidding or hit a wall and bounce uncontrollably backwards.
This particular function is setting the objects position like teleporting but you can also use this to move the character smoothly to a position. I suggest looking up 'tweens' for smoothly interpolating between variables.
//change the characters x by + 1 every tick,
Transform.transform.position.x += 1f;
Rigidbody.MovePosition(m_Rigidbody.position + movement);
From the docs:
If Rigidbody interpolation is enabled on the Rigidbody, calling Rigidbody.MovePosition results in a smooth transition between the two positions in any intermediate frames rendered. This should be used if you want to continuously move a rigidbody in each FixedUpdate.
https://docs.unity3d.com/ScriptReference/Rigidbody.MovePosition.html
Rigidbody.AddForce(15 * Time.deltaTime, 0, 0, ForceMode.VelocityChange);
This will make the object accelerate, so it won't travel at a constant velocity (this is because of Newton's second law, Force=mass*acceleration). Also if you have another force going in the opposite direction this force could get cancelled out and the object won't move at all.
Transform.transform.position = playerTransform.position + cameraOffset;
This will teleport the object. No smooth transition, no interaction with any forces already in the game, just an instant change in position.
I'm trying to make an object moved to a position, but, depending on the speed it's going, I want it to overhoot it's target and bounce back to it.
This is how I'm moving the object toward the other now:
void FixedUpdate() {
transform.position = Vector2.Lerp (transform.position, blackhole.transform.position, Time.deltaTime * 25f);
}
This obviously doesn't account for the "overshoot" effect. However I've been having trouble to achieve it, since when trying with physics all my attempts end up with my object orbiting indefinitely around it's target, instead of passing it just once and moving inside it.
There are a few ways you could go about this. Nathan's suggestion of using "gravity" by applying forces every step I'll call the "Physics" solution. Your current solution that simply sets position I'll call the "Tweening" solution. Both can certainly work, and both can benefit from simply using if statements. For both solutions, stop the "orbiting" or head back from overShootPos with simple checks.
For Tweening:
When the move first starts, start tweening to a position past where you actually want to be.
Vector3 overShootPos = destinationPos + (destinationPos-transform.position)*overShootPercentage;
Then in FixedUpdate:
float deltaP = 0.001f;
if((transform.position-overShootPos).magnitude<deltaP){
//start tweening to destinationPos rather than overShootPos. Possibly just
overShootPos = destinationPos;
}
For Physics:
The forces actually will take the object past the destination, and it may start "orbiting" like you were saying.
In FixedUpdate, stop it once it's close and slow enough:
float deltaP = 1f; //may want larger delta here since physics is less precise.
if((transform.position-destinationPos).magnitude<deltaP && rb.velocity.magnitude<deltaP){
rb.velocity = Vector3.zero;
transform.position = destinationPos;
}
This is not all the code, but the basic idea should work.
Also, consider some of the differences between Physics and Tweening solutions (that may include code other than this). The Tweening will be very precise, and work basically the same way every time, where the Physics one may scale more crazily with large distances/fast speeds. The Physics solution is clearly needed if you do want the object to respond to explosions, collisions, etc.. on its route to the destination. If you go with Tweening, consider looking at tweening libraries like iTween and DOTween, especially if you'll be using a lot of tweens. They'll be faster (less Updates) and provide a nice syntax for doing stuff like this.
I would use a basic spring system. Equation of a spring
F = k(x-l) (Force = Spring Constant * (Extension - Rest Length)
So to calculate the spring force on your body:
Force = SpringConstant * (PointToHeadTo - CurrentPosition)
You then either use the physics damping in your engine or you apply your own damping
D = Velocity * -DampingConstant (DampingForce = Velocity * -DampingConstant)
Which you then apply as a force. However Unity / UE4 have damping co-efficients you set so you just need the spring force.
To keep things stable you can limit the Spring Force to a maximum and only have it take effect when within a radius of the target. You can also ramp up the damping as you cross the target to help bring it to rest.
I am writing Cocos2D box2d game for iPhone.
I've 2 dynamic bodies, and I hope they are applied force from outside, but they don't apply force each other and detect their collision.
How can I achieve this?
And also I hope they move together at the same position after collision.
How can I do this?
they don't apply force each other and detect their collision
Sounds like you might want to look at collision filtering. This answer has a bit of code that changes the collision filtering index of a body dynamically https://stackoverflow.com/a/11283206/735204
they move together at the same position after collision
Probably some kind of joint (eg weldjoint?)
From the manual: http://www.box2d.org/manual.html
Joints are used to constrain bodies to the world or to each other. Typical examples in games include ragdolls, teeters, and pulleys. Joints can be combined in many different ways to create interesting motions.
Some joints provide limits so you can control the range of motion. Some joint provide motors which can be used to drive the joint at a prescribed speed until a prescribed force/torque is exceeded.
Joint motors can be used in many ways. You can use motors to control position by specifying a joint velocity that is proportional to the difference between the actual and desired position. You can also use motors to simulate joint friction: set the joint velocity to zero and provide a small, but significant maximum motor force/torque. Then the motor will attempt to keep the joint from moving until the load becomes too strong.
Sorry about last answer, just checking that I can write it.
What about this?
bodyDef.isSensor = true;
and use ContactListener to detect collision. Box2d for collision detection
Also you can use box2d filters. For example:
REMEMBER: if groupIndex < 0, same bodies never collide with each other. That is what you need.
b2Filter bodyFilter;
bodyFilter.groupIndex = -1;
bodyFilter.categoryBits = 0x0002;
fixtureDef.filter = bodyFilter;
I have worked out how to detect touching on an object using glReadPixels but how would I detect if a object hits another object (a bullet for example).
I cant do that with detecting colours.
As others have said, do this in the object model, not in the graphics.
For one simple model, give each object other than a bullet a size. Then check if a bullet's location is within that object's radius every tick. In pseudocode:
for each bullet
for each hittableObjectInWorld
if ([hittableObject isTouchedBy:bullet]) {/*handle collision*/}
endFor
endFor
hittableObject::isTouchedBy:(Sprite *)otherObject {
xDistance = [self x] - otherObject.x;
yDistance = [self y] - otherObject.y;
totalDistance = sqrt((xDistance*xDistance) + (yDistance*yDistance));
if (totalDistance <= [self size]) return YES;
else return NO;
}
Now you've got a simple collision detection system. There are some abstractions here: We treat every hittable object as if it were shaped like a sphere with its 'size' as its radius. Bullets are pinpoint small, but you can correct for that by adding a bullet's radius to the radius of each of the hittable objects and it makes the math run a wee bit faster this way.
This might be the simplest possible collision detection system. There's a lot of room for improvement here. The big thing is you're doing the number of bullets times the number of hittable objects checks each tick. If you have many bullets and many objects in the world, that can be a lot of processor time. There's all sorts of hacks to cut down on the number of checks you have to do. If you run into speed problems with this version, that's the next thing to start tuning up.
Good luck!
You do it in your object model, not in your graphics code. OpenGL is only tangentially related to collision detection.
OpenGL only deals with the graphical display of your game's objects. Any logic about how the objects in your game behave should be done in the code that manages the state of the objects not in the OpenGL graphics code.
What you are looking for is collision detection which can be a fairly deep topic. Just to be clear, once you detect a collision (e.g. a bullet hitting an object) you will more than likely run some OpenGL code to display the reaction of the collision to the user but the actual detection of the collision should not occur within the OpenGL realm.
Lastly, if you find all of this a bit overwhelming I would recommend the use of a game engine like cocos2d or Unity.