More code rambling
- sexy screenshots coming soon

markers & attachment points


by Nicholas Francis
Apr 30, 2013

In Unity it’s quite common to need to mark specific transform children as attachment points. You have a character, and want to attach a gun to his hand. How do you find the hand? GameObject.Find is too brittle (some artist changes the name of a gameObject in the file, and everything breaks).

What we do is that we add a component to a game object to serve as an extended tag.

public class Marker<T> : MonoBehaviour where T : MonoBehaviour {
	public static Transform Get (Transform rootToSearchFrom)
	{
		T marker = rootToSearchFrom.GetComponentInChildren<T> ();
		if (!marker)
		{
			Debug.LogError ("Unable to find " + typeof (T) + " in " + rootToSearchFrom.name, rootToSearchFrom);
			return rootToSearchFrom;
		}
		return marker.transform;		
	}
}

This does a search inside the local hierarchy, has some error checking and defaults to the root you’re searching from (so you don’t get nullrefs in other parts of the code)

(To see more about the templating trick I use, see my previous post)

To make your weapon hand, you’d do:

public class MkrWeaponHand : Marker<MkrWeaponHand> {}

Inside our main character, we can now do MkrWeaponHand.Get (transform) to find the right transform to attach a gun at.
Imagine you have a gun; it has a some graphics (so there’s a graphics model involved). However, you want flames and bullets to be spawned from a specific point inside the model.

public class MkrTurretOpening : Marker<MkrTurretOpening> {}

So we do MkrTurretOpening.Get (transform) to get the transform.

Notes:

  • We could just have an object pointer inside the controller object, but that doesn’t work when we’re assembling objects from code. I also prefer this semi-automatic configuration.
  • We can’t use tags as Unity has no way to locate a specific tag inside a specific sub-hierarchy (we’re basically missing GameObject.FindChildWithTag)
  • Instead of all this multiple-class dance, we could make Marker simply contain an enum, but then we need to call GetComponentsInChildren, which allocates an array, leading to GC problems later on.
  • The markers can easily be added automatically by a ModelPostProcessor based on object name – so an artist can name a GO Hand mkr:WeaponHand to get the weaponhand marker added at import.

    That’s it for now. And I have some graphics tricks, I’m dying to show you. That just takes a long time to write, so in the meantime you get this 😉

  • Add Your Comment