Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Question Player Attack Acting Weird

Discussion in 'Scripting' started by HumphreyGames, Nov 20, 2021.

  1. HumphreyGames

    HumphreyGames

    Joined:
    May 5, 2020
    Posts:
    40
    Hi all, sorry if the title isn't very clear, it was hard to sum up what is going on here.

    So basically I have a simple attack script that detects when an enemy enters the swords attack range using "OverLapSphere". It works ok when there is only one enemy, but when there are 2 or more, something really weird happens (see clip below).


    Below are the scripts related to this problem:

    -----Player Attack Script------
    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. public class Sword_Behaviour : MonoBehaviour
    6. {
    7.     [Header("Damage Amount")]
    8.     public float basicCombo_Damage = 100f;
    9.     public float heavy_Damage = 100f;
    10.  
    11.     [Header("Attack Regestering Data")]
    12.     public Transform attackPos;
    13.     public LayerMask enemyMask;
    14.  
    15.     public float attackRange_BasicCombo;
    16.     public float attackRange_HeavyAttack;
    17.  
    18.     public void BasicCombo_CheckForEnemies()
    19.     {
    20.         Collider[] hitEnemies = Physics.OverlapSphere(attackPos.position, attackRange_BasicCombo, enemyMask);
    21.         foreach (Collider enemy in hitEnemies)
    22.         {
    23.             enemy.GetComponent<Health>().TakeDamage(basicCombo_Damage);
    24.         }
    25.     }
    26.  
    27.     public void HeavyAttack_CheckForEnemies()
    28.     {
    29.         Collider[] enemiesInRange = Physics.OverlapSphere(transform.position, attackRange_HeavyAttack, enemyMask);
    30.         foreach (Collider enemy in enemiesInRange)
    31.         {
    32.             enemy.GetComponent<Health>().TakeDamage(heavy_Damage);
    33.         }
    34.     }
    35.  
    36.     private void OnDrawGizmos()
    37.     {
    38.         Gizmos.color = Color.blue;
    39.         Gizmos.DrawWireSphere(attackPos.position, attackRange_BasicCombo);
    40.  
    41.         Gizmos.color = Color.green;
    42.         Gizmos.DrawWireSphere(transform.position, attackRange_HeavyAttack);
    43.     }
    44. }
    -----Enemy Health Script-----
    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. public class Health : MonoBehaviour
    6. {
    7.     public static Health instance;
    8.  
    9.     public float maxHealth = 100f;
    10.     public float currentHealth;
    11.  
    12.     public GameObject player;
    13.  
    14.     [Header("Ragdoll Force")]
    15.     public float ragdollForce_BasicCombo = 30f;
    16.     public float ragdollForce_Heavy = 10f;
    17.  
    18.     private void Start()
    19.     {
    20.         instance = this;
    21.  
    22.         currentHealth = maxHealth;
    23.     }
    24.  
    25.     public void TakeDamage(float amount)
    26.     {
    27.         currentHealth -= amount;
    28.  
    29.         if (currentHealth <= 0)
    30.         {
    31.             Die();
    32.         }
    33.     }
    34.  
    35.     public void Die()
    36.     {
    37.         Ragdoll.instance.ActivateRagdoll();
    38.         Ragdoll.instance.ApplyForce(transform.forward * ragdollForce_BasicCombo);
    39.     }
    40. }
    -----Enemy Ragdoll Script-----

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. public class Ragdoll : MonoBehaviour
    6. {
    7.     public static Ragdoll instance;
    8.  
    9.     Rigidbody[] rigidBodies;
    10.     Animator animator;
    11.     CapsuleCollider capCollider;
    12.  
    13.     private void Start()
    14.     {
    15.         instance = this;
    16.  
    17.         rigidBodies = GetComponentsInChildren<Rigidbody>();
    18.         animator = GetComponent<Animator>();
    19.         capCollider = GetComponent<CapsuleCollider>();
    20.  
    21.         DeactivateRagdoll();
    22.     }
    23.  
    24.     public void DeactivateRagdoll()
    25.     {
    26.         foreach (var rigidbody in rigidBodies)
    27.         {
    28.             rigidbody.isKinematic = true;
    29.         }
    30.         animator.enabled = true;
    31.         capCollider.enabled = true;
    32.     }
    33.  
    34.     public void ActivateRagdoll()
    35.     {
    36.         foreach(var rigidBody in rigidBodies)
    37.         {
    38.             rigidBody.isKinematic = false;
    39.         }
    40.         animator.enabled = false;
    41.         capCollider.enabled = false;
    42.     }
    43.  
    44.     public void ApplyForce(Vector3 force)
    45.     {
    46.         var rigidbody = animator.GetBoneTransform(HumanBodyBones.Hips).GetComponent<Rigidbody>();
    47.         rigidbody.AddForce(force, ForceMode.VelocityChange);
    48.     }
    49. }
    Thanks,
    Josh
     
  2. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    38,517
    These might be your problem... static means there's only one and everybody uses it.

    Instead of accessing a things via the static instance reference, you need to only access things at the actual object instance level, based on who you're smacking with a sword.
     
    HumphreyGames likes this.
  3. HumphreyGames

    HumphreyGames

    Joined:
    May 5, 2020
    Posts:
    40
    Thanks man that worked perfectly. I didn't know that, I guess I just thought it was easier to do it that way. Anyway thanks very much :)
     
    Kurt-Dekker likes this.