Skip to content

Instantly share code, notes, and snippets.

@twobob
Created September 6, 2018 08:46
Show Gist options
  • Save twobob/22c3c9148a59dfffacd4ef1a250992f1 to your computer and use it in GitHub Desktop.
Save twobob/22c3c9148a59dfffacd4ef1a250992f1 to your computer and use it in GitHub Desktop.
Horrible code to reverse explode prefabs
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class TransformWithStoredPositions {
public Vector3 intendedLocationForTransform { get; set; }
public Transform actualLocationOfTransform { get; set; }
public Vector3 pastPosition { get; set; }
public ParticleSystem particleSystem { get; set; }
}
public class ZoomToTarget : MonoBehaviour {
private List<TransformWithStoredPositions> TransformsToProcess;
//private List<Transform> originalLocationOfTransform;
//private List<Vector3> pastFollowerPosition, pastTargetPosition, intendedLocationForTransform;
private Bounds bounds;
public GameObject particlePrefab;
public GameObject textReadoutPrefab;
private Text text;
public float throwDistance = 20f;
public void CalculatePrefabLocalBounds(BoxCollider boxcoll)
{
Quaternion currentRotation = this.transform.rotation;
Vector3 currentScale = this.transform.localScale;
this.transform.rotation = Quaternion.Euler(0f, 0f, 0f);
this.transform.localScale = Vector3.one;
Bounds bounds = new Bounds(this.transform.position, Vector3.zero);
foreach (Renderer renderer in GetComponentsInChildren<Renderer>())
{
bounds.Encapsulate(renderer.bounds);
}
Vector3 localCenter = bounds.center - this.transform.position;
bounds.center = localCenter;
Debug.Log("The local bounds of this model is " + bounds);
this.transform.rotation = currentRotation;
this.transform.localScale = currentScale;
boxcoll.center = bounds.center;
boxcoll.size = bounds.size;
}
private void CalculateLocalBounds(Transform referencePoint, ref Bounds bounds)
{
Quaternion currentRotation = referencePoint.transform.rotation;
referencePoint.transform.rotation = Quaternion.Euler(0f, 0f, 0f);
bounds = new Bounds(referencePoint.transform.position, Vector3.zero);
foreach (Renderer renderer in GetComponentsInChildren<Renderer>())
{
bounds.Encapsulate(renderer.bounds);
}
Vector3 localCenter = bounds.center - referencePoint.transform.position;
bounds.center = localCenter;
/// Debug.Log("The local bounds of this model "+ referencePoint.gameObject.name +" is " + bounds);
referencePoint.transform.rotation = currentRotation;
}
public float timeToArrive = 50f;
[SerializeField] public bool complete;
Dictionary<Transform, Transform> transformDictionary = new Dictionary<Transform, Transform>();
static List<Transform> GetAllTransforms(Transform parent)
{
var transformList = new List<Transform>(parent.GetComponentsInChildren<Transform>());
BuildTransformList(transformList, parent);
return transformList;
}
private static void BuildTransformList(ICollection<Transform> transforms, Transform parent)
{
if (parent == null) { return; }
foreach (Transform t in parent)
{
transforms.Add(t);
BuildTransformList(transforms, t);
}
}
void SetPositions(Transform parent)
{
foreach (Transform t in GetAllTransforms(parent) )// parent.GetComponentsInChildren<Transform>())
transformDictionary.Add(t,t);
}
void RestorePositions(Transform parent)
{
foreach (Transform t in GetAllTransforms(parent))
{
if (transformDictionary.ContainsKey(t) == true)
{
t.position = transformDictionary[t].position;
}
else
{
Debug.Log("Transform not found in dictionary, GameObject: " + t.gameObject.name);
}
}
}
void PrintPositions(Transform parent)
{
foreach (Transform t in GetAllTransforms(parent))
{
if (transformDictionary.ContainsKey(t) == true)
{
Debug.Log(t.gameObject.name + " STORED AS " + transformDictionary[t].position);
}
else
{
Debug.Log("Transform not found in dictionary, GameObject: " + t.gameObject.name);
}
}
}
void Start()
{
if (text == null)
{
GameObject textObject = Instantiate<GameObject>(textReadoutPrefab, gameObject.transform);
text = textObject.GetComponentInChildren<Text>();
}
if (text == null)
{
Debug.Log("Please attach TEXT PREFAB to "+ gameObject.name);
}
complete = false;
TransformsToProcess = new List<TransformWithStoredPositions>();
// intendedLocationForTransform = new List<Vector3>();
// originalLocationOfTransform = new List<Transform>();
// Calculate the center of the bounds
CalculateLocalBounds(transform, ref bounds);
// Debug.Log("---------- BEGIN foreach -------------");
List<float> offsets = new List<float>();
// implicitely retrieves local Transform and walks it's children
foreach (Transform item in GetAllTransforms(gameObject.transform))
// foreach (Transform item in gameObject.GetComponentsInChildren<Transform>())
{
if (item.GetComponent<ParticleSystem>() != null)
{
continue;
}
if (item.GetComponent<MeshRenderer>() == null)
{
continue;
}
TransformWithStoredPositions transformItem = new TransformWithStoredPositions();
if (particlePrefab != null)
{
GameObject particleSystem = Instantiate(particlePrefab);
particleSystem.SetActive(false);
transformItem.particleSystem = particleSystem.GetComponent<ParticleSystem>();
particleSystem.transform.SetParent(item.gameObject.transform, false);
}
// Here we setup our list of original intended transform positions
transformItem.intendedLocationForTransform = item.position;
// do an offset then store our starting offset position
// float dist = Vector3.Distance(item.position, transform.position);
Bounds newb = new Bounds();
CalculateLocalBounds(item, ref newb);
float dist = Vector3.Distance(newb.center, bounds.center);
// Debug.Log(item.gameObject.name + " " + dist);
offsets.Add(dist);
// next we need to create a copy that is exploded in a circluar x z space fashion.
// Seems like exploding about a unit sphere and disregarding the Y might work
transformItem.actualLocationOfTransform = item;
transformItem.pastPosition = transformItem.actualLocationOfTransform.position;
TransformsToProcess.Add(transformItem);
}
var i = 0;
float[] listedOffsets = offsets.ToArray();
TransformWithStoredPositions[] listedRes = TransformsToProcess.ToArray();
foreach (Transform item in GetAllTransforms(gameObject.transform))
// foreach (Transform item in gameObject.GetComponentsInChildren<Transform>())
{
if (item.GetComponent<ParticleSystem>() != null)
{
continue;
}
if (item.GetComponent<MeshRenderer>() == null)
{
continue;
}
item.transform.Translate(bounds.center * (listedOffsets[i] * throwDistance ) , Space.Self);
i++;
}
t = 0;
// Offset the world space readout canas offset by the bounds + center
if (text != null)
{
RectTransform canv = text.transform.parent.GetComponent<RectTransform>();
canv.anchoredPosition = new Vector2 (0f, bounds.extents.y * 3f);
}
}
public Color GizmoColor = new Color(1, 1, 1, 1);
private Vector3 halfExtents = Vector3.one;
[SerializeField] protected Vector3 centerOffset = Vector3.zero;
[SerializeField] protected bool useExtentsInGizmo = true;
private Vector3 internalGizmoOffset;
void OnDrawGizmos()
{
if (bounds == null)
return;
if (useExtentsInGizmo) internalGizmoOffset = centerOffset + new Vector3(0, bounds.extents.y, 0);
else { internalGizmoOffset = centerOffset; }
Gizmos.matrix = Matrix4x4.TRS(transform.localPosition, transform.localRotation, transform.localScale);
Gizmos.color = new Color(1, 1, 0, 0.2f);
Gizmos.DrawCube(internalGizmoOffset, halfExtents * 2f);
Gizmos.color = Color.white;
Gizmos.DrawWireCube(internalGizmoOffset, bounds.extents);
Gizmos.color = GizmoColor;
Gizmos.DrawWireCube(internalGizmoOffset, bounds.extents * throwDistance);
}
float t = 0;
void Update()
{
// here we roll through the list and slowly move them all towards the target
if (complete)
return;
foreach (var item in TransformsToProcess)
{
complete = true;
// move the item via originalLocationOfTransform reference
t += Time.deltaTime / (timeToArrive * 600f);
item.actualLocationOfTransform.position = Vector3.Lerp(item.actualLocationOfTransform.position, item.intendedLocationForTransform, t);
float DistanceLeft = Vector3.Distance(item.actualLocationOfTransform.position, item.intendedLocationForTransform);
if (DistanceLeft > 0.002f)
{
complete = false;
}
// item.actualLocationOfTransform.position = Vector3.SmoothDamp(item.actualLocationOfTransform.position, item.intendedLocationForTransform, ref vel , damping);
//item.actualLocationOfTransform.position = SmoothApproach( item.actualLocationOfTransform.position , item.pastPosition, item.intendedLocationForTransform, damping);
item.pastPosition = item.actualLocationOfTransform.position;
// if (complete) { if (item.particleSystem.gameObject.activeInHierarchy) { item.particleSystem.gameObject.SetActive(false); } }
// else
// {
if (complete) {
if (text != null)
{
text.text = item.actualLocationOfTransform.gameObject.name + " building";
}
}
if (item.particleSystem)
{
if (!item.particleSystem.gameObject.activeInHierarchy) { item.particleSystem.gameObject.SetActive(true); }
}
// }
}
if (complete)
{
foreach (var item in TransformsToProcess)
{
if (item.particleSystem)
{
GameObject.Destroy(item.particleSystem.gameObject);
}
}
}
if (complete)
{
if (text != null)
{
text.text = gameObject.name + " complete";
}
Debug.Log(gameObject.name + " is complete");
this.enabled = false;
}
//// move target //
//targetTransform.position += Vector3.right * Time.deltaTime * 200;
//// move follower //
//followerTransform.position = SmoothApproach(pastFollowerPosition, pastTargetPosition, targetTransform.position, 20f);
//pastFollowerPosition = followerTransform.position;
//pastTargetPosition = targetTransform.position;
//// move camera along side the target //
//camTransform.position = new Vector3(targetTransform.position.x, targetTransform.position.y, targetTransform.position.z - 15);
}
Vector3 SmoothApproach(Vector3 pastPosition, Vector3 pastTargetPosition, Vector3 targetPosition, float speed)
{
float t = Time.deltaTime * speed;
Vector3 v = (targetPosition - pastTargetPosition) / t;
Vector3 f = pastPosition - pastTargetPosition + v;
return targetPosition - v + f * Mathf.Exp(-t);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment