- Home /
Unity 2D Physics .AddForce
Hey Everyone,
So I am trying to implement knockback functionality for my enemies. When the enemy stands still, the knockback works correctly, but when its moving towards the player, .AddForce seems to be overwritten with my movement code, even though it doesn't get executed. Both entities have dynamic rigidbodies with isKinematic set initially to false.
Intended Functionality: Current Functionality when Entity Moves:
I know I'm missing something with the physics, but I cannot see what it is. Any help would be greatly appreciated. Here is my logic below:
internal void Hurt (GameObject Enemy) {
var EnemyEntity = Enemy.GetComponent<Entity>();
EnemyEntity.Health -= 10;
Rigidbody2D EnemyBody = Enemy.GetComponent<Rigidbody2D>();
PreviousBodyType = EnemyBody.bodyType;
WasKinematic = EnemyBody.isKinematic;
EnemyBody.bodyType = RigidbodyType2D.Dynamic;
EnemyBody.isKinematic = false;
Vector2 Difference = (Enemy.transform.position - transform.position);
Difference = Difference.normalized * GlobalVariables.Instance.KnockbackIntensity;
if (PreviousBodyType != RigidbodyType2D.Static) {
EnemyBody.AddForce(Difference, ForceMode2D.Impulse);
}
if (EnemyEntity.Health <= 0) {
EnemyBody.isKinematic = true;
StartCoroutine(EnemyEntity.Die());
}else {
EnemyEntity.IsHurting = true;
StartCoroutine(HurtRecovery(Enemy));
}
}
private IEnumerator HurtRecovery (GameObject Enemy) {
if (Enemy != null) {
var Sprite = Enemy.GetComponent<SpriteRenderer>();
var Entity = Enemy.GetComponent<Entity>();
var Body = Enemy.GetComponent<Rigidbody2D>();
var EnemySpriteColor = Sprite.color;
Sprite.color = Color.red;
yield return new WaitForSeconds(GlobalVariables.Instance.KnockbackTime);
Sprite.color = Entity.BaseColor;
Body.velocity = Vector2.zero;
Body.isKinematic = WasKinematic;
Body.bodyType = PreviousBodyType;
Entity.IsHurting = false;
}
}
Along with my movement script:
public void Move(Vector2 Movement) {
if (IsDead() || IsHurting) {
return;
}
if (IsFrozen == true) {
Body.velocity = new Vector2(0, 0);
Animator.SetBool("IsMoving", false);
return;
}
if (Movement.x == 0 && Movement.y == 0)
{
Body.velocity = new Vector2(0, 0);
Body.isKinematic = true;
Animator.SetBool("IsMoving", false);
return;
}
else
{
Body.isKinematic = false;
Body.MovePosition(Body.position + Movement * Speed * Time.deltaTime);
Animator.SetBool("IsMoving", true);
}
if (Movement.x != 0 && Mathf.Abs(Movement.x) > Mathf.Abs(Movement.y))
{
if (Movement.x > 0)
{
Animator.SetInteger("HorizontalMove", 1);
if (IsSimpleMovement == true) {
Sprite.flipX = true;
}
}
else if(Movement.x < 0)
{
Animator.SetInteger("HorizontalMove", -1);
if (IsSimpleMovement == true) {
Sprite.flipX = false;
}
}
Animator.SetInteger("VerticalMove", 0);
}
else
{
Animator.SetInteger("HorizontalMove", 0);
if (Movement.y != 0)
{
if (Movement.y > 0)
{
Animator.SetInteger("VerticalMove", 1);
}
else if (Movement.y < 0)
{
Animator.SetInteger("VerticalMove", -1);
}
}
else
{
Animator.SetInteger("VerticalMove", 0);
}
}
}
Answer by xxmariofer · Aug 29, 2019 at 07:28 AM
Try setting the velocity to 0 just before you add the force
if (PreviousBodyType != RigidbodyType2D.Static) {
EnemyBody.velocity = Vector2.zero;
EnemyBody.AddForce(Difference, ForceMode2D.Impulse);
}
Unfortunately it did not work, still had the same results :/ Perhaps, the $$anonymous$$ove() is getting called somewhere it shouldn't be. When I debugged it, the breakpoint wasn't being hit. But, I'll do some more testing tonight. Thanks for your help @xxmariofer
that was my first though, but at the very start of the method you have an if ishurt that should never get passed