/*void Update() * { * gun.LookAt(playerCamera.GetTargetPosition()); * * if (playerScript.Paused) * bulletsLeft = BurstCount; * }*/ // TODO unused, looks like it should go below in the homing firing //WeaponIndicatorScript.PlayerData GetFirstTarget() //{ // var aimedAt = targets.Where(x => x.SinceInCrosshair >= AimingTime ); // return aimedAt.OrderBy( x => Guid.NewGuid() ).First(); //} public void Update() { var actualTargetPosition = playerCamera.GetTargetPosition(); firingDirection = (actualTargetPosition - gun.transform.position).normalized; var gunRotationAngles = Quaternion.FromToRotation(Vector3.forward, firingDirection).eulerAngles; var desiredGunRotation = Quaternion.Euler(gunRotationAngles.x, gunRotationAngles.y, 0); gun.transform.rotation = Quaternion.Slerp(gun.transform.rotation, desiredGunRotation, 1.0f - Mathf.Pow(GunRotationSmoothingSpeed, -GunRotationSmoothingSpeed * Time.deltaTime)); var doReload = false; // Update local position of barrel from recoil foreach (var impulse in GunRecoilThrotter.Update()) { GunRecoilSpring.AddImpulse(impulse); } GunRecoilSpring.Update(); Vector3 barrelLocalPosition = BarrelTransform.localPosition; barrelLocalPosition.z = GunRecoilSpring.CurrentValue; BarrelTransform.localPosition = barrelLocalPosition; // Reload spring foreach (var impulse in ReloaderDelayer.Update()) { ReloaderSpring.AddImpulse(impulse); } ReloaderSpring.Update(); Vector3 reloadLocalPosition = ReloaderTransform.localPosition; reloadLocalPosition.z = ReloaderSpring.CurrentValue; ReloaderTransform.localPosition = reloadLocalPosition; if (playerScript.Paused) { bulletsLeft = BurstCount; } if (networkView.isMine && playerScript.lockMouse && !playerScript.Paused) { cooldownLeft = Mathf.Max(0, cooldownLeft - Time.deltaTime); heat = Mathf.Clamp01(heat - (Time.deltaTime * HeatCooldownScale)); weaponIndicator.CooldownStep = 1 - Math.Min(Math.Max(cooldownLeft - ShotCooldown, 0) / ReloadTime, 1); if (cooldownLeft <= Mathf.Epsilon) { // Shotgun if (Input.GetButton("Alternate Fire")) { OnShotFired(); OnShotgunFired(); // Rail shot if (bulletsLeft == BurstCount && playerCamera.IsZoomedIn) { DoRailShot(); bulletsLeft = 0; cooldownLeft += ReloadTime * 2.7f; var recoilImpulse = -playerCamera.LookingDirection * 2.35f; recoilImpulse *= playerScript.controller.isGrounded ? 25 : 87.5f; recoilImpulse.y *= playerScript.controller.isGrounded ? 0.1f : 0.375f; playerScript.AddRecoil(recoilImpulse); } // Homing/shotgun else { // find homing target(s) var aimedAt = targets.Where(x => x.SinceInCrosshair >= AimingTime).ToArray(); var bulletsShot = bulletsLeft; var first = true; int homingFired = 0; while (bulletsLeft > 0) { if (!aimedAt.Any()) { DoHomingShot(ShotgunSpread, null, 0, first); } else { var pd = aimedAt.OrderBy(x => Guid.NewGuid()).First(); DoHomingShot(ShotgunSpread, pd.Script, Mathf.Clamp01(pd.SinceInCrosshair / AimingTime) * ShotgunHomingSpeed, first); homingFired++; } cooldownLeft += ShotCooldown; first = false; } cooldownLeft += ReloadTime; float lockOnReduction = (float)homingFired / (float)BurstCount; float amountOfLockToRemove = WeaponIndicatorScript.PlayerData.LockStrengthLimitMultiplier * lockOnReduction; for (int i = 0; i < targets.Count; i++) { targets[i].LockStrength -= amountOfLockToRemove; targets[i].ClampStrength(); } var recoilImpulse = -gun.forward * ((float)bulletsShot / BurstCount); recoilImpulse *= playerScript.controller.isGrounded ? 25 : 87.5f; recoilImpulse.y *= playerScript.controller.isGrounded ? 0.1f : 0.375f; playerScript.AddRecoil(recoilImpulse); float cosmeticAmount = (float)bulletsShot / (float)BurstCount; playerCamera.AddGunShotImpulse(Mathf.Lerp(0.0f, 2.0f, cosmeticAmount)); AddGunImpulse(cosmeticAmount); } //cannonChargeCountdown = CannonChargeTime; } // Burst else if (Input.GetButton("Fire")) // burst fire { //OnShotFired(); DoShot(BurstSpread); cooldownLeft += CurrentShotCooldown; } if (Input.GetButton("Reload") || bulletsLeft <= 0) { doReload = true; } } if (Input.GetButtonUp("Fire")) { doReload = true; } if (doReload && bulletsLeft != BurstCount) { cooldownLeft += ReloadTime * (float)(BurstCount - bulletsLeft) / (float)BurstCount; bulletsLeft = BurstCount; if (GlobalSoundsScript.soundEnabled) { reloadSound.Play(); } AddReloadImpulse(); } TestScreenSpaceLockTargets(); CheckTargets(); // Update weapon indicator bullets count. Kind of hacky because // bullet availability is not tracked like you might expect it to // be. weaponIndicator.BulletCapacity = BurstCount; if (bulletsLeft == BurstCount && cooldownLeft >= Mathf.Epsilon) { weaponIndicator.BulletsAvailable = 0; } else if (cooldownLeft > Mathf.Epsilon && weaponIndicator.BulletsAvailable < bulletsLeft) { // Do nothing, probably reloading } else { weaponIndicator.BulletsAvailable = bulletsLeft; } } }
public void LateUpdate() { if (!mainCamera) { return; } if (player.Paused && mainCamera != null) { mainCamera.transform.localPosition = new Vector3(-85.77416f, 32.8305f, -69.88891f); mainCamera.transform.localRotation = Quaternion.Euler(16.48679f, 21.83607f, 6.487632f); return; } if (player.networkView.isMine) { // Update inferred position and velocity Vector3 newPosition = player.transform.position; Vector3 newVelocity = (newPosition - LastInferredBodyPosition) / Time.deltaTime; Vector3 velocityDelta = newVelocity - LastInferredVelocity; LastInferredVelocity = newVelocity; LastInferredBodyPosition = newPosition; AddYSpringImpulse(velocityDelta.y); YSpring.Update(); // Clamp magnitude to prevent camera from clipping through ground on hard landings YSpring.CurrentValue = Mathf.Clamp(YSpring.CurrentValue, -4f, 4f); if (IsExteriorView) { BarrelFirstPersonOffsetTransform.localPosition = Vector3.zero; } else { // Values between 0.3f and 0.8f seem to look best for scaling the gun offset Y. BarrelFirstPersonOffsetTransform.localPosition = new Vector3(0f, YSpring.CurrentValue * 0.3f, 0f); } ViewBobSpring.Update(); // Higher delay time when the camera is further from the gun QueuedScreenRecoils.DelayTime = IsExteriorView ? 0.071f : 0.048f; //QueuedScreenRecoils.DelayTime = 0.06f; // Remove stuff from the lag queue and put it in the actual spring foreach (var eulerAngles in QueuedScreenRecoils.Update()) { CosmeticSpring.AddImpulse(eulerAngles); } CosmeticSpring.Update(); if (Input.GetButtonDown("ToggleCameraSmoothing")) { HasSmoothedRotation = !HasSmoothedRotation; } if (Input.GetButtonDown("ToggleRaycastCrosshair")) { UsesRaycastCrosshair = !UsesRaycastCrosshair; } // Smooth changes in base field of view (if player adjusts FOV, we // want it to be a slower smoothing than zooming in/out) SmoothedBaseFieldOfView = Mathf.Lerp(SmoothedBaseFieldOfView, BaseFieldOfView, 1.0f - Mathf.Pow(0.0001f, Time.deltaTime)); // Interpolate field of view, set on main camera if necessary SmoothedFieldOfView = Mathf.Lerp(SmoothedFieldOfView, DesiredFieldOfView, 1.0f - Mathf.Pow(0.000001f, Time.deltaTime)); if (mainCamera != null) { if (!Mathf.Approximately(mainCamera.fieldOfView, SmoothedFieldOfView)) { mainCamera.fieldOfView = SmoothedFieldOfView; } } // Update and smooth view position SmoothedViewOffset = Vector3.Lerp(SmoothedViewOffset, DesiredViewOffset, 1.0f - Mathf.Pow(0.00001f, Time.deltaTime)); transform.localPosition = SmoothedViewOffset; // TODO we need smarter handling for toggilng smoothing and first/third person at the same time if (HasSmoothedRotation && IsExteriorView) { // TODO make a nicer interface for goofy power curve var amt = (float)Math.Pow(0.0000000000001, Time.deltaTime); actualCameraRotation = Quaternion.Slerp(actualCameraRotation, transform.rotation, 1.0f - amt); } else { actualCameraRotation = transform.rotation; } Vector3 scaledLocalPosition = Vector3.Scale(transform.localPosition, transform.lossyScale); Vector3 direction = actualCameraRotation * scaledLocalPosition; Vector3 cameraPosition = transform.parent.position + direction; // Modify Y for spring cameraPosition.y += YSpring.CurrentValue; // We don't want to use view bob when zoomed in: we want the // reticule to be very responsive. Quaternion usedViewBob = Quaternion.Lerp( ViewBobSpring.CurrentValue, Quaternion.identity, ZoomedAmount); // TODO can mainCamera be null here? if (mainCamera != null) { mainCamera.transform.position = cameraPosition; mainCamera.transform.rotation = actualCameraRotation * usedViewBob * CosmeticSpring.CurrentValue; } var rawCrosshairPosition = GetCrosshairPosition(); SmoothedCrosshairPosition = Vector2.Lerp(SmoothedCrosshairPosition, rawCrosshairPosition, 1.0f - Mathf.Pow(CrosshairSmoothingSpeed, -CrosshairSmoothingSpeed * Time.deltaTime)); Camera.main.GetComponent <WeaponIndicatorScript>() .CrosshairPosition = SmoothedCrosshairPosition; } }