-
Notifications
You must be signed in to change notification settings - Fork 454
feat: AttachableBehaviour and ComponentController #3518
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
base: develop-2.0.0
Are you sure you want to change the base?
feat: AttachableBehaviour and ComponentController #3518
Conversation
…d-object-controller
…d-object-controller
Minor XML API fixes.
Simplified the nameof AttachableBehaviour.Detach to just Detach.
…d-object-controller
Refactoring the ComponentController to provide more flexibility as well as being able to have component entries that will apply the inverse of the current ComponentController's current state....which allows for switching between different sets of components depending upon the controller's state.
switching to a Light component as opposed to BoxCollider as BoxCollider requires the physics package and we are just testing the functionality of ComponentController and not specifically any one other type of component.
…d-object-controller
…d-object-controller
…d-object-controller
Using RPCs and synchronizing the property being set using NetworkBehaviour.OnSynchronize in order to assure order of operations when it comes to messages. Updated the ComponentController to be able to stagger state updates in the event this occurs (wip and I might remove this part and not allow changes to state until any pending state is finished).
Minor adjustment to the range for delays allow it to be zero. Fixing spelling issues.
Had to make some minor adjustments in order to assure that users could handle sending any last micro-second tasks on any spawned instances prior to them despawning. Added NetworkBehaviour.OnNetworkPreDespawn. Did a slight order of operations on NetworkManager.Shutdown internal in order to assure sending RPCs during despawn would still work. Minor adjustments to the new helper components associated with this PR.
…d-object-controller
…d-object-controller
Fixing some PVP related issues.
Several improvements on the attach and detach processing. Added the ability to tie ComponentControllers to AttachableBehaviours in order to auto-notify when something is attaching and detaching. Several adjustments to fix the issue with ungraceful disconnects and re-synchronizing attachables. Added forced change based on flags applied, things like when an AttachableNode is despawning, changing ownership, or being destroyed then local instances, whether authority or not, will all force the attach or detach state. Added an internal virtual destroy method on NetworkBehaviour to allow for helper components to assure on destroy script is invoked.
Adding documentation to an undocumented enum value.
Updating the core components based on some bugs discovered during testing. Updated the AttachableBehaviourTests to validate the different types of auto-detach flag combinations. Fixed some spelling issues with "detatch" (not sure why I got into that habit)...corrected to "detach".
…d-object-controller
Adjusting the component section from a file and folder context. Adjusting the component section for the table of contents. Adding foundational components and helpers sub-sections to network components section. Moved foundational components into the foundational (components) folder and updated links and image paths. Adding AttachableBehaviour document along with images. Added some place holders for AttachableNode and ComponentController. Fixing some invalid image paths.
Removing white space at the end of lines.
Removing trickier white spaces...
Adding `AttachableNode` and `ComponentController` sections. Added "Synchronized RPC driven fields" section to networkbehaviour-synchronize.md. Updated various areas based on the additions.
Resolving more white space issues.
…d-object-controller
Removing a single sneaky white space.
@@ -218,7 +218,7 @@ private static void CheckPrefabStage(PrefabStage prefabStage) | |||
s_PrefabAsset = AssetDatabase.LoadAssetAtPath<NetworkObject>(s_PrefabStage.assetPath); | |||
} | |||
|
|||
if (s_PrefabInstance.GlobalObjectIdHash != s_PrefabAsset.GlobalObjectIdHash) | |||
if (s_PrefabAsset && s_PrefabInstance && s_PrefabInstance.GlobalObjectIdHash != s_PrefabAsset.GlobalObjectIdHash) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This code is inside a block of if (s_PrefabInstance) {}
(line 200)
if (s_PrefabAsset && s_PrefabInstance && s_PrefabInstance.GlobalObjectIdHash != s_PrefabAsset.GlobalObjectIdHash) | |
if (s_PrefabAsset && s_PrefabInstance.GlobalObjectIdHash != s_PrefabAsset.GlobalObjectIdHash) |
/// Used for naming each element entry. | ||
/// </summary> | ||
[HideInInspector] | ||
public string name; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you mind explaining what this does?
/// as the <see cref="NetworkObject"/>, this will automatically create a child and add an | ||
/// <see cref="AttachableBehaviour"/> to that. | ||
/// </remarks> | ||
protected virtual void OnValidate() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To my untrained eye, it looks like there's two OnValidate
functions and only one will run? What's the difference between this OnValidate
and the function on line 45?
if (componentController == null) | ||
{ | ||
continue; | ||
} | ||
componentController.OnValidate(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Definitely a nitpick: null propagation can simplify this block.
Using the null conditional allows you to change
foreach (var componentController in ComponentControllers)
{
if (componentController == null)
{
continue;
}
componentController.OnValidate();
}
to
foreach (var componentController in ComponentControllers)
{
componentController?.OnValidate();
}
protected AttachState m_AttachState { get; private set; } | ||
|
||
/// <summary> | ||
/// The original parent of this <see cref="AttachableBehaviour"/> instance. | ||
/// </summary> | ||
protected GameObject m_DefaultParent { get; private set; } | ||
|
||
/// <summary> | ||
/// If attached, attaching, or detaching this will be the <see cref="AttachableNode"/> this <see cref="AttachableBehaviour"/> instance is attached to. | ||
/// </summary> | ||
protected AttachableNode m_AttachableNode { get; private set; } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Out of interest, why do these need to be protected rather than internal?
} | ||
|
||
var propertyInfo = Components[i].Component.GetType().GetProperty("enabled", BindingFlags.Instance | BindingFlags.Public); | ||
if (propertyInfo == null && propertyInfo.PropertyType != typeof(bool)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm guessing we don't want to check for is null && has property
?
// Scan the GameObject and all of its children and add all valid components to the list. | ||
foreach (var entry in gameObjectsToScan) | ||
{ | ||
var asGameObject = entry.Component as GameObject; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does it make sense to change gameObjectsToScan
from List<ComponentEntry>
to List<GameObject>
?
gameObjectsToScan.Clear(); | ||
|
||
// Final (third) pass is to name each list element item as the component is normally viewed in the inspector view. | ||
for (int i = 0; i < Components.Count; i++) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
very nit: This might be simpler to read as a foreach
loop. I do not have strong feelings about this.
// Example of how to synchronize late joining clients when using an RPC to update | ||
// a local property's state. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this comment valid here?
/// to have the owner be the authority of this <see cref="ComponentController"/> instance. | ||
/// </remarks> | ||
/// <returns>true = has authoriy | false = does not have authority</returns> | ||
protected virtual bool OnHasAuthority() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same comment as for AttachableBehaviour
here
AttachableBehaviour and Support Components
The purpose of this PR (feat) is to address the complexity of "picking up" or "dropping" an item in the world which can become complex when using the traditional
NetworkObject
parenting pattern. In this PR there are three primary components added to help reduce this complexity:AttachableBehaviour
: Provides "out of the box" support for attaching (i.e. parenting) a nested childGameObject
that includes anAttachableBehaviour
component to another nested childGameObject
with anAttachableNode
component that is associated with a differentNetworkObject
.AttachableNode
: This component is required by theAttachableBehaviour
component in order to be able to attach (i.e. parent) to another GameObject without having to parent the entireNetworkObject
component theAttachableBehaviour
component is associated with.ComponentController
: This component provides users the ability to synchronize the enabling or disabling of anyObject
derived component that has anenabled
property.This PR also incorporates a new "Helpers" subfolder under the NGO components folder where additional helper components will live.
Documentation Update
New Documentation
AttachableBehaviour
Network Components Section Update
New Foundational Components Section
New Helper Components Section
NetworkBehaviour.OnNetworkPreDespawn
Added another virtual method to
NetworkBehaviour
,OnNetworkPreDespawn
, that is invoked before running through the despawn sequence for theNetworkObject
and allNetworkBehaviour
children of theNetworkObject
being despawned. This provides an opportunity to do any kind of cleanup up or last micro-second state updates prior to despawning.Changelog
AttachableBehaviour
helper component to provide an alternate approach to parenting items without using theNetworkObject
parenting.AttachableNode
helper component that is used byAttachableBehaviour
as the target node for parenting.ComponentController
helper component that can be used to synchronize the enabling and disabling of components and can be used in conjunction withAttachableBehaviour
.NetworkBehaviour.OnNetworkPreDespawn
that is invoked before running through the despawn sequence for theNetworkObject
and allNetworkBehaviour
children of theNetworkObject
being despawned.Testing and Documentation
AttachableBehaviourTests
ComponentControllerTests
Backport
This is a v2.x only feature.