Making arrows stick in enemies
by Christian S · in Torque 3D Professional · 09/24/2010 (8:54 pm) · 12 replies
Spent ~an hour reading tons of posts in the forum, but couldent find anything related to my task ahead.
I can fire my bow (currently fighting why directdamage wont damage, but areadamage does) and want the arrows to be stuck in the enemies when I hit them.
I assume it is possible to make an arrow stick to the point where it hit the enemy, as I have access to source ;)
Anyone with suggestions to the most network light approach to this, or a way to do it at all?
I can fire my bow (currently fighting why directdamage wont damage, but areadamage does) and want the arrows to be stuck in the enemies when I hit them.
I assume it is possible to make an arrow stick to the point where it hit the enemy, as I have access to source ;)
Anyone with suggestions to the most network light approach to this, or a way to do it at all?
#2
09/25/2010 (1:21 pm)
AFX has some nice methods for this.
#3
@JANR oh, I have AFX as well. what methods are you thinking off?
09/25/2010 (2:10 pm)
@ Ivan I was looking at that ress. from AL, but was unsure if the network issues mentioned was fixed. Going to look closer at it.@JANR oh, I have AFX as well. what methods are you thinking off?
#4
SceneObject has a method called "mountObject" which is accessible from script like so:
You'll need to take the hit position of the arrow and turn it into an offset transform before you pass it in, of course (offset is going to be from the origin of the object you're mounting to). You can either transform the arrow's transform when it hits by the inverse transform of the object you're mounting to, or you could maybe just subtract the position of the object you're mounting to from your arrow's position, then concatenate the rotation of your arrow onto the transform (i.e., you get the new position, then take the last 4 words of the arrow's current transform and do a string concatenation to add them onto the new position so you have a TransformF like (x y z r1 r2 r3 r4) where xyz are the position and r1-4 are the transform).
09/25/2010 (7:11 pm)
Is there a reason you can't use SceneObject's mounting functionality to achieve this?SceneObject has a method called "mountObject" which is accessible from script like so:
mountObject( SceneObject objB, S32 slot, TransformF txfm ); // Mount objB to this object at the desired slot with optional transform. // @param objB Object to mount onto us // @param slot Mount slot ID // @param txfm (optional) mount offset transform // @return true if successful, false if failed (objB is not valid)
You'll need to take the hit position of the arrow and turn it into an offset transform before you pass it in, of course (offset is going to be from the origin of the object you're mounting to). You can either transform the arrow's transform when it hits by the inverse transform of the object you're mounting to, or you could maybe just subtract the position of the object you're mounting to from your arrow's position, then concatenate the rotation of your arrow onto the transform (i.e., you get the new position, then take the last 4 words of the arrow's current transform and do a string concatenation to add them onto the new position so you have a TransformF like (x y z r1 r2 r3 r4) where xyz are the position and r1-4 are the transform).
#5
09/25/2010 (7:57 pm)
For non-moving objects it's fairly trivial to record the transform of a projectile when it hits (Projectile::onCollision()) and place your sticky arrow (TSStatic) at that location. For something that moves the easiest method that I know of is pretty much what Ross mentions: figuring out a positional offset and rotation of the projectile and applying that to a newly mounted object.
#6
I'm going to dive into the method you suggest there and see if I can figure how to make it work.
@ Michael Yes, I hope for the arrows to follow the targets movement.
09/25/2010 (9:14 pm)
@ Ross Dunno if theres a reason I cant achieve it with that, that was why I'm asking ;)I'm going to dive into the method you suggest there and see if I can figure how to make it work.
@ Michael Yes, I hope for the arrows to follow the targets movement.
#7
You might find that you'll have to figure out what the closest node on a character is, then parent to that, and figure out the offset from that node instead of from the character/object's origin. I suggest figuring out the basic method first, though.
09/25/2010 (9:21 pm)
One thing I guess you might run into problems with is if the projectile hits an animated part of a character (such as an arm or leg) it won't follow the animation. You might find that you'll have to figure out what the closest node on a character is, then parent to that, and figure out the offset from that node instead of from the character/object's origin. I suggest figuring out the basic method first, though.
#8
09/26/2010 (2:08 am)
I thought that you could find what 'normal' or 'face' in the geometry....and become 'sticky' to that? I am also interested in this type of gameplay/functionality....by attaching to the 'normal' location[IE, vertex data], again if possible, wouldn't that be bound to the animated node in the skeletal structure and follow by that method...just curious about the approach/possibility.
#9
@Rex, if you want to know more about the approach, hit me up on the BAG Vent sometime.
09/26/2010 (3:25 am)
Nah, the normal would give you an orientation for whatever is "sticking" but really if you want it to follow animation, you need to do what I described, which is figure out what node the object to be stickied is closest to, then you'd build an offset transform based on that node and call mountObject passing in the node and your offset transform. The SceneObject mounting already supports mounting to a node with an offset. There's no benefit to dealing with any geometry in that case.@Rex, if you want to know more about the approach, hit me up on the BAG Vent sometime.
#10
Stuff like meshhidings, mountImage and so works fine. So I'm either doing it wrong, or that mountObject dont work on players/AI...
heres my curr function;
09/26/2010 (9:34 pm)
@ Ross i tried some various usage of that mountObject, but it wont display any mounting attempts on the enemy hit. I can do other sorts of things on the target on impact, but not that.Stuff like meshhidings, mountImage and so works fine. So I'm either doing it wrong, or that mountObject dont work on players/AI...
heres my curr function;
function BowProjectile::onCollision(%this,%obj,%col,%fade,%pos,%normal)
{
// Apply damage to the object all shape base objects
if (%col.getType() & $TypeMasks::ShapeBaseObjectType)
{
%col.damage(%obj,%pos,%this.directDamage,"Arrow");
%location = %col.getDamageLocation(%pos); // getting where the enemy was damaged
%impactInfo = %obj.GetTransform(); //getting the arrow transformation info
// transform impact info into variables...
%impInf1 = getWord(%impactInfo,0);
%impInf2 = getWord(%impactInfo,1);
%impInf3 = getWord(%impactInfo,2);
%impInf4 = getWord(%impactInfo,3);
%impInf5 = getWord(%impactInfo,4);
%impInf6 = getWord(%impactInfo,5);
%impInf7 = getWord(%impactInfo,6);
%offsetInf1 = getWord(%normal,0);
%offsetInf2 = getWord(%normal,1);
%offsetInf3 = getWord(%normal,2);
%attachmentAngles = %offsetInf1 SPC%offsetInf2 SPC%offsetInf3;
echo("Arrow struck ", %col, " and damaged ", %location, " at ", %normal);
echo("raw transformation data: ", "x= ", %impInf1, ", y =", %impInf2, ", z= ", %impInf3, ", r1= ", %impInf4, ", r2= ", %impInf5, ", r3= ", %impInf6, ", r4= ", %impInf7);
echo("raw offset data: ", "r1= ", %offsetInf1, ", r2= ", %offsetInf2, ", r3= ", %offsetInf3);
echo("trying to mount: ", %obj, " at ", %attachmentAngles);
%col.mountImage("javelinImage", 0, 1, "none"); // trying to mount an arrow on enemy
%col.mountObject(%obj,1, "1 1 1 1 1 1 1");
}
}
#11
getNodeCount is not a legal function to iterate through it with ?!?
AIPlayer->Player->ShapeBase->GameBase->SceneObject->NetObject->SimObject
aint that kinda odd?
09/27/2010 (12:19 am)
Also, plans to iterate through the enemy (useing AI's atm) and see what node is closest to the impact. but...getNodeCount is not a legal function to iterate through it with ?!?
AIPlayer->Player->ShapeBase->GameBase->SceneObject->NetObject->SimObject
aint that kinda odd?
#12
Also, to start, try not passing in a node slot or offset
As to what node to use and the like, you might need to write a C++ function to figure that out, then expose it to script. Try to get it working without passing a node slot or offset transform. Also, you'll want to try "0 0 0 0 0 0 1" as your transform for testing as the one you passed would rotate your object a bunch and put it a meter away from your object.
09/27/2010 (1:52 am)
Well, you're going to need to create your arrow as a TSStatic and mount *that*, not your BowProjectile, first of all. So you'll need to create a new TSStatic with your arrow as the shape file. %yournewTSStatic = new TSStatic()
{
shapeFile = "path/to/dts.dts";
} or something like that. Also, to start, try not passing in a node slot or offset
%col.mountObject( %yourNewTSStatic );
As to what node to use and the like, you might need to write a C++ function to figure that out, then expose it to script. Try to get it working without passing a node slot or offset transform. Also, you'll want to try "0 0 0 0 0 0 1" as your transform for testing as the one you passed would rotate your object a bunch and put it a meter away from your object.
Torque Owner Ivan Mandzhukov
Liman3D
You can use staticshapes for arrows,but the tricky part is update their transform (and render transform) according to the enemy's translation and rotation. This can be done by parenting the arrow's transform to another one transform.
This is what the pathshape code is using for movable platforms.The player transform updates according to the platform's transform.
Check out the resource of Anthony Lovell : "Attachable SceneObjects in Hierarchical Coordinate Spaces".