- Home /
How to fix the player flying into the sky after applying velocity on the y to him.
Hi guys, I want to kill enemies by jumping on them something similar to mario, but with enemies that do not die after the first jump. With this implementation, I ran into several problems, first my player flies into the stratosphere after touching an enemy, the second is that the enemies take more damage than they should (continuing to fall the player continues to inflict damage). By the way, I managed to solve each of these problems, but separately. In the attached version of the code, only the problem of damage is solved, but not with flying. Thank you in advance.
MonoBehaviour
{
[SerializeField]
private LayerMask whatIsDamageable;
[SerializeField]
private float stunAmount = 3;
[SerializeField]
private Transform stampPosition;
[SerializeField]
private float attack1Damage;
[SerializeField]
private float jumpForce = 10;
public float attack1Radius = 5f;
private AttackDetails attackDetails;
private float currentHealth;
private float health = 100;
private GameObject player;
Rigidbody2D rb;
Collider2D detectedObject;
private float timeBetweenStamp = 1f;
private bool isEnemyDetected;
private bool playerJumpAfterHitEnemy;
private bool playerFinishedHisJump;
PlayerMovement playerMovement;
//animation
private void Update()
{
if(rb.velocity.y < 0){
CheckAttackHitBox();
}
ifStampedEnemy();
}
private void Start()
{
rb = GetComponent<Rigidbody2D>();
playerMovement = GetComponent<PlayerMovement>();
currentHealth = health;
player = GameObject.Find("Player");
}
private void CheckAttackHitBox()
{
isEnemyDetected = Physics2D.OverlapCircle(stampPosition.position, attack1Radius, whatIsDamageable);
detectedObject = Physics2D.OverlapCircle(stampPosition.position, attack1Radius, whatIsDamageable);
attackDetails.damageAmount = attack1Damage;
attackDetails.position = transform.position;
attackDetails.stunDamageAmount = stunAmount;
if(detectedObject != null && isEnemyDetected == true){
detectedObject.transform.parent.SendMessage("Damage", attackDetails);
timeBetweenStamp -= Time.deltaTime;
}
if(timeBetweenStamp <=0)
{
isEnemyDetected = false;
timeBetweenStamp = 2f;
}
// sendmeesage func is used to call a specific func in a script of an object
//Instantiate hit particle
}
private void ifStampedEnemy()
{
if(isEnemyDetected)
{
rb.velocity = new Vector2 (rb.velocity.x , jumpForce);
}
}
private void Damage(AttackDetails attackDetails)
{
currentHealth -= attackDetails.damageAmount;
}
private void OnDrawGizmos()
{
Gizmos.DrawWireSphere(stampPosition.position, attack1Radius);
}
}
`
Answer by rh_galaxy · Sep 29, 2020 at 11:40 PM
Your use of timeBetweenStamp will not work since you only count it down when you hit an enemy from above (one frame), it will not reach zero in a predictable way.
And isEnemyDetected will continue to be true until you are falling again, and since you set rb.velocity.y to jumpForce every frame that will never happen - you will fly away.
This could work better, and if you still want a minimum timeBetweenStamp you can add that.
private void Update()
{
if(rb.velocity.y < 0) {
CheckAttackHitBox();
}
}
private void CheckAttackHitBox()
{
detectedObject = Physics2D.OverlapCircle(stampPosition.position, attack1Radius, whatIsDamageable);
if(detectedObject != null)
{
attackDetails.damageAmount = attack1Damage;
attackDetails.position = transform.position;
attackDetails.stunDamageAmount = stunAmount;
detectedObject.transform.parent.SendMessage("Damage", attackDetails);
rb.velocity = new Vector2 (rb.velocity.x , jumpForce);
}
}