How to Spawn a decal with script - info
by Steve Acaster · in Torque 3D Professional · 11/25/2010 (3:30 pm) · 21 replies
I've got a basic hit-prediction scripted and whilst I can spawn applicable damage, explosion, etc at the end of the raycast, I've not worked out how to slap a decal at the position.
Anyone any ideas on spawning a decal with script? I'd hoped it would be a simple %decal = new decalData, datablock =, position=, etc but apparently it isn't ... or at least nothing happens and nothing in the console.
[edit]
Answer below!
Moved to useful Threads
Anyone any ideas on spawning a decal with script? I'd hoped it would be a simple %decal = new decalData, datablock =, position=, etc but apparently it isn't ... or at least nothing happens and nothing in the console.
[edit]
Answer below!
Moved to useful Threads
About the author
One Bloke ... In His Bedroom ... Making Indie Games ...
#2
11/25/2010 (10:57 pm)
Thanks for the pointer, foolishly I looked in the other code files but not that one ... not that I got it working properly ... keeps appearing at origin ...
#3
11/25/2010 (11:12 pm)
Okay got it working ... on flat ground plane ... but not objects ... I'm thinking that's what the normal is for ...
#4
11/25/2010 (11:32 pm)
Which is the transform of the impact position ... yay ... still a little stretched on certain surfaces ... I'm wondering if that's due to the truncation in the numbers ... e-00
#5
And all appears well in the world of scripting bullet holes on to raycasts.
Moved to "useful threads" forum.
:)
11/25/2010 (11:42 pm)
Apparently not - it was the rotation setting stretching things over too far, set to zero all is fine.%impact = "0.215927 19.9602 2.98508 -1 2.98023e-008 8.9407e-009";
%rot = getwords(%impact, 3, -1);
echo("decal wanted at normal rotation " @ %rot);
%pos = getwords(%impact, 0, 2);
echo("decal wanted at pos " @ %pos);
//decalManagerAddDecal( %position, %normal, %rotation, %scale, %decalData, %immortal);
decalManagerAddDecal(%pos, %rot, 0.0, 1.0, smallimpactsDecal, false);And all appears well in the world of scripting bullet holes on to raycasts.
Moved to "useful threads" forum.
:)
#6
This one goes in right there with the rest of the small gems.
Thanks Steve.
11/26/2010 (12:55 am)
You should consider writing a book with all the tricks you figure out! I have a number of these printed out for instant reference.This one goes in right there with the rest of the small gems.
Thanks Steve.
#7
11/26/2010 (6:58 am)
Yes,the rotation is an angle (in radians),because the AngAxisF class is used for it.
#8
maybe you can help me write a small function that lays a scorch decal, at the spot where a box has been destroyed, upon its scheduled delete?
it would really be a huge help, been struggling with it
11/27/2010 (5:05 pm)
@Steve,maybe you can help me write a small function that lays a scorch decal, at the spot where a box has been destroyed, upon its scheduled delete?
it would really be a huge help, been struggling with it
#9
11/27/2010 (6:20 pm)
i second konrad's post. your tricks and help you provide are invaluable.
#10
I'd think a raycast down from the centre (or at least above) the destroyed object from it's damage/onDamage/onDestroyed/etc fucntion would do the trick.
Been partying ... brain a little fuzzy ... but off the top of my head without testing ...
11/28/2010 (4:35 pm)
@DeepI'd think a raycast down from the centre (or at least above) the destroyed object from it's damage/onDamage/onDestroyed/etc fucntion would do the trick.
Been partying ... brain a little fuzzy ... but off the top of my head without testing ...
//I like my typemasks collected into a big global,
//saves typing them out individually everytime
$Obstacles =
$TypeMasks::VehicleObjectType |
$TypeMasks::PlayerObjectType |
$TypeMasks::TerrainObjectType |
$TypeMasks::StaticTSObjectType |
$TypeMasks::StaticShapeObjectType |
$TypeMasks::ForestObjectType; // InteriorObjectType replaced
Function Your_Class_Thing_Here::onCollision(%this, %col, %etc)
{
if(%this.getDamagelevel() >= %this.maxDamage)
{
%start = %this.getWorldBoxCenter;
%end = VectorAdd(%start, "0 0 -5");
//how big is the box? No point sending a raycast off for 20km
//so 5 units/metres here
%targetsearch = containerRayCast(%start, %end, $Obstacles, %this.getID());
%impactpoint = firstWord(%targetsearch);
%pos = getwords(%targetsearch, 1,6);
//do your explosion FX here, particles, audio etc
if(%impactpoint != false)
{
%rot = getwords(%pos, 3, -1);
//decalManagerAddDecal(%position,%normal,%rotation,%scale,%decalData,%immortal);
decalManagerAddDecal(%pos, %rot, 0.0, 1.0, ScorchBigDecal, false);
}
}
}
#11
02/04/2016 (3:00 am)
I'm trying to add this to my project but I'm not sure where to put Steve function to create the pool of blood decal when the player dies. Anyone know where I can put it to make it work?
#12
02/04/2016 (5:53 am)
Peruse the RTS Prototype - it deals with client-side decal placement but basically you should be able to place your decal in any server-side script function and it should display on all clients.
#13
if(%this.getDamagelevel() >= %this.maxDamage)
02/04/2016 (6:43 am)
So I tried placing that function in player.cs and I get this error with this line.if(%this.getDamagelevel() >= %this.maxDamage)
#14
02/04/2016 (10:28 am)
So I have placed the function in Armor::onCollision in player.cs. These are the errors I'm getting.scripts/server/player.cs (204): Unknown command getDamageLevel. Object DefaultPlayerData(269) DefaultPlayerData -> armor -> armor -> PlayerData -> ShapeBaseData -> GameBaseData -> SimDataBlock -> SimObject
#15
Without seeing the script that generates that error we have no way of knowing what you did there or why that error is being generated.
Using my superhuman powers of deduction here is my guess: You've tried to call %this.getDamageLevel(), but in the Armor::onCollision() callback %this is not the player object, it's the Armor datablock. %obj is the player and %col is the colliding object.
So, troubleshooting tip:
And if you want to spawn a decal whenever the player is damaged, you might want to put your decal code in onDamage. For a blood pool on death, put it in onDisabled.
02/05/2016 (5:51 am)
What version are you using?Without seeing the script that generates that error we have no way of knowing what you did there or why that error is being generated.
Using my superhuman powers of deduction here is my guess: You've tried to call %this.getDamageLevel(), but in the Armor::onCollision() callback %this is not the player object, it's the Armor datablock. %obj is the player and %col is the colliding object.
So, troubleshooting tip:
%thistype = %this.getClassName();
%objtype = %obj.getClassName();
%coltype = %col.getClassName();
echo("%this is a " @ %thistype);
echo("%obj is a " @ %objtype);
echo("%col is a " @ %coltype);So you can see what the parameters actually are....And if you want to spawn a decal whenever the player is damaged, you might want to put your decal code in onDamage. For a blood pool on death, put it in onDisabled.
#16
http://www.garagegames.com/community/forums/viewthread/143016/1#comment-865435
This might be conflicting with this function and why I'm getting that error. My player script is all default besides those changes to PlayerData::damage function.
I was hoping to create a animated blood pool decal where is expands for a few seconds.
02/05/2016 (8:39 am)
I was having a issue with the decals showing up for the client so Duion helped me with this.http://www.garagegames.com/community/forums/viewthread/143016/1#comment-865435
This might be conflicting with this function and why I'm getting that error. My player script is all default besides those changes to PlayerData::damage function.
I was hoping to create a animated blood pool decal where is expands for a few seconds.
#17
02/06/2016 (2:15 am)
I have added those troubleshooting code and this is what it came up with.%this is a PlayerData %obj is a Player %col is a TerrainBlock
#18
02/06/2016 (10:47 pm)
Yes. So. PlayerData doesn't have getDamageLevel(), Player does....
#20
This is the stock Armor::onCollision() from T3D 1.2, I've added comments for clarity:
Also, note that this datablock name was changed in one of the earlier MIT updates and no longer exists as "Armor."
02/07/2016 (7:49 am)
if %obj is the Player object then use %obj.getDamageLevel() to get the damage level of the player....This is the stock Armor::onCollision() from T3D 1.2, I've added comments for clarity:
function Armor::onCollision(%this, %obj, %col)
{
// %this - the PlayerData datablock
// %obj - the player object, it should probably have been %playerObj for clarity
// %col - the thing you hit, this should have been %collidingObj or something
if (!isObject(%col) || %obj.getState() $= "Dead") // if the thing we hit isn't an object or the player is already dead...
return; // bail.
// Try and pickup all items
if (%col.getClassName() $= "Item") // if the thing we hit is of class "Item"...
{
%obj.pickup(%col); // pick it up.
return;
}
// Mount vehicles
if (%col.getType() & $TypeMasks::GameBaseObjectType) // if the thing we hit has GameBaseObjectType type mask...
{
%db = %col.getDataBlock(); // get the datablock off of the thing we hit.
if ((%db.getClassName() $= "WheeledVehicleData" ) && %obj.mountVehicle && %obj.getState() $= "Move" && %col.mountable) // if the datablock is WheeledVehicleData and the player's state is "Move" AND the thing we hit is mountable...
{
// Do all of this stuff!
// Only mount drivers for now.
ServerConnection.setFirstPerson(0); // Pretty sure this won't work in a multiplayer game. You'd need to use %obj.client to ensure that the correct player was mounted - see newer versions of T3D, this might be fixed now.
// For this specific example, only one person can fit
// into a vehicle
%mount = %col.getMountNodeObject(0); // find out if there is already a player successfully mounted.
if(%mount)
return; // yes, can't mount because it's full, so we're done.
// For this specific FPS Example, always mount the player
// to node 0
%node = 0;
%col.mountObject(%obj, %node); // tell the thing we hit to mount the player at node 0
%obj.mVehicle = %col; // tell the player which vehicle object he's mounted to.
}
}
}So, you can see exactly what's happening there now. If you need to find out if the player has taken damage, you have to call getDamageLevel() on the player object, not the PlayerData object (%this, in this instance, is a PlayerData object and not a player).Also, note that this datablock name was changed in one of the earlier MIT updates and no longer exists as "Armor."
Torque Owner Ivan Mandzhukov
Liman3D
There is a method decalManagerAddDecal.
You can use decalManagerRemoveDecal also...
I'm not really sure,but decals should be instantiated on the client side.