- Home /
Knock Back only moving player up and down (vertical Y axis)
Anyone know why my character will only move up and down (vertically) on collision? It won't move left and right.
Code:
if (other.gameObject.CompareTag("Player"))
{
Rigidbody2D hit = other.GetComponent<Rigidbody2D>();
if (hit != null)
{
Vector2 difference = hit.transform.position - this.transform.position;
difference = difference.normalized * thrust;
hit.AddForce(difference, ForceMode2D.Impulse);
if (other.gameObject.CompareTag("Player") && other.isTrigger)
{
other.GetComponent<PlayerMovement>().currentState = PlayerState.stagger;
other.GetComponent<PlayerMovement>().Knock(hit, knockTime);
if(source != null)
{
source = hit.GetComponent<AudioSource>();
source.Play();
}
}
}
}
Other Code (from PlayerMovement referenced above):
public void Knock(Rigidbody2D myRigidbody, float knockTime)
{
StartCoroutine(KnockCo(myRigidbody, knockTime));
}
private IEnumerator KnockCo(Rigidbody2D myRigidbody, float knockTime)
{
if (myRigidbody != null)
{
yield return new WaitForSeconds(knockTime);
myRigidbody.velocity = Vector2.zero;
currentState = PlayerState.idle;
}
}
Eek, obfuscated JS vibes
Why are you using the difference in position as the direction vector? Shouldn't it be based on velocity, or is there something specific you're going for? Is it a raycast or a collision? Are your Rigidbody2D
s set to kinematic or not? What's the setup look like, and do you have any more specific information on the behaviour? Does the bug persist when your character gets hit in midair?
Answer by Captain_Pineapple · Aug 13, 2020 at 09:13 AM
as @CardboardComputers pointed out it is difficult/not possible to tell what's going on from the currntly provided information.
However my guess would be that you (just as too many before you) are doing one of the following:
directly manipulating the characters horizontal velocity to move the character
moving the character by moveposition or movetowards
Both versions would be a problem here since you overwrite the effects of "addForce" each frame.
if that is the case you either need to change the way you move your character for a force based system or implement your own knockback "force" that does not use rigidbody.addforce.
I tried disabling the controls completely and it still only pushes back up or down (when the enemy touches a player). I made an alternate code that gives a huge addforce and when I do, it seems to push the X value away 1 time, and the Y value away for the time specified by the timer.
(This is a top down game, not a platformer.) The controls move the character in all 4 directions but only the horizontal doesnt get affected when he gets hit.
What information would be helpful to submit to more accurately understand my problem do you think?
The code you use to move your character would be helpful. Your experiment with "trying to disable the movement controls" only further amplifies my assumption that you overwrite the objects x velocity somewhere.
// Start is called before the first frame update
void Start()
{
if(startingPosition != null) transform.position = startingPosition.initialValue;
currentState = PlayerState.walk;
animator = GetComponent<Animator>();
myRigidbody = GetComponent<Rigidbody2D>();
animator.SetFloat("moveX", 0);
animator.SetFloat("moveY", -1);
player$$anonymous$$axHp = GameObject.Find("playerstats").GetComponent<playerStats>().player$$anonymous$$axHp;
playerHp = GameObject.Find("playerstats").GetComponent<playerStats>().playerHp;
expToNextLevel = GameObject.Find("playerstats").GetComponent<playerStats>().expToNextLevel;
exp = GameObject.Find("playerstats").GetComponent<playerStats>().exp;
playerLevel = GameObject.Find("playerstats").GetComponent<playerStats>().playerLevel;
chests = 0;
}
void FixedUpdate()
{
//$$anonymous$$y Code to stop sliding
if (currentState == PlayerState.idle || currentState == PlayerState.walk)
{
myRigidbody.velocity = Vector2.zero;
}
change = Vector3.zero;
change.x = Input.GetAxisRaw("Horizontal");
change.y = Input.GetAxisRaw("Vertical");
UpdateAnimationAnd$$anonymous$$ove();
}
void Update()
{
if (Input.GetButtonDown("attack") && currentState != PlayerState.attack && currentState != PlayerState.stagger)
{
StartCoroutine(AttackCo());
}
else if (currentState == PlayerState.walk || currentState == PlayerState.idle)
{
UpdateAnimationAnd$$anonymous$$ove();
}
}
private IEnumerator AttackCo() { animator.SetBool("attacking", true); currentState = PlayerState.attack; yield return null; animator.SetBool("attacking", false); yield return new WaitForSeconds(0.16f); currentState = PlayerState.walk; GameObject.Find("playerstats").GetComponent().superBarCurrent += 5; }
void UpdateAnimationAnd$$anonymous$$ove()
{
if (change != Vector3.zero)
{
$$anonymous$$oveCharacter();
animator.SetFloat("moveX", change.x);
animator.SetFloat("moveY", change.y);
animator.SetBool("moving", true);
}
else
{
animator.SetBool("moving", false);
}
}
//$$anonymous$$ovement
void $$anonymous$$oveCharacter()
{
if (currentState != PlayerState.attack)
{
change.Normalize();
myRigidbody.$$anonymous$$ovePosition(transform.position + change * speed * Time.deltaTime);
}
}
public void Knock(Rigidbody2D myRigidbody, float knockTime)
{
StartCoroutine(KnockCo(myRigidbody, knockTime));
}
private IEnumerator KnockCo(Rigidbody2D myRigidbody, float knockTime)
{
if (myRigidbody != null)
{
yield return new WaitForSeconds(knockTime);
myRigidbody.velocity = Vector2.zero;
currentState = PlayerState.idle;
myRigidbody.velocity = Vector2.zero;
}
}
}
Your answer
Follow this Question
Related Questions
Allow collision but take no force from it, not increasing object mass 1 Answer
How do I effectively perform KnockBack whenever my character gets hit by an enemy/ harmful object? 0 Answers
Trouble creating knockback when setting velocity on RigidBody2D 0 Answers
The knockback function I made is pushing me to the left 0 Answers
animation not playing on collision2d 0 Answers