using UnityEngine; using System.Collections; using System.Collections.Generic; using GameKitController.Audio; using UnityEngine.UI; public class vehicleWeaponSystem : MonoBehaviour { public bool weaponsEnabled = true; public bool weaponsActivate; public AudioSource weaponsEffectsSource; public AudioClip outOfAmmo; public AudioElement outOfAmmoAudioElement; public LayerMask layer; public LayerMask targetForScorchLayer; public bool useCustomIgnoreTags; public List customTagsToIgnoreList = new List (); public float minimumX = 25; public float maximumX = 315; public float minimumY = 360; public float maximumY = 360; public bool hasBaseRotation = true; public GameObject mainVehicleWeaponsGameObject; public GameObject baseX; public GameObject baseY; public Transform weaponLookDirection; public int weaponsSlotsAmount; public float minSwipeDist = 20; public bool projectilesPoolEnabled = true; public int maxAmountOfPoolElementsOnWeapon = 30; public bool reloading; public bool aimingCorrectly; public List weapons = new List (); public GameObject vehicle; vehicleWeapons currentWeapon; bool currentWeaponLocated; public Transform noInputWeaponDirection; public bool canRotateWeaponsWithNoCameraInput; public float noCameraInputWeaponRotationSpeed; public float weaponCursorMovementSpeed; public float weaponCursorHorizontalLimit; public float weaponCursorVerticalLimit; public LayerMask weaponCursorRaycastLayer; public bool useWeaponCursorScreenLimit; public float circleCameraLimit2_5d = 7; public Vector2 currentLockedCameraCursorSize; bool weaponCursorDisabled; float horizontaLimit; float verticalLimit; public float baseXRotationSpeed = 10; public float baseYRotationSpeed = 10; public string mainDecalManagerName = "Decal Manager"; public string [] impactDecalList; decalManager impactDecalManager; List locatedEnemies = new List (); List shells = new List (); float rotationY = 0; float rotationX = 0; float lastShoot = 0; bool shellsOnSceneToRemove; float lastTimeFired; float destroyShellsTimer = 0; public int choosedWeapon; public int weaponIndexToStart; public string currentWeaponName; public bool aimingHomingProjectile; bool usingLaser; bool launchingProjectile; bool objectiveFound; bool touchPlatform; bool touchEnabled; bool touching; public bool shootingPreviously; GameObject currentProjectile; projectileSystem currentProjectileSystem; Rigidbody currentProjectileRigidbody; GameObject closestEnemy; Transform currentWeaponDirection; Transform vehicleCameraTransform; Vector3 baseXTargetRotation; Vector3 baseYTargetRotation; Quaternion noInputWeaponDirectionTargetRotation; Vector2 axisValues; float horizontalMouse; float verticalMouse; Vector2 lookAngle; public vehicleCameraController vehicleCameraManager; public Rigidbody mainRigidbody; public inputActionManager actionManager; public vehicleHUDManager hudManager; public launchTrayectory parable; public vehicleGravityControl gravityControlManager; public Transform vehicleCameraManagerTransform; bool gravityControlManagerLocated; bool mainRigidbodyLocated; bool hudManagerLocated; bool vehicleCameraManagerLocated; GKCSimpleRiderSystem mainGKCSimpleRiderSystem; bool mainGKCSimpleRiderSystemLocated; RaycastHit hit; Ray ray; GameObject parableGameObject; Touch currentTouch; Vector3 swipeStartPos; Vector3 aimedZone; GameObject currentDriver; Transform mainCameraTransform; Vector3 currentMainCameraPosition; Camera mainCamera; playerCamera playerCameraManager; playerHUDManager vehicleHUDInfoManager; playerInputManager playerInput; bool weaponsPaused; Coroutine muzzleFlashCoroutine; bool currentCameraUseRotationInput; RectTransform weaponCursor; Vector3 pointTargetPosition; Vector3 projectileDirectionToLook; RawImage weaponCursorImage; GameObject currentDetectedSurface; GameObject currentTargetDetected; Transform currentTargetToAim; float posX, posY; Ray newRay; Vector2 newCameraPosition; Vector3 targetDirection; Quaternion targetRotation; bool playerCameraIsLocked; bool playerMovingOn3dWorld; bool usingCameraWithNoInput; Vector3 homingProjectileRayPosition; Vector3 autoShootRayPosition; bool pointTargetPositionFound; bool pointTargetPositionSurfaceFound; GameObject currentPointTargetSurfaceFound; GameObject previousPointTargetSurfaceFound; playerHUDManager.vehicleHUDElements currentHUDElements; bool usingCustomReticle; Vector3 screenPoint; bool targetOnScreen; bool usingScreenSpaceCamera; vehicleLaser currentVehicleLaser; float screenWidth; float screenHeight; GameObject shellClone; AudioElement newClipToShell = new AudioElement (); weaponShellSystem newWeaponShellSystem; GameObject muzzleParticlesClone; Transform currentProjectilePosition; bool componentsInitialized; bool autoShootOnTagActive; GameObject previousTargetDetectedOnAutoShootOnTag; GameObject currentTargetDetectedOnAutoShootOnTag; Transform currentVehicleCameraTransform; private void InitializeAudioElements () { foreach (var weaponSettings in weapons) weaponSettings.InitializeAudioElements (); if (outOfAmmo != null) { outOfAmmoAudioElement.clip = outOfAmmo; } } void Start () { InitializeAudioElements (); if (!weaponsEnabled) { return; } initializeComponents (); } void initializeComponents () { if (componentsInitialized) { return; } if (parable != null) { parableGameObject = parable.gameObject; } // Check the current type of platform touchPlatform = touchJoystick.checkTouchPlatform (); if (weaponIndexToStart >= weapons.Count) { print ( "WARNING: The weapon index configured is higher than the current amount of weapons in the vehicle, " + "check that the index is lower than the current amount of weapons." ); } choosedWeapon = weaponIndexToStart; currentWeapon = weapons [choosedWeapon]; currentWeaponLocated = true; currentWeaponName = currentWeapon.Name; if (vehicle == null) { vehicle = gameObject; } if (weaponsSlotsAmount < 10) { weaponsSlotsAmount++; } if (vehicleCameraManagerTransform == null) { vehicleCameraManagerTransform = vehicleCameraManager.transform; } mainRigidbodyLocated = mainRigidbody != null; gravityControlManagerLocated = gravityControlManager != null; hudManagerLocated = hudManager != null; vehicleCameraManagerLocated = vehicleCameraManager != null; componentsInitialized = true; } void FixedUpdate () { if (!weaponsEnabled) { return; } if (weaponsActivate) { if (hasBaseRotation) { // Rotate every transform of the weapon base baseY.transform.localRotation = Quaternion.Lerp (baseY.transform.localRotation, Quaternion.Euler (baseXTargetRotation), Time.deltaTime * baseYRotationSpeed); baseX.transform.localRotation = Quaternion.Lerp (baseX.transform.localRotation, Quaternion.Euler (baseYTargetRotation), Time.deltaTime * baseXRotationSpeed); } } } void Update () { if (!weaponsEnabled) { return; } if (weaponsActivate) { getWeaponBaseRotation (); checkWeaponTouchInputActions (); setVehicleWeaponCameraDirection (); checkAutoShootOnTag (); checkOtherWeaponElements (); checkIfDisableWeaponCursor (); if (autoShootOnTagActive) { shootWeapon (true); } } // If the amount of shells from the projectiles is higher than 0, check the time to remove then if (shellsOnSceneToRemove && shells.Count > 0) { destroyShellsTimer += Time.deltaTime; if (destroyShellsTimer > 3) { for (int i = 0; i < shells.Count; i++) { if (projectilesPoolEnabled) { GKC_PoolingSystem.Despawn (shells [i]); } else { Destroy (shells [i]); } } shells.Clear (); destroyShellsTimer = 0; shellsOnSceneToRemove = false; } } } void getWeaponBaseRotation () { if (hasBaseRotation) { playerCameraIsLocked = !playerCameraManager.isCameraTypeFree (); if (vehicleCameraManagerLocated) { playerMovingOn3dWorld = vehicleCameraManager.isPlayerMovingOn3dWorld (); } else { playerMovingOn3dWorld = true; } if (currentCameraUseRotationInput && !playerCameraIsLocked) { currentWeaponDirection = vehicleCameraTransform; currentMainCameraPosition = mainCameraTransform.position; if (usingCameraWithNoInput) { resetWeaponCursorPosition (); usingCameraWithNoInput = false; } } else { usingCameraWithNoInput = true; currentWeaponDirection = noInputWeaponDirection; if (playerCameraIsLocked) { vehicleCameraTransform = playerCameraManager.getCurrentLockedCameraTransform (); mainCameraTransform = vehicleCameraTransform; currentCameraUseRotationInput = false; } if (weaponCursor != null) { if (currentWeapon.fireWeaponForward) { currentWeaponDirection = vehicleCameraTransform; currentMainCameraPosition = mainCameraTransform.position; weaponCursor.anchoredPosition = Vector2.zero; } else if (canRotateWeaponsWithNoCameraInput && !actionManager.isGameManagerPaused ()) { axisValues = actionManager.getPlayerMouseAxis (); horizontalMouse = axisValues.x; verticalMouse = axisValues.y; weaponCursor.Translate (new Vector3 (horizontalMouse, verticalMouse, 0) * weaponCursorMovementSpeed); if (playerMovingOn3dWorld) { newCameraPosition = weaponCursor.anchoredPosition; if (useWeaponCursorScreenLimit) { posX = Mathf.Clamp (newCameraPosition.x, -weaponCursorHorizontalLimit, weaponCursorHorizontalLimit); posY = Mathf.Clamp (newCameraPosition.y, -weaponCursorVerticalLimit, weaponCursorVerticalLimit); weaponCursor.anchoredPosition = new Vector2 (posX, posY); } else { newCameraPosition = weaponCursor.position; newCameraPosition.x = Mathf.Clamp (newCameraPosition.x, currentLockedCameraCursorSize.x, horizontaLimit); newCameraPosition.y = Mathf.Clamp (newCameraPosition.y, currentLockedCameraCursorSize.y, verticalLimit); weaponCursor.position = new Vector3 (newCameraPosition.x, newCameraPosition.y, 0); } newRay = mainCamera.ScreenPointToRay (weaponCursor.position); if (Physics.Raycast (newRay, out hit, Mathf.Infinity, weaponCursorRaycastLayer)) { pointTargetPositionFound = false; // Check if the object found is the current vehicle, to avoid to aim at it and aim in the proper direction even if this vehicle is found if (checkIfDetectSurfaceBelongToVehicle (hit.collider)) { if (currentWeapon.useRaycastAllToCheckSurfaceFound && !currentWeapon.fireWeaponForward) { RaycastHit [] hits = Physics.RaycastAll (newRay, currentWeapon.maxDistanceToRaycastAll, layer); System.Array.Sort (hits, (x, y) => x.distance.CompareTo (y.distance)); pointTargetPositionSurfaceFound = false; foreach (RaycastHit rh in hits) { if (!pointTargetPositionSurfaceFound && !checkIfDetectSurfaceBelongToVehicle (rh.collider)) { pointTargetPosition = rh.point; currentDetectedSurface = rh.collider.gameObject; pointTargetPositionSurfaceFound = true; } } } else { pointTargetPositionFound = true; } } else { pointTargetPositionFound = true; } if (pointTargetPositionFound) { pointTargetPosition = hit.point; currentDetectedSurface = hit.collider.gameObject; } } else { float currentDistanceToWeapon = mainCamera.transform.InverseTransformDirection (currentWeaponDirection.position - mainCamera.transform.position).z; Vector3 ScreenToWorldPoint = mainCamera.ViewportToWorldPoint (new Vector3 (weaponCursor.anchoredPosition.x, weaponCursor.anchoredPosition.y, currentDistanceToWeapon)); Debug.DrawLine (currentWeaponDirection.position, ScreenToWorldPoint, Color.red, 3); pointTargetPosition = ScreenToWorldPoint; if (currentDetectedSurface != null) { currentDetectedSurface = null; } } } else { Vector3 newCameraPosition = weaponCursor.localPosition; float currentClampValue = verticalLimit / circleCameraLimit2_5d; Vector3 newCirclePosition = Vector3.ClampMagnitude (newCameraPosition, currentClampValue); // if (currentLockedCameraAxisInfo.moveReticleInFixedCircleRotation2_5d) { Vector2 positionOnCircle = Vector2.zero; positionOnCircle = new Vector2 (newCirclePosition.x, newCirclePosition.y); positionOnCircle.Normalize (); positionOnCircle *= currentClampValue; weaponCursor.localPosition = new Vector3 (positionOnCircle.x, positionOnCircle.y, 0); float currentDistanceToWeapon = mainCamera.transform.InverseTransformDirection (currentWeaponDirection.position - mainCamera.transform.position).z; Vector3 ScreenToWorldPoint = mainCamera.ViewportToWorldPoint (new Vector3 (weaponCursor.anchoredPosition.x, weaponCursor.anchoredPosition.y, currentDistanceToWeapon)); Debug.DrawLine (currentWeaponDirection.position, ScreenToWorldPoint, Color.red, 3); pointTargetPosition = ScreenToWorldPoint; if (currentDetectedSurface != null) { currentDetectedSurface = null; } } if (currentTargetDetected != currentDetectedSurface) { currentTargetDetected = currentDetectedSurface; if (currentTargetDetected != null) { currentTargetToAim = applyDamage.getPlaceToShoot (currentTargetDetected); // if (currentTargetToAim) { // print (currentTargetToAim.name); // } } else { currentTargetToAim = null; } } if (currentTargetToAim != null) { pointTargetPosition = currentTargetToAim.position; } targetDirection = pointTargetPosition - currentWeaponDirection.position; targetRotation = Quaternion.LookRotation (targetDirection); lookAngle.x = targetRotation.eulerAngles.y; lookAngle.y = targetRotation.eulerAngles.x; noInputWeaponDirectionTargetRotation = Quaternion.Euler (lookAngle.y, lookAngle.x, 0); noInputWeaponDirection.rotation = Quaternion.Slerp (noInputWeaponDirection.rotation, noInputWeaponDirectionTargetRotation, noCameraInputWeaponRotationSpeed * Time.deltaTime); currentMainCameraPosition = pointTargetPosition; if (usingLaser) { currentVehicleLaser.updateCustomRayPosition (currentMainCameraPosition, newRay.direction); } } } } // Rotate the weapon to look in the camera direction Quaternion cameraDirection = Quaternion.LookRotation (currentWeaponDirection.forward); weaponLookDirection.rotation = cameraDirection; float angleX = weaponLookDirection.localEulerAngles.x; // Clamp the angle of the weapon, to avoid a rotation higher that the camera // In X axis if (angleX >= 0 && angleX <= minimumX) { rotationX = angleX; aimingCorrectly = true; } else if (angleX >= maximumX && angleX <= 360) { rotationX = angleX; aimingCorrectly = true; } else { aimingCorrectly = false; } // In Y axis float angleY = weaponLookDirection.localEulerAngles.y; if (angleY >= 0 && angleY <= minimumY) { rotationY = angleY; } else if (angleY >= maximumY && angleY <= 360) { rotationY = angleY; } baseXTargetRotation = new Vector3 (0, rotationY, 0); baseYTargetRotation = new Vector3 (rotationX, 0, 0); } } void checkWeaponTouchInputActions () { // Check if a key number has been pressed, to change the current weapon for the key pressed, if there is a weapon using that key if (!touchEnabled) { int currentNumberInput = playerInput.checkNumberInput (weaponsSlotsAmount); if (currentNumberInput > -1) { for (int k = 0; k < weapons.Count; k++) { if (choosedWeapon != k && weapons [k].numberKey == currentNumberInput) { if (weapons [k].enabled) { choosedWeapon = k; weaponChanged (); } } } } } // If the touch controls are enabled, activate the swipe option if (touchEnabled) { // Select the weapon by swiping the finger in the right corner of the screen, above the weapon info int touchCount = Input.touchCount; if (!touchPlatform) { touchCount++; } for (int i = 0; i < touchCount; i++) { if (!touchPlatform) { currentTouch = touchJoystick.convertMouseIntoFinger (); } else { currentTouch = Input.GetTouch (i); } // Get the start position of the swipe if (vehicleHUDInfoManager.isFingerPressingTouchPanel () && !touching) { swipeStartPos = currentTouch.position; touching = true; } // And the final position, and get the direction, to change to the previous or the next power if (currentTouch.phase == TouchPhase.Ended) { if (touching) { float swipeDistHorizontal = (new Vector3 (currentTouch.position.x, 0, 0) - new Vector3 (swipeStartPos.x, 0, 0)).magnitude; if (swipeDistHorizontal > minSwipeDist) { float swipeValue = Mathf.Sign (currentTouch.position.x - swipeStartPos.x); if (swipeValue > 0) { // Right swipe choosePreviousWeapon (); } else if (swipeValue < 0) { // Left swipe chooseNextWeapon (); } } touching = false; } vehicleHUDInfoManager.setTouchingMenuPanelState (false); } } } } void checkOtherWeaponElements () { // If the current weapon is the homing missiles if (aimingHomingProjectile) { // Check if the amount of located enemies is equal or lower that the number of remaining projectiles if (locatedEnemies.Count < currentWeapon.projectilePosition.Count) { // Uses a ray to detect enemies, to locked them homingProjectileRayPosition = mainCameraTransform.position; if (usingCameraWithNoInput) { homingProjectileRayPosition = weaponLookDirection.position; } if (Physics.Raycast (homingProjectileRayPosition, projectileDirectionToLook, out hit, Mathf.Infinity, layer)) { Debug.DrawLine (homingProjectileRayPosition, hit.point, Color.yellow, 2); GameObject target = applyDamage.getCharacterOrVehicle (hit.collider.gameObject); if (target != null) { if (target != vehicle) { if (currentWeapon.tagToLocate.Contains (target.tag)) { GameObject placeToShoot = applyDamage.getPlaceToShootGameObject (target); if (placeToShoot != null) { if (!locatedEnemies.Contains (placeToShoot)) { // If an enemy is detected, add it to the list of located enemies and instantiated an icon in screen to follow the enemy locatedEnemies.Add (placeToShoot); GKC_Utils.addElementToPlayerScreenObjectivesManager (currentDriver, placeToShoot.gameObject, currentWeapon.locatedEnemyIconName); } } } } } } } } // If the current weapon is the laser if (usingLaser) { if (currentWeapon.clipSize > 0) { // Play the animation if (currentWeapon.weaponAnimation != null) { currentWeapon.weaponAnimation.Play (currentWeapon.animation); } // Play the sound if (Time.time > lastShoot + currentWeapon.fireRate) { lastShoot = Time.time; checkIfEnableWeaponCursor (); playWeaponSoundEffect (true); // Reduce the amount of ammo useAmmo (); } checkShotShake (); } else { if (currentWeapon.autoReloadWhenClipEmpty) { autoReload (); } } } // If the current weapon launched the projectile if (launchingProjectile) { // If the launcher animation is not being played if (currentWeapon.weapon != null && !currentWeapon.animation.Equals ("")) { if (currentWeapon.weaponAnimation != null && !currentWeapon.weaponAnimation.IsPlaying (currentWeapon.animation)) { // Reverse it and play it again if (currentWeapon.weaponAnimation [currentWeapon.animation].speed == 1) { currentWeapon.weaponAnimation [currentWeapon.animation].speed = -1; currentWeapon.weaponAnimation [currentWeapon.animation].time = currentWeapon.weaponAnimation [currentWeapon.animation].length; currentWeapon.weaponAnimation.Play (currentWeapon.animation); currentProjectile.transform.SetParent (null); launchCurrentProjectile (mainCameraTransform.TransformDirection (Vector3.forward)); return; } // The launcher has thrown a projectile and the animation is over if (currentWeapon.weaponAnimation [currentWeapon.animation].speed == -1) { launchingProjectile = false; if (currentWeapon.projectileModel != null) { currentWeapon.projectileModel.SetActive (true); } } } } else { launchCurrentProjectile (mainCameraTransform.TransformDirection (Vector3.forward)); launchingProjectile = false; } } } public void checkIfEnableWeaponCursor () { if (currentWeapon.disableWeaponCursorWhileNotShooting) { if (weaponCursor != null && weaponCursorDisabled) { weaponCursor.gameObject.SetActive (true); weaponCursorDisabled = false; } lastTimeFired = Time.time; } } public void checkIfDisableWeaponCursor () { if (currentWeapon.disableWeaponCursorWhileNotShooting && (playerMovingOn3dWorld || !hasBaseRotation)) { if (weaponCursor != null && !weaponCursorDisabled) { if (Time.time > currentWeapon.delayToDisableWeaponCursor + lastTimeFired) { weaponCursor.gameObject.SetActive (false); weaponCursorDisabled = true; } } } else { if (hasBaseRotation) { if (weaponCursor != null && weaponCursorDisabled) { weaponCursor.gameObject.SetActive (true); weaponCursorDisabled = false; } } else { if (weaponCursor != null && !weaponCursorDisabled) { weaponCursor.gameObject.SetActive (false); weaponCursorDisabled = true; } } } } public void launchCurrentProjectile (Vector3 cameraDirection) { // Launch the projectile according to the velocity calculated according to the hit point of a raycast from the camera position Rigidbody currentProjectileRigidbody = currentProjectile.GetComponent (); currentProjectileRigidbody.isKinematic = false; if (currentWeapon.useParableSpeed) { Vector3 newVel = getParableSpeed (currentProjectile.transform.position, aimedZone, cameraDirection); if (newVel == -Vector3.one) { newVel = 100 * currentProjectile.transform.forward; } currentProjectileRigidbody.AddForce (newVel, ForceMode.VelocityChange); } else { currentProjectileRigidbody.AddForce (currentWeapon.projectileSpeed * currentWeapon.parableDirectionTransform.forward, ForceMode.Impulse); } } /// /// If the homing missile weapon has been fired or change when enemies were locked, remove the icons from the screen. /// void removeLocatedEnemiesIcons () { for (int i = 0; i < locatedEnemies.Count; i++) { if (locatedEnemies [i] != null) { GKC_Utils.removeElementToPlayerScreenObjectivesManager (currentDriver, locatedEnemies [i].gameObject); } } locatedEnemies.Clear (); } /// /// Play the fire sound or the empty clip sound. /// void playWeaponSoundEffect (bool hasAmmo) { if (hasAmmo) { if (currentWeapon.shootAudioElement != null) { if (weaponsEffectsSource != null) currentWeapon.shootAudioElement.audioSource = weaponsEffectsSource; AudioPlayer.Play (currentWeapon.shootAudioElement, gameObject); //weaponsEffectsSource.PlayOneShot (weapons [choosedWeapon].soundEffect); } } else { if (Time.time > lastShoot + currentWeapon.fireRate) { if (weaponsEffectsSource != null) outOfAmmoAudioElement.audioSource = weaponsEffectsSource; AudioPlayer.PlayOneShot (outOfAmmoAudioElement, gameObject); lastShoot = Time.time; checkIfEnableWeaponCursor (); } } } /// /// Calculate the speed applied to the launched projectile to make a parable according to a hit point. /// Vector3 getParableSpeed (Vector3 origin, Vector3 target, Vector3 cameraDirection) { // If a hit point is not found, return if (!objectiveFound) { if (currentWeapon.useMaxDistanceWhenNoSurfaceFound) { target = origin + currentWeapon.maxDistanceWhenNoSurfaceFound * cameraDirection; Debug.DrawLine (origin, target, Color.gray, 5); } else { return -Vector3.one; } } // Get the distance between positions Vector3 toTarget = target - origin; Vector3 toTargetXZ = toTarget; // Remove the Y axis value toTargetXZ -= vehicleCameraManagerTransform.transform.InverseTransformDirection (toTargetXZ).y * vehicleCameraManagerTransform.transform.up; float y = vehicleCameraManagerTransform.transform.InverseTransformDirection (toTarget).y; float xz = toTargetXZ.magnitude; // Get the velocity according to distance and gravity float t = GKC_Utils.distance (origin, target) / 20; float v0y = y / t + 0.5f * Physics.gravity.magnitude * t; float v0xz = xz / t; // Create result vector for calculated starting speeds Vector3 result = toTargetXZ.normalized; // Get direction of xz but with magnitude 1 result *= v0xz; // Set magnitude of xz to v0xz (starting speed in xz plane), setting the local Y value result -= vehicleCameraManagerTransform.transform.InverseTransformDirection (result).y * vehicleCameraManagerTransform.transform.up; result += v0y * vehicleCameraManagerTransform.transform.up; return result; } /// /// Fire the current weapon. /// public void shootWeapon (bool shootAtKeyDown) { if (!shootAtKeyDown && !aimingHomingProjectile) { if (shootingPreviously) { shootingPreviously = false; } return; } // If the weapon system is active and the clip size higher than 0 if (!weaponsActivate || weaponsPaused) { return; } if (currentWeapon.clipSize > 0) { // Else, fire the current weapon according to the fire rate if (Time.time > lastShoot + currentWeapon.fireRate) { shootingPreviously = true; // If the current weapon is the homing missile, set to true and return // If the current projectile is homing type, check when the shoot button is pressed and release if ((currentWeapon.isHommingProjectile && shootAtKeyDown)) { aimingHomingProjectile = true; //print ("1 "+ shootAtKeyDown + " " + locatedEnemiesIcons.Count + " " + aimingHomingProjectile); return; } if ((currentWeapon.isHommingProjectile && !shootAtKeyDown && locatedEnemies.Count <= 0) || (!currentWeapon.isHommingProjectile && !shootAtKeyDown)) { aimingHomingProjectile = false; shootingPreviously = false; checkShotShake (); //print ("2 "+shootAtKeyDown + " " + locatedEnemiesIcons.Count + " " + aimingHomingProjectile); return; } checkShotShake (); // If the current weapon is the laser, enable it and return if (currentWeapon.isLaser) { changeWeaponLaserState (true); return; } // Play the fire sound playWeaponSoundEffect (true); // Create the muzzle flash createMuzzleFlash (); // Play the fire animation if (currentWeapon.weapon != null && currentWeapon.animation != "" && currentWeapon.weaponAnimation) { if (currentWeapon.launchProjectile) { currentWeapon.weaponAnimation [currentWeapon.animation].speed = 1; // Disable the projectile model in the weapon if (currentWeapon.projectileModel != null) { currentWeapon.projectileModel.SetActive (false); } } currentWeapon.weaponAnimation.Play (currentWeapon.animation); } Vector3 currentUp = Vector3.up; if (gravityControlManagerLocated) { currentUp = gravityControlManager.currentNormal; } // Every weapon can shoot 1 or more projectiles at the same time, so for every projectile position to instantiate for (int j = 0; j < currentWeapon.projectilePosition.Count; j++) { Transform currentProjectilePosition = currentWeapon.projectilePosition [j]; for (int l = 0; l < currentWeapon.projectilesPerShoot; l++) { // Create the projectile if (projectilesPoolEnabled) { currentProjectile = GKC_PoolingSystem.Spawn (currentWeapon.projectileToShoot, currentProjectilePosition.position, currentProjectilePosition.rotation, maxAmountOfPoolElementsOnWeapon); } else { currentProjectile = (GameObject)Instantiate (currentWeapon.projectileToShoot, currentProjectilePosition.position, currentProjectilePosition.rotation); } // Set the info in the projectile, like the damage, the type of projectile, bullet or missile, etc... currentProjectileSystem = currentProjectile.GetComponent (); if (currentProjectileSystem != null) { currentProjectileSystem.checkToResetProjectile (); currentProjectileRigidbody = currentProjectileSystem.getProjectileRigibody (); } if (!currentWeapon.launchProjectile) { // Set its direction in the weapon forward or the camera forward according to if the weapon is aimed correctly or not if (Physics.Raycast (currentMainCameraPosition, projectileDirectionToLook, out hit, Mathf.Infinity, layer) && aimingCorrectly && !currentWeapon.fireWeaponForward) { if (!hit.collider.isTrigger) { currentProjectile.transform.LookAt (hit.point); } } } // If the current weapon launches projectiles instead of shooting else { // If the projectile is not being launched, then if (!launchingProjectile) { if (currentWeapon.projectileModel != null) { currentProjectile.transform.SetParent (currentProjectilePosition); currentProjectile.transform.localRotation = Quaternion.Euler (new Vector3 (0, 0, -90)); } if (currentProjectileRigidbody == null) { currentProjectileRigidbody = currentProjectile.GetComponent (); } currentProjectileRigidbody.isKinematic = true; // If the vehicle has a gravity control component, and the current gravity is not the regular one, add an artificial gravity component to the projectile // like this, it can make a parable in any surface and direction, setting its gravity in the same of the vehicle if (currentUp != Vector3.up) { currentProjectile.AddComponent ().setCurrentGravity (-currentUp); } explosiveBarrel currentExplosiveBarrel = currentProjectile.GetComponent (); if (currentExplosiveBarrel != null) { currentExplosiveBarrel.canExplodeState (true); currentExplosiveBarrel.setExplosiveBarrelOwner (vehicle); currentExplosiveBarrel.setExplosionValues (currentWeapon.explosionForce, currentWeapon.explosionRadius); } if (currentWeapon.useParableSpeed) { // Get the ray hit point where the projectile will fall if (Physics.Raycast (currentMainCameraPosition, projectileDirectionToLook, out hit, Mathf.Infinity, layer)) { aimedZone = hit.point; objectiveFound = true; } else { objectiveFound = false; } } launchingProjectile = true; } } // Add spread to the projectile Vector3 spreadAmount = Vector3.zero; if (currentWeapon.useProjectileSpread) { spreadAmount = setProjectileSpread (); currentProjectile.transform.Rotate (spreadAmount); } if (currentProjectileSystem != null) { setProjectileInfo (); currentProjectileSystem.setProjectileInfo (currentWeapon.newProjectileInfo); } if (currentWeapon.isSeeker) { closestEnemy = setSeekerProjectileInfo (currentProjectilePosition.position); if (closestEnemy != null) { // print (closestEnemy.name); currentProjectileSystem.setEnemy (closestEnemy); } } bool projectileFiredByRaycast = false; bool destroyProjectile = false; // If the weapon shoots setting directly the projectile in the hit point, place the current projectile in the hit point position if (currentWeapon.useRayCastShoot) { Vector3 forwardDirection = projectileDirectionToLook; Vector3 forwardPositon = currentMainCameraPosition; if (!aimingCorrectly || currentWeapon.fireWeaponForward) { forwardDirection = currentWeapon.weapon.transform.forward; forwardPositon = currentProjectilePosition.position; } if (!currentCameraUseRotationInput && !currentWeapon.fireWeaponForward) { forwardPositon = weaponLookDirection.position; forwardDirection = projectileDirectionToLook; } if (!currentCameraUseRotationInput && !hasBaseRotation) { forwardDirection = currentWeapon.weapon.transform.forward; } if (spreadAmount.magnitude != 0) { forwardDirection = Quaternion.Euler (spreadAmount) * forwardDirection; } //Debug.DrawLine (forwardPositon, currentMainCameraPosition, Color.white, 3); // Check what element the projectile will impact, if the vehicle is found, destroy the projectile to avoid shooting at your own vehicle if (Physics.Raycast (forwardPositon, forwardDirection, out hit, Mathf.Infinity, layer)) { //Debug.DrawLine (forwardPositon, hit.point, Color.red, 3); //print (hit.collider.name + " " + checkIfDetectSurfaceBelongToVehicle (hit.collider)); if (checkIfDetectSurfaceBelongToVehicle (hit.collider)) { if (currentWeapon.useRaycastAllToCheckSurfaceFound && !currentWeapon.fireWeaponForward) { ray = new Ray (); if (currentCameraUseRotationInput) { if (aimingCorrectly) { ray.direction = projectileDirectionToLook; ray.origin = currentMainCameraPosition; } else { ray.origin = currentProjectilePosition.position; ray.direction = currentWeapon.weapon.transform.forward; } } else { ray.origin = weaponLookDirection.position; ray.direction = projectileDirectionToLook; } if (!hasBaseRotation && !currentCameraUseRotationInput) { ray.direction = mainCameraTransform.TransformDirection (Vector3.forward); } if (spreadAmount.magnitude != 0) { ray.direction = Quaternion.Euler (spreadAmount) * ray.direction; } RaycastHit [] hits = Physics.RaycastAll (ray, currentWeapon.maxDistanceToRaycastAll, layer); System.Array.Sort (hits, (x, y) => x.distance.CompareTo (y.distance)); bool surfaceFound = false; foreach (RaycastHit rh in hits) { if (!surfaceFound && !checkIfDetectSurfaceBelongToVehicle (rh.collider)) { //Debug.DrawLine (ray.origin, rh.point, Color.yellow, 3); //print (rh.collider.name + " " + checkIfDetectSurfaceBelongToVehicle (rh.collider)); if (currentWeapon.useFakeProjectileTrails) { currentProjectileSystem.creatFakeProjectileTrail (rh.point); } currentProjectileSystem.rayCastShoot (rh.collider, rh.point + 0.02f * rh.normal, projectileDirectionToLook); surfaceFound = true; projectileFiredByRaycast = true; } } if (!surfaceFound) { destroyProjectile = true; } } else { if (Physics.Raycast (currentProjectilePosition.position, forwardDirection, out hit, Mathf.Infinity, layer)) { if (checkIfDetectSurfaceBelongToVehicle (hit.collider)) { destroyProjectile = true; } else { if (currentWeapon.useFakeProjectileTrails) { currentProjectileSystem.creatFakeProjectileTrail (hit.point); } currentProjectileSystem.rayCastShoot (hit.collider, hit.point + 0.02f * hit.normal, forwardDirection); projectileFiredByRaycast = true; } } else { destroyProjectile = true; } } } else { if (currentWeapon.useFakeProjectileTrails) { currentProjectileSystem.creatFakeProjectileTrail (hit.point); } currentProjectileSystem.rayCastShoot (hit.collider, hit.point + 0.02f * hit.normal, forwardDirection); projectileFiredByRaycast = true; } } else { destroyProjectile = true; } if (destroyProjectile) { currentProjectileSystem.initializeProjectile (); if (currentWeapon.useFakeProjectileTrails) { currentProjectileSystem.creatFakeProjectileTrail (forwardPositon + 50 * forwardDirection); currentProjectileSystem.setFakeProjectileTrailSpeedMultiplier (0.3f); currentProjectileSystem.setDestroyTrailAfterTimeState (true); currentProjectileSystem.destroyProjectileWithDelay (0.01f); } else { currentProjectileSystem.destroyProjectile (); } } //Debug.DrawLine (forwardPositon, hit.point, Color.red, 2); } if (!projectileFiredByRaycast && !destroyProjectile) { if (currentProjectileSystem != null) { currentProjectileSystem.initializeProjectile (); } } if (aimingHomingProjectile) { // Check that the located enemies are higher that 0 if (locatedEnemies.Count > 0) { // Shoot the missiles if (j < locatedEnemies.Count) { setProjectileInfo (); currentProjectileSystem.setProjectileInfo (currentWeapon.newProjectileInfo); currentProjectileSystem.setEnemy (locatedEnemies [j]); currentProjectileSystem.initializeProjectile (); } else { currentProjectileSystem.destroyProjectile (); } } } } useAmmo (); lastShoot = Time.time; checkIfEnableWeaponCursor (); if (mainRigidbodyLocated) { if (currentWeapon.applyForceAtShoot) { if (vehicleCameraManagerLocated) { currentVehicleCameraTransform = vehicleCameraManager.getCurrentCameraTransform (); } else { } if (currentWeapon.useCustomTransformToForceShoot) { currentVehicleCameraTransform = currentWeapon.customTransformToForceShoot; } Vector3 forceDirection = currentWeapon.forceAmount * (currentWeapon.forceDirection.x * currentVehicleCameraTransform.right + currentWeapon.forceDirection.y * currentVehicleCameraTransform.up + currentWeapon.forceDirection.z * currentVehicleCameraTransform.forward); mainRigidbody.AddForce (mainRigidbody.mass * forceDirection, ForceMode.Impulse); } } } // If the current weapon drops shells, create them createShells (); if (currentWeapon.isHommingProjectile && !shootAtKeyDown && aimingHomingProjectile) { // If the button to shoot is released, shoot a homing projectile for every located enemy // Check that the located enemies are higher that 0 if (locatedEnemies.Count > 0) { // Remove the icons in the screen removeLocatedEnemiesIcons (); } aimingHomingProjectile = false; } } } // Else, the clip in the weapon is over, so check if there is remaining ammo else { if (currentWeapon.autoReloadWhenClipEmpty) { autoReload (); } } } public void setVehicleWeaponCameraDirection () { projectileDirectionToLook = mainCameraTransform.TransformDirection (Vector3.forward); if (!currentCameraUseRotationInput) { if (playerMovingOn3dWorld) { projectileDirectionToLook = currentMainCameraPosition - weaponLookDirection.position; //Debug.DrawLine (weaponLookDirection.position, currentMainCameraPosition, Color.yellow, 2); } else { Vector3 heading = currentMainCameraPosition - weaponLookDirection.position; float distance = heading.magnitude; projectileDirectionToLook = heading / distance; } } } public void autoReload () { // Disable the laser changeWeaponLaserState (false); // If the weapon is not being reloaded, do it if (!reloading) { StartCoroutine (waitToReload (currentWeapon.reloadTime)); } //checkRemainAmmo (); } public void changeWeaponLaserState (bool state) { if (currentWeapon.weapon != null) { if (currentVehicleLaser == null) { currentVehicleLaser = currentWeapon.weapon.GetComponentInChildren (); } if (currentVehicleLaser != null) { currentVehicleLaser.changeLaserState (state); usingLaser = state; } } } public void createShells () { if (currentWeapon.ejectShellOnShot) { for (int j = 0; j < currentWeapon.shellPosition.Count; j++) { if (currentWeapon.shell != null) { if (projectilesPoolEnabled) { shellClone = GKC_PoolingSystem.Spawn (currentWeapon.shell, currentWeapon.shellPosition [j].position, currentWeapon.shellPosition [j].rotation, maxAmountOfPoolElementsOnWeapon); } else { shellClone = (GameObject)Instantiate (currentWeapon.shell, currentWeapon.shellPosition [j].position, currentWeapon.shellPosition [j].rotation); } newWeaponShellSystem = shellClone.GetComponent (); if (currentWeapon.shellDropAudioElements.Count > 0) { newClipToShell = currentWeapon.shellDropAudioElements [Random.Range (0, currentWeapon.shellDropAudioElements.Count - 1)]; } newWeaponShellSystem.setShellValues ((currentWeapon.shellEjectionForce * GKC_Utils.getCurrentScaleTime () * currentWeapon.shellPosition [j].right), null, newClipToShell); shells.Add (shellClone); if (shells.Count > 15) { GameObject shellToRemove = shells [0]; shells.RemoveAt (0); if (projectilesPoolEnabled) { GKC_PoolingSystem.Despawn (shellToRemove); } else { Destroy (shellToRemove); } } shellsOnSceneToRemove = true; } } destroyShellsTimer = 0; } } public void testWeaponShake (int weaponIndex) { vehicleWeapons weaponToTest = weapons [weaponIndex]; if (weaponToTest.shootShakeInfo.useDamageShake) { if (weaponToTest.shootShakeInfo.sameValueBothViews) { vehicleCameraManager.setCameraExternalShake (weaponToTest.shootShakeInfo.thirdPersonDamageShake); } else { if (vehicleCameraManager.currentState.firstPersonCamera) { if (weaponToTest.shootShakeInfo.useDamageShakeInFirstPerson) { vehicleCameraManager.setCameraExternalShake (weaponToTest.shootShakeInfo.firstPersonDamageShake); } } else { if (weaponToTest.shootShakeInfo.useDamageShakeInThirdPerson) { vehicleCameraManager.setCameraExternalShake (weaponToTest.shootShakeInfo.thirdPersonDamageShake); } } } } } public void checkShotShake () { if (vehicleCameraManagerLocated) { if (currentWeapon.shootShakeInfo.useDamageShake) { if (currentWeapon.shootShakeInfo.sameValueBothViews) { vehicleCameraManager.setCameraExternalShake (currentWeapon.shootShakeInfo.thirdPersonDamageShake); } else { if (vehicleCameraManager.currentState.firstPersonCamera) { if (currentWeapon.shootShakeInfo.useDamageShakeInFirstPerson) { vehicleCameraManager.setCameraExternalShake (currentWeapon.shootShakeInfo.firstPersonDamageShake); } } else { if (currentWeapon.shootShakeInfo.useDamageShakeInThirdPerson) { vehicleCameraManager.setCameraExternalShake (currentWeapon.shootShakeInfo.thirdPersonDamageShake); } } } } } } /// /// Create the muzzle flash particles if the weapon has it. /// void createMuzzleFlash () { if (currentWeapon.muzzleParticles != null) { for (int j = 0; j < currentWeapon.projectilePosition.Count; j++) { currentProjectilePosition = currentWeapon.projectilePosition [j]; if (projectilesPoolEnabled) { muzzleParticlesClone = GKC_PoolingSystem.Spawn (currentWeapon.muzzleParticles, currentProjectilePosition.position, currentProjectilePosition.rotation, maxAmountOfPoolElementsOnWeapon); } else { muzzleParticlesClone = (GameObject)Instantiate (currentWeapon.muzzleParticles, currentProjectilePosition.position, currentProjectilePosition.rotation); } if (projectilesPoolEnabled) { } else { Destroy (muzzleParticlesClone, 1); } muzzleParticlesClone.transform.SetParent (currentProjectilePosition); } } } /// /// Decrease the amount of ammo in the clip. /// void useAmmo () { currentWeapon.clipSize--; updateAmmo (); } void updateAmmo () { if (hudManagerLocated) { if (!currentWeapon.infiniteAmmo) { hudManager.useAmmo (currentWeapon.clipSize, currentWeapon.remainAmmo); } else { hudManager.useAmmo (currentWeapon.clipSize, -1); } } else { if (mainGKCSimpleRiderSystemLocated) { if (!currentWeapon.infiniteAmmo) { mainGKCSimpleRiderSystem.useAmmo (currentWeapon.clipSize, currentWeapon.remainAmmo); } else { mainGKCSimpleRiderSystem.useAmmo (currentWeapon.clipSize, -1); } } } } /// /// Check the amount of ammo. /// void checkRemainAmmo () { // If the weapon has not infinite ammo if (!currentWeapon.infiniteAmmo) { if (currentWeapon.clipSize == 0) { // If the remaining ammo is lower that the ammo per clip, set the final projectiles in the clip if (currentWeapon.remainAmmo < currentWeapon.ammoPerClip) { currentWeapon.clipSize = currentWeapon.remainAmmo; } // Else, refill it else { currentWeapon.clipSize = currentWeapon.ammoPerClip; } // If the remaining ammo is higher than 0, remove the current projectiles added in the clip if (currentWeapon.remainAmmo > 0) { currentWeapon.remainAmmo -= currentWeapon.clipSize; } } else { int usedAmmo = 0; if (currentWeapon.removePreviousAmmoOnClip) { currentWeapon.clipSize = 0; if (currentWeapon.remainAmmo < (currentWeapon.ammoPerClip)) { usedAmmo = currentWeapon.remainAmmo; } else { usedAmmo = currentWeapon.ammoPerClip; } } else { if (currentWeapon.remainAmmo < (currentWeapon.ammoPerClip - currentWeapon.clipSize)) { usedAmmo = currentWeapon.remainAmmo; } else { usedAmmo = currentWeapon.ammoPerClip - currentWeapon.clipSize; } } currentWeapon.remainAmmo -= usedAmmo; currentWeapon.clipSize += usedAmmo; } } else { // Else, the weapon has infinite ammo, so refill it currentWeapon.clipSize = currentWeapon.ammoPerClip; } currentWeapon.auxRemainAmmo = currentWeapon.remainAmmo; } /// /// A delay for reload the weapon. /// IEnumerator waitToReload (float amount) { // If the remaining ammo is higher than 0 or infinite if (currentWeapon.remainAmmo > 0 || currentWeapon.infiniteAmmo) { // Reload reloading = true; // Play the reload sound if (currentWeapon.reloadAudioElement != null) { if (weaponsEffectsSource != null) currentWeapon.reloadAudioElement.audioSource = weaponsEffectsSource; AudioPlayer.PlayOneShot (currentWeapon.reloadAudioElement, gameObject); } // Wait an amount of time WaitForSeconds delay = new WaitForSeconds (amount); yield return delay; // Check the ammo values checkRemainAmmo (); // Stop reload reloading = false; updateAmmo (); } else { // Else, the ammo is over, play the empty weapon sound playWeaponSoundEffect (false); } yield return null; } /// /// The vehicle has used an ammo pickup, so increase the correct weapon by name. /// public void getAmmo (string ammoName, int amount) { bool empty = false; for (int i = 0; i < weapons.Count; i++) { if (weapons [i].Name.Equals (ammoName)) { if (weapons [i].remainAmmo == 0 && weapons [i].clipSize == 0) { empty = true; } weapons [i].remainAmmo += amount; weaponChanged (); if (empty && weapons [i].autoReloadWhenClipEmpty) { autoReload (); } weapons [i].auxRemainAmmo = weapons [i].remainAmmo; return; } } } public void addAuxRemainAmmo (vehicleWeapons weaponToCheck, int amount) { weaponToCheck.auxRemainAmmo += amount; } /// /// Select next or previous weapon. /// public void chooseNextWeapon () { if (!weaponsActivate) { return; } // Check the index and get the correctly weapon int max = 0; int numberKey = currentWeapon.numberKey; numberKey++; if (numberKey > weaponsSlotsAmount) { numberKey = 0; } bool exit = false; while (!exit) { for (int k = 0; k < weapons.Count; k++) { if (weapons [k].enabled && weapons [k].numberKey == numberKey) { choosedWeapon = k; exit = true; } } max++; if (max > 100) { return; } // Get the current weapon index numberKey++; if (numberKey > weaponsSlotsAmount) { numberKey = 0; } } // Set the current weapon weaponChanged (); } public void choosePreviousWeapon () { if (!weaponsActivate) { return; } int max = 0; int numberKey = currentWeapon.numberKey; numberKey--; if (numberKey < 0) { numberKey = weaponsSlotsAmount; } bool exit = false; while (!exit) { for (int k = weapons.Count - 1; k >= 0; k--) { if (weapons [k].enabled && weapons [k].numberKey == numberKey) { choosedWeapon = k; exit = true; } } max++; if (max > 100) { return; } numberKey--; if (numberKey < 0) { numberKey = weaponsSlotsAmount; } } weaponChanged (); } /// /// Set the info of the selected weapon in the hud. /// void weaponChanged () { currentWeapon = weapons [choosedWeapon]; currentWeaponLocated = true; currentWeaponName = currentWeapon.Name; if (hudManagerLocated) { hudManager.setWeaponName (currentWeapon.Name, currentWeapon.ammoPerClip, currentWeapon.clipSize); } else { if (mainGKCSimpleRiderSystemLocated) { mainGKCSimpleRiderSystem.setWeaponName (currentWeapon.Name, currentWeapon.ammoPerClip, currentWeapon.clipSize); } } updateAmmo (); checkParableTrayectory (true); // Remove the located enemies icon removeLocatedEnemiesIcons (); checkCurrentWeaponCustomReticle (); checkIfEnableWeaponCursor (); } public void checkCurrentWeaponCustomReticle () { if (weaponCursorImage != null) { if (currentWeapon.useCustomReticle) { weaponCursorImage.texture = currentWeapon.customReticle; if (currentWeapon.useCustomReticleColor) { weaponCursorImage.color = currentWeapon.customReticleColor; } if (currentWeapon.useCustomReticleSize) { weaponCursor.sizeDelta = currentWeapon.customReticleSize; } usingCustomReticle = true; } else { if (usingCustomReticle) { weaponCursorImage.texture = currentHUDElements.defaultVehicleCursor; weaponCursorImage.color = currentHUDElements.defaultVehicleCursorColor; weaponCursor.sizeDelta = currentHUDElements.defaultVehicleCursorSize; } } } } public void checkParableTrayectory (bool parableState) { // Enable or disable the parable line renderer if (currentWeapon.activateLaunchParable && parableState && currentWeapon.launchProjectile) { if (parable != null) { if (currentWeapon.parableTrayectoryPosition) { parableGameObject.transform.position = currentWeapon.parableTrayectoryPosition.position; parableGameObject.transform.rotation = currentWeapon.parableTrayectoryPosition.rotation; if (currentWeapon.projectilePosition.Count > 0) { parable.shootPosition = currentWeapon.projectilePosition [0]; } } if (vehicleCameraManagerLocated) { parable.setMainCameraTransform (vehicleCameraManager.getCurrentCameraTransform ()); } parable.changeParableState (true); } } else { if (parable != null) { parable.changeParableState (false); } } } public bool isWeaponsEnabled () { return weaponsEnabled; } public void setVehicleHUDInfoManager (playerHUDManager newPlayerHUDManager) { vehicleHUDInfoManager = newPlayerHUDManager; } public void setCurrentDriver (GameObject newDriver) { currentDriver = newDriver; } public void setGKCSimpleRiderSystem (GKCSimpleRiderSystem newGKCSimpleRiderSystem) { mainGKCSimpleRiderSystem = newGKCSimpleRiderSystem; mainGKCSimpleRiderSystemLocated = mainGKCSimpleRiderSystem != null; } public bool checkIfDetectSurfaceBelongToVehicle (Collider colliderToCheck) { if (hudManagerLocated) { return hudManager.checkIfDetectSurfaceBelongToVehicle (colliderToCheck); } else { if (mainGKCSimpleRiderSystemLocated) { return mainGKCSimpleRiderSystem.checkIfDetectSurfaceBelongToVehicle (colliderToCheck); } } return false; } /// /// Enable or disable the weapons in the vehicle according to if it is being driven or not. /// public void changeWeaponState (bool state) { if (!weaponsEnabled) { return; } weaponsActivate = state; // If the player gets in, set the info in the hud if (weaponsActivate) { if (hudManagerLocated) { vehicleHUDInfoManager = hudManager.getCurrentVehicleHUDInfo (); } touchEnabled = actionManager.getIsUsingTouchControlsValue (); weaponChanged (); // Get player info if (hudManagerLocated) { currentDriver = hudManager.getCurrentDriver (); } if (currentDriver != null) { playerComponentsManager mainPlayerComponentsManager = currentDriver.GetComponent (); playerCameraManager = mainPlayerComponentsManager.getPlayerCamera (); mainCamera = playerCameraManager.getMainCamera (); usingScreenSpaceCamera = playerCameraManager.isUsingScreenSpaceCamera (); playerInput = mainPlayerComponentsManager.getPlayerInputManager (); playerMovingOn3dWorld = !playerCameraManager.is2_5ViewActive (); } getWeaponCursorElements (); checkCurrentWeaponCustomReticle (); if (hasBaseRotation) { weaponCursorDisabled = true; } else { weaponCursorDisabled = false; } checkIfEnableWeaponCursor (); } // Else, the player is getting off else { rotationX = 0; rotationY = 0; if (hasBaseRotation) { if (!hudManagerLocated || !hudManager.isForcingPassengersToGetOffOnVehicleDestroyedActive ()) { if (gameObject.activeInHierarchy) { StartCoroutine (rotateWeapon ()); } } } // If the laser is being used, disable it changeWeaponLaserState (false); } // Disable the parable line renderer checkParableTrayectory (weaponsActivate); if (!weaponsActivate) { if (locatedEnemies.Count > 0) { aimingHomingProjectile = false; // Remove the icons in the screen removeLocatedEnemiesIcons (); } } } /// /// Get the camera info of the vehicle. /// public void getCameraInfo (Transform camera, bool useRotationInput) { vehicleCameraTransform = camera; mainCameraTransform = vehicleCameraTransform; currentCameraUseRotationInput = useRotationInput; getWeaponCursorElements (); } public void getWeaponCursorElements () { if (vehicleHUDInfoManager != null && vehicleHUDInfoManager.getVehicleCursor ()) { if (weaponCursor == null) { weaponCursor = vehicleHUDInfoManager.getVehicleCursor ().GetComponent (); weaponCursorImage = weaponCursor.GetComponent (); currentHUDElements = vehicleHUDInfoManager.getHudElements (); } resetWeaponCursorPosition (); currentLockedCameraCursorSize = weaponCursor.sizeDelta; Vector2 currentResolution = GKC_Utils.getScreenResolution (); horizontaLimit = currentResolution.x - currentLockedCameraCursorSize.x; verticalLimit = currentResolution.y - currentLockedCameraCursorSize.y; } } void resetWeaponCursorPosition () { if (weaponCursor != null) { weaponCursor.anchoredPosition = Vector2.zero; } } /// /// Reset the weapon rotation when the player gets off. /// IEnumerator rotateWeapon () { Quaternion currentBaseXRotation = baseX.transform.localRotation; Quaternion currentBaseYRotation = baseY.transform.localRotation; for (float t = 0; t < 1;) { t += Time.deltaTime * 3; baseX.transform.localRotation = Quaternion.Slerp (currentBaseXRotation, Quaternion.identity, t); baseY.transform.localRotation = Quaternion.Slerp (currentBaseYRotation, Quaternion.identity, t); yield return null; } } public GameObject setSeekerProjectileInfo (Vector3 shootPosition) { return applyDamage.setSeekerProjectileInfo (shootPosition, currentWeapon.tagToLocate, usingScreenSpaceCamera, currentWeapon.targetOnScreenForSeeker, mainCamera, layer, transform.position, false, null); } public Vector3 setProjectileSpread () { float spreadAmount = currentWeapon.spreadAmount; if (spreadAmount > 0) { Vector3 randomSpread = Vector3.zero; randomSpread.x = Random.Range (-spreadAmount, spreadAmount); randomSpread.y = Random.Range (-spreadAmount, spreadAmount); randomSpread.z = Random.Range (-spreadAmount, spreadAmount); return randomSpread; } return Vector3.zero; } /// /// Shoot to any object with the tag configured in the inspector, in case the option is enabled. /// public void checkAutoShootOnTag () { if (currentWeapon.autoShootOnTag) { Vector3 raycastPosition = mainCameraTransform.position; Vector3 raycastDirection = mainCameraTransform.TransformDirection (Vector3.forward); if (Physics.Raycast (raycastPosition, raycastDirection, out hit, currentWeapon.maxDistanceToRaycast, currentWeapon.layerToAutoShoot)) { currentTargetDetectedOnAutoShootOnTag = hit.collider.gameObject; if (previousTargetDetectedOnAutoShootOnTag == null || previousTargetDetectedOnAutoShootOnTag != currentTargetDetectedOnAutoShootOnTag) { previousTargetDetectedOnAutoShootOnTag = currentTargetDetectedOnAutoShootOnTag; GameObject target = applyDamage.getCharacterOrVehicle (hit.collider.gameObject); if (target == null) { target = hit.collider.gameObject; } if (currentWeapon.autoShootTagList.Contains (target.tag) || (currentWeapon.shootAtLayerToo && (1 << target.layer & currentWeapon.layerToAutoShoot.value) == 1 << target.layer)) { autoShootOnTagActive = true; } else { if (autoShootOnTagActive) { resetAutoShootValues (); autoShootOnTagActive = false; } } } } else { resetAutoShootValues (); } } else { resetAutoShootValues (); } } void resetAutoShootValues () { if (autoShootOnTagActive) { shootWeapon (false); previousTargetDetectedOnAutoShootOnTag = null; currentTargetDetectedOnAutoShootOnTag = null; autoShootOnTagActive = false; } } public bool checkIfWeaponIsAvailable (string weaponName) { for (int i = 0; i < weapons.Count; i++) { if (weapons [i].enabled && weapons [i].Name.Equals (weaponName)) { return true; } } return false; } public bool canIncreaseRemainAmmo (vehicleWeapons weaponToCheck) { if (weaponToCheck.auxRemainAmmo < weaponToCheck.ammoLimit) { return true; } else { return false; } } public bool hasMaximumAmmoAmount (vehicleWeapons weaponToCheck) { if (weaponToCheck.useAmmoLimit) { print (weaponToCheck.Name + " " + weaponToCheck.remainAmmo + " " + weaponToCheck.ammoLimit); if (weaponToCheck.remainAmmo >= weaponToCheck.ammoLimit) { return true; } return false; } return false; } public bool hasAmmoLimit (string weaponName) { for (int i = 0; i < weapons.Count; i++) { if (weapons [i].enabled && weapons [i].Name.Equals (weaponName) && weapons [i].useAmmoLimit) { return true; } } return false; } public int ammoAmountToMaximumLimit (vehicleWeapons weaponToCheck) { return weaponToCheck.ammoLimit - weaponToCheck.auxRemainAmmo; } public bool hasMaximumAmmoAmount (string weaponName) { for (int i = 0; i < weapons.Count; i++) { if (weapons [i].enabled && weapons [i].Name.Equals (weaponName) && hasMaximumAmmoAmount (weapons [i])) { return true; } } return false; } public string getCurrentWeaponName () { if (currentWeaponLocated) { return currentWeaponName; } return ""; } public int getCurrentWeaponClipSize () { if (currentWeaponLocated) { return currentWeapon.clipSize; } return 0; } public int getCurrentWeaponRemainAmmo () { if (currentWeaponLocated) { return currentWeapon.remainAmmo; } return 0; } void setProjectileInfo () { if (!currentWeapon.newProjectileInfoCreated) { projectileInfo newProjectileInfo = new projectileInfo (); newProjectileInfo.isHommingProjectile = currentWeapon.isHommingProjectile; newProjectileInfo.isSeeker = currentWeapon.isSeeker; newProjectileInfo.targetOnScreenForSeeker = currentWeapon.targetOnScreenForSeeker; newProjectileInfo.waitTimeToSearchTarget = currentWeapon.waitTimeToSearchTarget; newProjectileInfo.useRayCastShoot = currentWeapon.useRayCastShoot; newProjectileInfo.useRaycastCheckingOnRigidbody = currentWeapon.useRaycastCheckingOnRigidbody; newProjectileInfo.customRaycastCheckingRate = currentWeapon.customRaycastCheckingRate; newProjectileInfo.customRaycastCheckingDistance = currentWeapon.customRaycastCheckingDistance; newProjectileInfo.useRaycastShootDelay = currentWeapon.useRaycastShootDelay; newProjectileInfo.raycastShootDelay = currentWeapon.raycastShootDelay; newProjectileInfo.getDelayWithDistance = currentWeapon.getDelayWithDistance; newProjectileInfo.delayWithDistanceSpeed = currentWeapon.delayWithDistanceSpeed; newProjectileInfo.maxDelayWithDistance = currentWeapon.maxDelayWithDistance; newProjectileInfo.useFakeProjectileTrails = currentWeapon.useFakeProjectileTrails; newProjectileInfo.projectileDamage = currentWeapon.projectileDamage; newProjectileInfo.projectileSpeed = currentWeapon.projectileSpeed; newProjectileInfo.impactForceApplied = currentWeapon.impactForceApplied; newProjectileInfo.forceMode = currentWeapon.forceMode; newProjectileInfo.applyImpactForceToVehicles = currentWeapon.applyImpactForceToVehicles; newProjectileInfo.impactForceToVehiclesMultiplier = currentWeapon.impactForceToVehiclesMultiplier; newProjectileInfo.checkObjectsWithMultipleDamageReceiversEnabled = currentWeapon.checkObjectsWithMultipleDamageReceiversEnabled; newProjectileInfo.projectileWithAbility = currentWeapon.projectileWithAbility; newProjectileInfo.impactSoundEffect = currentWeapon.impactSoundEffect; newProjectileInfo.impactAudioElement = currentWeapon.impactAudioElement; newProjectileInfo.scorch = currentWeapon.scorch; newProjectileInfo.scorchRayCastDistance = currentWeapon.scorchRayCastDistance; newProjectileInfo.owner = vehicle; newProjectileInfo.projectileParticles = currentWeapon.projectileParticles; newProjectileInfo.impactParticles = currentWeapon.impactParticles; newProjectileInfo.isExplosive = currentWeapon.isExplosive; newProjectileInfo.isImplosive = currentWeapon.isImplosive; newProjectileInfo.useExplosionDelay = currentWeapon.useExplosionDelay; newProjectileInfo.explosionDelay = currentWeapon.explosionDelay; newProjectileInfo.explosionForce = currentWeapon.explosionForce; newProjectileInfo.explosionRadius = currentWeapon.explosionRadius; newProjectileInfo.explosionDamage = currentWeapon.explosionDamage; newProjectileInfo.pushCharacters = currentWeapon.pushCharacters; newProjectileInfo.applyExplosionForceToVehicles = currentWeapon.applyExplosionForceToVehicles; newProjectileInfo.explosionForceToVehiclesMultiplier = currentWeapon.explosionForceToVehiclesMultiplier; newProjectileInfo.searchClosestWeakSpot = currentWeapon.searchClosestWeakSpot; newProjectileInfo.killInOneShot = currentWeapon.killInOneShot; newProjectileInfo.useDisableTimer = currentWeapon.useDisableTimer; newProjectileInfo.noImpactDisableTimer = currentWeapon.noImpactDisableTimer; newProjectileInfo.impactDisableTimer = currentWeapon.impactDisableTimer; newProjectileInfo.targetToDamageLayer = layer; newProjectileInfo.targetForScorchLayer = targetForScorchLayer; newProjectileInfo.useCustomIgnoreTags = useCustomIgnoreTags; newProjectileInfo.customTagsToIgnoreList = customTagsToIgnoreList; newProjectileInfo.impactDecalIndex = currentWeapon.impactDecalIndex; newProjectileInfo.launchProjectile = currentWeapon.launchProjectile; newProjectileInfo.adhereToSurface = currentWeapon.adhereToSurface; newProjectileInfo.adhereToLimbs = currentWeapon.adhereToLimbs; newProjectileInfo.ignoreSetProjectilePositionOnImpact = currentWeapon.ignoreSetProjectilePositionOnImpact; newProjectileInfo.useGravityOnLaunch = currentWeapon.useGravityOnLaunch; newProjectileInfo.useGraivtyOnImpact = currentWeapon.useGraivtyOnImpact; if (currentWeapon.breakThroughObjects) { newProjectileInfo.breakThroughObjects = currentWeapon.breakThroughObjects; newProjectileInfo.infiniteNumberOfImpacts = currentWeapon.infiniteNumberOfImpacts; newProjectileInfo.numberOfImpacts = currentWeapon.numberOfImpacts; newProjectileInfo.canDamageSameObjectMultipleTimes = currentWeapon.canDamageSameObjectMultipleTimes; newProjectileInfo.ignoreNewRotationOnProjectileImpact = currentWeapon.ignoreNewRotationOnProjectileImpact; newProjectileInfo.canBreakThroughArmorSurface = currentWeapon.canBreakThroughArmorSurface; newProjectileInfo.breakThroughArmorSurfacePriorityValue = currentWeapon.breakThroughArmorSurfacePriorityValue; } if (currentWeapon.damageTargetOverTime) { newProjectileInfo.damageTargetOverTime = currentWeapon.damageTargetOverTime; newProjectileInfo.damageOverTimeDelay = currentWeapon.damageOverTimeDelay; newProjectileInfo.damageOverTimeDuration = currentWeapon.damageOverTimeDuration; newProjectileInfo.damageOverTimeAmount = currentWeapon.damageOverTimeAmount; newProjectileInfo.damageOverTimeRate = currentWeapon.damageOverTimeRate; newProjectileInfo.damageOverTimeToDeath = currentWeapon.damageOverTimeToDeath; newProjectileInfo.removeDamageOverTimeState = currentWeapon.removeDamageOverTimeState; } if (currentWeapon.sedateCharacters) { newProjectileInfo.sedateCharacters = currentWeapon.sedateCharacters; newProjectileInfo.sedateDelay = currentWeapon.sedateDelay; newProjectileInfo.useWeakSpotToReduceDelay = currentWeapon.useWeakSpotToReduceDelay; newProjectileInfo.sedateDuration = currentWeapon.sedateDuration; newProjectileInfo.sedateUntilReceiveDamage = currentWeapon.sedateUntilReceiveDamage; } if (currentWeapon.pushCharacter) { newProjectileInfo.pushCharacter = currentWeapon.pushCharacter; newProjectileInfo.pushCharacterForce = currentWeapon.pushCharacterForce; newProjectileInfo.pushCharacterRagdollForce = currentWeapon.pushCharacterRagdollForce; } if (currentWeapon.useRemoteEventOnObjectsFound) { newProjectileInfo.useRemoteEventOnObjectsFound = currentWeapon.useRemoteEventOnObjectsFound; newProjectileInfo.remoteEventNameList = currentWeapon.remoteEventNameList; } if (currentWeapon.useRemoteEventOnObjectsFoundOnExplosion) { newProjectileInfo.useRemoteEventOnObjectsFoundOnExplosion = currentWeapon.useRemoteEventOnObjectsFoundOnExplosion; newProjectileInfo.remoteEventNameOnExplosion = currentWeapon.remoteEventNameOnExplosion; } if (currentWeapon.ignoreShield) { newProjectileInfo.ignoreShield = currentWeapon.ignoreShield; newProjectileInfo.canActivateReactionSystemTemporally = currentWeapon.canActivateReactionSystemTemporally; newProjectileInfo.damageReactionID = currentWeapon.damageReactionID; } newProjectileInfo.damageTypeID = currentWeapon.damageTypeID; newProjectileInfo.damageCanBeBlocked = currentWeapon.damageCanBeBlocked; newProjectileInfo.projectilesPoolEnabled = projectilesPoolEnabled; newProjectileInfo.maxAmountOfPoolElementsOnWeapon = maxAmountOfPoolElementsOnWeapon; newProjectileInfo.projectileCanBeDeflected = currentWeapon.projectileCanBeDeflected; if (currentWeapon.sliceObjectsDetected) { newProjectileInfo.sliceObjectsDetected = currentWeapon.sliceObjectsDetected; newProjectileInfo.layerToSlice = currentWeapon.layerToSlice; newProjectileInfo.useBodyPartsSliceList = currentWeapon.useBodyPartsSliceList; newProjectileInfo.bodyPartsSliceList = currentWeapon.bodyPartsSliceList; newProjectileInfo.maxDistanceToBodyPart = currentWeapon.maxDistanceToBodyPart; newProjectileInfo.randomSliceDirection = currentWeapon.randomSliceDirection; newProjectileInfo.showSliceGizmo = currentWeapon.showSliceGizmo; newProjectileInfo.activateRigidbodiesOnNewObjects = currentWeapon.activateRigidbodiesOnNewObjects; newProjectileInfo.useGeneralProbabilitySliceObjects = currentWeapon.useGeneralProbabilitySliceObjects; newProjectileInfo.generalProbabilitySliceObjects = currentWeapon.generalProbabilitySliceObjects; } currentWeapon.newProjectileInfo = newProjectileInfo; currentWeapon.newProjectileInfoCreated = true; } currentWeapon.newProjectileInfo.forwardDirection = projectileDirectionToLook; } public void enableMuzzleFlashLight () { if (!currentWeapon.useMuzzleFlash) { return; } if (muzzleFlashCoroutine != null) { StopCoroutine (muzzleFlashCoroutine); } muzzleFlashCoroutine = StartCoroutine (enableMuzzleFlashCoroutine ()); } IEnumerator enableMuzzleFlashCoroutine () { currentWeapon.muzzleFlahsLight.gameObject.SetActive (true); WaitForSeconds delay = new WaitForSeconds (currentWeapon.muzzleFlahsDuration); yield return delay; currentWeapon.muzzleFlahsLight.gameObject.SetActive (false); yield return null; } public void setWeaponsPausedState (bool state) { weaponsPaused = state; } public void setWeaponsEnabedStateAndWeaponMeshes (bool state) { setWeaponsEnabledState (state); if (mainVehicleWeaponsGameObject != null) { mainVehicleWeaponsGameObject.SetActive (state); } } public void setWeaponsEnabledState (bool state) { weaponsEnabled = state; if (weaponsEnabled) { initializeComponents (); } } public void setMainVehicleWeaponsGameObjectParent (Transform newParent) { if (mainVehicleWeaponsGameObject != null) { mainVehicleWeaponsGameObject.transform.SetParent (newParent); } } // CALL INPUT FUNCTIONS public void inputShootWeapon () { if (!weaponsEnabled) { return; } if (weaponsActivate) { // Fire the current weapon if (currentWeapon.automatic) { shootWeapon (true); } } } public void inputHoldOrReleaseShootWeapon (bool holdingButton) { if (!weaponsEnabled) { return; } if (weaponsActivate) { if (holdingButton) { shootWeapon (true); } else { // If the shoot button is released, reset the last shoot timer shootWeapon (false); lastShoot = 0; if (usingLaser) { if (currentWeapon.clipSize > 0) { changeWeaponLaserState (false); } } } } } public void inputNextOrPreviousWeapon (bool setNextWeapon) { if (!weaponsEnabled) { return; } if (weaponsActivate) { // Select the power using the mouse wheel or the change power buttons if (setNextWeapon) { chooseNextWeapon (); } else { choosePreviousWeapon (); } } } public void setVehicleWeaponsComponents () { // Get every the ammo per clip of every weapon according to their initial clip size for (int i = 0; i < weapons.Count; i++) { weapons [i].ammoPerClip = weapons [i].clipSize; if (weapons [i].weapon != null) { weapons [i].weaponAnimation = weapons [i].weapon.GetComponent (); } if (weapons [i].startWithEmptyClip) { weapons [i].clipSize = 0; } weapons [i].auxRemainAmmo = weapons [i].remainAmmo; } updateComponent (); } public void updateComponent () { GKC_Utils.updateComponent (this); } public void getImpactListInfo () { if (impactDecalManager == null) { GKC_Utils.instantiateMainManagerOnSceneWithType (mainDecalManagerName, typeof (decalManager)); impactDecalManager = FindObjectOfType (); } if (impactDecalManager != null) { impactDecalList = new string [impactDecalManager.impactListInfo.Count + 1]; for (int i = 0; i < impactDecalManager.impactListInfo.Count; i++) { string name = impactDecalManager.impactListInfo [i].name; impactDecalList [i] = name; } updateComponent (); } } [System.Serializable] public class vehicleWeapons { public string Name; public int numberKey; public bool useCustomReticle; public Texture customReticle; public bool useCustomReticleColor; public Color customReticleColor = Color.white; public bool useCustomReticleSize; public Vector2 customReticleSize = new Vector2 (60, 60); public bool disableWeaponCursorWhileNotShooting; public float delayToDisableWeaponCursor; public bool useRayCastShoot; public bool useRaycastAllToCheckSurfaceFound = true; public float maxDistanceToRaycastAll = 200; public bool useRaycastCheckingOnRigidbody; public float customRaycastCheckingRate; public float customRaycastCheckingDistance = 0.1f; public bool fireWeaponForward; public bool enabled; public bool useRaycastShootDelay; public float raycastShootDelay; public bool getDelayWithDistance; public float delayWithDistanceSpeed; public float maxDelayWithDistance; public bool useFakeProjectileTrails; public int ammoPerClip; public bool removePreviousAmmoOnClip; public bool infiniteAmmo; public int remainAmmo; public int clipSize; public bool startWithEmptyClip; public bool autoReloadWhenClipEmpty = true; public bool useAmmoLimit; public int ammoLimit; public int auxRemainAmmo; public bool shootAProjectile; public bool launchProjectile; public bool projectileWithAbility; public bool automatic; public float fireRate; public float reloadTime; public float projectileDamage; public float projectileSpeed; public int projectilesPerShoot; public bool useProjectileSpread; public float spreadAmount; public bool checkObjectsWithMultipleDamageReceiversEnabled; public bool isImplosive; public bool isExplosive; public float explosionForce; public float explosionRadius; public bool useExplosionDelay; public float explosionDelay; public float explosionDamage; public bool pushCharacters; public bool applyExplosionForceToVehicles = true; public float explosionForceToVehiclesMultiplier = 0.2f; public bool searchClosestWeakSpot; public List projectilePosition = new List (); public bool ejectShellOnShot; public GameObject shell; public List shellPosition = new List (); public float shellEjectionForce = 200; public List shellDropSoundList = new List (); public List shellDropAudioElements = new List (); public GameObject weapon; public string animation; public Animation weaponAnimation; public GameObject scorch; public float scorchRayCastDistance; public bool autoShootOnTag; public LayerMask layerToAutoShoot; public List autoShootTagList = new List (); public float maxDistanceToRaycast; public bool shootAtLayerToo; public bool applyForceAtShoot; public Vector3 forceDirection; public bool useCustomTransformToForceShoot; public Transform customTransformToForceShoot; public float forceAmount; public bool isHommingProjectile; public bool isSeeker; public bool targetOnScreenForSeeker = true; public float waitTimeToSearchTarget; public float impactForceApplied; public ForceMode forceMode; public bool applyImpactForceToVehicles; public float impactForceToVehiclesMultiplier = 1; public float forceMassMultiplier = 1; public AudioClip reloadSoundEffect; public AudioElement reloadAudioElement; public AudioClip shootSoundEffect; public AudioElement shootAudioElement; public AudioClip impactSoundEffect; public AudioElement impactAudioElement; public AudioClip outOfAmmo; public AudioElement outOfAmmoAudioElement; public GameObject muzzleParticles; public GameObject projectileParticles; public GameObject impactParticles; public bool killInOneShot; public bool useDisableTimer; public float noImpactDisableTimer; public float impactDisableTimer; public string locatedEnemyIconName = "Homing Located Enemy"; public List tagToLocate = new List (); public bool activateLaunchParable; public bool useParableSpeed; public Transform parableTrayectoryPosition; public Transform parableDirectionTransform; public bool useMaxDistanceWhenNoSurfaceFound; public float maxDistanceWhenNoSurfaceFound; public bool adhereToSurface; public bool adhereToLimbs; public bool ignoreSetProjectilePositionOnImpact; public bool useGravityOnLaunch; public bool useGraivtyOnImpact; public GameObject projectileModel; public GameObject projectileToShoot; public bool showShakeSettings; public vehicleCameraController.shakeSettingsInfo shootShakeInfo; public int impactDecalIndex; public string impactDecalName; public bool isLaser; public bool breakThroughObjects; public bool infiniteNumberOfImpacts; public int numberOfImpacts; public bool canDamageSameObjectMultipleTimes; public bool ignoreNewRotationOnProjectileImpact; public bool canBreakThroughArmorSurface; public int breakThroughArmorSurfacePriorityValue = -1; public bool useMuzzleFlash; public Light muzzleFlahsLight; public float muzzleFlahsDuration; public bool damageTargetOverTime; public float damageOverTimeDelay; public float damageOverTimeDuration; public float damageOverTimeAmount; public float damageOverTimeRate; public bool damageOverTimeToDeath; public bool removeDamageOverTimeState; public bool sedateCharacters; public float sedateDelay; public bool useWeakSpotToReduceDelay; public bool sedateUntilReceiveDamage; public float sedateDuration; public bool pushCharacter; public float pushCharacterForce; public float pushCharacterRagdollForce; public bool useRemoteEventOnObjectsFound; public List remoteEventNameList = new List (); public bool useRemoteEventOnObjectsFoundOnExplosion; public string remoteEventNameOnExplosion; public bool ignoreShield; public bool canActivateReactionSystemTemporally; public int damageReactionID = -1; public int damageTypeID = -1; public bool damageCanBeBlocked = true; public bool projectileCanBeDeflected = true; public bool sliceObjectsDetected; public LayerMask layerToSlice; public bool useBodyPartsSliceList; public List bodyPartsSliceList = new List (); public float maxDistanceToBodyPart; public bool randomSliceDirection; public bool showSliceGizmo; public bool activateRigidbodiesOnNewObjects = true; public bool useGeneralProbabilitySliceObjects; [Range (0, 100)] public float generalProbabilitySliceObjects; public bool newProjectileInfoCreated; public projectileInfo newProjectileInfo; public void InitializeAudioElements () { if (reloadSoundEffect != null) { reloadAudioElement.clip = reloadSoundEffect; } if (shootSoundEffect != null) { shootAudioElement.clip = shootSoundEffect; } if (impactSoundEffect != null) { impactAudioElement.clip = impactSoundEffect; } if (outOfAmmo != null) { outOfAmmoAudioElement.clip = outOfAmmo; } if (shellDropSoundList != null && shellDropSoundList.Count > 0) { foreach (var shellDropSound in shellDropSoundList) { shellDropAudioElements.Add (new AudioElement { clip = shellDropSound }); } } } } }