Skip to content

Instantly share code, notes, and snippets.

@digitalbreed
Last active December 5, 2023 23:33
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save digitalbreed/79179fa5ecf6720253844a95740a372c to your computer and use it in GitHub Desktop.
Save digitalbreed/79179fa5ecf6720253844a95740a372c to your computer and use it in GitHub Desktop.
Animated Scene Setup - animates an entire subtree to demonstrate a scene setup as shown in https://twitter.com/digitalbreed/status/1732084984603701429
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
// Needs DOTween: https://assetstore.unity.com/packages/tools/animation/dotween-hotween-v2-27676
using DG.Tweening;
namespace Prefabby
{
public class AnimateSceneSetup : MonoBehaviour
{
public enum AnimationType
{
Vertical,
Horizontal
}
[Tooltip("Central location or prefab as a reference point")]
public Transform Target;
[Tooltip("Distance from where to start moving the prefabs")]
public float Distance = 200f;
[Tooltip("Duration of a single prefab animation")]
public float Duration = .5f;
[Tooltip("Delay until the next prefab animation starts, 0 means all move instantly")]
public float Step = .05f;
[Tooltip("Weight for Manhattan distance calculation")]
public Vector3 Weights = new Vector3(1f, 5f, 1f);
public AnimationType Type = AnimationType.Vertical;
public Ease Easing = Ease.OutQuint;
[Tooltip("The number of levels to search under this GameObject, might be useful in case of many nested structures; 0 is only first level, -1 means no depth limit")]
public int Depth = -1;
private List<Transform> GetRelevantChildren(Transform parent, int depth)
{
List<Transform> result = new();
foreach (Transform child in parent)
{
result.Add(child);
if (depth != 0)
{
result.AddRange(GetRelevantChildren(child, depth - 1));
}
}
return result;
}
void Start()
{
Transform[] sortedChildren = GetRelevantChildren(transform, Depth)
.OrderBy((t) => {
float dx = (t.position.x - Target.position.x) * Weights.x;
float dy = (t.position.y - Target.position.y) * Weights.y;
float dz = (t.position.z - Target.position.z) * Weights.z;
return Mathf.Abs(dx) + Mathf.Abs(dy) + Mathf.Abs(dz);
})
.ToArray();
for (int i = 0; i < sortedChildren.Length; ++i)
{
Transform child = sortedChildren[i];
if (child != Target)
{
Vector3 position = child.localPosition;
if (Type == AnimationType.Vertical)
{
// Move the starting position up by "Distance"
child.localPosition = new Vector3(position.x, position.y + Distance, position.z);
}
else if (Type == AnimationType.Horizontal)
{
// Move the starting position away from the Target by "Distance"
Vector3 direction = (child.position - Target.position).normalized;
child.localPosition += direction * Distance;
}
// Initiate the tween back to the original position over "Duration"
child.DOLocalMove(position, Duration)
.SetEase(Easing)
.SetDelay(i * Step);
}
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment