You cannot select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
	
	
		
			199 lines
		
	
	
		
			8.2 KiB
		
	
	
	
		
			C#
		
	
			
		
		
	
	
			199 lines
		
	
	
		
			8.2 KiB
		
	
	
	
		
			C#
		
	
using System.Collections;
 | 
						|
using System.Collections.Generic;
 | 
						|
using UnityEngine;
 | 
						|
 | 
						|
namespace Autohand {
 | 
						|
    [RequireComponent(typeof(AutoGun))]
 | 
						|
    public class AutoGunEffects : MonoBehaviour {
 | 
						|
 | 
						|
 | 
						|
        [AutoSmallHeader("Visual Effects")]
 | 
						|
        public bool ignoreMe3;
 | 
						|
        [Tooltip("Whether or not racking the slide with a bullet already in the chamber ejects that bullet or not")]
 | 
						|
        public bool ejectUnfiredBullet = true;
 | 
						|
        [Tooltip("This is the unfired bullet prefab that will be instantiated and ejected if the 'ejectUnfiredBullet' value is true and the slide is racked while full")]
 | 
						|
        public GameObject bullet;
 | 
						|
        [Tooltip("This is the fired bullet shell prefab that will be instantiated and ejected if the when the gun is shot")]
 | 
						|
        public GameObject bulletShell;
 | 
						|
        [Tooltip("Particle effect that plays from the gun aim transform on shoot")]
 | 
						|
        public ParticleSystem shootParticle;
 | 
						|
        [Tooltip("The lifetime of the ejected bullets before they are added to the pool")]
 | 
						|
        public float ejectedBulletLifetime = 3f;
 | 
						|
        [Tooltip("The position and rotation where the bullets are instantiated")]
 | 
						|
        public Transform shellEjectionSpawnPoint;
 | 
						|
        [Tooltip("The forward direction of this point represents the direction the shells should be ejected")]
 | 
						|
        public Transform shellEjectionDirection;
 | 
						|
        [Tooltip("The amount of force to add to the ejected bullet")]
 | 
						|
        public float shellEjectionForce = 50;
 | 
						|
 | 
						|
        [AutoSmallHeader("Sound Effects")]
 | 
						|
        public bool ignoreMe4;
 | 
						|
        [Tooltip("This sound will play when a bullet is fired")]
 | 
						|
        public AudioSource shootSound;
 | 
						|
        [Tooltip("This sound will play when a the trigger is pressed and there is nothing to shoot")]
 | 
						|
        public AudioSource emptyShootSound;
 | 
						|
 | 
						|
        Dictionary<GameObject, float> bulletLifetimeTracker = new Dictionary<GameObject, float>();
 | 
						|
        Dictionary<GameObject, float> shellLifetimeTracker = new Dictionary<GameObject, float>();
 | 
						|
        List<GameObject> bulletPool = new List<GameObject>();
 | 
						|
        List<GameObject> bulletShellPool = new List<GameObject>();
 | 
						|
 | 
						|
        List<ParticleSystem> activeParticlePool = new List<ParticleSystem>();
 | 
						|
        List<ParticleSystem> inactiveParticlePool = new List<ParticleSystem>();
 | 
						|
        AutoGun gun;
 | 
						|
 | 
						|
 | 
						|
        private void OnEnable(){
 | 
						|
            gun = GetComponent<AutoGun>();
 | 
						|
            gun.OnShoot.AddListener(OnShoot);
 | 
						|
            gun.OnEmptyShoot.AddListener(OnEmptyShoot);
 | 
						|
            gun.OnSlideEvent.AddListener(OnSlideLoaded);
 | 
						|
        }
 | 
						|
 | 
						|
        private void OnDisable(){
 | 
						|
            gun.OnShoot.RemoveListener(OnShoot);
 | 
						|
            gun.OnEmptyShoot.RemoveListener(OnEmptyShoot);
 | 
						|
            gun.OnSlideEvent.RemoveListener(OnSlideLoaded);
 | 
						|
        }
 | 
						|
 | 
						|
        private void FixedUpdate() {
 | 
						|
            CheckBulletLifetime();
 | 
						|
            CheckParticlPlaying();
 | 
						|
 | 
						|
        }
 | 
						|
 | 
						|
        void CreateShootParticle() {
 | 
						|
            if(shootParticle != null) {
 | 
						|
                var newShootParticle = GameObject.Instantiate(shootParticle);
 | 
						|
                newShootParticle.transform.position = gun.shootForward.position;
 | 
						|
                newShootParticle.transform.forward = gun.shootForward.forward;
 | 
						|
                activeParticlePool.Add(newShootParticle);
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        void OnShoot(AutoGun gun){
 | 
						|
            shootSound?.PlayOneShot(shootSound.clip);
 | 
						|
            CreateShootParticle();
 | 
						|
        }
 | 
						|
 | 
						|
        void OnEmptyShoot(AutoGun gun){
 | 
						|
            emptyShootSound?.PlayOneShot(emptyShootSound.clip);
 | 
						|
        }
 | 
						|
 | 
						|
        void OnSlideLoaded(AutoGun gun, SlideLoadType loadType) {
 | 
						|
 | 
						|
            if(loadType == SlideLoadType.ShotLoaded){
 | 
						|
                if(gun.slideJoint != null) {
 | 
						|
                    if(Mathf.Abs(gun.slideJoint.xMinLimit) >= gun.slideJoint.xMaxLimit &&
 | 
						|
                        Mathf.Abs(gun.slideJoint.yMinLimit) >= gun.slideJoint.yMaxLimit &&
 | 
						|
                        Mathf.Abs(gun.slideJoint.zMinLimit) >= gun.slideJoint.zMaxLimit)
 | 
						|
                        gun.slideJoint.SetJointMin();
 | 
						|
                    else
 | 
						|
                        gun.slideJoint.SetJointMax();
 | 
						|
                }
 | 
						|
 | 
						|
                EjectShell();
 | 
						|
            }
 | 
						|
            else if(gun.IsSlideLoaded()) {
 | 
						|
                EjectBullet();
 | 
						|
            }
 | 
						|
 | 
						|
        }
 | 
						|
 | 
						|
        public void EjectBullet() {
 | 
						|
            if(bullet != null) {
 | 
						|
                GameObject newBullet;
 | 
						|
                if(bulletPool.Count > 0) {
 | 
						|
                    newBullet = bulletPool[0];
 | 
						|
                    bulletPool.RemoveAt(0);
 | 
						|
                    newBullet.transform.position = shellEjectionSpawnPoint.position;
 | 
						|
                    newBullet.transform.rotation = shellEjectionSpawnPoint.rotation;
 | 
						|
                    newBullet.SetActive(true);
 | 
						|
                }
 | 
						|
                else {
 | 
						|
                    newBullet = Instantiate(bullet, shellEjectionSpawnPoint.position, shellEjectionSpawnPoint.rotation);
 | 
						|
                }
 | 
						|
 | 
						|
                if(newBullet.CanGetComponent<Rigidbody>(out var body)) {
 | 
						|
                    if(AutoHandPlayer.Instance.IsHolding(gun.grabbable))
 | 
						|
                        body.velocity = AutoHandPlayer.Instance.body.velocity;
 | 
						|
                    body.velocity += gun.grabbable.body.velocity;
 | 
						|
                    body.AddForce(shellEjectionDirection.forward * shellEjectionForce, ForceMode.Force);
 | 
						|
                }
 | 
						|
                bulletLifetimeTracker.Add(newBullet, ejectedBulletLifetime);
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        public void EjectShell() {
 | 
						|
            if(bulletShell != null) {
 | 
						|
                GameObject newShell;
 | 
						|
                if(bulletShellPool.Count > 0) {
 | 
						|
                    newShell = bulletShellPool[0];
 | 
						|
                    bulletShellPool.RemoveAt(0);
 | 
						|
                    newShell.transform.position = shellEjectionSpawnPoint.position;
 | 
						|
                    newShell.transform.rotation = shellEjectionSpawnPoint.rotation;
 | 
						|
                    newShell.SetActive(true);
 | 
						|
                }
 | 
						|
                else {
 | 
						|
                    newShell = Instantiate(bulletShell, shellEjectionSpawnPoint.position, shellEjectionSpawnPoint.rotation);
 | 
						|
                }
 | 
						|
 | 
						|
                if(newShell.CanGetComponent<Rigidbody>(out var body)) {
 | 
						|
                    if(AutoHandPlayer.Instance.IsHolding(gun.grabbable))
 | 
						|
                        body.velocity = AutoHandPlayer.Instance.body.velocity;
 | 
						|
                    body.velocity += gun.grabbable.body.velocity;
 | 
						|
                    body.AddForce(shellEjectionDirection.forward * shellEjectionForce, ForceMode.Force);
 | 
						|
 | 
						|
                }
 | 
						|
                shellLifetimeTracker.Add(newShell, ejectedBulletLifetime);
 | 
						|
            }
 | 
						|
 | 
						|
        }
 | 
						|
 | 
						|
 | 
						|
 | 
						|
        void CheckBulletLifetime() {
 | 
						|
            if(bulletLifetimeTracker.Count > 0) {
 | 
						|
                var bulletKeys = new GameObject[bulletLifetimeTracker.Count];
 | 
						|
                bulletLifetimeTracker.Keys.CopyTo(bulletKeys, 0);
 | 
						|
                foreach(var bullet in bulletKeys) {
 | 
						|
                    bulletLifetimeTracker[bullet] -= Time.deltaTime;
 | 
						|
                    if(bulletLifetimeTracker[bullet] <= 0) {
 | 
						|
                        bullet.SetActive(false);
 | 
						|
                        bulletPool.Add(bullet);
 | 
						|
                        bulletLifetimeTracker.Remove(bullet);
 | 
						|
                    }
 | 
						|
                }
 | 
						|
            }
 | 
						|
 | 
						|
            if(shellLifetimeTracker.Count > 0) {
 | 
						|
                var shellKeys = new GameObject[shellLifetimeTracker.Count];
 | 
						|
                shellLifetimeTracker.Keys.CopyTo(shellKeys, 0);
 | 
						|
                foreach(var shell in shellKeys) {
 | 
						|
                    shellLifetimeTracker[shell] -= Time.deltaTime;
 | 
						|
                    if(shellLifetimeTracker[shell] <= 0) {
 | 
						|
                        shell.SetActive(false);
 | 
						|
                        bulletShellPool.Add(shell);
 | 
						|
                        shellLifetimeTracker.Remove(shell);
 | 
						|
                    }
 | 
						|
                }
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
 | 
						|
 | 
						|
        void CheckParticlPlaying() {
 | 
						|
            if(inactiveParticlePool.Count > 0) {
 | 
						|
                var playingKeys = new ParticleSystem[activeParticlePool.Count];
 | 
						|
                activeParticlePool.CopyTo(playingKeys, 0);
 | 
						|
                foreach(var particle in playingKeys) {
 | 
						|
                    if(!particle.isPlaying)
 | 
						|
                        particle.gameObject.SetActive(false);
 | 
						|
                    inactiveParticlePool.Add(particle);
 | 
						|
                    activeParticlePool.Remove(particle);
 | 
						|
                }
 | 
						|
            }
 | 
						|
        }
 | 
						|
    }
 | 
						|
}
 |