Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- public class BulletManagerExample : MonoBehaviour{
- public GameObject bulletExplosion;
- public Material bulletLine;
- public LayerMask bulletCollisionMask;
- public Transform bulletEmitterTransform;
- public Color bulletTrailColor1;
- public Color bulletTrailColor2;
- void Start(){
- BulletManager.Init(bulletCollisionMask, bulletLine, bulletExplosion);
- }
- void Update(){
- BulletManager.Shoot(bulletEmitterTransform.position, (bulletEmitterTransform.forward + (Random.onUnitSphere * 0.2f)).normalized, 200f);
- BulletManager.UpdateBulletManager();
- }
- void OnPostRender() {
- BulletManager.RenderBulletTrails();
- }
- void OnDrawGizmos() {
- Gizmos.color = Color.red;
- Gizmos.DrawCube(bulletEmitterTransform.position, bulletEmitterTransform.localScale);
- Gizmos.DrawLine(bulletEmitterTransform.position, bulletEmitterTransform.position + bulletEmitterTransform.forward);
- }
- }
- [RequireComponent(typeof(ParticleSystem))]
- public class BulletExplosion : MonoBehaviour{
- public ParticleSystem particles;
- private void Awake() {
- var main = particles.main;
- main.stopAction = ParticleSystemStopAction.Callback;
- }
- void OnParticleSystemStopped() {
- BulletManager.ReturnBulletExposionToPool(this);
- }
- }
- public static class BulletManager {
- struct Bullet {
- public Vector3 position;
- public Vector3 lastRenderedPosition;
- public Vector3 direction;
- public float velocity;
- public float aliveTime;
- public Bullet(Vector3 pos, Vector3 dir, float vel, float time) {
- position = lastRenderedPosition = pos;
- direction = dir;
- velocity = vel;
- aliveTime = time;
- }
- }
- const float BULLET_LIVE_TIME = 10f;
- static int layerMask;
- static Material material;
- static GameObject explosion;
- static Stack<BulletExplosion> explosions;
- static Bullet[] bulletsArray;
- static int bulletsCreated;
- static int[] freeIndexStack;
- static int freeIndexStackLength;
- public static Color col1, col2;
- public static void Init(LayerMask bulletCollisionMask, Material bulletMaterial, GameObject bulletExplosion) {
- layerMask = bulletCollisionMask.value;
- material = bulletMaterial;
- explosion = bulletExplosion;
- explosions = new Stack<BulletExplosion>();
- bulletsArray = new Bullet[10];
- bulletsCreated = 0;
- freeIndexStack = new int[10];
- freeIndexStackLength = 0;
- }
- public static void Shoot(Vector3 position, Vector3 direction, float velocity) {
- int index = freeIndexStackLength > 0 ? freeIndexStack[--freeIndexStackLength] : bulletsCreated++;
- if (index == bulletsArray.Length)
- System.Array.Resize(ref bulletsArray, bulletsArray.Length * 2);
- bulletsArray[index] = new Bullet(position, direction, velocity, BULLET_LIVE_TIME);
- }
- public static void ReturnBulletExposionToPool(BulletExplosion explosion) {
- explosions.Push(explosion);
- }
- public static void RenderBulletTrails() {
- GL.Begin(GL.LINES);
- material.SetPass(0);
- for (int bulletIndex = 0; bulletIndex < bulletsCreated; bulletIndex++) {
- Bullet bullet = bulletsArray[bulletIndex];
- if (bullet.aliveTime > 0f) {
- GL.Vertex(bullet.lastRenderedPosition);
- GL.Vertex(bullet.position);
- bulletsArray[bulletIndex].lastRenderedPosition = bullet.position;
- }
- }
- GL.End();
- }
- public static void UpdateBulletManager() {
- float deltaTime = Time.deltaTime;
- for (int bulletIndex = 0; bulletIndex < bulletsCreated; bulletIndex++) {
- Bullet bullet = bulletsArray[bulletIndex];
- if (bullet.aliveTime <= 0f)
- continue;
- float travelDistance = bullet.velocity * deltaTime;
- Vector3 newPos = bullet.position + (bullet.direction * travelDistance);
- float bulletLiveTime = bullet.aliveTime - deltaTime;
- RaycastHit hit;
- if (Physics.Raycast(bullet.position, bullet.direction, out hit, travelDistance, layerMask)) {
- bulletLiveTime = 0f;
- BulletExplosion explosionEffect = explosions.Count > 0 ? explosions.Pop() : Object.Instantiate(explosion).GetComponent<BulletExplosion>();
- explosionEffect.transform.position = hit.point;
- explosionEffect.particles.Play();
- }
- if (bulletLiveTime <= 0f) {
- if (freeIndexStack.Length == freeIndexStackLength)
- System.Array.Resize(ref freeIndexStack, freeIndexStack.Length * 2);
- freeIndexStack[freeIndexStackLength++] = bulletIndex;
- }
- bulletsArray[bulletIndex].aliveTime = bulletLiveTime;
- bulletsArray[bulletIndex].position = newPos;
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement