Skip to content

Commit

Permalink
feat(Extension): provide alternative method for isActiveAndEnabled
Browse files Browse the repository at this point in the history
It would seem that the behaviour.isActiveAndEnabled property does not
always return what is expected. If a GameObject is active and the
behaviour is enabled then isActiveAndEnabled can still return false
whilst in the OnEnable state.

It would seem that isActiveAndEnabled does not return true until
all of the relevant initial Unity moments have passed for an Object.

To counter this, a new BehaviourExtension has been added called
`CheckIsActiveAndEnabled()` that will do an absolute check on
the GameObject active state and the behaviour enabled state.

If the old isActiveAndEnabled check is still required then it can
be switched to by a scripting define symbol of:

`ZINNIA_USE_ISACTIVEANDENABLED`

All of the relevant files that use `isActiveAndEnabled` have now been
updated to use the new `CheckIsActiveAndEnabled()` extension method.
  • Loading branch information
thestonefox committed Mar 28, 2023
1 parent 70b42d3 commit 2abbbf4
Show file tree
Hide file tree
Showing 23 changed files with 59 additions and 33 deletions.
5 changes: 3 additions & 2 deletions Editor/Data/Attribute/RestrictedAttributeDrawer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
{
using UnityEditor;
using UnityEngine;
using Zinnia.Extension;

/// <summary>
/// Displays an inspector property drawer with restricted styles.
Expand Down Expand Up @@ -45,8 +46,8 @@ public override void OnGUI(Rect position, SerializedProperty property, GUIConten
RestrictedAttribute attrib = (RestrictedAttribute)attribute;
Behaviour behaviour = (Behaviour)property.serializedObject.targetObject;

bool isPlayingAndActiveAndEnabled = Application.isPlaying && behaviour.isActiveAndEnabled;
bool isPlayingAndActiveAndDisabled = Application.isPlaying && !behaviour.isActiveAndEnabled;
bool isPlayingAndActiveAndEnabled = Application.isPlaying && behaviour.CheckIsActiveAndEnabled();
bool isPlayingAndActiveAndDisabled = Application.isPlaying && !behaviour.CheckIsActiveAndEnabled();
bool makeReadOnly = (attrib.restrictions & RestrictedAttribute.Restrictions.ReadOnlyAlways) != 0 ||
((attrib.restrictions & RestrictedAttribute.Restrictions.ReadOnlyAtRunTime) != 0 && Application.isPlaying) ||
((attrib.restrictions & RestrictedAttribute.Restrictions.ReadOnlyAtRunTimeAndEnabled) != 0 && isPlayingAndActiveAndEnabled) ||
Expand Down
3 changes: 2 additions & 1 deletion Editor/Data/Collection/ObservableListEditor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
using UnityEditor;
using UnityEngine;
using Zinnia.Data.Collection.List;
using Zinnia.Extension;
using Zinnia.Utility;

/// <summary>
Expand Down Expand Up @@ -68,7 +69,7 @@ protected override void DrawProperty(SerializedProperty property)

bool drawAsDisabled = Application.isPlaying
&& property.serializedObject.targetObject is Behaviour behaviour
&& !behaviour.isActiveAndEnabled;
&& !behaviour.CheckIsActiveAndEnabled();
if (drawAsDisabled)
{
EditorGUILayout.HelpBox(
Expand Down
3 changes: 2 additions & 1 deletion Editor/Utility/ZinniaInspector.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
using System.Reflection;
using UnityEditor;
using UnityEngine;
using Zinnia.Extension;
using Object = UnityEngine.Object;

[CustomEditor(typeof(Object), true)]
Expand Down Expand Up @@ -108,7 +109,7 @@ protected virtual void ProcessObjectProperty(SerializedProperty property, string

protected virtual bool CanApplyChangeHandlers(Object targetObject)
{
return Application.isPlaying && targetObject is Behaviour behaviour && behaviour.isActiveAndEnabled;
return Application.isPlaying && targetObject is Behaviour behaviour && behaviour.CheckIsActiveAndEnabled();
}

protected virtual bool TryApplyChangeHandlersToProperty(Object targetObject, SerializedProperty property)
Expand Down
2 changes: 1 addition & 1 deletion Runtime/Action/Action.cs
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ protected set
/// <returns><see langword="true"/> if the event should be emitted.</returns>
protected virtual bool CanEmit()
{
return isActiveAndEnabled;
return this.CheckIsActiveAndEnabled();
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ public Vector2Component ComponentToExtract
/// <returns>The extracted <see cref="float"/>.</returns>
public virtual float? Extract()
{
if (!isActiveAndEnabled)
if (!this.CheckIsActiveAndEnabled())
{
Result = null;
return null;
Expand Down
4 changes: 2 additions & 2 deletions Runtime/Data/Operation/Mutation/TransformPropertyMutator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ public virtual void SetMutateOnAxisZ(bool value)
/// Sets the property to the new value.
/// </summary>
/// <param name="input">The value to set it to.</param>
/// <returns>The mutated value if the current component is <see cref="Behaviour.isActiveAndEnabled"/> and the <see cref="Target"/> is valid. Otherwise returns the default value for <see cref="Vector3"/>.</returns>
/// <returns>The mutated value if the current component is <see cref="Behaviour.CheckIsActiveAndEnabled()"/> and the <see cref="Target"/> is valid. Otherwise returns the default value for <see cref="Vector3"/>.</returns>
public virtual Vector3 SetProperty(Vector3 input)
{
if (!IsValid())
Expand Down Expand Up @@ -153,7 +153,7 @@ public virtual void DoSetProperty(Vector3 input)
/// Increments the property by the given value.
/// </summary>
/// <param name="input">The value to increment by.</param>
/// <returns>The mutated value if the current component is <see cref="Behaviour.isActiveAndEnabled"/> and the <see cref="Target"/> is valid. Otherwise returns the default value for <see cref="Vector3"/>.</returns>
/// <returns>The mutated value if the current component is <see cref="Behaviour.CheckIsActiveAndEnabled()"/> and the <see cref="Target"/> is valid. Otherwise returns the default value for <see cref="Vector3"/>.</returns>
public virtual Vector3 IncrementProperty(Vector3 input)
{
if (!IsValid())
Expand Down
2 changes: 1 addition & 1 deletion Runtime/Data/Type/Transformation/Transformer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
/// Transforms the given input into the relevant output.
/// </summary>
/// <param name="input">The input to transform.</param>
/// <returns>The transformed input or the default of <see cref="TOutput"/> if the current component is not <see cref="Behaviour.isActiveAndEnabled"/>.</returns>
/// <returns>The transformed input or the default of <see cref="TOutput"/> if the current component is not <see cref="Behaviour.CheckIsActiveAndEnabled()"/>.</returns>
public virtual TOutput Transform(TInput input)
{
if (!this.IsValidState())
Expand Down
8 changes: 4 additions & 4 deletions Runtime/Event/BehaviourEnabledObserver.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
using Zinnia.Extension;

/// <summary>
/// Emits an event once a list of <see cref="Behaviour"/>s all are <see cref="Behaviour.isActiveAndEnabled"/>.
/// Emits an event once a list of <see cref="Behaviour"/>s all are <see cref="Behaviour.CheckIsActiveAndEnabled()"/>.
/// </summary>
public class BehaviourEnabledObserver : MonoBehaviour
{
Expand Down Expand Up @@ -73,7 +73,7 @@ public BehaviourObservableList Behaviours
}

/// <summary>
/// Emitted when all <see cref="Behaviours"/> are <see cref="Behaviour.isActiveAndEnabled"/>.
/// Emitted when all <see cref="Behaviours"/> are <see cref="Behaviour.CheckIsActiveAndEnabled()"/>.
/// </summary>
public UnityEvent ActiveAndEnabled = new UnityEvent();

Expand Down Expand Up @@ -146,7 +146,7 @@ protected virtual IEnumerator Check()
}

/// <summary>
/// Checks whether all <see cref="Behaviours"/> are <see cref="Behaviour.isActiveAndEnabled"/> and emits <see cref="ActiveAndEnabled"/> if they are.
/// Checks whether all <see cref="Behaviours"/> are <see cref="Behaviour.CheckIsActiveAndEnabled()"/> and emits <see cref="ActiveAndEnabled"/> if they are.
/// </summary>
/// <returns>Whether all <see cref="Behaviours"/> are active and enabled.</returns>
protected virtual bool AreBehavioursEnabled()
Expand All @@ -158,7 +158,7 @@ protected virtual bool AreBehavioursEnabled()

foreach (Behaviour behaviour in Behaviours.NonSubscribableElements)
{
if (!behaviour.isActiveAndEnabled)
if (!behaviour.CheckIsActiveAndEnabled())
{
return false;
}
Expand Down
3 changes: 2 additions & 1 deletion Runtime/Event/Proxy/EventProxyEmitter.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
namespace Zinnia.Event.Proxy
{
using UnityEngine;
using Zinnia.Extension;

/// <summary>
/// Forms the basis for all proxy emitters.
Expand All @@ -13,7 +14,7 @@ public abstract class EventProxyEmitter : MonoBehaviour
/// <returns><see langword="true"/> if the emitter is in a valid state.</returns>
protected virtual bool IsValid()
{
return isActiveAndEnabled;
return this.CheckIsActiveAndEnabled();
}
}
}
23 changes: 20 additions & 3 deletions Runtime/Extension/BehaviourExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ void OnBeforeRender()
return;
}

if (!behaviour.isActiveAndEnabled)
if (!behaviour.CheckIsActiveAndEnabled())
{
return;
}
Expand All @@ -51,7 +51,7 @@ void OnBeforeRender()
action();
}

if (behaviour.isActiveAndEnabled)
if (behaviour.CheckIsActiveAndEnabled())
{
action();
return;
Expand Down Expand Up @@ -84,7 +84,24 @@ public static bool IsValidState(this Behaviour behaviour, GameObjectActivity gam
/// <returns>Whether the member change method is allowed to run.</returns>
public static bool IsMemberChangeAllowed(this Behaviour behaviour)
{
return Application.isPlaying && behaviour.isActiveAndEnabled;
return Application.isPlaying && behaviour.CheckIsActiveAndEnabled();
}

/// <summary>
/// Checks to see if the behaviour <see cref="GameObject"/> is active in the hierarchy and whether it's enabled.
/// </summary>
/// <remarks>
/// This is a replacement for <see cref="Behaviour.isActiveAndEnabled"/> as that does not always return the expected result.
/// </remarks>
/// <param name="behaviour">The <see cref="Behaviour"/> to check against.</param>
/// <returns>Whether the gameobject is active and the behaviour is enabled.</returns>
public static bool CheckIsActiveAndEnabled(this Behaviour behaviour)
{
#if ZINNIA_USE_ISACTIVEANDENABLED
return behaviour.isActiveAndEnabled;
#else
return behaviour.gameObject.activeInHierarchy && behaviour.enabled;
#endif
}
}
}
3 changes: 2 additions & 1 deletion Runtime/Haptics/HapticProcess.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
namespace Zinnia.Haptics
{
using UnityEngine;
using Zinnia.Extension;

/// <summary>
/// The basis of a haptic process that can be started or cancelled.
Expand All @@ -13,7 +14,7 @@ public abstract class HapticProcess : MonoBehaviour
/// <returns><see langword="true"/> if the <see cref="Component"/> is considered active.</returns>
public virtual bool IsActive()
{
return isActiveAndEnabled;
return this.CheckIsActiveAndEnabled();
}

/// <summary>
Expand Down
2 changes: 1 addition & 1 deletion Runtime/Pointer/ObjectPointer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -578,7 +578,7 @@ protected virtual void UpdateRenderData()
/// <param name="ignoreBehaviourState">Determines if the events should be emitted based on the <see cref="Behaviour.enabled"/> state.</param>
protected virtual void TryDeactivate(bool ignoreBehaviourState)
{
if ((!isActiveAndEnabled && !ignoreBehaviourState) || !IsActivated)
if ((!this.CheckIsActiveAndEnabled() && !ignoreBehaviourState) || !IsActivated)
{
return;
}
Expand Down
2 changes: 1 addition & 1 deletion Runtime/Process/Moment/MomentProcess.cs
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ public virtual void Process()
/// </summary>
public virtual void ProcessNow()
{
if (Source == null || (OnlyProcessOnActiveAndEnabled && !isActiveAndEnabled))
if (Source == null || (OnlyProcessOnActiveAndEnabled && !this.CheckIsActiveAndEnabled()))
{
return;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ public virtual void DoSort(ActiveCollisionsContainer.EventData originalList)
/// <returns>The sorted collision collection.</returns>
public virtual ActiveCollisionsContainer.EventData Sort(ActiveCollisionsContainer.EventData originalList)
{
if (!isActiveAndEnabled || Source == null)
if (!this.CheckIsActiveAndEnabled() || Source == null)
{
return originalList;
}
Expand Down
3 changes: 2 additions & 1 deletion Runtime/Tracking/Collision/Active/Operation/OrderReverser.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
namespace Zinnia.Tracking.Collision.Active.Operation
{
using UnityEngine;
using Zinnia.Extension;

/// <summary>
/// Reverses the order of the given collision collection.
Expand Down Expand Up @@ -33,7 +34,7 @@ public virtual void DoReverse(ActiveCollisionsContainer.EventData originalList)
/// <returns>The reversed collision collection.</returns>
public virtual ActiveCollisionsContainer.EventData Reverse(ActiveCollisionsContainer.EventData originalList)
{
if (!isActiveAndEnabled)
if (!this.CheckIsActiveAndEnabled())
{
return originalList;
}
Expand Down
5 changes: 3 additions & 2 deletions Runtime/Tracking/Collision/Active/Operation/Slicer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
using System.Linq;
using UnityEngine;
using UnityEngine.Events;
using Zinnia.Extension;

/// <summary>
/// Slices a selection of the collection from the given <see cref="StartIndex"/> for the given <see cref="Length"/> and provides the sliced collection and the remaining collection separately.
Expand Down Expand Up @@ -116,7 +117,7 @@ public virtual ActiveCollisionsContainer.EventData Slice(ActiveCollisionsContain
SlicedList.Clear();
RemainingList.Clear();

if (!isActiveAndEnabled)
if (!this.CheckIsActiveAndEnabled())
{
return SlicedList;
}
Expand Down Expand Up @@ -193,7 +194,7 @@ protected virtual void CreateRemainedList(ActiveCollisionsContainer.EventData or
public virtual ActiveCollisionsContainer.EventData Slice(ActiveCollisionsContainer.EventData originalList, out ActiveCollisionsContainer.EventData remaining)
{
ActiveCollisionsContainer.EventData returnList = Slice(originalList);
remaining = (isActiveAndEnabled ? RemainingList : originalList);
remaining = (this.CheckIsActiveAndEnabled() ? RemainingList : originalList);
return returnList;
}

Expand Down
2 changes: 1 addition & 1 deletion Runtime/Tracking/Collision/CollisionIgnorer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -214,7 +214,7 @@ protected virtual void ToggleCollisions(bool state)
/// <param name="state">Whether to ignore collisions or not.</param>
protected virtual void ToggleCollisions(GameObject source, GameObjectObservableList sources, GameObjectObservableList targets, bool state)
{
if (source == null || (!state && isActiveAndEnabled && sources.Contains(source)))
if (source == null || (!state && this.CheckIsActiveAndEnabled() && sources.Contains(source)))
{
return;
}
Expand Down
2 changes: 1 addition & 1 deletion Runtime/Tracking/Velocity/ComponentTrackerProxy.cs
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ protected virtual void OnEnable()
/// <inheritdoc />
public override bool IsActive()
{
return base.IsActive() && cachedVelocityTracker != null && cachedVelocityTracker.isActiveAndEnabled;
return base.IsActive() && cachedVelocityTracker != null && cachedVelocityTracker.CheckIsActiveAndEnabled();
}

/// <inheritdoc />
Expand Down
2 changes: 1 addition & 1 deletion Runtime/Tracking/Velocity/VelocityMultiplier.cs
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ public virtual void SetAngularVelocityMultiplierFactorZ(float value)
/// <inheritdoc />
public override bool IsActive()
{
return base.IsActive() && Source != null && Source.isActiveAndEnabled;
return base.IsActive() && Source != null && Source.CheckIsActiveAndEnabled();
}

/// <inheritdoc />
Expand Down
3 changes: 2 additions & 1 deletion Runtime/Tracking/Velocity/VelocityTracker.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
namespace Zinnia.Tracking.Velocity
{
using UnityEngine;
using Zinnia.Extension;

/// <summary>
/// Tracked Velocity information.
Expand All @@ -13,7 +14,7 @@ public abstract class VelocityTracker : MonoBehaviour
/// <returns>Whether the <see cref="Behaviour"/> is considered active.</returns>
public virtual bool IsActive()
{
return isActiveAndEnabled;
return this.CheckIsActiveAndEnabled();
}

/// <summary>
Expand Down
2 changes: 1 addition & 1 deletion Tests/Editor/Extension/BehaviourExtensionsTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ public class MockBehaviour : MonoBehaviour

public void ExecuteOnlyWhenEnabled()
{
if (!isActiveAndEnabled)
if (!this.CheckIsActiveAndEnabled())
{
return;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using Zinnia.Tracking.Collision;
using Zinnia.Extension;
using Zinnia.Tracking.Collision;
using Zinnia.Tracking.Collision.Active;

namespace Test.Zinnia.Tracking.Collision.Active
Expand All @@ -13,7 +14,7 @@ public class ActiveCollisionConsumerMock : ActiveCollisionConsumer
public override bool Consume(ActiveCollisionPublisher.PayloadData publisher, CollisionNotifier.EventData currentCollision)
{
received = false;
if (isActiveAndEnabled)
if (this.CheckIsActiveAndEnabled())
{
received = true;
}
Expand Down
4 changes: 2 additions & 2 deletions Tests/Editor/Visual/CameraBackgroundMutatorTest.cs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
using Zinnia.Visual;
using Zinnia.Data.Collection.List;
using Zinnia.Visual;

namespace Test.Zinnia.Visual
{
using global::Zinnia.Data.Collection.List;
using NUnit.Framework;
using UnityEngine;

Expand Down

0 comments on commit 2abbbf4

Please sign in to comment.