protected override void OnUpdate() { float deltaTime = Time.deltaTime; while (DamageQueue.Count != 0) { var damageData = DamageQueue.Dequeue(); for (int i = 0; i < DamageableComponents.Length; i++) { Damageable damageable = DamageableComponents.Damageables[i]; float distance = Vector3.Distance(damageable.transform.position, damageData.HitPosition); if (distance < damageData.DamageRange) { float lerp = 1f - Mathf.Clamp(distance / damageData.DamageRange, 0f, 1f); float damage = damageData.DamageAmount * damageData.DamageFalloff.Evaluate(lerp); ApplyDamage(damageable, damage); } } } // apply color changes and despawn if needed for (int i = 0; i < DamageableComponents.Length; i++) { Transform transform = DamageableComponents.Transforms[i]; Damageable damageable = DamageableComponents.Damageables[i]; Despawnable despawnable = DamageableComponents.Despawnables[i]; // check health points value if (damageable.HealthPoints <= 0) { despawnable.EnqueueDespawn = true; } else { // animate color of the material (ex: green to red, as health goes down) var meshRenderers = damageable.Renderers; float lerp = 1f - Mathf.Clamp(damageable.HealthPoints / damageable.MaxHealthPoints, 0f, 1f); Color color = Color.Lerp(damageable.Animated.Start, damageable.Animated.End, damageable.Animated.Curve.Evaluate(lerp)); for (int j = 0; j < meshRenderers.Count; j++) { var meshRenderer = meshRenderers[j]; // maintain alpha from material but not the color color.a = meshRenderer.material.color.a; meshRenderer.material.color = color; } } } }
protected override void OnUpdate() { float time = Time.time; var toDestroy = new List <GameObject>(); // despawnable objects that must be destroyed for (int i = 0; i < DespawnableComponents.Length; i++) { Transform transform = DespawnableComponents.Transforms[i]; Despawnable despawnable = DespawnableComponents.Despawnables[i]; if (despawnable != null && despawnable.AllowDespawn) { bool destroy = false; bool startedOrEnqueued = despawnable.StartDespawn || despawnable.EnqueueDespawn; if (despawnable.TimeBeforeDespawnStart >= 0 || startedOrEnqueued) { float timeAlive = time - despawnable.TimeAtSpawn; // animate despawn if (startedOrEnqueued || timeAlive >= despawnable.TimeBeforeDespawnStart) { // initialize despawn animation if (!despawnable.StartDespawn) { despawnable.StartDespawn = true; despawnable.TimeAnimatedFloat.AnimationTimeStart = time; } TimeAnimatedFloat timeAnimatedFloat = despawnable.TimeAnimatedFloat; if (timeAnimatedFloat.Enabled) { if (timeAnimatedFloat.AnimationTime < ForceDespawnEpsilon) { destroy = true; } else { // FADE effect float lerp = Mathf.Clamp((time - timeAnimatedFloat.AnimationTimeStartDelayed) / timeAnimatedFloat.AnimationTime, 0f, 1f); float alpha = Mathf.Lerp(timeAnimatedFloat.Start, timeAnimatedFloat.End, timeAnimatedFloat.Curve.Evaluate(lerp)); RendererSetMatAlpha(despawnable.Renderers, alpha); if (alpha < ForceDespawnEpsilon) { destroy = true; } } } } } if (despawnable.ForceDespawn || destroy) { if (despawnable.IsPooledObject) { RendererSetMatAlpha(despawnable.Renderers, 1f); // reset despawnable despawnable.TimeAtSpawn = time; despawnable.EnqueueDespawn = false; despawnable.StartDespawn = false; despawnable.ForceDespawn = false; // TODO: fix this!!! // TODO: do not destroy a pooled object find a way to disactivate it instead var entity = despawnable.gameObject.GetComponent <GameObjectEntity>().Entity; EntityManager.DestroyEntity(entity); transform.gameObject.SetActive(false); } else { toDestroy.Add(DespawnableComponents.Transforms[i].gameObject); } } } } // destroy loop foreach (var go in toDestroy) { GameObject.Destroy(go); } }