public override void OnHit(RaycastHit rh) { if (origin.CanDamage(Character.FromObject(rh.collider.gameObject), allowFriendlyFire, allowSelfDamage)) { // If the target has health, damage it DamageHitbox hitbox = rh.collider.GetComponent <DamageHitbox>(); if (hitbox != null) { // Calculate damage int damageToDeal = damage; if (hitbox.critical) { damageToDeal = Mathf.CeilToInt(damageToDeal * criticalMultiplier); } hitbox.Damage(damageToDeal, origin, type); // Play damage effects } // If the target has physics, knock it around Rigidbody rb = rh.collider.GetComponentInParent <Rigidbody>(); if (rb != null) { rb.AddForceAtPosition(transform.forward * knockback, rh.point, ForceMode.Impulse); // Play knockback effects } base.OnHit(rh); } // Otherwise, ignore and resume normal operation }
public static void PointDamage(GameObject origin, Faction originFaction, GameObject attackedObject, int damage, DamageType cause, bool isSevere) { DamageHitbox hitbox = attackedObject.GetComponent <DamageHitbox>(); // Checks collider gameObject for a damageHitbox script if (hitbox != null) { hitbox.Damage(damage, origin, originFaction, cause, isSevere); } }
public void SingleAttack(Entity attacker, Vector3 position, Vector3 direction) { attackEffects.Invoke(); bool hitSuccessful = false; Character attackingCharacter = attacker as Character; List <Health> alreadyDamaged = new List <Health>(); Collider[] inRange = Physics.OverlapSphere(position, range, detection); for (int i = 0; i < inRange.Length; i++) { Vector3 closestPoint = Explosion.GetColliderPointFromCentre(inRange[i], position); bool inAngle = Vector3.Angle(direction, closestPoint - position) <= angle / 2; if (!inAngle) { continue; } Ray checkRay = new Ray(position, closestPoint - position); bool lineOfSight = Physics.Raycast(checkRay, out RaycastHit hit, range, detection) && hit.collider == inRange[i]; if (!lineOfSight) { continue; } bool canAttack = attackingCharacter == null || attackingCharacter.CanDamage(hit.collider.GetComponent <Character>(), attackFriendlies, false); if (!canAttack) { continue; } hitSuccessful = true; DamageHitbox dh = hit.collider.GetComponent <DamageHitbox>(); if (dh != null && !alreadyDamaged.Contains(dh.healthScript)) { dh.Damage(damage, attacker, type); alreadyDamaged.Add(dh.healthScript); } Rigidbody rb = hit.collider.GetComponentInParent <Rigidbody>(); if (rb != null) { rb.AddForceAtPosition(checkRay.direction * knockback, hit.point, ForceMode.Impulse); } } if (hitSuccessful == true) { hitEffects.Invoke(); } }
public static void PointDamage(GameObject origin, Faction originFaction, GameObject attackedObject, int damage, float criticalMultiplier, DamageType normalCause, DamageType criticalCause) { DamageHitbox hitbox = attackedObject.GetComponent <DamageHitbox>(); // Checks collider gameObject for a damageHitbox script if (hitbox != null) { Debug.Log("Hit"); hitbox.Damage(damage, criticalMultiplier, origin, originFaction, normalCause, criticalCause); } }
/* * // Start is called before the first frame update * void Start() * { * * } * * // Update is called once per frame * void Update() * { * * } */ private void OnTriggerStay(Collider c) { //print("Dealing damage at " + Time.time); DamageHitbox dh = c.GetComponent <DamageHitbox>(); if (dh != null) { //print("Hitbox detected"); dh.Damage(Mathf.RoundToInt(damagePerSecond * Time.deltaTime), gameObject, null, damageType, isSevere); } }
public static void InstantExplosion(GameObject origin, Faction originFaction, Transform explosionOrigin, int damage, float knockback, float blastRadius, float explosionTime, AnimationCurve damageFalloff, AnimationCurve knockbackFalloff, LayerMask blastDetection, DamageType cause, bool isSevere) { List <Health> alreadyDamaged = new List <Health>(); Collider[] affectedObjects = Physics.OverlapSphere(explosionOrigin.position, blastRadius, blastDetection); foreach (Collider c in affectedObjects) { Vector3 targetDirection = c.transform.position - explosionOrigin.position; RaycastHit isVulnerable; if (Physics.Raycast(explosionOrigin.position, targetDirection, out isVulnerable, blastRadius, blastDetection)) { if (isVulnerable.collider == c) { float i = isVulnerable.distance / blastRadius; DamageHitbox hitbox = c.GetComponent <DamageHitbox>(); // Checks collider gameObject for a damageHitbox script if (hitbox != null) { bool undamagedCheck = false; foreach (Health h in alreadyDamaged) { if (h == hitbox.healthScript) { undamagedCheck = true; } } if (undamagedCheck == false) { int d = Mathf.RoundToInt(damage * damageFalloff.Evaluate(i)); hitbox.Damage(d, origin, originFaction, cause, isSevere); Debug.Log("Dealt " + d + " damage to " + hitbox.name + " at " + hitbox.transform.position + "."); alreadyDamaged.Add(hitbox.healthScript); } } Knockback(isVulnerable.collider.gameObject, knockback * knockbackFalloff.Evaluate(i), targetDirection); } } } }
public IEnumerator HitboxTakesDamage() { // Instantiates 'attacker', adds Character script and Faction scriptableObject GameObject o = Object.Instantiate(GameObject.CreatePrimitive(PrimitiveType.Cube), new Vector3(0, 0, -3), Quaternion.identity); Character c = o.AddComponent <Character>(); c.faction = Resources.Load("Factions/Good Guys") as Faction; // Creates 'attacked' gameObject and adds health script GameObject g = Object.Instantiate(GameObject.CreatePrimitive(PrimitiveType.Cube), Vector3.zero, Quaternion.identity); Health h = g.AddComponent <Health>(); int currentHealth = h.values.current; // Saves attacked gameObject's current health // Adds DamageHitbox script to object, and links it to health script DamageHitbox dh = g.AddComponent <DamageHitbox>(); dh.healthScript = h; Debug.Log(h.values.current); Debug.Log(currentHealth); yield return(new WaitForEndOfFrame()); Debug.Log("schlep"); // Deals damage to attacked gameObject's hitbox dh.Damage(5, c, DamageType.Shot); Debug.Log("frank"); yield return(new WaitForEndOfFrame()); Debug.Log("hashbrown"); Debug.Log(h.values.current); Debug.Log(currentHealth); // Checks if attacked object's health has changed Assert.IsTrue(h.values.current != currentHealth); }
public void DoDamage() { _damageHitbox.Damage(); }
public void Detonate(Vector3 centre, Entity origin) { onExplosionStart.Invoke(); Character attacker = origin as Character; List <Health> alreadyDamaged = new List <Health>(); //RaycastHit[] affected = Physics.SphereCastAll(position, blastRadius, Vector3.forward, 0, hitDetection); Collider[] affected = Physics.OverlapSphere(centre, blastRadius, hitDetection); for (int i = 0; i < affected.Length; i++) { // Calculates the closest point and raycast towards it to check that it is not behind cover Vector3 closestPoint = GetColliderPointFromCentre(affected[i], centre); Ray checkRay = new Ray(centre, closestPoint - centre); bool lineOfSight = Physics.Raycast(checkRay, out RaycastHit hit, blastRadius, hitDetection) && hit.collider == affected[i]; if (!lineOfSight) { continue; } // If raycast hits, collider is in the path of the explosion. Check if the object can be attacked by the user bool canAttack = attacker == null || attacker.CanDamage(hit.collider.GetComponent <Character>(), friendlyFire, selfDamage); if (!canAttack) { continue; } // If check is positive, attacker is not restricted from attacking the target (no faction or faction is hostile) float distanceZeroToOne = hit.distance / blastRadius; // If the collider is attached to an object that wasn't already damaged by the explosion DamageHitbox dh = hit.collider.GetComponent <DamageHitbox>(); if (dh != null && !alreadyDamaged.Contains(dh.healthScript)) { float multipliedDamage = damage * damageFalloff.Evaluate(distanceZeroToOne); Debug.Log(multipliedDamage); dh.Damage(Mathf.RoundToInt(multipliedDamage), origin, type); alreadyDamaged.Add(dh.healthScript); } // If the collider is affected by physics, knock it around Rigidbody rb = hit.collider.GetComponentInParent <Rigidbody>(); if (rb != null) { float multipliedKnockback = knockback * knockbackFalloff.Evaluate(distanceZeroToOne); rb.AddForceAtPosition(checkRay.direction * multipliedKnockback, hit.point, ForceMode.Impulse); } } /* * List<Health> alreadyDamaged = new List<Health>(); * List<Rigidbody> alreadyKnockedBack = new List<Rigidbody>(); * Character attacker = origin as Character; * * Collider[] affectedObjects = Physics.OverlapSphere(position, blastRadius, hitDetection); * foreach (Collider c in affectedObjects) * { * Ray check = new Ray(position, c.transform.position - position); * // If a check is successful between the collider and the blast origin * if (Physics.Raycast(check, out RaycastHit hit, blastRadius, hitDetection) && hit.collider == c) * { * // If the collider can be attacked * if (Character.CanDamage(attacker, Character.FromObject(hit.collider.gameObject), friendlyFire, selfDamage)) * { * float distanceFromOrigin = blastRadius / hit.distance; * * // Check if entity can be damaged, and if it hasn't already * DamageHitbox dh = hit.collider.GetComponent<DamageHitbox>(); * if (dh != null && !alreadyDamaged.Contains(dh.healthScript)) * { * int damageToDeal = Mathf.RoundToInt(damage * damageFalloff.Evaluate(distanceFromOrigin)); * dh.Damage(damageToDeal, origin, type); * alreadyDamaged.Add(dh.healthScript); * } * * // Check if entity can be knocked back, and if it hasn't already * Rigidbody rb = hit.collider.GetComponentInParent<Rigidbody>(); * if (rb != null && !alreadyKnockedBack.Contains(rb)) * { * float knockbackToInflict = knockback * knockbackFalloff.Evaluate(distanceFromOrigin); * rb.AddForceAtPosition(check.direction * knockbackToInflict, hit.point, ForceMode.Impulse); * } * } * * * * * * * * * * * } * } */ onExplosionEnd.Invoke(); }