ExtendRealityLtd / ExtendRealityLtd/Zinnia.Unity

Add search options to AnyComponentTypeRule

Open
#141 0 comments 0 reactions 0 assignees View on GitHub
enhancement w_bug
Dominant language
C#
Stars
321
Forks
36
PR merge metrics
No merged PRs in 30d

Description

`AnyComponentTypeRule` should allow setting what to search through when trying to find a component of a type.

If an enum **flags** type is used the implementation seems to need to be done manually completely as Unity's `GetComponentInChildren` has an overload that allows specifying whether to search inactive game objects, but the one taking a `Type` argument doesn't. On top of that `GetComponentInParent` doesn't have any overload taking that argument...
Any implementation therefore needs to properly test **combinations** of search options, too, to really ensure these work.

Expand to see AnyComponentTypeRule.cs before it was simplified.

```c#
namespace VRTK.Core.Rule
{
using UnityEngine;
using System;
using System.Collections.Generic;
using System.Linq;
using VRTK.Core.Data.Attribute;
using VRTK.Core.Data.Type;
using VRTK.Core.Extension;

///


/// Determines whether a has any component found in a list.
///
public class AnyComponentTypeRule : BaseGameObjectRule
{
///
/// Specifies how to search for s on a .
///
[Flags]
public enum SearchOptions
{
///
/// Search through the 's components.
///
GameObjectItself = 1 << 0,
///
/// Search upwards through the hierarchy's components.
///
AnyParent = 1 << 1,
///
/// Search downwards through the hierarchy's components.
///
AnyChild = 1 << 2,
///
/// Search through components of inactive s.
///
IncludeInactiveGameObjects = 1 << 3
}

///
/// The component types to look for.
///
[TypePicker(typeof(Component))]
[Tooltip("The component types to look for.")]
public List componentTypes = new List();
///
/// The to use.
///
[UnityFlags]
[Tooltip("The SearchOptions to use.")]
public SearchOptions searchOptions = SearchOptions.GameObjectItself | SearchOptions.IncludeInactiveGameObjects;

///
protected override bool Accepts(GameObject targetGameObject)
{
return componentTypes.EmptyIfNull()
.Where(serializedType => serializedType.ActualType != null)
.Any(
serializedType =>
{
bool includeInactiveGameObjects = searchOptions.HasFlag(SearchOptions.IncludeInactiveGameObjects);

bool result = false;
if (searchOptions.HasFlag(SearchOptions.GameObjectItself))
{
result = (includeInactiveGameObjects || !gameObject.activeInHierarchy)
&& targetGameObject.GetComponent(serializedType) != null;
}

if (!result && searchOptions.HasFlag(SearchOptions.AnyParent))
{
Transform parent = targetGameObject.transform.parent;
while (!result && parent != null)
{
result = (includeInactiveGameObjects || !parent.gameObject.activeInHierarchy)
&& parent.GetComponent(serializedType) != null;
}
}

if (!result && searchOptions.HasFlag(SearchOptions.AnyChild))
{
Component component = targetGameObject.GetComponentInChildren(serializedType, includeInactiveGameObjects);
result = component != null && (includeInactiveGameObjects || component.gameObject != targetGameObject);
}

return result;
});
}
}
}
```

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.