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.
private void OnTriggerEnter2D(Collider2D other)
{
if (other.gameObject.CompareTag("enemy") || other.gameObject.CompareTag("Player"))
{
Rigidbody2D objectToHit = other.GetComponent<Rigidbody2D>();
if (objectToHit != null)
{
Vector2 direction = objectToHit.transform.position - transform.position;
objectToHit.AddForce(direction.normalized * thrust, ForceMode2D.Impulse);
if (other.gameObject.CompareTag("enemy"))
{
objectToHit.GetComponent<Enemy>().currentState = EnemyState.stagger;
other.GetComponent<Enemy>().Knock(objectToHit, knockTime);
}
if(other.gameObject.CompareTag("Player"))
{
if (other.gameObject.GetComponent<PlayerMovement>().currentState != PlayerState.stagger)
{
objectToHit.GetComponent<PlayerMovement>().currentState = PlayerState.stagger;
other.GetComponent<PlayerMovement>().Knock(objectToHit, knockTime, damage);
}
}
}
}
public void Knock(Rigidbody2D playerRB, float knockTime, float damage)
{
currentHealth.RuntimeValue -= damage;
playerHealthSignal.Raise();
if (currentHealth.RuntimeValue > 0)
{
StartCoroutine(KnockCo(playerRB, knockTime));
}
else
{
this.gameObject.SetActive(false);
}
}
private IEnumerator KnockCo(Rigidbody2D playerRB, float knockTime)
{
if (playerRB != null)
{
yield return new WaitForSeconds(knockTime);
playerRB.velocity = Vector2.zero;
currentState = PlayerState.idle;
}
}
RakNet
August 19, 2020, 3:41am
2
OnTriggerEnter is only called for the the GameObject that has the collider, not the GameObject that touched the collider.
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.
RakNet
August 24, 2020, 5:29pm
4
Is your player using character controller? Add force doesn’t work with CharacterController
Does the player have a Rigidbody2D?
What is the value of thrust? I do not see that being set anywhere.
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.
PraetorBlue:
You have two box colliders on your player. Is that intentional?
Cna you show the properties of the rigidbody2d? Especially the “Constraints” portion, as well as the “Is Kinematic” checkbox.
The second box collider was me testing things out, just forgot to delete it before posting the screenshot. Attached is the player RB.
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.
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.
using System.Collections;
using UnityEngine;
public enum PlayerState
{
idle,
walk,
attack,
interact,
stagger
}
public class PlayerMovement : MonoBehaviour
{
public PlayerState currentState;
public float playerSpeed;
private Rigidbody2D playerRB;
private Vector2 change;
private Animator animator;
public FloatValue currentHealth;
public SignalSender playerHealthSignal;
public VectorValue startingPosition;
public Inventory playerInventory;
// Start is called before the first frame update
void Start()
{
currentState = PlayerState.idle;
animator = GetComponent<Animator>();
playerRB = GetComponent<Rigidbody2D>();
animator.SetFloat("moveX", 0);
animator.SetFloat("moveY", -1);
transform.position = startingPosition.initialValue;
}
// Update is called once per frame
void Update() {
if(currentState == PlayerState.interact)
{
return;
}
change = Vector2.zero;
if (currentState != PlayerState.stagger)
{
change.x = Input.GetAxisRaw("Horizontal");
change.y = Input.GetAxisRaw("Vertical");
}
if (Input.GetButtonDown("attack") && currentState != PlayerState.attack && currentState != PlayerState.stagger)
{
StartCoroutine(AttackCo());
}
else if (currentState == PlayerState.walk || currentState == PlayerState.idle)
{
UpdateAnimatonAndMove();
}
}
void FixedUpdate()
{
change.Normalize();
playerRB.MovePosition(playerRB.position + change * playerSpeed * Time.fixedDeltaTime);
}
private IEnumerator AttackCo()
{
animator.SetBool("attacking", true);
currentState = PlayerState.attack;
yield return null;
animator.SetBool("attacking", false);
yield return new WaitForSeconds(.2f);
if (currentState != PlayerState.interact)
{
currentState = PlayerState.walk;
}
}
void UpdateAnimatonAndMove()
{
if(change != Vector2.zero)
{
animator.SetFloat("moveX", change.x);
animator.SetFloat("moveY", change.y);
currentState = PlayerState.walk;
}
else if (change == Vector2.zero)
{
currentState = PlayerState.idle;
}
animator.SetFloat("speed", change.sqrMagnitude);
}
public void Knock(Rigidbody2D playerRB, float knockTime, float damage)
{
currentHealth.RuntimeValue -= damage;
playerHealthSignal.Raise();
if (currentHealth.RuntimeValue > 0)
{
StartCoroutine(KnockCo(playerRB, knockTime));
}
else
{
this.gameObject.SetActive(false);
}
}
private IEnumerator KnockCo(Rigidbody2D playerRB, float knockTime)
{
if (playerRB != null)
{
yield return new WaitForSeconds(knockTime);
playerRB.velocity = Vector2.zero;
currentState = PlayerState.idle;
}
}
}
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?
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.
if (currentState != PlayerState.stagger)
{
change.Normalize();
playerRB.MovePosition(playerRB.position + change * playerSpeed * Time.fixedDeltaTime);
}