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 에서 볼 수 있습니다.
public class HUD : MonoBehaviour {
[ComponentConnect] public Text scoreText; // ← finds GameObject "scoreText"
[ComponentConnect] public Slider hpBar; // ← finds GameObject "hpBar"
[GetComponent] public Canvas canvas; // ← 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.
using UnityEngine;
using UnityEngine.UI;
public class ShopPanel : MonoBehaviour {
// 1. Match by field name → looks for a GameObject called "title"
[ComponentConnect] public Text title;
// 2. Match by an explicit name → looks for "BuyButton"
[ComponentConnect("BuyButton")] public Button buyButton;
// 3. Private / protected / [SerializeField] all work
[ComponentConnect, SerializeField] private Image icon;
[ComponentConnect] protected Text description;
// 4. GameObject reference (instead of a component)
[ComponentConnect("Backdrop")] public GameObject backdrop;
}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:
public class Inventory : MonoBehaviour {
// Matches "Slot0", "Slot_A", "SlotEpic", ... in document order
[ComponentConnect("Slot~")] public GameObject[] slots;
// Component arrays work too — each match's component is grabbed
[ComponentConnect("Enemy~")] public Enemy[] 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):
public class HeaderBar : MonoBehaviour {
// Finds a child named "Icon" under a parent named "Header"
[ComponentConnect("Header...Icon")] public Image headerIcon;
// Finds "Label" under "Footer"
[ComponentConnect("Footer...Label")] public Text footerLabel;
}public class Player : MonoBehaviour {
[GetComponent] public Rigidbody2D body;
[GetComponent] public SpriteRenderer sprite;
[GetComponent] public Animator animator;
}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.
using UnityEngine;
public class MainMenu : MonoBehaviour, IComponentConnector {
[OnClick("StartButton")]
private void OnStart() {
Debug.Log("Start!");
}
[OnClick("QuitButton")]
private void OnQuit() {
Application.Quit();
}
// The same method can be bound to multiple buttons
[OnClick("HelpButton")]
[OnClick("InfoButton")]
private void ShowHelp() { /* ... */ }
}using UnityEngine;
using UnityEngine.UI;
public class CharacterCard : MonoBehaviour, IComponentConnector {
[GetComponent] public CanvasGroup canvasGroup;
[GetComponent] public RectTransform rectTransform;
[ComponentConnect] public Image portrait;
[ComponentConnect("Name")] public Text nameLabel;
[ComponentConnect("HP...Fill")] public Image hpFill;
[ComponentConnect("Buff~")] public GameObject[] buffIcons;
[ComponentConnect, SerializeField] private Button equipButton;
[ComponentConnect, SerializeField] private Button dismissButton;
[OnClick("EquipButton")]
private void OnEquip() { /* ... */ }
[OnClick("DismissButton")]
private void OnDismiss() { /* ... */ }
}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.


