[SOLVED] Applying force consistently

Updated on January 9, 2017 in [A] Unity Scripting
Share on Facebook0Tweet about this on TwitterShare on Google+0Share on Reddit0
9 on January 7, 2017

I am trying to add a force to knock my player away from an enemy upon triggering a collider placed on that enemy. The force is being applied, but very inconsistently.

I have only been using Unity and JS for 5 days, so perhaps the problem is Ive over simplified a complex concept, but  after doing some research I feel like Im close.

Here is the script I have placed on the collider:

 var knockBack = 300;
 function OnTriggerEnter () {
 GameMaster.currentScore -=1;
 var dirKnockBack=(gameObject.transform.position - player.GetComponent.().transform.position);
 //dirKnockBack.Normalize();
 player.GetComponent.().AddForce(-dirKnockBack * knockBack, ForceMode.Force);
 }
 

Ive commented out the .Normalize function, as I still havent researched it completely enough to fully understand it. Also, it did not seem to make a difference when implemented.

ps. Could you be a friend, and let me know how to correctly copy and paste code from MoneDevelop into these posts? Ive tried and it turned into a mess.

Thanks a bunch for your time.

  • Liked by
Reply
1 on January 7, 2017

When you say consistently, what do you mean, as hitting an enemy cannot be consistent can it? Because if you hit an enemy, you get knocked back, you then need to return to that enemy to be blasted back again.

Are you saying you are hitting into the enemy, being thrown back, and when you hit into it again, it doesn’t? 

OR are you saying that, triggering the collision event, when you travel back the force you travel back at isn’t consistent?

on January 7, 2017

When I hit the enemy, I get pushed back a little. Then hit the enemy again and I dont get pushed at all. Then I hit it a third time, and I get blasted off the screen.

It actually seems like if I hit it from the top, the force remains consistent each time, but its a completely different amount than if I hit it from the side.

Show more replies
  • Liked by
Reply
Cancel
3 on January 7, 2017

It seems like you’re doing things pretty well…
Firstly, how have you turned your code into a mess? it seems pretty good to me.
Second, I’m guessing your problem is that your character isn’t getting knocked back much (if at all)…?
If that’s true, then I think it might be because applying a force in a single frame doesn’t do too much, but rather, forces are usually applied over several frames (like in a fixed update method)
instead, maybe try something like this:

var knockBackMultiplier = 300; // I changed the name of this variable and used it below in a new line. change this value as needed
function OnTriggerEnter () {
GameMaster.currentScore -=1;
var dirKnockBack=(gameObject.transform.position - player.GetComponent.<Rigidbody>().transform.position);
//dirKnockBack.Normalize();
 
// I added this line
var newVelocity: Vector3 = player.GetComponent.<Rigidbody>().velocity - dirKnockBack*knockBackMultiplier
 
//and changed this line
player.GetComponent.<Rigidbody>().velocity = newVelocity;
}

This should instantly change your player’s velocity in a single frame, resulting in an immediate ‘kicked away’ pseudo force.
 
Let me know if this makes sense and feel free to ask further questions about differences between changing velocities and AddForce methods.

Devoted
on January 7, 2017

The code is messy. It’s always messy on this forum, since it doesn’t allow the tabs, so everything snaps to the left. Unfortunately, there is nothing we can do about that.

on January 9, 2017

Thanks @BinaryBeal and @Or Aviram.

About the messy code, I was referring to literally copy/pasting from MonoDevelop into this forum, which turned into a mess. I ended up just re-writing the code to post. Maybe that’s what it takes, and not just lazy copy pasta.

After more research, a bit of cursing at my screens, and buying a bunch of whiteboards to “math” on, I found a solution that seems to get the results I was looking for.

I tried @BinaryBeal ‘s code, but it didn’t fully work. After only a few days of experience with Unity and JS I cant say for sure why, but i think its because line 9 calls for the player velocity, which at the point of impact is possibly zero (?).

So I ended up with a mix of what I had and the solution you gave me.

var dirKnockBack : Vector 3;
var knockBack = 5;
function OnTriggerEnter(){
      var dirKnockBack = (player.GetComponent.<Rigidbody>().transform.position - gameObject.transform.position);
   dirKnockBack = dirKnockback * knockBack;
  
   player.GetComponent.<Rigidbody>().velocity = dirKnockBack;
}

Funny enough, I was having a problem where the player and enemy would not collide when the player was standing still. By changing addforce to .velocity it fixed that as well. Not sure why, but hey, I’ll take it!

So, cheers! Thanks for helping a newbie get into what I hope is a long-lasting relationship with Unity.

(New to everything, including this forum…is there a way to tag this post as answered? or do i just edit the title to say {answered}? Should I place an answer below all these with an explanation of the fix?)

Thanks ladies and/or gentlemen.

Devoted
on January 9, 2017

The messy code is a bug on the forum, since you are supposed to copy-paste. When you get the bug just try doing it again and again until it works.

There is no way to mark a post as answered, unfortunately. There should be one, though, where the person who gave the answer will get points like in other forums. For now you could either just leave it or add something at the title to indicate it’s solved.

Show more replies
  • Liked by
Reply
Cancel
2 on January 7, 2017

Try using ForceMode.VelocityChange. You could also use ForceMode.Impulse, if you don’t want the mass to be ignored.

As for normalizing, this is a very very important thing you must know. I won’t go in-depth, but basically: A vector has a direction and a magnitude (speed/length). A normalized version of a vector is basically a vector that the sum of its axes is 1, which means it only has a direction, not a magnitude.

Devoted
on January 7, 2017

Pretty sure it’s the sum of the axes squared, but yes. Minor detail. That results in the magnitude of the vector itself to be a value of 1.

on January 9, 2017

Thank you. I did a little more research and am starting to get the concept. I will continue to figure it out as I further my learning.

Cheers.

Show more replies
  • Liked by
Reply
Cancel