This is a VERY hard one for the math wizards.

Post » Thu Jun 21, 2012 8:13 am

So this gives me a random direction push from the opponent when the target gets hit:

me.ApplyHavokImpulse(Utility.RandomFloat(-2.0, 2.0), Utility.RandomFloat(-2.0, 2.0), 0.5, 50)

The target may go flying in any compass direction.
How would I get a controlled direction (not random) based on the direction the attacker is facing?
What Math wizardry is needed to match the x and y of the impulse to the direction the attacker is facing?


see here: http://www.creationkit.com/ApplyHavokImpulse_-_ObjectReference


Maybe I could just get the attackers last pos before the attack and compare to their cur pos to get the x and y direction they are facing?
Not perfect but will work most of the time unless someone else has a better way.
User avatar
Charlotte X
 
Posts: 3318
Joined: Thu Dec 07, 2006 2:53 am

Post » Thu Jun 21, 2012 12:44 pm

http://www.creationkit.com/GetHeadingAngle_-_ObjectReference

I'm not a maths wizard, so it went right over my head ... should work though ;)
User avatar
tiffany Royal
 
Posts: 3340
Joined: Mon Dec 25, 2006 1:48 pm

Post » Thu Jun 21, 2012 5:14 am

I am still learning papyrus but is there a "get" function so that you can get x and y?
lol sorry I guess I just answered your question with another question but I am just thinking out loud.
Note that I am a noob but I will try to help any way lol.
I am just thinking you are going to have to use a "set" function and then a "get" function then on the next line put "me.ApplyHavokImpulse(Utility.RandomFloat(-2.0, 2.0), Utility.RandomFloat(-2.0, 2.0), 0.5, 50)"

so prob http://www.creationkit.com/GetAngleX_-_ObjectReference and http://www.creationkit.com/GetAngleY_-_ObjectReference and http://www.creationkit.com/SetAngle_-_ObjectReference

float.http://www.creationkit.com/SetAngle_-_ObjectReference(aktarget).http://www.creationkit.com/GetAngleX_-_ObjectReference(180.0, 0.0, 0.0) as int)

Yeah not very helpful but I try my best.
User avatar
yermom
 
Posts: 3323
Joined: Mon Oct 15, 2007 12:56 pm

Post » Thu Jun 21, 2012 12:45 pm

I'm hardly a math wizard, but I think this is basic trigonometry?

Use GetAngleZ on the actor to get the horizontal facing direction. Use Cos(z-angle) to get the Y push direction and Sin(z-angle) to get the X push direction.

For example, if the actor's GetAngleZ returns 125 degrees, then the Y push is Cos(125) = -0.57 and X push is Sin(125) = 0.82.

If you also want to push the actor up or down based on if the actor is looking up or down, use GetAngleX on the actor and use Sin(x-angle) to determine the Z push. If the Papyrus GetAngleX behaves the same as the console command GetAngle x, the actor will be pushed up in the air when the actor is looking down, and pushed down if the actor is looking up. Multiple by -1 to reverse this. Note that often GetAngleX returns 0 on NPC's, and may only work correctly on the player character if the camera is in first person.


My approach may be completely wrong though, like I said I'm hardly a math wizard.


edit: Wait, you want to push a victim based on the relative position of an attacker? Like a kick, flying in the opposite direction of the position of the attacker? In that case use (Victim.GetAngleZ() + Victim.GetHeadingAngle(Attacker) + 180) instead of just GetAngleZ. Then use Cos on the outcome for the Y push and Sin on the outcome for the X push.
User avatar
Vivien
 
Posts: 3530
Joined: Fri Apr 13, 2007 2:47 pm

Post » Thu Jun 21, 2012 10:07 am

Also keep in mind that while megafaer is right, you are essentially creating a unit vector in the directon of me from the target, so if you want your havok impulse to be stronger than a magnitude of "1", then multiply all 3 parameters by a constant, like 20. Keep the constant the same across all 3 parameters, though you could always do something like give a slightly larger constant to the z impulse to give the victim more air time
User avatar
natalie mccormick
 
Posts: 3415
Joined: Fri Aug 18, 2006 8:36 am

Post » Thu Jun 21, 2012 6:38 am

Did you know that in order for ApplyHavokImpulse to show any effects on an actor, you need to apply PushActorAway first?

I'm not sure I understand what you wanted. For example, assume that the "target" is northwest of the "source", and the "source" is facing west. Do you want to apply the force in the west direction or the northwest direction?

If the former, you should use this:

float AngleZ = Source.GetAngleZ()Target.ApplyHavokImpulse(Math.Sin(AngleZ), Math.Cos(AngleZ), afZ, afMagnitude)

If the latter, you should use this:

float AngleZ = Source.GetAngleZ() + Source.GetHeadingAngle(Target)Target.ApplyHavokImpulse(Math.Sin(AngleZ), Math.Cos(AngleZ), afZ, afMagnitude)

If it's the latter and you wanted the direction of the force to be 3 dimensional (taking into account the different in elevation between the source and the target as well), then you would want to use this:

float DistanceTotal = Source.GetDistance(Target)float ComponentX = (Target.X - Source.X) / DistanceTotalfloat ComponentY = (Target.Y - Source.Y) / DistanceTotalfloat ComponentZ = (Target.Z - Source.Z) / DistanceTotalTarget.ApplyHavokImpulse(ComponentX, ComponentY, ComponentZ, afMagnitude)
User avatar
Joanne Crump
 
Posts: 3457
Joined: Sat Jul 22, 2006 9:44 am

Post » Thu Jun 21, 2012 11:52 am

Also keep in mind that while megafaer is right, you are essentially creating a unit vector in the directon of me from the target, so if you want your havok impulse to be stronger than a magnitude of "1", then multiply all 3 parameters by a constant, like 20. Keep the constant the same across all 3 parameters, though you could always do something like give a slightly larger constant to the z impulse to give the victim more air time

No no, the magnitude is a separate parameter. So keep the component parameters equal to or between -1 and 1.
User avatar
Gaelle Courant
 
Posts: 3465
Joined: Fri Apr 06, 2007 11:06 pm

Post » Thu Jun 21, 2012 12:52 am

No no, the magnitude is a separate parameter. So keep the component parameters equal to or between -1 and 1.

Oh, neat. I had never looked at applyhavokimpulse so I just assumed magnitude was built into the vector components much like applyforce() in E2 for Garry's Mod.

Thanks for correcting me!
User avatar
Sunny Under
 
Posts: 3368
Joined: Wed Apr 11, 2007 5:31 pm

Post » Thu Jun 21, 2012 1:38 pm

Yep! I knew about PUSHACTORAWAY (use that a heck of a lot in Oblivion combat and did find it was needed here to kick Havok awake ) I already have the Havok impulse working now but only with a RANDOM direction.

I did NOT know all the other sweet and chewy details however...thank you VERY much and thanks to Elseagoat and Maegfaer for the help on this as well and to 3djake and 4vent for trying to help.

I am going to go try this right now...


Did you know that in order for ApplyHavokImpulse to show any effects on an actor, you need to apply PushActorAway first?

I'm not sure I understand what you wanted. For example, assume that the "target" is northwest of the "source", and the "source" is facing west. Do you want to apply the force in the west direction or the northwest direction?

If the former, you should use this:

float AngleZ = Source.GetAngleZ()Target.ApplyHavokImpulse(Math.Sin(AngleZ), Math.Cos(AngleZ), afZ, afMagnitude)

If the latter, you should use this:

float AngleZ = Source.GetAngleZ() + Source.GetHeadingAngle(Target)Target.ApplyHavokImpulse(Math.Sin(AngleZ), Math.Cos(AngleZ), afZ, afMagnitude)

If it's the latter and you wanted the direction of the force to be 3 dimensional (taking into account the different in elevation between the source and the target as well), then you would want to use this:

float DistanceTotal = Source.GetDistance(Target)float ComponentX = (Target.X - Source.X) / DistanceTotalfloat ComponentY = (Target.Y - Source.Y) / DistanceTotalfloat ComponentZ = (Target.Z - Source.Z) / DistanceTotalTarget.ApplyHavokImpulse(ComponentX, ComponentY, ComponentZ, afMagnitude)
User avatar
Prue
 
Posts: 3425
Joined: Sun Feb 11, 2007 4:27 am

Post » Thu Jun 21, 2012 7:29 am

hey long as I got your attention:

This kind of thing would work in Oblivion to hard cap var because yes and no or true and false was always returned as 1 or 0:

impulse = impulse - ((impulse - 16) * (impulse > 16))

Is there no way to do it in Skyrim?
Will I be forced to do this :

if impulse > 16
impulse = 16
endif

Is this not slower than the one line way?
User avatar
Sharra Llenos
 
Posts: 3399
Joined: Wed Jan 17, 2007 1:09 pm

Post » Thu Jun 21, 2012 12:11 am

If you cast the bool as an int, it should work.
User avatar
TWITTER.COM
 
Posts: 3355
Joined: Tue Nov 27, 2007 3:15 pm

Post » Thu Jun 21, 2012 1:36 am

oh yay that did work! :laugh:

THANKS!

If you cast the bool as an int, it should work.
User avatar
abi
 
Posts: 3405
Joined: Sat Nov 11, 2006 7:17 am


Return to V - Skyrim