-
Notifications
You must be signed in to change notification settings - Fork 452
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
Open
NoelStephensUnity
wants to merge
37
commits into
develop-2.0.0
Choose a base branch
from
feat/attachable-networkbehaviour-and-object-controller
base: develop-2.0.0
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
feat: AttachableBehaviour and ComponentController #3518
NoelStephensUnity
wants to merge
37
commits into
develop-2.0.0
from
feat/attachable-networkbehaviour-and-object-controller
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
…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
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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.
Attaching vs NetworkObject parenting
Fundamentally, attaching is another form of synchronized (i.e. netcode) parenting that does not require one to use the traditional
NetworkObject
parenting. Attaching a childGameObject
nested under aNeworkObject
(really theGameObject
theNetworkObject
component belongs to) will only take the childGameObject
and parent it under another childGameObject
nested under or on the sameGameObject
with a differentNeworkObject
.NetworkObject parenting
The traditional approach has been to spawn two network prefab instances:

Then parent one instance under the other:

This is simple enough for many scenarios, but can become cumbersome under more specific scenarios where a user might want to have a "world" version of the item and a "picked up" version of the item.
Attaching
With attaching, a user would create nested

GameObject
children that represent the item when it is picked up and when it is dropped/placed somewhere in the scene (i.e. world).NetworkObject
component is placed.By placing an

AttachableBehaviour
component on the NestedChild-PickedUpGameObject
and anAttachableNode
component on the TargetNode, a user can then invoke theAttachableBehaviour.Attach
method while passing in theAttachableNode
component and the NestedChild-PickedUpGameObject
will get parented under the TargetNode while also synchronizing this action with all other clients.AttachableBehaviour
The basic functionality of the
AttachableBehaviour
component provides:ComponetController
components from any part of the parent-child hierarchy.ComponentControllerEntry
provides the ability to select when theComponentController
should be triggered (via the Auto Trigger property) and whether its enabled state should be enabled or disabled upon attaching (via the Enable On Attach property). The default setting is to be disabled upon theAttachableBehaviour
attaching to anAttachableNode
and enabled upon detaching. When the Enable On Attach property is enabled, theComponentController
will be set to enabled upon theAttachableBehaviour
attaching to anAttachableNode
and disabled upon detaching.AttachableBehaviour
component will automatically detach from anAttachableNode
via the Auto Detach property.AttachableBehaviour
will detach from anyAttachableNode
it is attached to.AttachableBehaviour
being despawned, it will detach from anyAttachableNode
it is attached to.AttachableNode
being destroyed, any attachedAttachableBehaviour
with this flag will automatically detach from theAttachableNode
.Any of the
AttachableBehaviour.AutoDetach
settings will be invoked on all instances without the need for the owner to synchronize the end result(i.e. detaching) which provides a level of redundancy for edge case scenarios like a player being disconnected abruptly by the host or by timing out or any scenario where a spawned object is being destroyed with the owner or perhaps being redistributed to another client authority in a distributed authority session. Having the ability to select or deselect any of the auto-detach flags coupled with the ability to derive fromAttachableBehaviour
provides additional levels of modularity/customization.AttachableNode
The simplest component in the bunch, this provides a valid connection point (i.e. what an
AttachableBehaviour
can attach to) with the ability to have it automatically detach from any attachedAttachableBehaviour
instances when it is despawned.ComponentController
Taking the above example into consideration, it would make sense that a user would want to be able to easily control whether a specific component is enabled or disabled when something is attached or detached.
As an example:
MeshRenderer
,Collider
, and other components on the NestedChild-PickedUpGameObject
while enabling similar types of components on the NestedChild-World.MeshRenderer
,Collider
, and other components on the NestedChild-PickedUpGameObject
while disabling similar types of components on the NestedChild-World.The
ComponentController
provides this type of functionality:AttachableBehaviour
or independently for another purpose.ComponentController
's current state.AttachableBehaviour
, delays are ignored when anAttachableNode
is being destroyed and the changes are immediate.The
ComponentController
could be daisy chained with minimal user script:Example of synchronized RPC driven properties
Both the
AttachableBehaviour
and theComponentController
provide an example of using synchronized RPC driven properties in place ofNetworkVariable
. Under certain conditions it is better to use RPCs when a specific order of operations is needed as opposed toNetworkVariable
s which can update out of order (regarding the order in which certain states were updated) depending upon several edge case scenarios.Under this condition using reliable RPCs will assure the messages are received in the order they were generated while also reducing the latency time between the change and the non-authority instances being notified of the change. Synchronized RPC driven properties only require overriding the
NetworkBehaviour.OnSynchronize
method and serializing any properties that need to be synchronized with late joining players or handling network object visibility related scenarios.Usage Walk Through
Introduction
For example purposes, we will walk through a common scenario where you might want to have a world item that had unique visual and scripted components active while while placed in the world but then can switch to a different set of visual and scripted components when picked up by a player's avatar. Additionally, you might want to be able to easily "attach" only the portion of the item, that is active when picked up, to one of the player's avatar's child nodes. Below is a high-level diagram overview of what both the player and world item network prefabs could look like:
Player
The player prefab in the above diagram is not complete, includes the components of interest, and some additional children and components for example purposes. A complete diagram would most definitely have additional components and children. The
AttachableNode
components provide a "target attach point" that any other spawned network prefab with anAttachableBehaviour
could attach itself to.World Item
This diagram has a bit more detail to it and introduces one possible usage of a
ComponentController
andAttachableBehaviour
. TheComponentController
will be used to control the enabling and disabling of components and synchronizing this with non-authority instances. TheAttachableBehaviour
resides on the childAttachedView
'sGameObject
and will be the catalyst for attaching to a player.World vs Attached View Modes
In the diagram above, we see arrows pointing from the
ComponentController
to the non-netcode standard Unity components such as aMeshRenderer
,Collider
, or any other component that should only be enabled when either in "World View" or "Attached View" modes. Below is a screenshot of what theComponentController
would look like in the inspector view:World Item Component Controller
Looking at the
ComponentController
's Components property, we can see two of the component entries have references to theWorldItemView
'sBoxCollider
andMeshRenderer
that are both configured to be enabled when theComponentController
's state istrue
. We can also see that theCarryView
'sMeshRenderer
is added and configured to be the inverse of the currentComponentController
's state. Since theComponentController
's Start Enabled property is enabled we can logically deduce the WorldItem network prefab will start with theWorldItemView
being active when spawned. Taking a look at the CarryObject child's properties:We can see the
AttachableBehaviour
's Component Controllers list containsComponentControllerEntry
(WorldItem Component Controller) that references to theWorldItem
'sComponentController
. We can also see that theComponentControllerEntry
is configured to trigger on everything (OnAttach and OnDetach) and will set theComponentController
's state to disabled (false). This means when theAttachableBehaviour
is attached theComponentController
will be in the disabled state along with theWorldItemView
components while theCarryView
'sMeshRenderer
will be enabled.Summarized Overview:
AttachableBehaviour
sets theComponentController
state (true/enabled or false/disabled).ComponentController
states:Attaching
The above diagram represents what the Player and World Item spawned objects (including cloned/non-authority instances) would look like once the Attached View object has been parented under the avatar's Right Attach object. The green area and arrow represent the still existing relationship that the Attached View has with the World Item's
NetworkObject
.AttachableBehaviour & NetworkObject Relationship (convert to note)
Upon a
NetworkObject
component being spawned, all associatedNetworkBehaviour
based component instances, that are directly attached to theNetworkObject
'sGameObject
or are on any childGameObject
, will be registered with theNetworkObject
instance. Even if a childGameObject
containing one or moreNetworkBehaviour
based component instances is parented under some otherGameObject
whether it is associated with a spawnedNetworkObject
or not. Of course, there are additional considerations like what happens when theNetworkObject
is de-spawned, how to assure the child attachable returns back to its default parent, and several other edge case scenarios.AttachableBehaviour
leverages from this "spawn lifetime" relationship to provide another type of "parenting" while also taking into consideration the previously mentioned "additional considerations" for you.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.