Force Push via RayCast
by Shane "Tibius" Barber · 07/02/2009 (3:38 pm) · 11 comments
This is some of the code I have recently put together for Telekinetic push.
First you need to have a function that will perform a RayCast:
Place this in a seperate .cs file called push.cs
This will fire a ray from the player's eye out to a certain predefined distance until it reaches its limit or until an object of specified TypeMask has been encountered. It will then parse out the handle of the object encountered and Return the Handle.
Then you need to use another function to apply the pushback:
Place in push.cs
%vec can simply be the player's eye vector:
So to call the code:
Where %distance and %force are amounts you specify.
If you run this as a serverCmd the client handle will be passed trough and allow you to then grab the handle of the player. But if you attach this to a ShapeImage, like a weapon, some alterations will need to be made.
Then finally just bind the serverCmdForcePush to a hotkey in the actionmap.
Place this in default.bind.cs
Hope this was helpful.
First you need to have a function that will perform a RayCast:
Place this in a seperate .cs file called push.cs
function Eye_Distance_HandleRay(%player, %distance, %typeMasks)
{
echo("**************Commencing Eye_Distance_HandleRay**************");
echo("--------------------Checking For Objects--------------------");
%eye = %player.getEyeVector();
%vec = vectorScale(%eye, %distance);
%start = %player.getEyeTransform();
%end = VectorAdd(%start, %vec);
echo("Eye Vec: "@ %eye); // Remove this Line When Script is Complete
echo("Vec Scl: "@ %vec); // Remove this Line When Script is Complete
echo("Vec Str: "@ %start); // Remove this Line When Script is Complete
echo("Vec End: "@ %end); // Remove this Line When Script is Complete
%found = ContainerRayCast (%start, %end, %typeMasks, %player);
if(%found)
{
echo("======Raycast has found an Object within the Specified TypeMask.======");
//Parse out the Found Object's ID Handle
%handle = getWord(%found, 0);
echo("Object has been found. ID: "@ %handle); // Remove this Line When Script is Complete
return %handle;
}
else
{
echo("======Raycast did not encounter any Object within the Specified TypeMask.======");
}
echo("--------------------Raycast Complete--------------------");
}This will fire a ray from the player's eye out to a certain predefined distance until it reaches its limit or until an object of specified TypeMask has been encountered. It will then parse out the handle of the object encountered and Return the Handle.
Then you need to use another function to apply the pushback:
Place in push.cs
// This Function applies the physical force to the object.
// %this = Object ID
// %vec = Vector Force is to Follow
// %force = Ammount of Force Applied
function PushBack(%this, %vec, %force)
{
%objectMass = %this.getDatablock().mass;
echo("Object's Mass:"@ %objectMass);
echo("Force Vector:"@ %vec);
echo("Force Applied:"@ %force);
%impulseVector = vectorScale(%vec, %objectMass * %force);
%this.applyImpulse( %this.getWorldBoxCenter(), %impulseVector);
}%vec can simply be the player's eye vector:
%player.getEyeVector();
So to call the code:
function serverCmdForcePush(%client)
{
%player = %client.player;
%handle = Eye_Distance_HandleRay(%player, %distance, PlayerObjectType);
PushBack(%handle, %client.player.getEyeVector(), %force);
}Where %distance and %force are amounts you specify.
If you run this as a serverCmd the client handle will be passed trough and allow you to then grab the handle of the player. But if you attach this to a ShapeImage, like a weapon, some alterations will need to be made.
Then finally just bind the serverCmdForcePush to a hotkey in the actionmap.
Place this in default.bind.cs
moveMap.bindCmd(keyboard, "q", "commandToServer('ForcePush');", "");Hope this was helpful.
#2
07/03/2009 (9:24 am)
There was a gravity gun code somewhere around here.. I think it was removed, a telekinesis gun would just be awesome.
#3
07/05/2009 (11:49 am)
you can quite easily extend this to work with vehicles, where the effect gets activated when objects come into contact with the vehicles Bbox, it could become a solution to the "push things you hit" problem, vehicles dont move things when they collide with them. (think of driving into another vehicle, and that vehicle gets pushed away, or drive into players and send them flying)
#4
theres a gravity gun in T3D, really fun hurling ragdolls about with it
07/05/2009 (11:56 am)
@Edward,theres a gravity gun in T3D, really fun hurling ragdolls about with it
#5
@Edward & deepscratch:
There is a simple "gravity gun" onFire() script here. Not as useful as this, or as cool as the gravity gun in T3D.
07/05/2009 (2:21 pm)
Can't believe I overlooked this resource, one of the simplest yet useful push methods I've seen here. It's very good for manipulating rigidshapes too!@Edward & deepscratch:
There is a simple "gravity gun" onFire() script here. Not as useful as this, or as cool as the gravity gun in T3D.
#6
07/05/2009 (4:19 pm)
ahh there it is, thank you deepscratch, i have been looking for that link for over a year!!
#7
07/06/2009 (2:07 pm)
*I see a repulsor beam... hmmm...
#8
07/06/2009 (9:53 pm)
star wars jedi force :D
#9
07/07/2009 (9:57 am)
This is very cool, I will have to try this! Thanks for this resource.
#10
Here are the errors from the console log:
Mapping string: ForcePush to index: 3
**************Commencing Eye_Distance_HandleRay**************
--------------------Checking For Objects--------------------
Eye Vec: 0.999475 -0.0255499 0.0199404
Vec Scl: 99.9475 -2.55499 1.99404
Vec Str: 571.634 1294.24 1138.72 -0.00971862 0.00997024 0.999903 1.59645
Vec End: 671.581 1291.69 1140.71
======Raycast did not encounter any Object within the Specified TypeMask.======
--------------------Raycast Complete--------------------
scriptsAndAssets/server/scripts/push.cs (49): Unable to find object: '' attempting to call function 'getDataBlock'
Object's Mass:
Eye Vector:0.999475 -0.0255499 0.0199404
Force Applied:50
scriptsAndAssets/server/scripts/push.cs (55): Unable to find object: '' attempting to call function 'getWorldBoxCenter'
scriptsAndAssets/server/scripts/push.cs (55): Unable to find object: '' attempting to call function 'applyImpulse'
As we have been implementing the resource, we were unsure of where to put at least one line of code.
Specifically, we are concerned about the instruction in the resource that says:
"%vec can simply be the player's eye vector:
%player.getEyeVector();"
Currently, we have put this line at the beginning of the raycast function. We were also a little uncertain as to where to specify %distance, but we also put it at the beginning of the raycast function.
We would really appreciate any help.
Thanks.
12/03/2009 (8:34 pm)
A game design student from my class and I have been working on implementing this resource. I think we are very close to having it working, but we are running into two related errors. The first is that the raycast function does not appear to be recognizing an object an retrieving its handle. The second, related error, is that push.cs is unable to retrieve an object handle and therefore cannot determine which object to push or the mass of this object.Here are the errors from the console log:
Mapping string: ForcePush to index: 3
**************Commencing Eye_Distance_HandleRay**************
--------------------Checking For Objects--------------------
Eye Vec: 0.999475 -0.0255499 0.0199404
Vec Scl: 99.9475 -2.55499 1.99404
Vec Str: 571.634 1294.24 1138.72 -0.00971862 0.00997024 0.999903 1.59645
Vec End: 671.581 1291.69 1140.71
======Raycast did not encounter any Object within the Specified TypeMask.======
--------------------Raycast Complete--------------------
scriptsAndAssets/server/scripts/push.cs (49): Unable to find object: '' attempting to call function 'getDataBlock'
Object's Mass:
Eye Vector:0.999475 -0.0255499 0.0199404
Force Applied:50
scriptsAndAssets/server/scripts/push.cs (55): Unable to find object: '' attempting to call function 'getWorldBoxCenter'
scriptsAndAssets/server/scripts/push.cs (55): Unable to find object: '' attempting to call function 'applyImpulse'
As we have been implementing the resource, we were unsure of where to put at least one line of code.
Specifically, we are concerned about the instruction in the resource that says:
"%vec can simply be the player's eye vector:
%player.getEyeVector();"
Currently, we have put this line at the beginning of the raycast function. We were also a little uncertain as to where to specify %distance, but we also put it at the beginning of the raycast function.
We would really appreciate any help.
Thanks.
#11
12/06/2009 (6:04 pm)
Just in case anybody runs into the same issues, we solved this problem by specifying the Typemask of objects that need to be selected, as in Typemasks::VehicleObjectType. The sticking point was that rigidshapes, including bouncing boulders, actually have a Typemask of VehicleObjectType. Once we changed this, we could push a boulder telekinetically out of our way.
Associate Konrad Kiss
Bitgap Games
Really cool idea and an awesome first resource to come out with! Congratulations!