Stop dragging things into the Inspector. Component Connector wires up your serialized references automatically, by name, the moment you build the hierarchy.
🇰🇷 한국어 README는 README.ko.md 에서 볼 수 있습니다.
publicclassHUD:MonoBehaviour{[ComponentConnect]publicTextscoreText;// ← finds GameObject "scoreText"[ComponentConnect]publicSliderhpBar;// ← finds GameObject "hpBar"[GetComponent]publicCanvascanvas;// ← grabs Canvas on this GameObject}That's it. No Find(), no manual drag, no setup component, no runtime cost.
V2 is a complete rewrite. Same attributes, dramatically better behavior:
| V1 | V2 | |
|---|---|---|
| Helper component on GameObject | Required (ComponentConnector MonoBehaviour) | Not needed |
| Trigger | Update() poll every 0.1s | Event-driven (hierarchyChanged, prefabStageOpened, prefabSaving) |
| Prefab Mode | ❌ Scene only | ✅ Fully supported (isolated stage + on-save) |
| Dirty marking | ❌ Changes silently lost on reload | ✅ EditorUtility.SetDirty |
| Undo support | ❌ | ✅ Undo.RecordObject |
| Field visibility | public only | public / private / protected / [SerializeField] |
Method visibility ([OnClick]) | public only | All visibilities |
| Reflection | Re-scanned every tick | Cached per Type |
[OnClick] re-binding | Removed & re-added every tick → constant scene dirty | No-op when already correct |
[GetComponent] overrides | Always overwritten | User assignments preserved |
| Distribution | Single file copy | Single file copy or UPM |
V2 is drop-in compatible with V1 — the legacy ComponentConnector MonoBehaviour ships as a no-op stub so existing scenes and prefabs keep loading without errors. See CHANGELOG.md for the full list.
Copy one file. That's the whole installation.
Download ComponentConnector.cs and drop it anywhere under your Assets/ folder.
- No setup component to attach
- No initialization step
- No package manifest to edit
- The editor-only logic is wrapped in
#if UNITY_EDITORand stripped from player builds
If you prefer dependency-managed installs:
In Unity: Window → Package Manager → + → Install package from git URL...
https://github.com/synchrok/ComponentConnector.git
Or add to Packages/manifest.json:
{
"dependencies": {
"com.synchrok.componentconnector": "https://github.com/synchrok/ComponentConnector.git"
}
}To pin a version, append #v2.0.0:
https://github.com/synchrok/ComponentConnector.git#v2.0.0
Add the attribute to any field that's visible in the inspector. The matched GameObject (or its component) gets assigned automatically.
usingUnityEngine;usingUnityEngine.UI;publicclassShopPanel:MonoBehaviour{// 1. Match by field name → looks for a GameObject called "title"[ComponentConnect]publicTexttitle;// 2. Match by an explicit name → looks for "BuyButton"[ComponentConnect("BuyButton")]publicButtonbuyButton;// 3. Private / protected / [SerializeField] all work[ComponentConnect,SerializeField]privateImageicon;[ComponentConnect]protectedTextdescription;// 4. GameObject reference (instead of a component)[ComponentConnect("Backdrop")]publicGameObjectbackdrop;}Search order
this.gameObjectand its descendantstransform.rootand all its descendants (skipped wheninChildren = true, which is the default for the parameterless overload)- Every other root GameObject in the active scene (or in the open prefab stage)
Suffix the lookup name with ~ to gather every GameObject whose name starts with the keyword:
publicclassInventory:MonoBehaviour{// Matches "Slot0", "Slot_A", "SlotEpic", ... in document order[ComponentConnect("Slot~")]publicGameObject[]slots;// Component arrays work too — each match's component is grabbed[ComponentConnect("Enemy~")]publicEnemy[]enemies;}Use ... between a parent name and a child name when several siblings share the same name (think: every list row has its own Icon child):
publicclassHeaderBar:MonoBehaviour{// Finds a child named "Icon" under a parent named "Header"[ComponentConnect("Header...Icon")]publicImageheaderIcon;// Finds "Label" under "Footer"[ComponentConnect("Footer...Label")]publicTextfooterLabel;}publicclassPlayer:MonoBehaviour{[GetComponent]publicRigidbody2Dbody;[GetComponent]publicSpriteRenderersprite;[GetComponent]publicAnimatoranimator;}If the field already has a value you assigned manually, v2 leaves it alone.
Mark the class with IComponentConnector, then put [OnClick("ButtonName")] on the handler method. The matching Button.onClick persistent listener is wired up at edit time — fully serialized, zero runtime cost.
usingUnityEngine;publicclassMainMenu:MonoBehaviour,IComponentConnector{[OnClick("StartButton")]privatevoidOnStart(){Debug.Log("Start!");}[OnClick("QuitButton")]privatevoidOnQuit(){Application.Quit();}// The same method can be bound to multiple buttons[OnClick("HelpButton")][OnClick("InfoButton")]privatevoidShowHelp(){/* ... */}}usingUnityEngine;usingUnityEngine.UI;publicclassCharacterCard:MonoBehaviour,IComponentConnector{[GetComponent]publicCanvasGroupcanvasGroup;[GetComponent]publicRectTransformrectTransform;[ComponentConnect]publicImageportrait;[ComponentConnect("Name")]publicTextnameLabel;[ComponentConnect("HP...Fill")]publicImagehpFill;[ComponentConnect("Buff~")]publicGameObject[]buffIcons;[ComponentConnect,SerializeField]privateButtonequipButton;[ComponentConnect,SerializeField]privateButtondismissButton;[OnClick("EquipButton")]privatevoidOnEquip(){/* ... */}[OnClick("DismissButton")]privatevoidOnDismiss(){/* ... */}}V2 is event-driven. Wiring runs automatically when:
- The hierarchy changes (add / move / rename a GameObject)
- A prefab is opened in Prefab Mode
- A prefab is saved
- You right-click any component header → Component Connect (manual trigger)
It does not poll. It is dormant during play mode, compilation, and asset import.
V1's full-scene scan every 100 ms is gone. V2:
- Caches reflection per
Type(one-time cost per script type) - Skips fields that already hold a live
Object - Coalesces multiple
hierarchyChangedevents in one frame viaEditorApplication.delayCall - Marks dirty only when something actually changed
- Skips
[OnClick]re-binding when the listener already points at(target, method)
You should see effectively zero overhead in normal editor use.
- Replace your old
ComponentConnector.cswith the V2 file (same name and location works perfectly), or install via UPM. - Optional cleanup: remove the
ComponentConnectorMonoBehaviour from scene roots — it's no longer needed. (V2 keeps a no-op stub class so existing scenes still load.)
No attribute signatures changed. Your existing [ComponentConnect] / [GetComponent] / [OnClick] code keeps working as-is.
Does this run in builds?
No. The processor is wrapped in #if UNITY_EDITOR and stripped from player builds. References get baked into the serialized scene/prefab — at runtime there is zero overhead.
Will it overwrite a reference I assigned manually?
No. V2 only fills fields whose current value is null (or an empty array).
What about [OnClick] — will it nuke my existing button bindings?
It only touches buttons matched by name, and only if the existing persistent listener doesn't already point to (this, method). If it's already correct, it's a no-op.
Does it work with nested prefabs / prefab variants?
Yes — PrefabStage events fire for both, and the on-save hook catches anything the live editor missed.
Why isn't my newly-added [ComponentConnect] field getting populated?
The processor reacts to hierarchy changes, not to script edits. After adding the attribute, either change the hierarchy (rename / re-parent any object), save the prefab, or right-click the component header and pick Component Connect.
Minimum Unity version?
2021.3 LTS or newer (uses the UnityEditor.SceneManagement.PrefabStage API).
- Help Me! Endz (Google Play / App Store)
- King God Castle (Google Play / App Store)
- AXIS BLADE (Google Play / App Store)
I take no responsibility for issues you may encounter using this code. But it has saved me a lot of time on the projects above.
Component Connector is released under the MIT license. See LICENSE for details.


