Hello, I am making a 2D sidescrolling game, and I want to make critical hit system in game, but I tried few things but it didint really work, does anyone have experience with making a critical hit system for 2d game?
3 Answers
3This is really not enough information to go on. What did you try that didn’t work? What exactly do you want a crit to do that is different from a normal hit?
If you just want some hits to randomly do more damage, you can use Random.value to get a random number.
float critChance = 0.1f;
if(Random.value <= critChance)
{
DoDamage(critDamage);
}
else
{
DoDamage(normalDamage);
}
Hello I tried this code
float critChance = 0.0f;
void IncreaseCritChance(float critInc)
{
critChance += critInc;
//Never let the crit chance go out of range
if(critChance > 100.0f)
{
critChance = 100.0f;
}
}
void DoAttack()
{
float randValue = Random.value;
if(randValue < critChance)
{
CritAttack();
}
else
{
Attack();
}
}
and it didnt work. I want crit system that will make random number from 1% to 100% and make it that when that random number is same or bigger than critchance, for exaple 5% it will do damage x2,and I dont exactly know how to put the crit script into my code.
using System;
using System.Collections;
using System.Collections.Generic;
using System.Security.Cryptography.X509Certificates;
using TMPro;
using UnityEngine;
using UnityEngine.Events;
public class PlayerMovement : MonoBehaviour
{
public Animator animator;
public EssanceManager em;
public Transform attackPoint;
public GameObject popUpPrefab;
public float attackRange = 0.5f;
public int attackDamage = 40;
public float CritDamage = 40 * 2f;
public LayerMask enemyLayers;
public int damage;
public float attackRate = 3f;
float nextAttackTime = 0f;
private float horizontal;
private float speed = 8f;
private float jumpingPower = 16f;
private bool isFacingRight = true;
private bool inAir;
private bool canDash = true;
private bool isDashing;
private float dashingPower = 150f;
private float dashingTime = 0.2f;
private float dashingCooldown = 1f;
private bool doubleJump;
[SerializeField] private Rigidbody2D rb;
[SerializeField] private Transform groundCheck;
[SerializeField] private LayerMask groundLayer;
[SerializeField] private TrailRenderer tr;
void Update()
{
animator.SetBool("IsDashing", isDashing);
animator.SetFloat("Speed", Mathf.Abs(horizontal));
if (isDashing)
{
return;
}
if (Time.time >= nextAttackTime)
{
if (Input.GetKeyDown(KeyCode.Space))
{
Attack();
nextAttackTime = Time.time + 1f / attackRate;
}
}
horizontal = Input.GetAxisRaw("Horizontal");
if(IsGrounded() && !Input.GetKey(KeyCode.W))
{
doubleJump = false;
}
if (Input.GetKeyDown(KeyCode.W))
{
if(IsGrounded() || doubleJump)
{
animator.SetTrigger("isJumping");
rb.velocity = new Vector2(rb.velocity.x, jumpingPower);
doubleJump = !doubleJump;
}
}
if (Input.GetKeyUp(KeyCode.W) && rb.velocity.y > 0f)
{
rb.velocity = new Vector2(rb.velocity.x, rb.velocity.y * .5f);
}
if (Input.GetKeyDown(KeyCode.LeftShift) && canDash)
{
StartCoroutine(Dash());
}
Flip();
}
void Attack()
{
animator.SetTrigger("Attack");
Collider2D[] hitEnemies = Physics2D.OverlapCircleAll(attackPoint.position, attackRange, enemyLayers);
foreach (Collider2D enemy in hitEnemies)
{
Invoke(nameof(DelayPopUps), .5f);
enemy.GetComponent<BansheeHealth>().TakeDamage(attackDamage);
}
}
private void FixedUpdate()
{
if (isDashing)
{
return;
}
else
{
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;
}
void OnDrawGizmosSelected()
{
if (attackPoint == null)
return;
Gizmos.DrawWireSphere(attackPoint.position, attackRange);
}
public void DelayPopUps()
{
GameObject popUp = Instantiate(popUpPrefab, attackPoint.position, Quaternion.identity);
popUp.GetComponentInChildren<TMP_Text>().text = attackDamage.ToString();
}
void OnTriggerEnter2D(Collider2D other)
{
if (other.gameObject.CompareTag("Collectable"))
{
Destroy(other.gameObject);
em.essenceCount++;
}
}
}
Random.value gives you a number between 0 and 1 (inclusive). If you want a number between 0 and 100, you need to use Random.Range.
if(Random.Range(0f, 100f) <= critChance)
You would likely want to check for a crit in your Attack() code. If there is a crit, pass 2*attackDamage into the TakeDamage() function.