I'm making my first game in unity and I'm trying to make a simple 2D platformer combat game. I got the movement and dashing to work and now I want to use dashing as a way to fight. In my player script I have a variable "isDashing" which is set to true after the player presses "left shift" aka dashes. To use dashing also as combat mechanic I used a public bool
public bool touchingEnemy()
{
return Physics2D.OverlapCircle(damageReach.position, reach, enemyLayer);
}
to detect if the player is colliding with the enemy. And then in my enemy script I reference the two variables and if there true I reduce the enemy's health. This is done in the Update() void. The problem however, is that because it's in the update It get's triggered multiple times. I couldn't figure out how to damage the enemy only once. Here are the full scripts if you need them. I know they're pretty messy but It's my first time coding and actual game.
**Player's script:**
using UnityEngine;
using System.Collections;
public class PlayerMovement : MonoBehaviour
{
private float horizontal;
private float speed = 8f;
private float jumpingPower = 16f;
private bool isFacingRight = true;
private bool canDash = true;
public bool isDashing;
private float dashingPower = 48f;
private float dashingTime = 0.1f;
private float dashingCooldown = 1f;
[SerializeField] private Rigidbody2D rb;
[SerializeField] private Transform groundCheck;
[SerializeField] private Transform damageReach;
[SerializeField] private float reach;
[SerializeField] private LayerMask groundLayer;
[SerializeField] private LayerMask enemyLayer;
[SerializeField] private TrailRenderer tr;
void Update()
{
if (isDashing)
{
return;
}
horizontal = Input.GetAxisRaw("Horizontal");
if (Input.GetButtonDown("Jump") && IsGrounded())
{
rb.velocity = new Vector2(rb.velocity.x, jumpingPower);
}
if (Input.GetButtonUp("Jump") && rb.velocity.y > 0f)
{
rb.velocity = new Vector2(rb.velocity.x, rb.velocity.y * 0.5f);
}
if (Input.GetKeyDown(KeyCode.LeftShift) && canDash)
{
StartCoroutine(Dash());
}
Flip();
}
private void FixedUpdate()
{
if (isDashing)
{
return;
}
rb.velocity = new Vector2(horizontal * speed, rb.velocity.y);
}
private bool IsGrounded()
{
return Physics2D.OverlapCircle(groundCheck.position, 0.2f, groundLayer);
}
private void Flip()
{
if (isFacingRight && horizontal < 0f || !isFacingRight && horizontal > 0f)
{
isFacingRight = !isFacingRight;
Vector3 localScale = transform.localScale;
localScale.x *= -1f;
transform.localScale = localScale;
}
}
private IEnumerator Dash()
{
canDash = false;
isDashing = true;
float originalGravity = rb.gravityScale;
rb.gravityScale = 0f;
rb.velocity = new Vector2(transform.localScale.x * dashingPower, 0f);
tr.emitting = true;
yield return new WaitForSeconds(dashingTime);
tr.emitting = false;
rb.gravityScale = originalGravity;
isDashing = false;
yield return new WaitForSeconds(dashingCooldown);
canDash = true;
}
public bool touchingEnemy()
{
return Physics2D.OverlapCircle(damageReach.position, reach, enemyLayer);
}
}
**Enemy's script**
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class TakeDamage_Enemy : MonoBehaviour
{
[SerializeField] private float enemyHealth;
private bool isDead;
[SerializeField] private GameObject deathFX;
[SerializeField] GameObject enemy;
[SerializeField] private bool isPlayerDashing;
// Start is called before the first frame update
void Start()
{
Mathf.Clamp(enemyHealth, 0, 20);
GameObject player = GameObject.FindGameObjectWithTag("Player");
Physics2D.IgnoreCollision(player.GetComponent(), GetComponent());
}
// Update is called once per frame
void FixedUpdate()
{
isPlayerDashing = GameObject.Find("Player").GetComponent().isDashing;
if(isPlayerDashing && GameObject.Find("Player").GetComponent().touchingEnemy())
{
enemyHealth -= 20;
enemy.GetComponent().color = new Color (255, 18, 18, 1);
}
if(enemyHealth == 0)
{
Dead();
}
}
private void Dead()
{
Destroy(enemy);
}
public void OnDestroy()
{
Instantiate(deathFX, transform.position, Quaternion.identity);
}
}
↧