Skip to content

Instantly share code, notes, and snippets.

@aprius
Created August 6, 2019 07:58
Show Gist options
  • Save aprius/eb331487294ce3423041c867e85bb6be to your computer and use it in GitHub Desktop.
Save aprius/eb331487294ce3423041c867e85bb6be to your computer and use it in GitHub Desktop.
using System.Linq;
using UnityEngine;
// ReSharper disable once CheckNamespace
namespace Unity.Linq
{
public static class TraverseExtension
{
public static Vector3 TotalPositionAncestor(this GameObject origin, int level)
{
var position = Vector3.zero;
var enumerable = origin.Ancestors();
var count = enumerable.Count();
count = count <= level ? count : level;
for (var i = 0; i < count; i++)
{
position += enumerable.ElementAt(i).transform.localPosition;
}
return position;
}
public static Vector3 TotalPositionAncestorSelf(this GameObject origin, int level)
{
var position = Vector3.zero;
var enumerable = origin.AncestorsAndSelf();
var count = enumerable.Count();
count = count <= level ? count : level;
for (var i = 0; i < count; i++)
{
position += enumerable.ElementAt(i).transform.localPosition;
}
return position;
}
/// <summary>
/// Require RectTransform Component In All Ancestor
/// </summary>
/// <param name="origin"></param>
/// <returns></returns>
public static Vector3 TotalPositioEndNoChangeSelf(this GameObject origin)
{
var array = new GameObject[0];
// travese but no allocate memory
var size = origin.AncestorsAndSelf().ToArrayNonAlloc(ref array);
for (var i = size - 1; i >= 0; i--)
{
var rect = array[i].GetComponent<RectTransform>();
if (rect.anchorMin.Equals(Vector2.zero) && (rect.anchorMax.Equals(Vector2.one) || rect.anchorMax.Equals(Vector2.zero)))
{
array[i] = null;
continue;
}
break;
}
return array.Where(_ => _ != null).Aggregate<GameObject, Vector3>(Vector2.zero, (current, item) => current + item.transform.localPosition);
}
/// <summary>
/// Require RectTransform Component In All Ancestor
/// </summary>
/// <param name="origin"></param>
/// <returns></returns>
public static Vector3 TotalPositioEndNoChange(this GameObject origin)
{
var array = new GameObject[0];
// travese but no allocate memory
var size = origin.Ancestors().ToArrayNonAlloc(ref array);
for (var i = size - 1; i >= 0; i--)
{
var rect = array[i].GetComponent<RectTransform>();
if (rect.offsetMin.Equals(Vector2.zero) && rect.offsetMax.Equals(Vector2.one))
{
array[i] = null;
continue;
}
break;
}
return array.Where(_ => _ != null).Aggregate<GameObject, Vector3>(Vector2.zero, (current, item) => current + item.transform.localPosition);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment