Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Resolved AddForce doesn't seem to be working.

Discussion in 'Scripting' started by Chimaira, Aug 18, 2020.

  1. Chimaira

    Chimaira

    Joined:
    Jul 8, 2020
    Posts:
    12
    So I'm trying to use the same knockback script for both player and enemies but I'm having a problem with the knockback being applied to the player. I have the trigger collider on a separate object and set as a child of the enemy object. I've verified that the rigidbody is set to dynamic and have verified its being called via debugging. Strange part is this works just fine when the player hits the enemy but when the enemy hits the player no knockback is applied. I'm stumped, please help.

    Code (CSharp):
    1.     private void OnTriggerEnter2D(Collider2D other)
    2.     {
    3.         if (other.gameObject.CompareTag("enemy") || other.gameObject.CompareTag("Player"))
    4.         {
    5.             Rigidbody2D objectToHit = other.GetComponent<Rigidbody2D>();
    6.             if (objectToHit != null)
    7.             {
    8.                 Vector2 direction = objectToHit.transform.position - transform.position;
    9.                 objectToHit.AddForce(direction.normalized * thrust, ForceMode2D.Impulse);
    10.  
    11.                 if (other.gameObject.CompareTag("enemy"))
    12.                 {
    13.                     objectToHit.GetComponent<Enemy>().currentState = EnemyState.stagger;
    14.                     other.GetComponent<Enemy>().Knock(objectToHit, knockTime);
    15.                 }
    16.                 if(other.gameObject.CompareTag("Player"))
    17.                 {
    18.                     if (other.gameObject.GetComponent<PlayerMovement>().currentState != PlayerState.stagger)
    19.                     {
    20.                         objectToHit.GetComponent<PlayerMovement>().currentState = PlayerState.stagger;
    21.                         other.GetComponent<PlayerMovement>().Knock(objectToHit, knockTime, damage);
    22.                     }
    23.                 }
    24.             }
    25.            
    26.         }
    Code (CSharp):
    1.     public void Knock(Rigidbody2D playerRB, float knockTime, float damage)
    2.     {
    3.         currentHealth.RuntimeValue -= damage;
    4.         playerHealthSignal.Raise();
    5.  
    6.         if (currentHealth.RuntimeValue > 0)
    7.         {
    8.             StartCoroutine(KnockCo(playerRB, knockTime));
    9.         }
    10.         else
    11.         {
    12.             this.gameObject.SetActive(false);
    13.         }
    14.  
    15.     }
    16.  
    17.     private IEnumerator KnockCo(Rigidbody2D playerRB, float knockTime)
    18.     {
    19.         if (playerRB != null)
    20.         {
    21.             yield return new WaitForSeconds(knockTime);
    22.             playerRB.velocity = Vector2.zero;
    23.             currentState = PlayerState.idle;
    24.         }
    25.     }
     
  2. RakNet

    RakNet

    Joined:
    Oct 9, 2013
    Posts:
    313
    OnTriggerEnter is only called for the the GameObject that has the collider, not the GameObject that touched the collider.
     
  3. Chimaira

    Chimaira

    Joined:
    Jul 8, 2020
    Posts:
    12
    The trigger is actually working as it should. When my enemy collides with my player the player RB is called but the physics are not applied from addforce.
     
  4. RakNet

    RakNet

    Joined:
    Oct 9, 2013
    Posts:
    313
    Is your player using character controller? Add force doesn't work with CharacterController
     
  5. PraetorBlue

    PraetorBlue

    Joined:
    Dec 13, 2012
    Posts:
    7,697
    Does the player have a Rigidbody2D?
     
  6. jbnlwilliams1

    jbnlwilliams1

    Joined:
    May 21, 2019
    Posts:
    267
    What is the value of thrust? I do not see that being set anywhere.
     
  7. Chimaira

    Chimaira

    Joined:
    Jul 8, 2020
    Posts:
    12
    I feel like this is probably just something dumb but I did verify a character controller is not used, my player does have a rigidbody2d and a thrust is set in the inspector. I attached a screenshot for reference. Thanks for the help btw.

    upload_2020-8-26_14-4-22.png
    upload_2020-8-26_14-4-53.png
    upload_2020-8-26_14-5-34.png
     
  8. PraetorBlue

    PraetorBlue

    Joined:
    Dec 13, 2012
    Posts:
    7,697
    1. You have two box colliders on your player. Is that intentional?
    2. Cna you show the properties of the rigidbody2d? Especially the "Constraints" portion, as well as the "Is Kinematic" checkbox.
     
  9. Chimaira

    Chimaira

    Joined:
    Jul 8, 2020
    Posts:
    12
    The second box collider was me testing things out, just forgot to delete it before posting the screenshot. Attached is the player RB.

    upload_2020-8-26_14-58-22.png
     
  10. PraetorBlue

    PraetorBlue

    Joined:
    Dec 13, 2012
    Posts:
    7,697
    Ok so a couple other things to check:

    • As mentioned before, what's the value of "thrust"? Maybe Debug.Log it?
    • Perhaps try increasing the thrust value
    • What's the value of Time.timeScale?
    • Is the player touching anything else/ It could just be not moving due to friction or some other object blocking it.
     
  11. Chimaira

    Chimaira

    Joined:
    Jul 8, 2020
    Posts:
    12
    - debug shows thrust to be correct at 10 (what i have set in the inspector)
    - I've set thrust as high as 100 and still not working.
    - debug shows time.timescale to be 1
    - nothing else is touching it but i was thinking my player movement could be a cause somehow.

    Code (CSharp):
    1. using System.Collections;
    2. using UnityEngine;
    3.  
    4. public enum PlayerState
    5. {
    6.     idle,
    7.     walk,
    8.     attack,
    9.     interact,
    10.     stagger
    11. }
    12.  
    13. public class PlayerMovement : MonoBehaviour
    14. {
    15.     public PlayerState currentState;
    16.     public float playerSpeed;
    17.     private Rigidbody2D playerRB;
    18.     private Vector2 change;
    19.     private Animator animator;
    20.     public FloatValue currentHealth;
    21.     public SignalSender playerHealthSignal;
    22.     public VectorValue startingPosition;
    23.     public Inventory playerInventory;
    24.  
    25.     // Start is called before the first frame update
    26.     void Start()
    27.     {
    28.         currentState = PlayerState.idle;
    29.         animator = GetComponent<Animator>();
    30.         playerRB = GetComponent<Rigidbody2D>();
    31.         animator.SetFloat("moveX", 0);
    32.         animator.SetFloat("moveY", -1);
    33.         transform.position = startingPosition.initialValue;
    34.     }
    35.  
    36.     // Update is called once per frame
    37.     void Update() {
    38.         if(currentState == PlayerState.interact)
    39.         {
    40.             return;
    41.         }
    42.         change = Vector2.zero;
    43.         if (currentState != PlayerState.stagger)
    44.         {
    45.             change.x = Input.GetAxisRaw("Horizontal");
    46.             change.y = Input.GetAxisRaw("Vertical");
    47.         }
    48.         if (Input.GetButtonDown("attack") && currentState != PlayerState.attack && currentState != PlayerState.stagger)
    49.         {
    50.             StartCoroutine(AttackCo());
    51.         }
    52.         else if (currentState == PlayerState.walk || currentState == PlayerState.idle)
    53.         {
    54.             UpdateAnimatonAndMove();
    55.         }
    56.     }
    57.  
    58.     void FixedUpdate()
    59.     {
    60.         change.Normalize();
    61.         playerRB.MovePosition(playerRB.position + change * playerSpeed * Time.fixedDeltaTime);
    62.     }
    63.  
    64.     private IEnumerator AttackCo()
    65.     {
    66.         animator.SetBool("attacking", true);
    67.         currentState = PlayerState.attack;
    68.         yield return null;
    69.         animator.SetBool("attacking", false);
    70.         yield return new WaitForSeconds(.2f);
    71.         if (currentState != PlayerState.interact)
    72.         {
    73.             currentState = PlayerState.walk;
    74.         }
    75.     }
    76.  
    77.     void UpdateAnimatonAndMove()
    78.     {
    79.         if(change != Vector2.zero)
    80.         {
    81.             animator.SetFloat("moveX", change.x);
    82.             animator.SetFloat("moveY", change.y);
    83.             currentState = PlayerState.walk;
    84.         }
    85.         else if (change == Vector2.zero)
    86.         {
    87.             currentState = PlayerState.idle;
    88.         }
    89.                
    90.         animator.SetFloat("speed", change.sqrMagnitude);
    91.     }
    92.  
    93.     public void Knock(Rigidbody2D playerRB, float knockTime, float damage)
    94.     {
    95.         currentHealth.RuntimeValue -= damage;
    96.         playerHealthSignal.Raise();
    97.  
    98.         if (currentHealth.RuntimeValue > 0)
    99.         {
    100.             StartCoroutine(KnockCo(playerRB, knockTime));
    101.         }
    102.         else
    103.         {
    104.             this.gameObject.SetActive(false);
    105.         }
    106.  
    107.     }
    108.  
    109.     private IEnumerator KnockCo(Rigidbody2D playerRB, float knockTime)
    110.     {
    111.         if (playerRB != null)
    112.         {
    113.             yield return new WaitForSeconds(knockTime);
    114.             playerRB.velocity = Vector2.zero;
    115.             currentState = PlayerState.idle;
    116.         }
    117.     }
    118. }
    119.  
     
  12. PraetorBlue

    PraetorBlue

    Joined:
    Dec 13, 2012
    Posts:
    7,697
    If your player's motion is driven by an animator, that may indeed be why your player can't move. The animator is known to overwrite any other movement on an object.

    Perhaps try disabling the animator temporarily to test this theory?
     
  13. Chimaira

    Chimaira

    Joined:
    Jul 8, 2020
    Posts:
    12
    I finally figured it out. Seems the playerRB.MovePosition() was the issue. I wrapped it in an if statement to have it pass over it during the knockback. Not sure why this was the issue but I'd love to know why.

    Code (CSharp):
    1. if (currentState != PlayerState.stagger)
    2.         {
    3.             change.Normalize();
    4.             playerRB.MovePosition(playerRB.position + change * playerSpeed * Time.fixedDeltaTime);
    5.         }