// use this function to instantiate already indexed gameobject in prefab pool // and add gameobject into pool automatically public GameObject AddGameobject(string indexKey) { // check the avaiblelity of pool List <GameObject> poolRef; this.gameObjectsPools.TryGetValue(indexKey, out poolRef); if (poolRef == null) { return(null); } // instantiate gameObject and set to not active GameObject reference = Instantiate(this.gameObjectsPrefabPools[indexKey] , transform); reference.SetActive(false); // add to pool poolRef.Add(reference); // Add properties into PooledGameObjectManager PooledGameObjectManager pooled = reference.GetComponent <PooledGameObjectManager>(); pooled.SetProperties(indexKey, this.gameObjectsPrefabPools[indexKey]); return(reference); }
public void DeleteRandom() { if (this.pooleds.Count == 0) { return; } int randomIndex = Random.Range(0, this.pooleds.Count); PooledGameObjectManager reference = this.pooleds[randomIndex]; GameObjectPoolManager.poolManager["Main"].DestroyGameobject(reference.gameObject); this.pooleds.RemoveAt(randomIndex); }
///<summary>Use this function to remove Gameobject from scene into pool, ///and don't use this on non-pooled Gameobject ///<param name="reference">Gameobject that want to be destroyed</param> ///</summary> // use this function to deinstantiate gameobject from pool public void DestroyGameobject(GameObject reference) { // OnDestroyEvent PooledGameObjectManager pooled = reference.GetComponent <PooledGameObjectManager>(); pooled.OnDestroyed(); reference.transform.parent = transform; reference.transform.localPosition = Vector3.zero; reference.transform.localRotation = Quaternion.identity; // set gameobject as disable(available for use) reference.SetActive(false); }
///<summary>Use this function to Instantiate Gameobject from pool ///<param name="indexKey">Pooled gameobject ID(string)</param> ///<param name="where">Where gameobject will be instantiated</param> ///<param name="rotation">Instantiated gameobject rotation</param> ///<returns>Return reference to instantiated gameobject ///, or return <c>null</c> of no pool found</returns> ///</summary> // use this function to instantiate gameobject from pool // don't use this function for non gameobject from pool // return null if no pool found // return reference to gameobject instantiated from pool if succeed public GameObject InstantiateGameobject(string indexKey, Vector3 where, Quaternion rotation) { List <GameObject> poolRef; this.gameObjectsPools.TryGetValue(indexKey, out poolRef); if (poolRef == null) { Debug.Log(indexKey + " not found"); return(null); } GameObject reference = null; bool notAvailable = true; // Search for available gameobject // available gameobject always not active foreach (GameObject available in poolRef) { if (!available.activeSelf) { reference = available; notAvailable = false; break; } } // if not available // create a new gameobject from prefabPool and add to pool // get the reference if (notAvailable) { reference = AddGameobject(indexKey); } reference.SetActive(true); // detach from parent and Move and Rotate reference.transform.parent = null; reference.transform.position = where; reference.transform.rotation = rotation; // OnInstantiateEvent PooledGameObjectManager pooled = reference.GetComponent <PooledGameObjectManager>(); pooled.OnInstantiate(); return(reference); }
//############################################################################################## // Check for required data, then setup the gun //############################################################################################## protected void Start() { if (muzzleTransform == null) { Logger.Error("Muzzle Actor on " + gameObject.name + "'s GunComponent cannot be null"); } gunTimer = new Timer(currentGunData.coolDown); reloadTimer = new Timer(currentGunData.reloadTime); player = GetComponent <FirstPersonPlayerComponent>(); if (currentGunData.usePooledBullets) { if (!PooledGameObjectManager.HasPoolForIdentifier(currentGunData.poolIdentifier)) { PooledGameObjectManager.SetupPool(currentGunData.poolIdentifier, currentGunData.poolSize, currentGunData.bulletPrefab); } } }
//############################################################################################## // Update the bullet, moving it along it's velocity, unless it collides with something. // If that something is a damageable, deal the damage to it. Either way, mark the bullet // for destruction next update. // This is done in Fixed Update so that the physics is properly synchronized for the bullet. //############################################################################################## void FixedUpdate() { // Prevents updating before firing information has been provided, since fixed update is // disjoint from regular unity update if (!fired) { return; } // The destruction is done 1 frame after being marked for kill so the bullet and effects // appear in the correct position visually for that last frame, before bullet is destroyed. if (shouldKill) { // Notify all delegates if (bulletDestroyedDelegates != null) { foreach (OnBulletDestroyed bulletDestroyedDelegate in bulletDestroyedDelegates) { bulletDestroyedDelegate(); } } // Destroy if not pooled, otherwise mark this bullet as freed if (poolIdentifier == null) { Destroy(gameObject); } else { PooledGameObjectManager.FreeInstanceToPool(poolIdentifier, gameObject); } return; } velocity += Physics.gravity * gravityModifier * Time.deltaTime * Time.deltaTime; Vector3 move = velocity * Time.deltaTime; float moveDist = move.magnitude; // Kill the bullet if it's gone too far if ((transform.position - startPosition).sqrMagnitude >= maxDistance * maxDistance) { shouldKill = true; } // See if move would hit anything, ignoring the 'no bullet collide' layer and triggers RaycastHit hit; if (Physics.Raycast(transform.position, move, out hit, moveDist, ~NO_BULLET_COLLIDE_LAYER, QueryTriggerInteraction.Ignore)) { if (hit.collider.gameObject != firer) { transform.position = hit.point; DamageableComponent damageable = hit.collider.gameObject.GetComponent <DamageableComponent>(); if (damageable == null) { DamageablePieceComponent damageablePiece = hit.collider.gameObject.GetComponent <DamageablePieceComponent>(); if (damageablePiece != null) { damageable = damageablePiece.GetDamageableComponent(); } } if (damageable != null) { // Never ricochet off a damageable collisionsRemaining = 0; damageable.DealDamage(damage, type, startPosition, firer); } else { // Don't spawn decals when hitting damageable if (optionalDecalObject != null && damageable == null) { GameObject decalInstance = GameObject.Instantiate(optionalDecalObject); // Add random offset to prevent z-fighting float randomOffset = (Random.value * BULLET_EFFECTS_OFFSET); decalInstance.transform.position = hit.point + (hit.normal * (BULLET_DECAL_OFFSET + randomOffset)); decalInstance.transform.rotation = Quaternion.LookRotation(hit.normal); } // TODO add impact effects lookup system for hit object if (optionalImpactEffects != null) { GameObject fx = GameObject.Instantiate(optionalImpactEffects); // Scoot fx back away from collision a little fx.transform.position = transform.position + (-move).normalized * BULLET_EFFECTS_OFFSET; } } // Play impact sound if needed if (impactSound != null) { SoundManagerComponent.PlaySound(impactSound, gameObject); } if (collisionsRemaining > 0) { collisionsRemaining--; if (Random.value <= collisionModeChance) { if (collisionMode == CollisionMode.Ricochet) { float velocityMagnitude = velocity.magnitude; velocity = Vector3.Reflect(velocity.normalized, hit.normal).normalized *velocityMagnitude; transform.position = hit.point + (velocity * 0.01f); } else if (collisionMode == CollisionMode.Pierce) { transform.position += move; } } else { collisionsRemaining = 0; } } if (collisionsRemaining <= 0) { shouldKill = true; } } } else { transform.position += move; } }
//############################################################################################## // Create the bullet(s) and send them shooting in the direction of muzzleTransform. Also spawn // effects if available. // The argument can be used to change the damage amount (usually called from subclasses to // modify damage) // return value indicates whether or not the gun actually fired. //############################################################################################## public bool Shoot(float damage) { if (gunTimer.Finished() && !reloading) { if (remainingMagazineAmmoCount == 0 && remainingBoxAmmoCount == 0) { return(BULLET_NOT_FIRED); } gunTimer.Start(); shooting = true; remainingMagazineAmmoCount--; if (remainingMagazineAmmoCount == 0 && remainingBoxAmmoCount > 0) { ReloadGun(); } // This is for shotgun-type weapons. It spawns several bullets in a random cone for (int i = 0; i < currentGunData.shots; ++i) { GameObject bulletInstance = null; if (currentGunData.usePooledBullets) { bulletInstance = PooledGameObjectManager.GetInstanceFromPool(currentGunData.poolIdentifier); } else { bulletInstance = GameObject.Instantiate(currentGunData.bulletPrefab); } BulletComponent bullet = bulletInstance.GetComponent <BulletComponent>(); if (currentGunData.usePooledBullets) { bullet.SetAsPooled(currentGunData.poolIdentifier); } if (bullet == null) { Logger.Error("Bullet Prefab " + currentGunData.bulletPrefab.name + " must have a bullet component"); return(BULLET_NOT_FIRED); } // Apply non-zero spread. This can be for shotgun scatter, // or for inaccurate, normal guns Quaternion spreadOffset = Quaternion.identity; if (currentGunData.spread > 0.0f) { spreadOffset = Quaternion.AngleAxis(Random.value * currentGunData.spread, Vector3.right); Quaternion rot = Quaternion.AngleAxis(Random.value * 360.0f, Vector3.forward); spreadOffset = rot * spreadOffset; } Vector3 bulletVelocity = Vector3.zero; bulletInstance.transform.position = muzzleTransform.position + muzzleTransform.TransformDirection(currentGunData.muzzleOffset); bulletInstance.transform.rotation = muzzleTransform.rotation * spreadOffset; bulletVelocity = bulletInstance.transform.forward * currentGunData.muzzleVelocity; // Add in player velocity if necessary if (player != null) { bulletVelocity += player.GetVelocity(); } // Notify the bullet it's been fired bullet.Fire(damage, currentGunData.damageType, bulletVelocity, gameObject); } // Spawn effects if available, outside the loop, so there's only ever one if (currentGunData.firingEffectsPrefab != null) { GameObject effectsInstance = GameObject.Instantiate(currentGunData.firingEffectsPrefab); effectsInstance.transform.parent = muzzleTransform; effectsInstance.transform.localPosition = currentGunData.firingEffectsOffset; } // If there's a casing particle, emit 1 if (optionalCasingParticle != null) { optionalCasingParticle.Emit(1); } // Play firing sound if it exists, outside the loop, so there's only ever one if (currentGunData.fireSound != null) { SoundManagerComponent.PlaySound(currentGunData.fireSound, muzzleTransform.gameObject); } return(BULLET_FIRED); } else { return(BULLET_NOT_FIRED); } }