/// <summary> /// Creates the pool /// </summary> public void Start() { pool = new List <GameObject> [pooledObjects.Length]; if (!isServer) { return; } for (int i = 0; i < pooledObjects.Length; i++) { pool[i] = new List <GameObject>(); for (int j = 0; j < pooledAmount[i]; j++) { GameObject gameobject = (GameObject)Instantiate(pooledObjects[i]); AbstractFish fish = gameobject.GetComponent <AbstractFish>(); if (fish != null) { fish.OnActiveChange(false); } else { gameobject.SetActive(false); } pool[i].Add(gameobject); LightSource lightSource = gameobject.GetComponent <LightSource>(); NpcID npcID = gameobject.GetComponent <NpcID>(); if (npcID != null) { string identity = lightSource.LightSourceID; npcID.ID = identity; } } } }
/// <summary> /// Spawns an individual fish. /// </summary> private void SpawnFish(int spawnTypeIndex, Vector3 spawnLocation) { GameObject fish = pool.GetPooledObject(spawnTypeIndex); if (fish == null) { return; } fish.transform.position = spawnLocation; fish.transform.rotation = Quaternion.identity; LightSource lightSource = fish.GetComponent <LightSource>(); AbstractFish abstractFish = fish.GetComponent <AbstractFish>(); if (lightSource != null) { float variance = Random.Range(0, lightSource.LightEnergy.CurrentEnergy * energyVariance); lightSource.LightEnergy.Deplete(variance); } if (abstractFish != null) { // Override the fish's default swim direction abstractFish.DefaultWanderAngle = initialSwimAngle; abstractFish.OnActiveChange(true); } fishes.Add(fish); NpcID npcID = fish.GetComponent <NpcID>(); if (npcID != null) { string identity = lightSource.LightSourceID; npcID.ID = identity; } }
/// <summary> /// Update is called every frame, if the MonoBehaviour is enabled /// <see cref="Unity Documentation"> /// </summary> protected virtual void Update() { // Cycle through each absorbable light source being touched by this GameObject for (int i = 0; i < absorbableLightDetector.NeighbourCount; i++) { GameObject absorbableLight = absorbableLightDetector.GetNeighbour(i); if (absorbableLight == null) { continue; } LightSource otherLightSource = absorbableLight.GetComponentInParent <LightSource>(); if (otherLightSource == null) { continue; } // If this GameObject can absorb the touched light source, // Transfer light energy from the other light source to this one if (CanAbsorb(otherLightSource)) { if (this is Player) { PlayerSound playerSound = GetComponent <PlayerSound>(); playerSound.EatSound(); } LightEnergy lightEnergyToAbsorb = otherLightSource.LightEnergy; // Calculate the amount of light to absorb from the other light source float lightToAbsorb = absorptionRate * Time.deltaTime; // If the player was hit if (otherLightSource is Player) { if (this is AbstractFish) { // Absorb a certain amount of light from the player to the fish AbstractFish fish = (AbstractFish)this; lightToAbsorb = fish.damageInflicted; } // Debug.Log("Absorb " + lightToAbsorb + " from player"); // Knockback the player away from the enemy fish otherLightSource.Knockback(this); } // Transfer light energy from the other light source to this one float lightAbsorbed = lightEnergyToAbsorb.Deplete(lightToAbsorb); lightEnergy.Add(lightAbsorbed); // Inform subscribers that this light source consumed another light source. ConsumedLightSource(otherLightSource); } } }
/// <summary> /// Restores the default energy of the pooled object /// </summary> private void ReactivateObjectLight(GameObject current) { LightSource light = current.GetComponent <LightSource>(); if (light != null) { light.LightEnergy.Add(light.DefaultEnergy); AbstractFish fish = current.GetComponent <AbstractFish>(); if (fish) { fish.Dead = false; } } }
public override void ReactToNPC(Transform other) { LightSource currentFishTarget = otherFishBehaviour.TargetLightSource; if (currentFishTarget == null) { AbstractFish fish = other.gameObject.GetComponent <AbstractFish>(); string id = fish.GetID(); otherFishBehaviour.TargetLightSource = fish; otherFishBehaviour.SetID(id); AddAction(otherFishBehaviour); } }
/// <summary> /// Checks the distance from the fish to the player. /// Activates the fish if sufficiently close to the player, /// and deactivates it otherwise. /// </summary> private void CheckDistanceToPlayer(AbstractFish fish) { if (fish == null) { return; } float distanceSquared = (fish.transform.position - player.position).sqrMagnitude; if (distanceSquared > maxDistanceSquared) { fish.gameObject.SetActive(false); } else if (fish.gameObject.activeSelf == false && !fish.Dead) { fish.gameObject.SetActive(true); } }
/// <summary> /// Check and update existing fish status. /// Check if fish should be active or deactivated. /// </summary> private void UpdateFishStatus() { if (fishes.Count > 0) { for (int i = 0; i < fishes.Count; i++) { if (fishes[i] != null) { AbstractFish fish = fishes[i].GetComponent <AbstractFish>(); if (fish != null) { fish.OnActiveChange(true); CheckDistanceToPlayer(fish); } } } } }
/// <summary> /// Resets the pool, as if it had never been used /// </summary> public void ResetPool() { for (int i = 0; i < pooledObjects.Length; i++) { for (int j = 0; j < pool[i].Count; j++) { GameObject current = pool[i][j]; if (current.activeSelf == true) { AbstractFish fish = current.GetComponent <AbstractFish>(); if (fish != null) { fish.OnActiveChange(false); } else { current.SetActive(false); } } ReactivateObjectLight(current); } } }