/// <summary> /// create pool (array) of fragment game objects with all necessary components /// </summary> /// <param name="poolSize">number of fragments</param> public void Allocate(int poolSize) { Exploder2DUtils.Assert(poolSize > 0, ""); if (pool == null || pool.Length < poolSize) { DestroyFragments(); pool = new Fragment2D[poolSize]; for (int i = 0; i < poolSize; i++) { var fragment = new GameObject("fragment_" + i); fragment.AddComponent <SpriteRenderer>(); fragment.AddComponent <PolygonCollider2D>(); fragment.AddComponent <Rigidbody2D>(); fragment.AddComponent <Exploder2DOption>(); var fragmentComponent = fragment.AddComponent <Fragment2D>(); fragment.transform.parent = gameObject.transform; pool[i] = fragmentComponent; Exploder2DUtils.SetActiveRecursively(fragment.gameObject, false); fragmentComponent.RefreshComponentsCache(); fragmentComponent.Sleep(); } } }
/// <summary> /// this is called from exploder class to start the explosion /// </summary> public void Explode() { activeObj = true; Exploder2DUtils.SetActiveRecursively(gameObject, true); visibilityCheckTimer = 0.1f; visible = true; deactivateTimer = deactivateTimeout; originalScale = transform.localScale; if (explodable) { tag = Exploder2DObject.Tag; } Emit(true); }
bool Postprocess(long timeOffset) { var postTimer = new Stopwatch(); postTimer.Start(); var count = postList.Count; #if DBG postProcessingFrames++; #endif while (poolIdx < count) { var fragment = pool[poolIdx]; var mesh = postList[poolIdx]; poolIdx++; if (!mesh.original) { continue; } if (crack) { Exploder2DUtils.SetActiveRecursively(fragment.gameObject, false); } fragment.CreateSprite(mesh.spriteMesh, mesh.sprite, mesh.original.transform, mesh.sortingLayer, mesh.orderInLayer, mesh.color); var oldParent = fragment.transform.parent; fragment.transform.parent = mesh.parent; fragment.transform.position = new Vector3(mesh.position.x, mesh.position.y, mesh.original.transform.position.z); fragment.transform.rotation = mesh.rotation; fragment.transform.localScale = mesh.localScale; fragment.transform.parent = null; fragment.transform.parent = oldParent; if (!crack) { if (mesh.original != gameObject) { Exploder2DUtils.SetActiveRecursively(mesh.original, false); } else { Exploder2DUtils.EnableCollider(mesh.original, false); Exploder2DUtils.SetVisible(mesh.original, false); } } if (!FragmentOptions.DisableColliders) { Core.MeshUtils.GeneratePolygonCollider(fragment.polygonCollider2D, mesh.spriteMesh); } if (mesh.option) { mesh.option.DuplicateSettings(fragment.options); } if (!crack) { fragment.Explode(); } var force = Force; if (mesh.option && mesh.option.UseLocalForce) { force = mesh.option.Force; } // apply force to rigid body fragment.ApplyExplosion2D(mesh.transform, mesh.centroidLocal, mainCentroid, FragmentOptions, UseForceVector, ForceVector, force, mesh.original, TargetFragments); #if SHOW_DEBUG_LINES UnityEngine.Debug.DrawLine(mainCentroid, forceVector * Force, Color.yellow, 3); #endif if (postTimer.ElapsedMilliseconds + timeOffset > FrameBudget) { return(false); } } #if DBG var watch = new Stopwatch(); watch.Start(); #endif if (!crack) { if (DestroyOriginalObject) { foreach (var mesh in postList) { if (mesh.original && !mesh.original.GetComponent <Fragment2D>()) { Object.Destroy(mesh.original); } } } if (ExplodeSelf) { if (!DestroyOriginalObject) { Exploder2DUtils.SetActiveRecursively(gameObject, false); } } if (HideSelf) { Exploder2DUtils.SetActiveRecursively(gameObject, false); } #if DBG Exploder2DUtils.Log("Explosion finished! " + postList.Count + postList[0].original.transform.gameObject.name); #endif OnExplosionFinished(true); } else { cracked = true; if (CrackedCallback != null) { CrackedCallback(); } } #if DBG postProcessingTimeEnd = watch.ElapsedMilliseconds; #endif return(true); }
void PostCrackExplode(OnExplosion callback) { if (callback != null) { callback(0.0f, ExplosionState.ExplosionStarted); } var count = postList.Count; poolIdx = 0; while (poolIdx < count) { var fragment = pool[poolIdx]; var mesh = postList[poolIdx]; poolIdx++; if (mesh.original != gameObject) { Exploder2DUtils.SetActiveRecursively(mesh.original, false); } else { Exploder2DUtils.EnableCollider(mesh.original, false); Exploder2DUtils.SetVisible(mesh.original, false); } fragment.Explode(); } if (DestroyOriginalObject) { foreach (var mesh in postList) { if (mesh.original && !mesh.original.GetComponent <Fragment2D>()) { Object.Destroy(mesh.original); } } } if (ExplodeSelf) { if (!DestroyOriginalObject) { Exploder2DUtils.SetActiveRecursively(gameObject, false); } } if (HideSelf) { Exploder2DUtils.SetActiveRecursively(gameObject, false); } #if DBG Exploder2DUtils.Log("Crack finished! " + postList.Count + postList[0].original.transform.gameObject.name); #endif ExplosionCallback = callback; OnExplosionFinished(true); }
void Update() { if (activeObj) { // // clamp velocity // if (rigidBody) { if (rigidBody.velocity.sqrMagnitude > maxVelocity * maxVelocity) { var vel = rigidBody.velocity.normalized; rigidBody.velocity = vel * maxVelocity; } } else if (rigid2D) { if (rigid2D.velocity.sqrMagnitude > maxVelocity * maxVelocity) { var vel = rigid2D.velocity.normalized; rigid2D.velocity = vel * maxVelocity; } } if (deactivateOptions == DeactivateOptions.Timeout) { deactivateTimer -= Time.deltaTime; if (deactivateTimer < 0.0f) { Sleep(); activeObj = false; Exploder2DUtils.SetActiveRecursively(gameObject, false); // return fragment to previous fadout state switch (fadeoutOptions) { case FadeoutOptions.FadeoutAlpha: break; } } else { var t = deactivateTimer / deactivateTimeout; switch (fadeoutOptions) { case FadeoutOptions.FadeoutAlpha: var color = spriteRenderer.color; color.a = t; spriteRenderer.color = color; break; case FadeoutOptions.ScaleDown: gameObject.transform.localScale = originalScale * t; break; } } } visibilityCheckTimer -= Time.deltaTime; if (visibilityCheckTimer < 0.0f && UnityEngine.Camera.main) { var viewportPoint = UnityEngine.Camera.main.WorldToViewportPoint(transform.position); if (viewportPoint.z < 0 || viewportPoint.x < 0 || viewportPoint.y < 0 || viewportPoint.x > 1 || viewportPoint.y > 1) { if (deactivateOptions == DeactivateOptions.OutsideOfCamera) { Sleep(); activeObj = false; Exploder2DUtils.SetActiveRecursively(gameObject, false); } visible = false; } else { visible = true; } visibilityCheckTimer = Random.Range(0.1f, 0.3f); if (explodable) { var size = GetComponent <Collider>().bounds.size; if (Mathf.Max(size.x, size.y, size.z) < minSizeToExplode) { tag = string.Empty; } } } } }