protected IEnumerator RemoteFiringEffects() { while (isRemotelyFiring) { Debug.Log("RemoteFiringEffects"); // fire dummy shots straight forward along barrel Vector3 targetPoint = barrelTransform.forward * 1000; RaycastHitDetails raycastTracerDetails = Fire_HitscanWeaponTracer(targetPoint); // fire effects based on raycastTracerDetails // ------------ local firing procedure: // if we hit, then fire a ray effect playing hitsound on hit if (raycastTracerDetails.hasHealth && raycastTracerDetails.validTarget) { FireHitscanRoundEffect(raycastTracerDetails.worldHitPoint); } // if we miss, then fire a ray effect playing missound on hit else if (!raycastTracerDetails.hasHealth && raycastTracerDetails.validTarget) { FireHitscanRoundEffectMiss(raycastTracerDetails.worldHitPoint); } // if valid target is null, then fire a ray effect with no impact else { FireHitscanRoundEffectNoValidTarget(raycastTracerDetails.worldHitPoint); } // AnimatorSetTriggerNetwork(primaryFireAnimatorTriggerName); Debug.Log("RemoteFiringEffects done"); yield return(new WaitForSeconds(fireRate)); } }
// this is the true shot that we are firing at the enemy // fire the ray, determine the world, local protected RaycastHitDetails Fire_HitscanWeaponTracer(Vector3 targetPoint) { // fire a ray from the barrel transform to the targetpoint Vector3 startPos = barrelTransform.position; Ray ray = new Ray(startPos, targetPoint - startPos); RaycastHitDetails raycastHitDetails = FindClosestRaycastHitDetails(ray, targetPoint); // we now have our hit details, return themmuzzleFlashChildOfBarrel return(raycastHitDetails); }
protected RaycastHitDetails FindClosestRaycastHitDetails(Ray ray, Vector3 targetPoint) { RaycastHitDetails raycastHitDetails = new RaycastHitDetails(targetPoint, Vector3.zero, null, false, false);; //RaycastHit[] hits = Physics.RaycastAll(ray); // if (PhysXRaycast.Fire(sensorStartPos, transform.forward, hit, sensorLength, sensorLayerMask, myRb.vehicleId)) { Transform closestHit = null; float distance = 0; Vector3 hitPoint = Vector3.zero; PhysXRaycastHit hitPhysX = PhysXRaycast.GetRaycastHit(); if (PhysXRaycast.Fire(ray.origin, ray.direction, hitPhysX, 999, raycastLayers, rigidbodyVehicleId)) { closestHit = hitPhysX.transform; distance = hitPhysX.distance; hitPoint = hitPhysX.point; // get local hitpoint Vector3 localHitPoint = closestHit.root.InverseTransformPoint(hitPoint); // the health script exists if (hitPhysX.transform.root.GetComponent <VehicleHealthManager>() != null) { raycastHitDetails = new RaycastHitDetails(hitPoint, localHitPoint, closestHit, true, true); } else { raycastHitDetails = new RaycastHitDetails(hitPoint, localHitPoint, closestHit, false, true); } } PhysXRaycast.ReleaseRaycastHit(hitPhysX); return(raycastHitDetails); }
public override void Fire(Vector3 targetPoint) { /*if (gunnerPhotonView.IsMine && !isRemotelyFiring && HasAmmoToShoot()) * { * * }*/ /* * if (!CanFire() && gunnerPhotonView.IsMine) * { * SetIsRemotelyFiring(false); * CeaseFire(); * }*/ if (base.CanFire() && gunnerPhotonView.IsMine && CanFire()) { timeSinceLastFire = 0; targetPoint = CalculateFireDeviation(targetPoint, projectileDeviationDegrees); currentCooldown = fireRate; UseAmmo(ammoPerShot); float distanceMultiplier = CalculateDamageMultiplierCurve(Vector3.Distance(barrelTransform.position, targetPoint)); // define weapon damage details if (!isRemotelyFiring) { //create beam localFirstFire = true; CreateBeam(); SetIsRemotelyFiring(true); } else { localFirstFire = false; } if (!HasAmmoToShoot() && !isRecharging) { // StartCoroutine(DoBonusRecharge(extraRechargeTimeOnDepletion)); // Debug.Log("cease fire"); CeaseFire(); } else { RaycastHitDetails raycastTracerDetails = Fire_HitscanWeaponTracer(targetPoint); // if the raycast tracer details health field is not null, then damage em if (raycastTracerDetails.hasHealth) { WeaponDamageDetails weaponDamageDetails = new WeaponDamageDetails(myNickName, myPlayerId, myTeamId, damageType, baseDamage * distanceMultiplier, raycastTracerDetails.localHitPoint); raycastTracerDetails.hitTransform.gameObject.GetComponentInParent <VehicleHealthManager>() .TakeDamage(weaponDamageDetails); } // do the fire effect on our end // ------------ local firing procedure: // if we hit, then fire a ray effect playing hitsound on hit if (raycastTracerDetails.hasHealth && raycastTracerDetails.validTarget) { FireBeamRoundEffectHit(raycastTracerDetails.worldHitPoint); } // if we miss, then fire a ray effect playing missound on hit else if (!raycastTracerDetails.hasHealth && raycastTracerDetails.validTarget) { FireBeamRoundEffectMiss(raycastTracerDetails.worldHitPoint); } // ----------- remote firing procedure: // if optimisations are not enabled, for all other players: // if corrections are applied and we hit a target with health then fire a ray using FireHitscanRoundEffectCorrected, playing the hitsound on hit if (raycastTracerDetails.hasHealth && raycastTracerDetails.validTarget) { int hitTeamId = raycastTracerDetails.hitTransform.GetComponentInParent <NetworkPlayerVehicle>() .teamId; weaponPhotonView.RPC(nameof(FireBeamRoundEffect_RPC), RpcTarget.Others, true, raycastTracerDetails.worldHitPoint, true, raycastTracerDetails.localHitPoint, hitTeamId); } else if (raycastTracerDetails.validTarget) { weaponPhotonView.RPC(nameof(FireBeamRoundEffect_RPC), RpcTarget.Others, true, raycastTracerDetails.worldHitPoint, false, raycastTracerDetails.localHitPoint, 0); } else { weaponPhotonView.RPC(nameof(FireBeamRoundEffect_RPC), RpcTarget.Others, false, raycastTracerDetails.worldHitPoint, false, raycastTracerDetails.localHitPoint, 0); } } } // now deal with beam effects if (beam != null && gunnerPhotonView.IsMine) { if (localFirstFire && !instantBeam) { // calculate target point interpolated along targetPoint - barrelEndMuzzleTransform.position direction vector by value timeSinceLastShot / maxLerpTime ShotBeamAtPointFirstFireLerp(targetPoint); } else { ShootBeamInDir(barrelEndMuzzleTransform.position, (targetPoint - barrelEndMuzzleTransform.position)); } } }
// Start is called before the first frame update // ---------------------- COPY THESE FUNCTIONS FOR EACH CHILD CLASS --------------------------------// // ---------------------- RPCs DO NOT INHERIT FROM PARENT ------------------------------------------// // method called by weaponController // we need a new version of this for every child class, otherwise the top level RPC will be called public override void Fire(Vector3 targetPoint) { if (CanFire() && gunnerPhotonView.IsMine) { targetPoint = CalculateFireDeviation(targetPoint, projectileDeviationDegrees); currentCooldown = fireRate; UseAmmo(ammoPerShot); float distanceMultiplier = CalculateDamageMultiplierCurve(Vector3.Distance(barrelTransform.position, targetPoint)); // define weapon damage details // now fire the original true round on the host's end // this is the shot that deals damage // this shot also returns the hit transform of what we hit // depending on if useTracerHitCorrection is enabled, call either of the FireHitscanRoundEffect rpcs RaycastHitDetails raycastTracerDetails = Fire_HitscanWeaponTracer(targetPoint); // if the raycast tracer details health field is not null, then damage em if (raycastTracerDetails.hasHealth) { WeaponDamageDetails weaponDamageDetails = new WeaponDamageDetails(myNickName, myPlayerId, myTeamId, damageType, baseDamage * distanceMultiplier, raycastTracerDetails.localHitPoint); raycastTracerDetails.hitTransform.gameObject.GetComponentInParent <VehicleHealthManager>().TakeDamage(weaponDamageDetails); // var bh = Instantiate(bulletHoles[0],raycastTracerDetails.worldHitPoint, Quaternion.Euler(raycastTracerDetails.normalAngle * 360)); //bh.transform.rotation.SetEulerAngles(raycastTracerDetails.hitTransform.rotation.eulerAngles); // bh.transform.SetParent(raycastTracerDetails.hitTransform.gameObject.transform, true); // Debug.Log("aaaaaaaaaaa" + raycastTracerDetails.normalAngle * 360) ; // Debug.Log(bh.transform.rotation.eulerAngles); } // do the fire effect on our end // ------------ local firing procedure: // if we hit, then fire a ray effect playing hitsound on hit if (raycastTracerDetails.hasHealth && raycastTracerDetails.validTarget) { FireHitscanRoundEffect(raycastTracerDetails.worldHitPoint); } // if we miss, then fire a ray effect playing missound on hit else if (!raycastTracerDetails.hasHealth && raycastTracerDetails.validTarget) { FireHitscanRoundEffectMiss(raycastTracerDetails.worldHitPoint); } // if valid target is null, then fire a ray effect with no impact else { FireHitscanRoundEffectNoValidTarget(raycastTracerDetails.worldHitPoint); } // do camera shake ShakeCameras(cameraShakeAmplitude, cameraShakeDuration); shakeTimerCur = 0; // ----------- remote firing procedure: // if optimisations are not enabled, for all other players: if (!useRapidFireOptimisation) { // if corrections are applied and we hit a target with health then fire a ray using FireHitscanRoundEffectCorrected, playing the hitsound on hit if (raycastTracerDetails.hasHealth && raycastTracerDetails.validTarget && useTracerHitCorrection) { int hitTeamId = raycastTracerDetails.hitTransform.GetComponentInParent <NetworkPlayerVehicle>().teamId; weaponPhotonView.RPC(nameof(FireHitscanRoundEffectCorrected), RpcTarget.Others, raycastTracerDetails.localHitPoint, hitTeamId); } // if corrections are not applied and we hit a target, then fire a ray usig FireHitscanRoundEffect, playing hitsound on hit else if (raycastTracerDetails.hasHealth && raycastTracerDetails.validTarget && !useTracerHitCorrection) { weaponPhotonView.RPC(nameof(FireHitscanRoundEffect), RpcTarget.Others, raycastTracerDetails.worldHitPoint); } // if we hit something without health, then fire effect at hitpoint playing missound else if (!raycastTracerDetails.hasHealth && raycastTracerDetails.validTarget) { weaponPhotonView.RPC(nameof(FireHitscanRoundEffectMiss), RpcTarget.Others, raycastTracerDetails.worldHitPoint); } // if we hit no valid target (ie we hit the air), then just fire effect at hitpoint and instantiate no impact else { weaponPhotonView.RPC(nameof(FireHitscanRoundEffectNoValidTarget), RpcTarget.Others, targetPoint); } } // if optimisations are enabled, then get the other clients to start firing pretend shots // this is useful for very rapid fire weapons where we don't really care where the bullets graphically go if (useRapidFireOptimisation) { // instantiate relevant hit impact on vehicle if (raycastTracerDetails.hasHealth && raycastTracerDetails.validTarget && useTracerHitCorrection) { int hitTeamId = raycastTracerDetails.hitTransform.GetComponentInParent <NetworkPlayerVehicle>().teamId; weaponPhotonView.RPC(nameof(FireHitscanCorrectedImpact), RpcTarget.Others, raycastTracerDetails.localHitPoint, hitTeamId); } // this bool is synchronised via rpc on cooldown // the fire effects will fire the gun graphically in its current direction as long as it is active, causing no actual damage SetIsRemotelyFiring(true); // now that this is enabled, the guest will just fire and look after itself } } }
// Start is called before the first frame update // ---------------------- COPY THESE FUNCTIONS FOR EACH CHILD CLASS --------------------------------// // ---------------------- RPCs DO NOT INHERIT FROM PARENT ------------------------------------------// // method called by weaponController // we need a new version of this for every child class, otherwise the top level RPC will be called public override void Fire(Vector3 targetPoint) { if (CanFire() && gunnerPhotonView.IsMine) { ShakeCameras(cameraShakeAmplitude, cameraShakeDuration); targetPoint = CalculateFireDeviation(targetPoint, projectileDeviationDegrees); currentCooldown = fireRate; UseAmmo(ammoPerShot); float distanceMultiplier = CalculateDamageMultiplierCurve(Vector3.Distance(barrelTransform.position, targetPoint)); // define weapon damage details // now fire the original true round on the host's end // this is the shot that deals damage // this shot also returns the hit transform of what we hit // depending on if useTracerHitCorrection is enabled, call either of the FireHitscanRoundEffect rpcs RaycastHitDetails raycastTracerDetails = Fire_HitscanWeaponTracer(targetPoint); // if the raycast tracer details health field is not null, then damage em if (raycastTracerDetails.hasHealth) { WeaponDamageDetails weaponDamageDetails = new WeaponDamageDetails(myNickName, myPlayerId, myTeamId, damageType, baseDamage * distanceMultiplier, raycastTracerDetails.localHitPoint); raycastTracerDetails.hitTransform.gameObject.GetComponentInParent <VehicleHealthManager>().TakeDamage(weaponDamageDetails); } // do the fire effect on our end // ------------ local firing procedure: // if we hit, then fire a ray effect playing hitsound on hit if (raycastTracerDetails.hasHealth && raycastTracerDetails.validTarget) { FireHitscanRoundEffect(raycastTracerDetails.worldHitPoint); } // if we miss, then fire a ray effect playing missound on hit else if (!raycastTracerDetails.hasHealth && raycastTracerDetails.validTarget) { FireHitscanRoundEffectMiss(raycastTracerDetails.worldHitPoint); } // if valid target is null, then fire a ray effect with no impact else { FireHitscanRoundEffectNoValidTarget(raycastTracerDetails.worldHitPoint); } // do camera shake ShakeCameras(cameraShakeAmplitude, cameraShakeDuration); shakeTimerCur = 0; // ----------- remote firing procedure: // if optimisations are not enabled, for all other players: // if corrections are applied and we hit a target with health then fire a ray using FireHitscanRoundEffectCorrected, playing the hitsound on hit if (raycastTracerDetails.hasHealth && raycastTracerDetails.validTarget && useTracerHitCorrection) { int hitTeamId = raycastTracerDetails.hitTransform.GetComponentInParent <NetworkPlayerVehicle>().teamId; weaponPhotonView.RPC(nameof(FireHitscanRoundEffectCorrected), RpcTarget.Others, raycastTracerDetails.localHitPoint, hitTeamId); } // if corrections are not applied and we hit a target, then fire a ray usig FireHitscanRoundEffect, playing hitsound on hit else if (raycastTracerDetails.hasHealth && raycastTracerDetails.validTarget && !useTracerHitCorrection) { weaponPhotonView.RPC(nameof(FireHitscanRoundEffect), RpcTarget.Others, raycastTracerDetails.worldHitPoint); } // if we hit something without health, then fire effect at hitpoint playing missound else if (!raycastTracerDetails.hasHealth && raycastTracerDetails.validTarget) { weaponPhotonView.RPC(nameof(FireHitscanRoundEffectMiss), RpcTarget.Others, raycastTracerDetails.worldHitPoint); } // if we hit no valid target (ie we hit the air), then just fire effect at hitpoint and instantiate no impact else { weaponPhotonView.RPC(nameof(FireHitscanRoundEffectNoValidTarget), RpcTarget.Others, targetPoint); } } }