Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Help with my current block system.

Discussion in 'Scripting' started by radar089, Oct 2, 2014.

  1. radar089

    radar089

    Joined:
    Jan 2, 2014
    Posts:
    216
    So, currently i have a fps shooter that has block placement. a block is placed at the crossair when the user pushes c, or x. c makes a cement block. x makes a hesco. thank u nobiax.

    this is all fine and dandy but it is unlimited. all walls in the game can be destroyed and drop something. along with rigid bodys so buildings can fall if made in a modular work flow. i am going to make walls drop a weapon. the weapon will be a block. the block will have 1 starting ammo. then whenever the player picks up another "ammo weapon" it will just destroy the ammo game object and add +1 to the block ammo clip/count. the script already does this when you pick up ammo etc..

    this is the point that i need help. combining the script for shooting/damage with the place object script. so that when the block weapon shoots it just places 1 cube. 1 cube per shot in clip.

    i will post the scripts below. you need to have realistic fps prefab from the asset store to use the script but someone smarter then i will know what to look for. this is weapon behavior it is cscript.

    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. public class WeaponBehavior : MonoBehaviour {
    5.  
    6. public bool haveWeapon = false;//true if player has this weapon in their inventory
    7. [HideInInspector]
    8. public int weaponNumber = 0;//number of this weapon in the weaponOrder array in playerWeapons script
    9.  
    10. //Other objects accessed by this script
    11. [HideInInspector]
    12. public GameObject playerObj;
    13. [HideInInspector]
    14. public GameObject weaponObj;
    15. public GameObject weaponMesh;
    16. [HideInInspector]
    17. public GameObject cameraObj;
    18. [HideInInspector]
    19. public GameObject ammoGuiObj;
    20. private Transform myTransform;
    21.  
    22. //gun position amounts
    23. public float weaponUnzoomXPosition = -0.02f;//horizontal modifier of gun position when not zoomed
    24. public float weaponUnzoomYPosition = 0.0127f;//vertical modifier of gun position when not zoomed
    25. public float weaponUnzoomXPositionSprint = 0.075f;//horizontal modifier of gun position when sprinting
    26. public float weaponUnzoomYPositionSprint = 0.0075f;//vertical modifier of gun position when sprinting
    27. public float weaponZoomXPosition = -0.07f;//horizontal modifier of gun position when zoomed
    28. public float weaponZoomYPosition = 0.032f;//vertical modifier of gun position when zoomed
    29. public float zoomFOV = 55.0f;//FOV value to use when zoomed, lower values can be used with scoped weapons for higher zoom
    30. public float swayAmountUnzoomed = 1.0f;//sway amount for this weapon when not zoomed
    31. public float swayAmountZoomed = 1.0f;//sway amount for this weapon when zoomed
    32. public bool PistolSprintAnim = false;//set to true to use alternate sprinting animation with pistols
    33. public float sprintBobAmountX = 1.0f;//to fine tune horizontal weapon sprint bobbing amounts
    34. public float sprintBobAmountY = 1.0f;//to fine tune vertical weapon sprint bobbing amounts
    35.  
    36. //Sprinting and Player States
    37. private bool canShoot = true;//true when player is allowed to shoot
    38. [HideInInspector]
    39. public bool shooting = false;//true when shooting
    40. [HideInInspector]
    41. public bool sprintAnimState = false;//to control playback of sprinting animation
    42. [HideInInspector]
    43. public bool sprintState = false;//to control timing of weapon recovery after sprinting
    44. private float recoveryTime = 0.000f;//time that sprint animation started playing
    45. private float horizontal = 0;//player movement
    46. private float vertical = 0;//player movement
    47.  
    48. //Shooting
    49. public int projectileCount = 1;//amount of projectiles to be fired per shot ( > 1 for shotguns)
    50. public bool fireModeSelectable = false;//true if weapon can switch between burst and semi-auto
    51. private bool fireModeState = false;
    52. public bool semiAuto = false;//true when weapon is in semi-auto mode
    53. private bool semiState = false;
    54. public bool unarmed = false;//should this weapon be null/unarmed?
    55. public float meleeSwingDelay = 0.0f;//this weapon will be treated as a melee weapon when this value is > 0
    56. private bool swingSide = false;//to control which direction to swing melee weapon
    57. private float shootStartTime = 0.0f;//time that shot started
    58. public float range = 100;//range that weapon can hit targets
    59. public float fireRate = 0.097f;//time between shots
    60. public float fireAnimSpeed = 1.0f;//speed to play the firing animation
    61. public float shotSpread = 0.0f;//defines accuracy cone of fired bullets
    62. private float shotSpreadAmt = 0.0f;//actual accuracy amount
    63. public int force= 200;//amount of physics push to apply to rigidbodies on contact
    64. public int damage = 10;//damage to inflict on objects with ApplyDamage(); function
    65. public LayerMask bulletMask = 0;//only layers to include in bullet hit detection (for efficiency)
    66.  
    67. //Ammo and Reloading
    68. public int bulletsPerClip = 30;//maximum amount of bullets per magazine
    69. public int bulletsToReload = 50;//number of bullets to reload per reload cycle (when < bulletsPerClip, allows reloading one or more bullets at a time)
    70. private int bulletsNeeded = 0;//number of bullets absent in magazine
    71. public int bulletsLeft = 0;//bullets left in magazine
    72. private int bulletsReloaded = 0;//number of bullets reloaded during this reloading cycle
    73. public int ammo = 150;//ammo amount for this weapon in player's inventory
    74. public int maxAmmo = 999;//maximum ammo amount player's inventory can hold for this weapon
    75. public float reloadTime = 1.75f;//time per reload cycle, should be shorter if reloading one bullet at a time and longer if reloading magazine
    76. private float reloadStartTime = 0.0f;
    77. private bool sprintReloadState = false;
    78. private float reloadEndTime = 0.0f;//used to allow fire button to cancel a reload if not reloading a magazine and bulletsLeft > 1
    79. public float reloadAnimSpeed = 1.15f;//speed of reload animation playback
    80. public float shellRldAnimSpeed = 0.7f;//speed of single shell/bullet reload animation playback
    81. public float readyAnimSpeed = 1.0f;//speed of ready animation playback
    82. public float readyTime = 0.6f;//amount of time needed to finish the ready anim after weapon has just been switched to/selected
    83. private float recoveryTimeAmt = 0.0f;//amount of time needed to recover weapon center position after sprinting
    84. private float startTime = 0.0f;//track time that weapon was selected to calculate readyTime
    85. [HideInInspector]
    86. public float reloadLastTime = 1.2f;//to track when last bullet is reloaded if not reloading magazine, to play chambering animation and sound
    87. [HideInInspector]
    88. public float reloadLastStartTime = 0.0f;
    89. [HideInInspector]
    90. public bool lastReload = false;//true when last bullet of a non -magazine reload is being loaded, to play chambering animation and sound
    91. private bool noAmmoState = false;//to track ammo depletion and to play out of ammo sound
    92.  
    93. //Muzzle Flash
    94. public Renderer muzzleFlash;//the game object that will be used as a muzzle flash
    95. private float muzzleFlashReduction = 6.5f;//value to control time that muzzle flash is on screen (lower value make muzzle flash fade slower)
    96. [HideInInspector]
    97. public Color muzzleFlashColor = new Color(1, 1, 1, 0.0f);
    98.  
    99. //View Kick
    100. [HideInInspector]
    101. public Quaternion kickRotation;//rotation used for screen kicks
    102. public float kickUp = 7.0f;//amount to kick view up when firing (set in editor)
    103. public float kickSide = 2.0f;//amount to kick view sideways when firing (set in editor)
    104. private float kickUpAmt = 0.0f;//actual amount to kick view up when firing
    105. private float kickSideAmt = 0.0f;//actual amount to kick view sideways when firing
    106.  
    107. //Shell Ejection
    108. public GameObject shellPrefab;//game object to use as empty casing and eject from shellEjectPosition
    109. public Vector3 shellEjectDirection = new Vector3(0.0f, 0.0f, 0.0f);//direction of ejected shell casing
    110. [HideInInspector]
    111. public Transform shellEjectPosition;//position shell is ejected from (use origin of ShellEjectPos object attatched to weapon)
    112. public Vector3 shellScale = new Vector3(1.0f, 1.0f, 1.0f);//scale of shell, can be used to make different shaped shells from one model
    113. public float shellEjectDelay = 0.0f;//delay before ejecting shell (used for bolt action rifles and pump shotguns)
    114. public float shellForce = 0.2f;//overall movement force of ejected shell
    115. public float shellUp = 0.75f;//random vertical direction to apply to shellForce
    116. public float shellSide = 1.0f;//random horizontal direction to apply to shellForce
    117. public float shellForward = 0.1f;//random forward direction to apply to shellForce
    118. public float shellRotateUp = 0.25f;//amount of vertical shell rotation
    119. public float shellRotateSide = 0.25f;//amount of horizontal shell rotation
    120. public int shellDuration = 5;//time in seconds that shells persist in the world before being removed
    121.  
    122. //Particle Emitters
    123. //used for weapon fire and bullet impact effects
    124. public ParticleEmitter sparkParticles;
    125. public ParticleEmitter hitSpark;
    126. public ParticleEmitter tracerParticles;
    127. public ParticleEmitter slowSmokeParticles;
    128. public ParticleEmitter muzzleSmokeParticles;
    129. public ParticleEmitter fastSmokeParticles;
    130. public ParticleEmitter debrisParticles;
    131. public GameObject[] BulletMarkObj;
    132.  
    133. //Audio Sources
    134. private AudioSource firefx;//use multiple audio sources to play weapon sfx without skipping
    135. private AudioSource otherfx;
    136. public AudioClip fireSnd;
    137. public AudioClip reloadSnd;
    138. public AudioClip reloadLastSnd;//usually shell reload sound + shotgun pump or rifle chambering sound
    139. public AudioClip noammoSnd;
    140. public AudioClip readySnd;
    141. public AudioClip[] hitSounds;//sound of bullets hitting surfaces
    142.  
    143. void Start (){
    144.  
    145. //define external script references
    146. PlayerWeapons PlayerWeaponsComponent = weaponObj.GetComponent<PlayerWeapons>();
    147. //Access GUIText instance that was created by the PlayerWeapons script
    148. ammoGuiObj = PlayerWeaponsComponent.ammoGuiObjInstance;
    149.  
    150. //do not perform weapon actions if this is an unarmed/null weapon
    151. if(!unarmed){
    152.  
    153. myTransform = transform;//define transform for efficiency
    154.  
    155. if(meleeSwingDelay == 0){//initialize muzzle flash color if not a melee weapon
    156. muzzleFlash.enabled = false;
    157. muzzleFlashColor = muzzleFlash.renderer.material.GetColor("_TintColor");
    158. //clamp initial ammo amount in clip for non melee weapons
    159. bulletsLeft = Mathf.Clamp(bulletsLeft,0,bulletsPerClip);
    160. }else{
    161. //initial ammo amount in clip for melee weapons
    162. bulletsLeft = bulletsPerClip;
    163. }
    164.  
    165. if(semiAuto){//make muzzle flash fade out slower when gun is semiAuto
    166. if(projectileCount < 2){//make muzzle flash last slightly longer for shotguns
    167. muzzleFlashReduction = 3.5f;
    168. }else{
    169. muzzleFlashReduction = 2.0f;
    170. }
    171. }else{
    172. if(projectileCount < 2){//make muzzle flash last slightly longer for shotguns
    173. muzzleFlashReduction = 6.5f;
    174. }else{
    175. muzzleFlashReduction = 2.0f;
    176. }
    177. }
    178.  
    179. //initialize shot timers and animation settings
    180. shootStartTime = -1.0f;
    181. shotSpreadAmt = shotSpread;
    182.  
    183. animation["RifleSprinting"].speed = -1.5f;//init at this speed for correct rifle switching anim
    184. if(PistolSprintAnim){animation["PistolSprinting"].speed = -1.5f;}//init at this speed for correct pistol switching anim
    185. weaponMesh.animation["Fire"].speed = fireAnimSpeed;//initialize weapon mesh animation speeds
    186. weaponMesh.animation["Reload"].speed = reloadAnimSpeed;
    187. weaponMesh.animation["Ready"].speed = readyAnimSpeed;
    188. //If weapon reloads one bullet at a time, use anim called "Neutral" of hand returning to idle position
    189. //from reloading position to allow smooth anims when single bullet reloading is cancelled by sprinting.
    190. //The "Neutral" animation's wrap mode also needs to be set to "clamp forever" in the animation import settings.
    191. if(bulletsToReload != bulletsPerClip){
    192. weaponMesh.animation["Neutral"].speed = 1.5f;
    193. }
    194.  
    195.  
    196. //limit ammo to maxAmmo value
    197. ammo = Mathf.Clamp(ammo, 0, maxAmmo);
    198. //limit bulletsToReload value to bulletsPerClip value
    199. bulletsToReload = Mathf.Clamp(bulletsToReload, 0, bulletsPerClip);
    200. }
    201.  
    202. }
    203.  
    204. void OnEnable () {
    205.  
    206. //do not perform weapon actions if this is an unarmed/null weapon
    207. if(!unarmed){
    208.  
    209. //define external script references
    210. PlayerWeapons PlayerWeaponsComponent = weaponObj.GetComponent<PlayerWeapons>();
    211. Ironsights IronsightsComponent = playerObj.GetComponent<Ironsights>();
    212.  
    213. if(Time.timeSinceLevelLoad > 2 && PlayerWeaponsComponent.switching){//don't ready weapon on level load, just when switching weapons
    214. AudioSource []aSources = weaponObj.GetComponents<AudioSource>();//Set up reference to Audio Sources using aSources array
    215. AudioSource otherfx = aSources[1] as AudioSource;//Use first audio source for weapon sound effects
    216.  
    217. StopCoroutine("Reload");//stop reload coroutine if interrupting a non-magazine reload
    218. IronsightsComponent.reloading = false;//update reloading var in Ironsights script if cancelling reload to fire
    219.  
    220. //play weapon readying sound
    221. otherfx.volume = 1.0f;
    222. otherfx.pitch = 1.0f * Time.timeScale;
    223. otherfx.clip = readySnd;
    224. otherfx.PlayOneShot(otherfx.clip, 1.0f / otherfx.volume);
    225.  
    226. //track time that weapon was made active to calculate readyTime for syncing ready anim with weapon firing
    227. startTime = Time.time - Time.deltaTime;
    228.  
    229. //play weapon readying animation after it has just been selected
    230. weaponMesh.animation["Ready"].speed = readyAnimSpeed;
    231. weaponMesh.animation.CrossFade("Ready",0.35f,PlayMode.StopAll);
    232. }
    233. }
    234.  
    235. }
    236.  
    237. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    238. //FixedUpdate Actions
    239. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    240. void FixedUpdate (){
    241.  
    242. if(Time.timeScale > 0){//allow pausing by setting timescale to 0
    243.  
    244. //define external script references
    245. AmmoText AmmoText = ammoGuiObj.GetComponent<AmmoText>();//set reference for main color element of ammo GUIText
    246. AmmoText[] AmmoText2 = ammoGuiObj.GetComponentsInChildren<AmmoText>();//set reference for shadow background color element of heath GUIText
    247. PlayerWeapons PlayerWeaponsComponent = weaponObj.GetComponent<PlayerWeapons>();
    248. FPSRigidBodyWalker FPSWalkerComponent = playerObj.GetComponent<FPSRigidBodyWalker>();
    249. Ironsights IronsightsComponent = playerObj.GetComponent<Ironsights>();
    250. FPSPlayer FPSPlayerComponent = playerObj.GetComponent<FPSPlayer>();
    251.  
    252. horizontal = FPSWalkerComponent.inputX;//Get input from player movement script
    253. vertical = FPSWalkerComponent.inputY;
    254.  
    255. AudioSource []aSources = weaponObj.GetComponents<AudioSource>();//Set up reference to Audio Sources using aSources array
    256. AudioSource otherfx = aSources[1] as AudioSource;//Use first audio source for weapon sound effects
    257.  
    258. //pass ammo amounts to the ammo GuiText object if not a melee weapon or unarmed
    259. if(meleeSwingDelay == 0 && !unarmed){
    260. //pass ammo amount to Gui object to be rendered on screen
    261. AmmoText.ammoGui = bulletsLeft;//main color
    262. AmmoText.ammoGui2 = ammo;
    263. AmmoText2[1].ammoGui = bulletsLeft;//shadow background color
    264. AmmoText2[1].ammoGui2 = ammo;
    265. AmmoText.horizontalOffsetAmt = AmmoText.horizontalOffset;//normal position on screen
    266. AmmoText.verticalOffsetAmt = AmmoText.verticalOffset;
    267. AmmoText2[1].horizontalOffsetAmt = AmmoText2[1].horizontalOffset;
    268. AmmoText2[1].verticalOffsetAmt = AmmoText2[1].verticalOffset;
    269. }else{
    270. AmmoText.horizontalOffsetAmt = 5;//make ammo GUIText move off screen if using a melee weapon
    271. AmmoText.verticalOffsetAmt = 5;
    272. AmmoText2[1].horizontalOffsetAmt = 5;
    273. AmmoText2[1].verticalOffsetAmt = 5;
    274. }
    275.  
    276. //do not perform weapon actions if this is an unarmed/null weapon
    277. if(!unarmed){
    278.  
    279. //Determine if player is reloading last round during a non-magazine reload.
    280. if(reloadLastStartTime + reloadLastTime > Time.time){
    281. lastReload = true;
    282. }else{
    283. lastReload = false;
    284. }
    285.  
    286. //cancel auto and manual reload if player starts sprinting
    287. if(FPSWalkerComponent.sprintActive
    288. && !Input.GetKey (FPSPlayerComponent.fire)
    289. && !lastReload//allow player to finish chambering last round of a non-magazine reload
    290. && !FPSWalkerComponent.cancelSprint
    291. && (Mathf.Abs(horizontal) > 0 || Mathf.Abs(vertical) > 0)){
    292. if(IronsightsComponent.reloading){
    293. IronsightsComponent.reloading = false;
    294. //use StopCoroutine to completely stop reload() function and prevent
    295. //"yield return new WaitForSeconds(reloadTime);" from continuing to excecute
    296. StopCoroutine("Reload");
    297. if(bulletsToReload != bulletsPerClip){bulletsReloaded = 0;}//reset bulletsReloaded value
    298.  
    299. if(bulletsToReload != bulletsPerClip){
    300. //rewind Neutral animation when sprinting
    301. weaponMesh.animation["Neutral"].speed = 1.5f;
    302. weaponMesh.animation.Play("Neutral", PlayMode.StopAll);//play reloading animation
    303. }
    304.  
    305. //fast forward camera animations to stop playback if sprinting
    306. Camera.main.animation["CameraReloadMP5"].normalizedTime = 1.0f;
    307. Camera.main.animation["CameraReloadAK47"].normalizedTime = 1.0f;
    308. Camera.main.animation["CameraReloadPistol"].normalizedTime = 1.0f;
    309. Camera.main.animation["CameraReloadSingle"].normalizedTime = 1.0f;
    310. Camera.main.animation["CameraSwitch"].normalizedTime = 1.0f;
    311. //if sprint interrupts reload more than half-way through, just give bulletsNeeded
    312. if(bulletsToReload == bulletsPerClip && reloadStartTime + reloadTime / 2 < Time.time && !sprintReloadState){
    313. bulletsNeeded = bulletsPerClip - bulletsLeft;
    314. //we have ammo left to reload
    315. if(ammo >= bulletsNeeded){
    316. ammo -= bulletsNeeded;//subtract bullets needed from total ammo
    317. bulletsLeft = bulletsPerClip;//add bullets to magazine
    318. }else{
    319. bulletsLeft += ammo;//if ammo left is less than needed to reload, so just load all remaining bullets
    320. ammo = 0;//out of ammo for this weapon now
    321. }
    322. sprintReloadState = true;//only preform this action once at beginning of sprint/reload check
    323. }else{//if we are less than half way through reload before sprint interrupted, cancel reload
    324. //stop reload sound from playing
    325. otherfx.clip = null;
    326. if(bulletsToReload == bulletsPerClip){
    327. //rewind reload animation when sprinting
    328. weaponMesh.animation["Reload"].speed = -reloadAnimSpeed * 1.5f;
    329. weaponMesh.animation.CrossFade("Reload", 0.35f, PlayMode.StopAll);//play reloading animation
    330. }
    331. }
    332. }
    333. }else{
    334. //Start automatic reload if player is out of ammo and firing time has elapsed to allow finishing of firing animation and sound
    335. if (bulletsLeft <= 0
    336. && shootStartTime + fireRate < Time.time
    337. && canShoot){
    338. if( ammo > 0
    339. && !IronsightsComponent.reloading
    340. && !PlayerWeaponsComponent.switching
    341. && ((startTime + readyTime) < Time.time)){
    342. StartCoroutine("Reload");
    343. //set animation speeds
    344. //make this check to prevent slow playing of non magazine anim for last bullet in inventory
    345. if(bulletsToReload == bulletsPerClip){
    346. weaponMesh.animation["Reload"].speed = reloadAnimSpeed;
    347. }
    348. weaponMesh.animation["Ready"].speed = readyAnimSpeed;
    349. }
    350. }
    351. }
    352.  
    353. //don't spawn shell if player started sprinting to avoid unrealistic movement of shell if sprint stops
    354. if(FPSWalkerComponent.canRun){
    355. StopCoroutine("SpawnShell");
    356. }
    357.  
    358. //start reload if reload button is pressed
    359. if (Input.GetKey (FPSPlayerComponent.reload)
    360. && !IronsightsComponent.reloading
    361. && ammo > 0
    362. && bulletsLeft < bulletsPerClip
    363. && shootStartTime + fireRate < Time.time
    364. && !Input.GetKey (FPSPlayerComponent.fire)){
    365. StartCoroutine("Reload");
    366. }
    367.  
    368. //enable/disable shooting based on various player states
    369. if (!FPSWalkerComponent.sprintActive
    370. ||FPSWalkerComponent.crouched
    371. ||(FPSPlayerComponent.zoomed && meleeSwingDelay == 0)
    372. ||((Mathf.Abs(horizontal) > 0) && (Mathf.Abs(vertical) < 1))
    373. ||FPSWalkerComponent.cancelSprint
    374. ||(!FPSWalkerComponent.grounded && FPSWalkerComponent.jumping)//don't play sprinting anim while jumping
    375. ||(FPSWalkerComponent.fallingDistance > 1.5f)//don't play sprinting anim while falling
    376. ||Input.GetKey (FPSPlayerComponent.fire)){
    377. //not sprinting
    378. //set sprint recovery timer so gun only shoots after returning to neutral
    379. if(!sprintState){
    380. recoveryTime = Time.time;
    381. sprintState = true;
    382. }
    383. canShoot = true;
    384. sprintReloadState = false;//reset sprintReloadState to allow another sprint reload cancel check
    385. }else{
    386. //sprinting
    387. if (Mathf.Abs(horizontal) != 0 || Mathf.Abs(vertical) > 0.75f){
    388. sprintState = false;
    389. if(IronsightsComponent.reloading){
    390. canShoot = false;
    391. }else{
    392. if(FPSPlayerComponent.zoomed && meleeSwingDelay == 0){
    393. canShoot = true;
    394. }else{
    395. canShoot=false;
    396. }
    397. }
    398. }else{
    399. //set sprint recovery timer so gun only shoots after returning to center
    400. if(!sprintState){
    401. recoveryTime = Time.time;
    402. sprintState = true;
    403. }
    404. canShoot = true;
    405. }
    406. }
    407.  
    408. //Play noammo sound
    409. if (Input.GetKey(FPSPlayerComponent.fire)){
    410. if((noAmmoState)
    411. && (canShoot)
    412. && (bulletsLeft <= 0)
    413. && (ammo <= 0)
    414. && ((!PistolSprintAnim && animation["RifleSprinting"].normalizedTime < 0.35f)//only play sound when weapon is centered
    415. ||(PistolSprintAnim && animation["PistolSprinting"].normalizedTime < 0.35f))){
    416. otherfx.volume = 1.0f;
    417. otherfx.pitch = 1.0f;
    418. otherfx.clip = noammoSnd;
    419. otherfx.PlayOneShot(otherfx.clip, 1.0f / otherfx.volume);
    420. shooting = false;
    421. noAmmoState = false;
    422. }
    423. }else{
    424. noAmmoState = true;
    425. }
    426.  
    427. //Change fire mode
    428. if (Input.GetKey(FPSPlayerComponent.fireMode)){
    429. if(fireModeState
    430. && canShoot
    431. && !IronsightsComponent.reloading
    432. && ((!PistolSprintAnim && animation["RifleSprinting"].normalizedTime < 0.35f)//only play sound when weapon is centered
    433. ||(PistolSprintAnim && animation["PistolSprinting"].normalizedTime < 0.35f))){
    434.  
    435. if(fireModeSelectable && semiAuto){
    436.  
    437. semiAuto = false;
    438. fireModeState = false;
    439. if(projectileCount < 2){//make muzzle flash last slightly longer for semiAuto
    440. muzzleFlashReduction = 6.5f;
    441. }else{
    442. muzzleFlashReduction = 2.0f;
    443. }
    444. otherfx.volume = 1.0f;
    445. otherfx.pitch = 1.0f;
    446. otherfx.clip = noammoSnd;
    447. otherfx.PlayOneShot(otherfx.clip, 1.0f / otherfx.volume);
    448.  
    449. }else if(fireModeSelectable && !semiAuto){
    450.  
    451. semiAuto = true;
    452. fireModeState = false;
    453. if(projectileCount < 2){//make muzzle flash last slightly longer for shotguns
    454. muzzleFlashReduction = 3.5f;
    455. }else{
    456. muzzleFlashReduction = 2.0f;
    457. }
    458. otherfx.volume = 1.0f;
    459. otherfx.pitch = 1.0f;
    460. otherfx.clip = noammoSnd;
    461. otherfx.PlayOneShot(otherfx.clip, 1.0f / otherfx.volume);
    462. }
    463. }
    464. }else{
    465. fireModeState = true;
    466. }
    467.  
    468. //Run weapon sprinting animations
    469. if(canShoot
    470. ||FPSWalkerComponent.crouched
    471. ||FPSWalkerComponent.midPos < 0.9f//player is crouching
    472. ||IronsightsComponent.reloading
    473. ||FPSWalkerComponent.cancelSprint){
    474. if(sprintAnimState){//animate weapon up
    475. //store time that sprint anim started to disable weapon switching during transition
    476. PlayerWeaponsComponent.sprintSwitchTime = Time.time;
    477.  
    478. if(!PistolSprintAnim){
    479. //keep playback at last frame of animation to prevent it from being interrupted and to allow
    480. //instant reversal of playback intstead of continuing past an animation playback time of 1
    481. if(animation["RifleSprinting"].normalizedTime > 1){animation["RifleSprinting"].normalizedTime = 1;}
    482. //reverse animation speed for smooth changing of direction/reversal
    483. //animation will need to finish before recoveryTime has elapsed to prevent twisting of view when recovering from sprint
    484. animation["RifleSprinting"].speed = -1.4f;
    485. animation.CrossFade("RifleSprinting", 0.35f,PlayMode.StopAll);
    486. }else{
    487. if(animation["PistolSprinting"].normalizedTime > 1){animation["PistolSprinting"].normalizedTime = 1;}
    488. //reverse animation speed for smooth changing of direction/reversal
    489. //animation will need to finish before recoveryTime has elapsed to prevent twisting of view when recovering from sprint
    490. animation["PistolSprinting"].speed = -1.75f;
    491. animation.CrossFade("PistolSprinting", 2.25f,PlayMode.StopAll);
    492. }
    493. //set sprintAnimState to false to only perform these actions once per change of sprinting state checks
    494. sprintAnimState = false;
    495. }
    496. }else{
    497. if(!sprintAnimState){//animate weapon down
    498. //store time that sprint anim started to disable weapon switching during transition
    499. PlayerWeaponsComponent.sprintSwitchTime = Time.time;
    500.  
    501. if(!PistolSprintAnim){
    502. //keep playback at first frame of animation to prevent it from being interrupted and to allow
    503. //instant reversal of playback intstead of continuing past an animation playback time of 0 into negative values
    504. if(animation["RifleSprinting"].normalizedTime < 0){animation["RifleSprinting"].normalizedTime = 0;}
    505. //reverse animation speed for smooth changing of direction
    506. animation["RifleSprinting"].speed = 1.4f;
    507. animation.CrossFade("RifleSprinting", 0.35f,PlayMode.StopAll);
    508. }else{
    509. //keep playback at first frame of animation to prevent it from being interrupted and to allow
    510. //instant reversal of playback intstead of continuing past an animation playback time of 0 into negative values
    511. if(animation["PistolSprinting"].normalizedTime < 0){animation["PistolSprinting"].normalizedTime = 0;}
    512. //reverse animation speed for smooth changing of direction
    513. animation["PistolSprinting"].speed = 1.75f;
    514. animation.CrossFade("PistolSprinting", 2.25f,PlayMode.StopAll);
    515. }
    516.  
    517. //set sprintAnimState to true to only perform these actions once per change of sprinting state checks
    518. sprintAnimState = true;
    519. //rewind reloading animation if reload is interrupted by sprint
    520. if(PlayerWeaponsComponent.switching && IronsightsComponent.reloading){
    521. weaponMesh.animation.CrossFade("Reload", 0.35f,PlayMode.StopAll);//play firing animation
    522. }
    523. }
    524. }
    525. }
    526. }
    527.  
    528. }
    529.  
    530. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    531. //Update Actions
    532. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    533. void Update (){
    534.  
    535. if(Time.timeScale > 0){//allow pausing by setting timescale to 0
    536.  
    537. //do not perform weapon actions if this is an unarmed/null weapon
    538. if(!unarmed){
    539. FPSPlayer FPSPlayerComponent = playerObj.GetComponent<FPSPlayer>();
    540. //Fade out muzzle flash alpha
    541. if (muzzleFlash.enabled){
    542. if(muzzleFlashColor.a > 0.0f){
    543. muzzleFlashColor.a -= muzzleFlashReduction * (Time.deltaTime);
    544. muzzleFlash.renderer.material.SetColor("_TintColor", muzzleFlashColor);
    545. }else{
    546. muzzleFlash.enabled = false;//disable muzzle flash object after alpha has faded
    547. }
    548. }
    549.  
    550. //Detect firemode (auto or semi auto) and call fire function
    551. if (Input.GetKey (FPSPlayerComponent.fire)){
    552. if(semiAuto){
    553. if(!semiState){
    554. Fire();
    555. semiState = true;
    556. }
    557. }else{
    558. Fire();
    559. }
    560. }else{
    561. semiState = false;
    562. }
    563.  
    564. //set shooting var to false
    565. if(shootStartTime + fireRate > Time.time){
    566. shooting = false;
    567. }
    568.  
    569. }
    570. }
    571. }
    572.  
    573. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    574. //Weapon Muzzle Flash
    575. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    576. void MuzzFlash (){
    577. //enable muzzle flash
    578. if (muzzleFlash){
    579. //add random rotation to muzzle flash
    580. muzzleFlash.transform.localRotation = Quaternion.AngleAxis(Random.value * 360, Vector3.forward);
    581. muzzleFlash.enabled = true;
    582. //set muzzle flash color
    583. muzzleFlashColor.a = Random.Range(0.4f, 0.5f);
    584. //emit smoke particle effect from muzzle
    585. if (muzzleSmokeParticles) {
    586. muzzleSmokeParticles.transform.position = muzzleFlash.transform.position;
    587. muzzleSmokeParticles.Emit();
    588. }
    589. }
    590.  
    591. }
    592.  
    593. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    594. //Shell Ejection
    595. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    596. IEnumerator SpawnShell (){
    597.  
    598. if(shellEjectDelay > 0){//delay shell ejection for shotguns and bolt action rifles by shellEjectDelay amount
    599. yield return new WaitForSeconds(shellEjectDelay);
    600. }
    601. //instantiate shell object
    602. GameObject shell = Instantiate(shellPrefab,shellEjectPosition.position,shellEjectPosition.transform.rotation) as GameObject;
    603. shell.transform.localScale = shellScale;//scale size of shell object by shellScale amount
    604. //direction of ejected shell casing, adding random values to direction for realism
    605. shellEjectDirection = new Vector3((shellSide * 0.7f) + (shellSide * 0.4f * Random.value),
    606. (shellUp * 0.6f) + (shellUp * 0.5f * Random.value),
    607. (shellForward * 0.4f) + (shellForward * 0.2f * Random.value));
    608. //Apply velocity to shell
    609. if(shell.rigidbody){
    610. shell.rigidbody.AddForce((transform.TransformDirection(shellEjectDirection) * shellForce / Time.timeScale), ForceMode.Impulse);
    611. }
    612. //Initialize object references for instantiated shell object
    613. shell.GetComponent<ShellEjection>().playerObj = playerObj;
    614. shell.GetComponent<ShellEjection>().gunObj = transform.gameObject;
    615. }
    616.  
    617. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    618. //Set Up Fire Event
    619. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    620. void Fire (){
    621.  
    622. //do not proceed to fire if out of ammo, have already fired in semi-auto mode, or chambering last round
    623. if (bulletsLeft <= 0 || (semiAuto && semiState) || lastReload){
    624. return;
    625. }
    626. //only fire at fireRate value
    627. if(shootStartTime + fireRate > Time.time){
    628. return;
    629. }
    630.  
    631. //initialize script references and audio sources
    632. PlayerWeapons PlayerWeaponsComponent = weaponObj.GetComponent<PlayerWeapons>();
    633. Ironsights IronsightsComponent = playerObj.GetComponent<Ironsights>();
    634. AudioSource []aSources = weaponObj.GetComponents<AudioSource>();
    635. AudioSource otherfx = aSources[1] as AudioSource;
    636.  
    637. //fire weapon
    638. //don't allow fire button to interrupt a magazine reload
    639. if((bulletsToReload == bulletsPerClip && !IronsightsComponent.reloading)
    640. //allow normal firing when weapon does not reload by magazine
    641. || (!IronsightsComponent.reloading && bulletsToReload != bulletsPerClip && bulletsLeft > 0)
    642. //allow fire button to interrupt a non-magazine reload if there are at least 2 shells loaded
    643. || (IronsightsComponent.reloading && bulletsToReload != bulletsPerClip && bulletsLeft > 1 && reloadEndTime + reloadTime < Time.time)){
    644. if (canShoot && !PlayerWeaponsComponent.switching){//don't allow shooting when reloading, sprinting, or switching
    645.  
    646. //make weapon recover faster from sprinting if using the pistol sprint anim
    647. //because the gun/rifle style anims have more yaw movement and take longer to return to center
    648. if(!PistolSprintAnim){recoveryTimeAmt = 0.6f;}else{recoveryTimeAmt = 0.3f;}
    649. //reset bullets reloaded for non magazine reloading weapons
    650. if(bulletsToReload != bulletsPerClip){bulletsReloaded = 0;}
    651. //Check sprint recovery timer so gun only shoots after returning to center.
    652. //NOTE: If this is set before view rotation can return to neutral (too small a value)
    653. //the view recoil while shooting just after sprinting will "twist" strangely
    654. //for the first shot.
    655. if((recoveryTime + recoveryTimeAmt < Time.time) && (startTime + readyTime < Time.time)){
    656.  
    657. StartCoroutine("FireOneShot");//fire bullet
    658. StopCoroutine("Reload");//stop reload coroutine if interrupting a non-magazine reload
    659. IronsightsComponent.reloading = false;//update reloading var in Ironsights script if cancelling reload to fire
    660. otherfx.clip = null;//stop playing reload sound effect if cancelling reload to fire
    661.  
    662. if(meleeSwingDelay == 0){//eject shell and perform muzzle flash if not a melee weapon
    663. MuzzFlash();
    664. StartCoroutine("SpawnShell");
    665. }
    666.  
    667. //track time that we started firing and keep fire rate as frame rate independent as possible
    668. shootStartTime = Time.time - (Time.deltaTime/20.0f);
    669. shooting = true;
    670. }
    671. }
    672. }
    673.  
    674. }
    675.  
    676. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    677. //Fire Projectile
    678. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    679. IEnumerator FireOneShot (){
    680. //do not allow shooting when sprinting
    681. if (canShoot){
    682. CapsuleCollider capsule = playerObj.GetComponent<CapsuleCollider>();
    683. //Initialize audio source
    684. AudioSource []aSources = weaponObj.GetComponents<AudioSource>();
    685. AudioSource firefx = aSources[0] as AudioSource;
    686. firefx.clip = fireSnd;//play fire sound
    687. firefx.pitch = Random.Range(0.96f * Time.timeScale, 1 * Time.timeScale);//add slight random value to firing sound pitch for variety
    688. firefx.PlayOneShot(firefx.clip, 0.9f / firefx.volume);//play fire sound
    689.  
    690. if(meleeSwingDelay == 0){//if this is not a melee weapon
    691. //rewind firing animation and set speed
    692. weaponMesh.animation.Rewind("Fire");
    693. weaponMesh.animation["Fire"].speed = fireAnimSpeed;
    694. weaponMesh.animation.CrossFade("Fire", 0.35f,PlayMode.StopAll);//play firing animation
    695. //make view recoil with shot
    696. KickBack();
    697. bulletsLeft -= 1;//subtract fired bullet from magazine amount
    698.  
    699. }else{
    700.  
    701. if(swingSide){//determine which side to swing melee weapon
    702. Camera.main.animation.Rewind("CameraMeleeSwingRight");//rewind camera swing animation
    703. Camera.main.animation["CameraMeleeSwingRight"].speed = 1.7f;//set camera animation speed
    704. Camera.main.animation.CrossFade("CameraMeleeSwingRight", 0.35f,PlayMode.StopAll);//play camera view animation
    705.  
    706. weaponMesh.animation["MeleeSwingRight"].speed = fireAnimSpeed;//set weapon swing animation speed
    707. weaponMesh.animation.Play("MeleeSwingRight",PlayMode.StopAll);//play weapon swing animation
    708.  
    709. swingSide = false;//set swingSide to false to make next swing from other direction
    710. }else{
    711. Camera.main.animation.Rewind("CameraMeleeSwingLeft");//rewind camera swing animation
    712. Camera.main.animation["CameraMeleeSwingLeft"].speed = 1.6f;//set camera animation speed
    713. Camera.main.animation.CrossFade("CameraMeleeSwingLeft", 0.35f,PlayMode.StopAll);//play camera view animation
    714.  
    715. weaponMesh.animation["MeleeSwingLeft"].speed = fireAnimSpeed;//set weapon swing animation speed
    716. weaponMesh.animation.Play("MeleeSwingLeft",PlayMode.StopAll);//play weapon swing animation
    717.  
    718. swingSide = true;//set swingSide to true to make next swing from other direction
    719. }
    720. //wait for the meleeSwingDelay amount while swinging forward before hitting anything
    721. yield return new WaitForSeconds(meleeSwingDelay);
    722. }
    723. //fire the number of projectiles defined by projectileCount
    724. for(float i = 0; i < projectileCount; i++){
    725. Vector3 direction = SprayDirection();
    726. RaycastHit hit;
    727.  
    728. if(meleeSwingDelay == 0){
    729. //check for ranged weapon hit
    730. if(Physics.Raycast(Camera.main.transform.position, direction, out hit, range, bulletMask)){
    731. HitObject(hit, direction);
    732. }
    733. }else{
    734. //check for melee weapon hit
    735. //use SphereCast instead of Raycast to simulate swinging arc where melee weapon may contact objects
    736. if(Physics.SphereCast(Camera.main.transform.position, capsule.radius / 3, direction, out hit, range, bulletMask)){
    737. HitObject(hit, direction);
    738. }
    739. }
    740. }
    741. return false;
    742. }
    743.  
    744. }
    745.  
    746. //weapon or projectile damage and effects for collider that is hit
    747. void HitObject ( RaycastHit hit, Vector3 direction ){
    748. // Apply a force to the rigidbody we hit
    749. if (hit.rigidbody){
    750. hit.rigidbody.AddForceAtPosition(force * direction, hit.point);
    751. }
    752.  
    753. //Call the ApplyDamage function in the hit object
    754. hit.collider.SendMessageUpwards("ApplyDamage", damage, SendMessageOptions.DontRequireReceiver);
    755.  
    756. //Play sounds of bullets hitting surface/ricocheting
    757. AudioSource.PlayClipAtPoint(hitSounds[Random.Range(0, hitSounds.Length)], hit.point, 0.75f);
    758. //Emit tracers for fired bullet
    759. if(meleeSwingDelay == 0){
    760. BulletTracers(direction);
    761. }
    762. BulletMarks(hit);//draw a bullet mark where the weapon hit
    763. ImpactEffects(hit);//draw impact effects where the weapon hit
    764.  
    765. }
    766.  
    767. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    768. //Calculate angle of bullet fire from muzzle
    769. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    770. private Vector3 SprayDirection (){
    771. //Initialize script references
    772. FPSRigidBodyWalker FPSWalkerComponent = playerObj.GetComponent<FPSRigidBodyWalker>();
    773. FPSPlayer FPSPlayerComponent = playerObj.GetComponent<FPSPlayer>();
    774. //increase weapon accuracy if player is crouched
    775. float crouchAccuracy = 1.0f;
    776. if(FPSWalkerComponent.crouched){
    777. crouchAccuracy = 0.75f;
    778. }else{
    779. crouchAccuracy = 1.0f;
    780. }
    781. //make firing more accurate when sights are raised and/or in semi auto
    782. if(FPSPlayerComponent.zoomed && meleeSwingDelay == 0){
    783. if(fireModeSelectable && semiAuto){
    784. shotSpreadAmt = shotSpread/5 * crouchAccuracy;
    785. }else{
    786. shotSpreadAmt = shotSpread/3 * crouchAccuracy;
    787. }
    788. }else{
    789. if(fireModeSelectable && semiAuto){
    790. shotSpreadAmt = shotSpread/2 * crouchAccuracy;
    791. }else{
    792. shotSpreadAmt = shotSpread * crouchAccuracy;
    793. }
    794. }
    795. //apply accuracy spread amount to weapon facing angle
    796. float vx = (1 - 2 * Random.value) * shotSpreadAmt;
    797. float vy = (1 - 2 * Random.value) * shotSpreadAmt;
    798. float vz = 1.0f;
    799. return myTransform.TransformDirection(new Vector3(vx,vy,vz));
    800.  
    801. }
    802.  
    803. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    804. //Reload Weapon
    805. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    806. IEnumerator Reload (){
    807.  
    808. if(Time.timeSinceLevelLoad > 2){//prevent any unwanted reloading behavior at level start
    809. //Initialize script references
    810. FPSRigidBodyWalker FPSWalkerComponent = playerObj.GetComponent<FPSRigidBodyWalker>();
    811. Ironsights IronsightsComponent = playerObj.GetComponent<Ironsights>();
    812. FPSPlayer FPSPlayerComponent = playerObj.GetComponent<FPSPlayer>();
    813. AudioSource []aSources = weaponObj.GetComponents<AudioSource>();//Initialize audio source
    814. AudioSource otherfx = aSources[1] as AudioSource;
    815.  
    816. horizontal = FPSWalkerComponent.inputX;//Get input from player movement script
    817. vertical = FPSWalkerComponent.inputY;
    818.  
    819. if(!(FPSWalkerComponent.sprintActive && (Mathf.Abs(horizontal) > 0.75f || Mathf.Abs(vertical) > 0.75f))//allow reload while walking
    820. //allow auto reload when sprint button is held, even if stationary
    821. || FPSWalkerComponent.cancelSprint){
    822.  
    823. if(ammo > 0){//if player has no ammo in their inventory for this weapon, do not proceed with reload
    824.  
    825. //cancel zooming when reloading
    826. FPSPlayerComponent.zoomed = false;
    827.  
    828. //if loading by magazine, start these reloading actions immediately and wait for reloadTime before adding ammo and completing reload
    829. if(bulletsToReload == bulletsPerClip){
    830. //play reload sound once at start of reload
    831. otherfx.volume = 1.0f;
    832. otherfx.pitch = 1.0f * Time.timeScale;
    833. otherfx.clip = reloadSnd;
    834. otherfx.PlayOneShot(otherfx.clip, 1.0f / otherfx.volume);//play magazine reload sound effect
    835.  
    836. //determine which weapon is selected and play camera view reloading animation
    837. if(!PistolSprintAnim){
    838. if(weaponNumber == 5 || weaponNumber == 6){
    839. //rewind animation if already playing to allow overlapping playback
    840. Camera.main.animation.Rewind("CameraReloadAK47");
    841. //set camera reload animation speed to positive value to play forward because
    842. //it might have been reversed if we canceled a reload by sprinting
    843. Camera.main.animation.animation["CameraReloadAK47"].speed = 1.0f;
    844. Camera.main.animation.CrossFade("CameraReloadAK47", 0.35f,PlayMode.StopAll);
    845. }else{
    846. Camera.main.animation.Rewind("CameraReloadMP5");
    847. Camera.main.animation.animation["CameraReloadMP5"].speed = 1.0f;
    848. Camera.main.animation.CrossFade("CameraReloadMP5", 0.35f,PlayMode.StopAll);
    849. }
    850. }else{
    851. Camera.main.animation.Rewind("CameraReloadPistol");
    852. Camera.main.animation.animation["CameraReloadPistol"].speed = 1.0f;
    853. Camera.main.animation.CrossFade("CameraReloadPistol", 0.35f,PlayMode.StopAll);
    854. }
    855.  
    856. //Rewind reloading animation, set speed, and play animation. This can cause sudden/jerky start of reload anim
    857. //if sprinting very briefly, but is necessary to keep reload animation and sound synchronized.
    858. weaponMesh.animation.Rewind("Reload");
    859. weaponMesh.animation["Reload"].speed = reloadAnimSpeed;
    860. weaponMesh.animation.CrossFade("Reload", 0.35f,PlayMode.StopAll);//play reloading animation
    861. }
    862.  
    863. //set reloading var in ironsights script to true
    864. IronsightsComponent.reloading = true;
    865. reloadStartTime = Time.time;
    866. //do not wait for reloadTime if this is not a magazine reload and this is the first bullet/shell to be loaded,
    867. //otherwise, adding of ammo and finishing reload will wait for reloadTime while animation and sound plays
    868. if((bulletsToReload != bulletsPerClip && bulletsReloaded > 0) || bulletsToReload == bulletsPerClip){
    869. // Wait for reload time first, then proceed
    870. yield return new WaitForSeconds(reloadTime);
    871. }
    872.  
    873. //determine how many bullets need to be reloaded
    874. bulletsNeeded = bulletsPerClip - bulletsLeft;
    875.  
    876. //if loading a magazine, update bullet amount and set reloading var to false after reloadTime has elapsed
    877. if(bulletsToReload == bulletsPerClip){
    878.  
    879. //set reloading var in ironsights script to false after reloadTime has elapsed
    880. IronsightsComponent.reloading = false;
    881.  
    882. //we have ammo left to reload
    883. if(ammo >= bulletsNeeded){
    884. ammo -= bulletsNeeded;//subtract bullets needed from total ammo
    885. bulletsLeft = bulletsPerClip;//add bullets to magazine
    886. }else{
    887. bulletsLeft += ammo;//if ammo left is less than needed to reload, so just load all remaining bullets
    888. ammo = 0;//out of ammo for this weapon now
    889. }
    890.  
    891. }else{//If we are reloading weapon one bullet at a time (or bulletsToReload is less than the magazine amount) run code below
    892. //determine if bulletsToReload var needs to be changed based on how many bullets need to be loaded
    893. if(bulletsNeeded >= bulletsToReload){//bullets needed are more or equal to bulletsToReload amount, so add bulletsToReload amount
    894. if(ammo >= bulletsToReload){
    895. bulletsLeft += bulletsToReload;//add bulletsToReload amount to magazine
    896. ammo -= bulletsToReload;//subtract bullets needed from total ammo
    897. bulletsReloaded ++;//increment bulletsReloaded so we can track our progress in this non-magazine reload
    898. }else{
    899. bulletsLeft += ammo;//if ammo left is less than needed to reload, just load all remaining bullets
    900. ammo = 0;//out of ammo for this weapon now
    901. }
    902. }else{//if bullets needed are less than bulletsToReload amount, just add the ammo that is needed
    903. if(ammo >= bulletsNeeded){
    904. bulletsLeft += bulletsNeeded;
    905. ammo -= bulletsNeeded;//subtract bullets needed from total ammo
    906. bulletsReloaded ++;//increment bulletsReloaded so we can track our progress in this non-magazine reload
    907. }else{
    908. bulletsLeft += ammo;//if ammo left is less than needed to reload, just load all remaining bullets
    909. ammo = 0;//out of ammo for this weapon now
    910. }
    911. }
    912.  
    913. if(bulletsNeeded > 0){//if bullets still need to be reloaded and we are not loading a magazine
    914. StartCoroutine("Reload");//start reload coroutine again to load number of bullets defined by bulletsToReload amount
    915. }else{
    916. IronsightsComponent.reloading = false;//if magazine is full, set reloading var in ironsights script to false
    917. bulletsReloaded = 0;
    918. return false;//also stop coroutine here to prevent sound from playing below
    919. }
    920.  
    921. if(bulletsNeeded == bulletsToReload || ammo <= 0){//if reloading last round, play normal reloading sound and also chambering effect
    922. otherfx.clip = reloadLastSnd;//set otherfx audio clip to reloadLastSnd
    923. weaponMesh.animation["Reload"].speed = 1.0f;
    924. //track time we started reloading last bullet to allow for additional time to chamber round before allowing weapon firing
    925. reloadLastStartTime = Time.time;
    926. IronsightsComponent.reloading = false;
    927. }else{
    928. otherfx.clip = reloadSnd;//set otherfx audio clip to reloadSnd
    929. weaponMesh.animation["Reload"].speed = shellRldAnimSpeed;
    930.  
    931. }
    932.  
    933. //play reloading sound effect
    934. otherfx.volume = 1.0f;
    935. otherfx.pitch = Random.Range(0.95f * Time.timeScale, 1 * Time.timeScale);
    936. otherfx.PlayOneShot(otherfx.clip, 1.0f / otherfx.volume);
    937. //play reloading animation
    938. weaponMesh.animation.Rewind("Reload");
    939. weaponMesh.animation.CrossFade("Reload", 0.35f,PlayMode.StopAll);
    940.  
    941. //play camera reload animation
    942. Camera.main.animation.Rewind("CameraReloadSingle");
    943. //set camera reload animation speed to positive value to play forward because
    944. //it might have been reversed if we canceled a reload by sprinting
    945. Camera.main.animation.animation["CameraReloadSingle"].speed = 1.0f;
    946. Camera.main.animation.CrossFade("CameraReloadSingle", 0.35f,PlayMode.StopAll);
    947.  
    948. reloadEndTime = Time.time;//track time that we finished reload to determine if this reload can be interrupted by fire button
    949.  
    950. }
    951. }
    952. }
    953. }
    954.  
    955. }
    956.  
    957. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    958. //Draw Bullet Tracers
    959. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    960. void BulletTracers ( Vector3 direction ){
    961. //Draw Bullet Tracers
    962. if (tracerParticles) {
    963. //Set tracer origin to a small amount forward of the end of gun barrel (muzzle flash position)
    964. tracerParticles.transform.position = muzzleFlash.transform.position + muzzleFlash.transform.forward * 0.5f;
    965. //add shotSpray/accuracy value to straight-forward rotation to make tracers follow raycast to hit position
    966. tracerParticles.transform.rotation = Quaternion.FromToRotation(Vector3.forward, direction);
    967. //emit tracer particle for every shot fired
    968. tracerParticles.Emit();
    969. }
    970.  
    971. }
    972.  
    973. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    974. //Draw Impact Effects
    975. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    976. void ImpactEffects ( RaycastHit hit ){
    977. //draw bullet impact effects
    978. if (hitSpark){//bright, circular sparks around hit location with very short duration
    979. hitSpark.transform.position = hit.point + (hit.normal * 0.075f);//align emitter position with contact position and move up from surface slightly
    980. hitSpark.transform.rotation = Quaternion.FromToRotation(Vector3.up, hit.normal);//rotate impact effects so they are perpendicular to surface hit
    981. hitSpark.Emit();//emit the particle(s)
    982. }
    983. if (sparkParticles){//fast, bright sparks that bounce against world colliders
    984. sparkParticles.transform.position = hit.point;
    985. sparkParticles.transform.rotation = Quaternion.FromToRotation(Vector3.up, hit.normal);
    986. sparkParticles.Emit();
    987. }
    988. if (slowSmokeParticles && meleeSwingDelay == 0) {//large puff of smoke that moves upwards slowly and lingers
    989. slowSmokeParticles.transform.position = hit.point;
    990. slowSmokeParticles.transform.rotation = Quaternion.FromToRotation(Vector3.up, hit.normal);
    991. slowSmokeParticles.Emit();
    992. }
    993. if(meleeSwingDelay == 0){
    994. if (fastSmokeParticles) {//medium size smoke puff that quickly moves upwards from impact point and dissapates
    995. fastSmokeParticles.transform.position = hit.point;
    996. fastSmokeParticles.transform.rotation = Quaternion.FromToRotation(Vector3.up, hit.normal);
    997. fastSmokeParticles.Emit();
    998. }
    999. }
    1000. if (debrisParticles){//opaque debris that emit from impact point and bounce against world colliders
    1001. debrisParticles.transform.position = hit.point;
    1002. debrisParticles.transform.rotation = Quaternion.FromToRotation(Vector3.up, hit.normal);
    1003. debrisParticles.Emit();
    1004. }
    1005.  
    1006. }
    1007.  
    1008. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    1009. //Draw Bullet Marks
    1010. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    1011. void BulletMarks ( RaycastHit hit ){
    1012. if(hit.collider//check only objects with colliders attatched to prevent null reference error
    1013. && hit.collider.gameObject.layer != 9//don't leave marks on ragdolls
    1014. && hit.collider.gameObject.tag != "NoHitMark"//don't leave marks on active NPCs or objects with NoHitMark or PickUp tag
    1015. && hit.collider.gameObject.tag != "PickUp"){
    1016. //create an instance of the bullet mark and place it parallel and slightly above the hit surface to prevent z buffer fighting
    1017. GameObject clone = Instantiate(BulletMarkObj[Random.Range(0, BulletMarkObj.Length)], hit.point + (hit.normal * 0.025f), Quaternion.FromToRotation(Vector3.up, hit.normal)) as GameObject;
    1018. //create empty game object for parent of bullet mark to prevent bullet mark object from inheriting hit object's scale
    1019. //we do this to create another layer between the bullet mark object and the hit object which may have been unevenly scaled in editor
    1020. var emptyObject = new GameObject();
    1021. //define transforms for efficiency
    1022. Transform tempObjTransform = emptyObject.transform;
    1023. Transform cloneTransform = clone.transform;
    1024. //save initial scaling of bullet mark prefab object
    1025. Vector3 scale = cloneTransform.localScale;
    1026. //set parent of empty game object to hit object's transform
    1027. tempObjTransform.parent = hit.transform;
    1028. //set scale of empty game object to (1,1,1) to prepare it for applying the inverse scale of the object that was hit
    1029. tempObjTransform.localScale = Vector3.one;
    1030. //sync empty game object's rotation quaternion with hit object's quaternion for correct scaling of euler angles (use the same orientation of axes)
    1031. Quaternion tempQuat = hit.transform.rotation;
    1032. tempObjTransform.rotation = tempQuat;
    1033. //calculate inverse of hit object's scale to compensate for objects that have been unevenly scaled in editor
    1034. Vector3 tempScale1 = new Vector3(1.0f / tempObjTransform.parent.transform.localScale.x,
    1035. 1.0f / tempObjTransform.parent.transform.localScale.y,
    1036. 1.0f / tempObjTransform.parent.transform.localScale.z);
    1037. //apply inverse scale of the collider that was hit to empty game object's transform
    1038. tempObjTransform.localScale = tempScale1;
    1039. //set parent of bullet mark object to empy game object and set localScale to (1,1,1)
    1040. cloneTransform.parent = null;
    1041. cloneTransform.parent = tempObjTransform;
    1042. //apply hit mark's initial scale to hit mark instance
    1043. cloneTransform.localScale = scale;
    1044. //randomly scale bullet marks slightly for more natural visual effect
    1045. if(meleeSwingDelay == 0){//not a melee weapon
    1046. float tempScale = Random.Range (-0.25f, 0.25f);//find random scale amount
    1047. cloneTransform.localScale = scale + new Vector3(tempScale, 0, tempScale);//apply random scale to bullet mark object's localScale
    1048. }
    1049. //rotate hit mark randomly for more variation
    1050. cloneTransform.RotateAround(hit.point, hit.normal, Random.Range (-50, 50));
    1051. //destroy bullet mark instance after a time
    1052. Destroy(clone.gameObject, 30);
    1053. }
    1054.  
    1055. }
    1056.  
    1057. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    1058. //Camera Recoil Kick
    1059. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    1060. void KickBack (){
    1061. //Initialize script references
    1062. FPSRigidBodyWalker FPSWalkerComponent = playerObj.GetComponent<FPSRigidBodyWalker>();
    1063. FPSPlayer FPSPlayerComponent = playerObj.GetComponent<FPSPlayer>();
    1064. //make recoil less when zoomed in and more when zoomed out
    1065. if(FPSPlayerComponent.zoomed && meleeSwingDelay == 0){
    1066. kickUpAmt = kickUp;//set kick amounts to those set in the editor
    1067. kickSideAmt = kickSide;
    1068. }else{
    1069. if(!FPSWalkerComponent.crouched
    1070. //normal view kick when crouching and not moving
    1071. ||(FPSWalkerComponent.crouched && Mathf.Abs(horizontal) == 0 && Mathf.Abs(vertical) == 0)){
    1072. kickUpAmt = kickUp * 1.75f;
    1073. kickSideAmt = kickSide * 1.75f;
    1074. }else{
    1075. //increase view kick to offset increased bobbing
    1076. //amounts when crouching and moving
    1077. kickUpAmt = kickUp * 2.75f;
    1078. kickSideAmt = kickSide * 2.75f;
    1079. }
    1080. }
    1081. //Set rotation quaternion to random kick values
    1082. kickRotation = Quaternion.Euler(Camera.main.transform.localRotation.eulerAngles - new Vector3(kickUpAmt * 2, Random.Range(-kickSideAmt * 2, kickSideAmt * 2), 0));
    1083. //smooth current camera angles to recoil kick up angles using Slerp
    1084. Camera.main.transform.localRotation = Quaternion.Slerp(myTransform.localRotation, kickRotation, 0.1f);
    1085. }
    1086.  
    1087. }
    1088.  

    and the place object script. it is javascript.

    Code (JavaScript):
    1. #pragma strict
    2.  
    3. var TowerPrefab : Transform;
    4.  
    5. function Update () {
    6. if(Input.GetKeyDown("c"))
    7. {
    8. var ray = Camera.main.ScreenPointToRay (Input.mousePosition);
    9. var hit : RaycastHit;
    10. if (Physics.Raycast (ray, hit))
    11. Instantiate(TowerPrefab, hit.point, Quaternion.identity);
    12. }
    13. }
     

    Attached Files:

    Last edited: Oct 2, 2014
  2. Suddoha

    Suddoha

    Joined:
    Nov 9, 2013
    Posts:
    2,824
    Oh wow, such as long post. It's even more important to use code tags here. Please update/re-post your code with code tags.
     
  3. radar089

    radar089

    Joined:
    Jan 2, 2014
    Posts:
    216
    ok done sry bout that
     
  4. radar089

    radar089

    Joined:
    Jan 2, 2014
    Posts:
    216
    so did you have any input besides that? i need heeelp lol.
     
  5. Suddoha

    Suddoha

    Joined:
    Nov 9, 2013
    Posts:
    2,824
    You basically only need to find the fire method and call the code then (without the if statement). If you wanna do it in one script (as you talked about combining those two) you need to convert it to C#, maybe put it into a function and call this function whenever it's needed.

    I haven't had a look at the full script, it's still not well formatted and pretty long (if you click on the fourth icon from the right, choose code and pass in your code, it should almost look like the original code from monodelevop/VS). Unfortunately it's still a pain to read through. :p

    So far, one thing i personally don't like about the first script is that references are pulled every fixedUpdate, which can most likely be avoided and save overhead.
     
  6. radar089

    radar089

    Joined:
    Jan 2, 2014
    Posts:
    216
    i really have no scripting background at all. i do allot of work in blender atm. the first script i dont really want to alter besides adding the blocks since it works great ingame. very fast.
     
  7. radar089

    radar089

    Joined:
    Jan 2, 2014
    Posts:
    216
    but if u can help at all you will be credited. and who knows how things will go later with a kickstarter :)
     
  8. Suddoha

    Suddoha

    Joined:
    Nov 9, 2013
    Posts:
    2,824
    You can add
    Code (CSharp):
    1. Instantiate(TowerPrefab, hit.point, Quaternion.identity);
    to the 'HitObject' method. Ofcourse you'll need to add the variable to the script with
    Code (CSharp):
    1. public GameObject TowerPrefab;
    However, depending on your prefab that you'll spawn this may cause unexpected collisions/behaviour, as you said you want to use a lot of physics controlled objects in your scenes.

    Just curious, but why are the walls supposed to drop weapons? :)
     
  9. radar089

    radar089

    Joined:
    Jan 2, 2014
    Posts:
    216
    well im no coder... i can follow a script somewhat though. i have done allot of brackeys and speedtutor tutorials.
    when an enemy dies they can be replaced with something. say a pistol or ammo.

    so my walls all have a cut down version of the npc health script on them alsoe, so i can make a wall leave behind a weapon.

    this weapon will be a pistol prefab with the pistol mesh replaced with a block mesh. it will look like your holding a brick or block or whatever it is you destroyed.

    at this point i needed the weapons script merged with the place object script. So that when i shoot the block a block is placed.

    this is my half ass late night drinking attempt at a minecraft type system.
     
  10. radar089

    radar089

    Joined:
    Jan 2, 2014
    Posts:
    216
    imagine, busting down a brick wall with a sledge hammer for blocks to build fortifications.