public void FireRPC(CheckFireAction checkFireAction) { if (checkFireAction == CheckFireAction.DontFire) { return; } if (checkFireAction == CheckFireAction.PlayDrySound) { GameManager.Instance.AudioManager.PlayOneShotSound(_drySound, 1, 1, 1, transform.position); return; } // Here, we are sure to fire, so we start by moving the reticle. But only if it's the local player if (_player.isLocalPlayer) { GameManager.Instance.LocalPlayer.MyCrosshair.Destabilize(); } FireEffect(); if (_fireSound != null) { GameManager.Instance.AudioManager.PlayOneShotSound(_fireSound, 1, 1, 1, transform.position); } }
public virtual void Fire(CheckFireAction checkFireAction, Vector3 origin, Vector3 direction) { RaycastHit[] hitInfos = Physics.RaycastAll(origin, direction, _range, LayerMask.GetMask("Default", "BodyPart", "Wood", "Metal", "Grass", "Mine")); Debug.DrawRay(origin, direction, Color.red, 2); int closestHitIndex = -1; if (hitInfos.Length > 0) { for (int i = 0; i < hitInfos.Length; i++) { RaycastHit hitInfo = hitInfos[i]; // We make sure we don't hit something behind us if (Vector3.Angle(hitInfo.transform.position - _player.transform.position, _player.transform.forward) > 90) { continue; } bool hitInfoIsOurselves = false; // We make sure we don't hit ourselves foreach (Rigidbody bodyPart in BodyParts) { if (hitInfo.transform.gameObject == bodyPart.gameObject) { hitInfoIsOurselves = true; continue; } } if (hitInfoIsOurselves) { continue; } if (closestHitIndex == -1) { closestHitIndex = i; } else { float thisDistance = (hitInfo.point - transform.position).magnitude; float closestDistance = (hitInfos[closestHitIndex].point - transform.position).magnitude; if (thisDistance < closestDistance) { closestHitIndex = i; } } } if (closestHitIndex != -1) { RaycastHit hitInfo = hitInfos[closestHitIndex]; Rigidbody rigidbody = hitInfo.transform.GetComponent <Rigidbody>(); if (rigidbody != null) { rigidbody.AddForce(direction * _pushForce); } if (_bullet != null) { Bullet bullet = Instantiate(_bullet, _firePosition.position, Quaternion.identity); //bullet.GetComponent<NetworkIdentity>().AssignClientAuthority(GameManager.Instance.LocalPlayer.connectionToClient); bullet.transform.forward = hitInfo.point - _firePosition.position; bullet.ThrowerIdentifier = _player.netId; NetworkServer.Spawn(bullet.gameObject, GameManager.Instance.LocalPlayer.connectionToClient); } else { // We check if it's a mine SpawnedTool spawnedTool = hitInfo.transform.GetComponent <SpawnedTool>(); bool collidedWithMine = false; if (spawnedTool != null) { spawnedTool.Explode(); collidedWithMine = true; } // We check if it's a destructable Health selfHealth = hitInfo.transform.GetComponent <Health>(); if (selfHealth != null) { selfHealth.TakeDamage(_damage, hitInfo.point, _player.netId); } // This is the health of the parent object of player or that of a state machine AIStateMachine stateMachine = hitInfo.transform.GetComponentInParent <AIStateMachine>(); if (stateMachine != null) { stateMachine.Health.TakeDamage(_damage, hitInfo.point, _player.netId); } Player player = hitInfo.transform.GetComponentInParent <Player>(); if (player != null) { player.Health.TakeDamage(_damage, hitInfo.point, _player.netId); } // We instantiate bullethole (only if we didn't hit a body part) if (_bulletHole != null && hitInfo.transform.gameObject.layer != LayerMask.NameToLayer("BodyPart") && !collidedWithMine) { _player.PlayerShoot.RpcSpawnBulletHole(hitInfo.point + hitInfo.normal / 1000, -hitInfo.normal); } } } } }