Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Extensions for GameObject, Transform, and String to provide convience methods #416

Merged
merged 28 commits into from
Nov 18, 2023
Merged
Show file tree
Hide file tree
Changes from 15 commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
622f9af
Add Transform.FindDeepChild extension
searica Nov 17, 2023
923b82f
Add string extensions for handling substrings, prefixes, and suffixes
searica Nov 17, 2023
5115e84
Add string extension to help with formatting piece names to match Van…
searica Nov 17, 2023
feacd85
Add extension to convert a null string to an empty string to prevent …
searica Nov 17, 2023
a881562
Fix access modifiers
searica Nov 17, 2023
dfb2342
Fix access modifiers to be public
searica Nov 17, 2023
24eca2a
GameObject extension to check if gameObject has a component, used to …
searica Nov 17, 2023
5ed7695
Extensions method (with overloads) to check if gameObject contains an…
searica Nov 17, 2023
0b979ec
Extension method (with overloads) to check if a gameObject has all of…
searica Nov 17, 2023
5c28bf3
Extension method to check if gameObject has any of the given componen…
searica Nov 17, 2023
d2d7f74
Extension method to check if gameObject or any of it's children has a…
searica Nov 17, 2023
5b507f6
Extension method to search for a specific component based on the name…
searica Nov 17, 2023
310f1f5
Extension to expose the Transform extension FindDeepChild as a method…
searica Nov 17, 2023
43a011e
Improved parameter descriptions
searica Nov 17, 2023
1d08d21
Fix build failure due to ambiguous reference to Object introduced by …
searica Nov 17, 2023
3ff63a5
Update JotunnLib/Extensions/GameObjectExtension.cs
searica Nov 18, 2023
7ae8bbc
Wrap Vanilla Valheim method instead of using custom version
searica Nov 18, 2023
9518875
Remove redundant methods
searica Nov 18, 2023
2eff6f8
Remove null checks
searica Nov 18, 2023
f799a32
Fix missing param in doc
searica Nov 18, 2023
3c9b434
Better accomplished by using Utils.FindChild() + GetComponent() so re…
searica Nov 18, 2023
20643f9
Remove unneeded null check
searica Nov 18, 2023
6d1bee6
This method is redundant and can be written as string ?? string.Empty…
searica Nov 18, 2023
030b8c8
Rewrite to avoid null checks, not sure if I could just use if (!gameO…
searica Nov 18, 2023
bebcbbc
Remove redundant method
searica Nov 18, 2023
64c0300
Merge branch 'Extensions' of https://github.com/searica/Jotunn into E…
searica Nov 18, 2023
b2220bf
Fix doc format
searica Nov 18, 2023
f7441aa
Take advantage of Monobehavior implicit cast to bool and use bool che…
searica Nov 18, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
178 changes: 174 additions & 4 deletions JotunnLib/Extensions/GameObjectExtension.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
using System.Reflection;
using TMPro;
using UnityEngine;
using System.Reflection;
using System;
using TMPro;
using UnityEngine;
using UnityEngine.UI;
using Jotunn.Extensions;

namespace Jotunn
{
Expand All @@ -26,7 +28,7 @@ public static GameObject OrNull(this GameObject @this)
/// <typeparam name="T">Any type that inherits MonoBehaviour</typeparam>
/// <param name="this">this</param>
/// <returns>Returns null when MonoBehaviours.op_equality returns false.</returns>
public static T OrNull<T>(this T @this) where T : Object
public static T OrNull<T>(this T @this) where T : UnityEngine.Object
{
return (T)(@this ? @this : null);
}
Expand Down Expand Up @@ -104,6 +106,174 @@ public static Component AddComponentCopy<T>(this GameObject gameObject, T duplic

return target;
}

/// <summary>
/// Extension method to check if GameObject has a component.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="gameObject"></param>
/// <returns></returns>
public static bool HasComponent<T>(this GameObject gameObject) where T : Component
{
return gameObject.GetComponent<T>() != null;
MSchmoecker marked this conversation as resolved.
Show resolved Hide resolved
}

/// <summary>
/// Extension method to check if GameObject has a component.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="gameObject"></param>
/// <returns></returns>
public static bool HasComponent(this GameObject gameObject, string componentName)
{
return gameObject.GetComponent(componentName) != null;
}

/// <summary>
/// Check if GameObject has any of the specified components.
/// </summary>
/// <param name="gameObject"></param>
/// <param name="components"></param>
/// <returns></returns>
public static bool HasAnyComponent(this GameObject gameObject, params Type[] components)
{
foreach (var compo in components)
{
if (gameObject.GetComponent(compo) != null)
searica marked this conversation as resolved.
Show resolved Hide resolved
{
return true;
}
}
return false;
}

/// <summary>
/// Check if GameObject has any of the specified components.
/// </summary>
/// <param name="gameObject"></param>
/// <param name="componentNames"></param>
/// <returns></returns>
public static bool HasAnyComponent(this GameObject gameObject, params string[] componentNames)
{
foreach (var name in componentNames)
{
if (gameObject.GetComponent(name) != null)
{
return true;
}
}
return false;
}

/// <summary>
/// Check if GameObject has all of the specified components.
/// </summary>
/// <param name="gameObject"></param>
/// <param name="componentNames"></param>
/// <returns></returns>
public static bool HasAllComponents(this GameObject gameObject, params string[] componentNames)
{
foreach (var name in componentNames)
{
if (gameObject.GetComponent(name) == null)
{
return false;
}
}
return true;
}

/// <summary>
/// Check if GameObject has all of the specified components.
/// </summary>
/// <param name="gameObject"></param>
/// <param name="components"></param>
/// <returns></returns>
public static bool HasAllComponents(this GameObject gameObject, params Type[] components)
{
foreach (var compo in components)
{
if (gameObject.GetComponent(compo) == null)
{
return false;
}
}
return true;
}

/// <summary>
/// Check if GameObject or any of it's children
/// have any of the specified components.
/// </summary>
/// <param name="gameObject"></param>
/// <param name="components"></param>
/// <returns></returns>
MSchmoecker marked this conversation as resolved.
Show resolved Hide resolved
public static bool HasAnyComponentInChildren(
this GameObject gameObject,
bool includeInactive = false,
params Type[] components
)
{
foreach (var compo in components)
{
if (gameObject.GetComponentInChildren(compo, includeInactive) != null)
{
return true;
}
}
return false;
}

/// <summary>
/// Check if GameObject or any of it's children
/// have the specific component.
/// </summary>
/// <param name="gameObject"></param>
/// <param name="includeInactive">Whether to include inactive child objects in the search or not.</param>
/// <returns></returns>
public static bool HasComponentInChildren<T>(this GameObject gameObject, bool includeInactive = false) where T : Component
{
return gameObject.GetComponentInChildren<T>(includeInactive) != null;
}

/// <summary>
/// Extension method to get the first component in the GameObject
/// or it's children that has the specified name.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="gameObject"></param>
/// <param name="name"></param>
/// <param name="includeInactive">Whether to include inactive child objects in the search or not.</param>
/// <returns></returns>
public static T GetComponentInChildrenByName<T>(
MSchmoecker marked this conversation as resolved.
Show resolved Hide resolved
this GameObject gameObject,
string name,
bool includeInactive = false
) where T : Component
{
foreach (var compo in gameObject.GetComponentsInChildren<T>(includeInactive))
{
if (compo.name == name)
{
return compo;
}
}
Logger.LogWarning($"No {nameof(T)} with name {name} found for GameObject: {gameObject.name}");
return null;
}

/// <summary>
/// Extension method to find nested children by name using either
/// a breadth-first or depth-first search. Default is breadth-first.
/// </summary>
/// <param name="gameObject"></param>
/// <param name="childName">Name of the child object to search for.</param>
/// <param name="breadthFirst"> Whether to preform a breadth first or depth first search. Default is breadth first.</param>
/// <returns></returns>
public static Transform FindDeepChild(this GameObject gameObject, string childName, bool breadthFirst = true)
{
return gameObject?.transform.FindDeepChild(childName, breadthFirst);
}
MSchmoecker marked this conversation as resolved.
Show resolved Hide resolved
}

/// <summary>
Expand Down
121 changes: 121 additions & 0 deletions JotunnLib/Extensions/StringExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
namespace Jotunn.Extensions
{
public static class StringExtensions
{
/// <summary>
/// Returns true if the string contains any of the substrings.
/// </summary>
/// <param name="str"></param>
/// <param name="substrings"></param>
/// <returns></returns>
public static bool ContainsAny(this string str, params string[] substrings)
{
foreach (var substring in substrings)
{
if (str.Contains(substring))
{
return true;
}
}
return false;
}

/// <summary>
/// Returns true if the string ends with any one of the suffixes.
/// </summary>
/// <param name="str"></param>
/// <param name="suffixes"></param>
/// <returns></returns>
public static bool EndsWithAny(this string str, params string[] suffixes)
{
foreach (var substring in suffixes)
{
if (str.EndsWith(substring))
{
return true;
}
}
return false;
}

/// <summary>
/// Returns true if the string starts with any one of the prefixes.
/// </summary>
/// <param name="str"></param>
/// <param name="prefixes"></param>
/// <returns></returns>
public static bool StartsWithAny(this string str, params string[] prefixes)
{
foreach (var substring in prefixes)
{
if (str.StartsWith(substring))
{
return true;
}
}
return false;
}

/// <summary>
/// If the string ends with the suffix then return a copy of the string
/// with the suffix stripped, otherwise return the original string.
/// </summary>
/// <param name="s"></param>
/// <param name="suffix"></param>
/// <returns></returns>
public static string RemoveSuffix(this string s, string suffix)
{
if (s.EndsWith(suffix))
{
return s.Substring(0, s.Length - suffix.Length);
}

return s;
}

/// <summary>
/// If the string starts with the prefix then return a copy of the string
/// with the prefix stripped, otherwise return the original string.
/// </summary>
/// <param name="s"></param>
/// <param name="prefix"></param>
/// <returns></returns>
public static string RemovePrefix(this string s, string prefix)
{
if (s.StartsWith(prefix))
{
return s.Substring(prefix.Length, s.Length - prefix.Length);
}
return s;
}

/// <summary>
/// Returns a copy of the string with the first character capitalized
/// </summary>
/// <param name="s"></param>
/// <returns></returns>
public static string CapitalizeFirstLetter(this string s)
{
if (s.Length == 0)
return s;
else if (s.Length == 1)
return $"{char.ToUpper(s[0])}";
else
return char.ToUpper(s[0]) + s.Substring(1);
}

/// <summary>
/// Returns an Empty string if value is null
/// </summary>
/// <param name="value"></param>
/// <returns></returns>
public static string EmptyIfNull(this object value)
{
if (value == null)
{
return string.Empty;
}
return value.ToString();
}
MSchmoecker marked this conversation as resolved.
Show resolved Hide resolved
}
}
59 changes: 59 additions & 0 deletions JotunnLib/Extensions/TransformExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
using System.Collections.Generic;
using UnityEngine;

namespace Jotunn.Extensions
{
public static class TransformExtensions
{
/// <summary>
/// Extension method to find nested children by name using either
/// a breadth-first or depth-first search. Default is breadth-first.
/// </summary>
/// <param name="transform"></param>
/// <param name="childName">Name of the child object to search for.</param>
/// <param name="breadthFirst"> Whether to preform a breadth first or depth first search. Default is breadth first.</param>
/// <returns></returns>
public static Transform FindDeepChild(
MSchmoecker marked this conversation as resolved.
Show resolved Hide resolved
this Transform transform,
string childName,
bool breadthFirst = true
)
{
if (breadthFirst)
{
var queue = new Queue<Transform>();
queue.Enqueue(transform);
while (queue.Count > 0)
{
var child = queue.Dequeue();
if (child.name == childName)
{
return child;
}

foreach (Transform t in child)
{
queue.Enqueue(t);
}
}
return null;
}
else
{
foreach (Transform child in transform)
{
if (child.name == childName)
{
return child;
}
var result = child.FindDeepChild(childName);
if (result != null)
{
return result;
}
}
return null;
}
}
}
}