Skip to content

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

Draft
wants to merge 17 commits into
base: develop-2.0.0
Choose a base branch
from

Conversation

NoelStephensUnity
Copy link
Collaborator

@NoelStephensUnity NoelStephensUnity commented Jun 24, 2025

AttachableNetworkBehaviour 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 child GameObject that includes an AttachableBehaviour component to another nested child GameObject with an AttachableNode component that is associated with a different NetworkObject.
  • AttachableNode: This component is required by the AttachableBehaviour component in order to be able to attach (i.e. parent) to another GameObject without having to parent the entire NetworkObject component the AttachableBehaviour component is associated with.
  • ComponentController: This component provides users the ability to synchronize the enabling or disabling of any Object derived component that has an enabled 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 child GameObject nested under a NeworkObject (really the GameObject the NetworkObject component belongs to) will only take the child GameObject and parent it under another child GameObject nested under or on the same GameObject with a different NeworkObject.

NetworkObject parenting

The traditional approach has been to spawn two network prefab instances:
image

Then parent one instance under the other:
image

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).
image

  • The WorldItemRoot is where the NetworkObject component is placed.
  • The NestedChild-World contains the components needed for the item when it is placed in the world.
  • The NestedChild-PickedUp contains the components needed for the item when it is picked up by a player.

By placing an AttachableBehaviour component on the NestedChild-PickedUp GameObject and an AttachableNode component on the TargetNode, a user can then invoke the AttachableBehaviour.Attach method while passing in the AttachableNode component and the NestedChild-PickedUp GameObject will get parented under the TargetNode while also synchronizing this action with all other clients.
image

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. As an example:

  • When the WorldItemRoot is in the "placed in the world" state, it would make sense to disable any MeshRenderer, Collider, and other components on the NestedChild-PickedUp GameObject while enabling similar types of components on the NestedChild-World.
  • When the WorldItemRoot is in the "picked up" state, it would make sense to enable any MeshRenderer, Collider, and other components on the NestedChild-PickedUp GameObject while disabling similar types of components on the NestedChild-World.
  • It would also make sense to synchronize the enabling or disabling of components with all instances.

The ComponentController provides this type of functionality.

Changelog

  • Added: WIP

Testing and Documentation

  • Includes integration tests.
  • No documentation changes or additions were necessary.
  • Requires public documentation that provides usage and examples (wip).

Backport

These new helper components are currently only targeting v2.x.

Adding AttachableBehaviour and ObjectController.
Renaming ObjectController to ComponentController.
Added some additional validation checking and handling.
Updated XML API.
Adding helpers meta.
Adding an AttachableNode as the target for AttachableBehaviour.
Refactoring AttachableBehaviour.
Adding new test for attachables.
Replacing any improperly spelled "detatch" with "detach".
XML API and private methods.
Minor XML API fixes.
Simplified the nameof AttachableBehaviour.Detach to just Detach.
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.
Made some minor adjustments while writing the base test for ComponentController.
Adding the base ComponentController test.
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.
Removing using directive.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant