private void OnTriggerEnter(Collider other) { if (!_isAttacking || !_isScanning) { return; } if (Character != null && other.gameObject == Character.gameObject) { return; } var shield = BulletShield.Get(other.gameObject); if (shield != null) { return; } var part = other.GetComponent <BodyPartHealth>(); var obj = (part == null || part.Target == null) ? other.gameObject : part.Target.gameObject; if (_receptors.Contains(obj)) { return; } _receptors.Add(obj); var normal = (Character.transform.position - obj.transform.position).normalized; HitType type; switch (Type) { case WeaponType.Pistol: type = HitType.PistolMelee; break; case WeaponType.Rifle: type = HitType.RifleMelee; break; case WeaponType.Shotgun: type = HitType.ShotgunMelee; break; case WeaponType.Sniper: type = HitType.SniperMelee; break; case WeaponType.Fist: type = HitType.Fist; break; case WeaponType.Machete: type = HitType.Machete; break; default: type = HitType.Fist; Debug.Assert(false, "Invalid melee type"); break; } var hit = new Hit(other.ClosestPointOnBounds(transform.position), normal, Damage, Character.gameObject, other.gameObject, type, DamageResponseWaitTime); other.SendMessage("OnHit", hit, SendMessageOptions.DontRequireReceiver); for (int i = 0; i < _listeners.Length; i++) { _listeners[i].OnMeleeHit(); } }
/// <summary> /// Finds an object and a hit position a bullet would hit if fired. Checks if it is a friend. /// </summary> public RaycastHit Raycast(Vector3 origin, Vector3 direction, out bool isFriend, bool friendCheck) { RaycastHit closestHit = new RaycastHit(); float closestDistance = Distance * 10; var minDistance = 0f; if (_isUsingCustomRaycast) { minDistance = Vector3.Distance(Origin, RaycastOrigin); } if (minDistance > 0.5f) { minDistance -= 0.5f; } isFriend = false; var count = Physics.RaycastNonAlloc(origin, direction, _hits, Distance); for (int i = 0; i < count; i++) { var hit = _hits[i]; if (Character != null && Util.InHiearchyOf(hit.collider.gameObject, Character.gameObject)) { continue; } if (hit.distance < closestDistance && hit.distance > minDistance) { var isOk = true; var isShield = false; if (hit.collider.isTrigger) { if (BodyPartHealth.Contains(hit.collider.gameObject)) { isOk = true; } else { var shield = BulletShield.Get(hit.collider.gameObject); if (shield != null) { if (Vector3.Dot(shield.transform.forward, hit.normal) >= -0.2f) { isOk = true; isShield = true; } else { isOk = false; } } else { isOk = false; } } } else { var health = CharacterHealth.Get(hit.collider.gameObject); if (health != null) { isOk = health.IsRegisteringHits; } } if (isOk) { if (!isShield && (_isIgnoringSelf || _hasFireCondition) && friendCheck) { var root = getHealthTarget(hit.collider.gameObject); if (root != null) { if (_isIgnoringSelf && Character != null && root == Character.gameObject) { isFriend = true; } else if (_hasFireCondition) { var actor = Actors.Get(root); if (actor != null) { isFriend = actor.Side == _fireConditionSide; } else { isFriend = false; } } else { isFriend = false; } } else { isFriend = false; } } closestHit = hit; closestDistance = hit.distance; } } } return(closestHit); }