Pulling a player into an object
by Eric den Boer · in Torque 3D Professional · 09/22/2009 (4:19 pm) · 2 replies
Hi guys!
Situation: I'm trying to create objects (in C++) that pull in a player once the player gets too close to it - kinda like a gravitational force. I call those objects "Anti-Objects", because it's awesome. I've managed to do this, very roughly, but I'm stuck with two problems:
1. There isn't any proper interpolation between the different setPosition() calls within the processTick()
2. Right now I'm brute-forcing the pull, so the player just gets assigned a new position, without checking for collision.
Question is, how would I fix those issues? I searched for both, but came out empty handed. Right now my "applyAntiObject()" code looks like this:
In short: I check if the player can see the object, if so I get a direction vector between the object and the player and use the strength of the attraction based on the normalized distance between the player and the object. Using the following function I apply the force to the player:
applyAttractionToCharacter
Using standard physics formulas. It works, but the movement is very rigid as the position gets set in the processTick() which is run server-side every 32ms as we all know.
I tried many approaches to interpolating the new position, but it just didn't work so I removed it again. If anyone could help me with this, thanks!
Situation: I'm trying to create objects (in C++) that pull in a player once the player gets too close to it - kinda like a gravitational force. I call those objects "Anti-Objects", because it's awesome. I've managed to do this, very roughly, but I'm stuck with two problems:
1. There isn't any proper interpolation between the different setPosition() calls within the processTick()
2. Right now I'm brute-forcing the pull, so the player just gets assigned a new position, without checking for collision.
Question is, how would I fix those issues? I searched for both, but came out empty handed. Right now my "applyAntiObject()" code looks like this:
// do parent
Parent::applyAntiObject(antiobject, distNorm);
// get vectors
Point3F antiObjectPos = antiobject->getPosition();
Point3F myPos = getPosition();
// offset the z-axis to create a centroid vector on PENIS HEIGHT (lol)
myPos.z += 2;
antiObjectPos.z += 2;
Point3F dir = antiObjectPos - myPos;
dir.normalize();
// Are we even seeing this?
static RayInfo vRay;
if(gServerContainer.castRay(myPos, antiObjectPos, StaticTSObjectType, &vRay))
{
// make sure we're not seeing the object itself
if(vRay.object != antiobject)
return;
}
// Traffic Light
if(antiobject->getTypeMaskUT() == UTAntiObject::TrafficLight)
{
// cast trafficlight
UTAntiObjectTrafficLight* trafficlight = dynamic_cast<UTAntiObjectTrafficLight*>(antiobject);
// check if we're infront of the traffic light in a 100 degree cone, with the forward vector as the middle of that cone
Point3F forwardVector = trafficlight->getTransform().getForwardVector();
F32 dot = mDot(forwardVector, dir);
F32 angleX = mAcos(-dot) * 57.2957795130823208768f;
// if within the effect cone
if(angleX >= -50 && angleX <= 50)
{
// prevent division by zero
if(distNorm == 0.0f) distNorm = 0.1f;
// apply the attraction to the character
trafficlight->applyAttractionToCharacter(this, dir, distNorm);
// are we within range? if so, play sequence
Point3F distToObject = antiObjectPos - myPos;
if(distToObject.lenSquared() < trafficlight->getEffectMinRadius())
{
// SCRIPT! - cause I dont know how schedule works in C++ :(
}
}
}In short: I check if the player can see the object, if so I get a direction vector between the object and the player and use the strength of the attraction based on the normalized distance between the player and the object. Using the following function I apply the force to the player:
applyAttractionToCharacter
void UTAntiObject::applyAttractionToCharacter( UTCharacter* character, Point3F& direction, F32 distNorm )
{
Point3F charPos = ((this->getEffectMass() * 0.981f) / (this->getEffectRadius() * this->getEffectRadius())) * (direction - (direction * distNorm));
character->setPosition(character->getPosition() + charPos, character->getRotation());
}Using standard physics formulas. It works, but the movement is very rigid as the position gets set in the processTick() which is run server-side every 32ms as we all know.
I tried many approaches to interpolating the new position, but it just didn't work so I removed it again. If anyone could help me with this, thanks!
#2
How could I forget? It was in the book and everything! This fixes all the issues, now all that's left is tweaking.
Thank you so much!
09/22/2009 (5:15 pm)
applyImpulse()How could I forget? It was in the book and everything! This fixes all the issues, now all that's left is tweaking.
Thank you so much!
Torque Owner Ivan Mandzhukov
Liman3D
Why not applying an impulse ?
I would prefer to integrate a drag force into the phisycal zone class.
It is something easy to do and will apply the same magnet effect without much coding...
Finally you will have no problems with collision,because the phisycal zone reacts on your velocity
That's why the player will get proper velocity prediction ... and collision.