Quantcast
Viewing latest article 1
Browse Latest Browse All 3

Dynamic creation of GameObjects with Sprites

In a project that I’m working on, I had to create lots of GameObjects to hold some sprites as a response of an event. To help in this task I had created a helper class and two extension methods for the GameObject class.

Although functional, the solution left me with a question: Is there a problem when using the new operator and not the Instantiate method, as indicated in the documentation, to create a new GameObject? Seems to me that the Instantiate method is only a cloner of previously instantiated objects or prefabs. If anyone knows, please respond in the comments.

Let’s get to the code:

Without fear of being redundant, I had created two extension methods to help the helper class: SafeGetComponent and SetSpriteOpacity. I made them extension methods because they can be used outside the scope of the problem being solved.

SafeGetComponent is just a wrapper around GetComponent that throws an Exception if the requested component is not found on the GameObject. I don’t know if the naming is ok, but I couldn’t think of anything better.

SetSpriteOpacity is a simple way to create a new temporary Material with the same Color as the current SpriteRenderer‘s Material changing only his alpha channel.

public static class GameObjectExtensions
{
	public static T SafeGetComponent(this GameObject go)
		where T : UnityEngine.Component
	{
		T component = go.GetComponent();

		if (component == null)
			throw new System.Exception(
				string.Format(
					"The component '{0}' was not found on GameObject '{1}'.",
					typeof(T).FullName,
					go.name
				)
			);

		return component;
	}

	public static void SetSpriteOpacity(this GameObject go, float value)
	{
		var spriteRenderer = go.SafeGetComponent();
		var currColor = spriteRenderer.material.color;
		spriteRenderer.material.color = new Color(currColor.r, currColor.g, currColor.b, value);
	}
}

The helper class itself I’ve named UnityHelper and has only the CreateGameObject static method on it. This method has many optional parameters that should be used to setup the new GameObject:

public static class UnityHelpers
{
	/// <summary>
	/// Creates a new GameObject.
	/// </summary>
	public static GameObject CreateGameObject(
		string name = null,
		Vector3? position = null,
		Quaternion? rotation = null,
		Vector3? scale = null,
		GameObject parent = null,
		Sprite sprite = null,
		string spriteSortLayerName = null,
		int? spriteSortOrder = null,
		float? spriteOpacity = null
		)
	{
		var go = new GameObject(name ?? "New GameObject");

		if (position.HasValue) 
			go.transform.position = position.Value;

		if (rotation.HasValue)
			go.transform.rotation = rotation.Value;

		if (scale.HasValue)
			go.transform.localScale = scale.Value;

		if (parent != null)
			go.transform.parent = parent.transform;

		if (sprite != null) {

			var spriteRenderer = go.AddComponent<SpriteRenderer>();
			spriteRenderer.sprite = sprite;
			
			if (!string.IsNullOrEmpty(spriteSortLayerName))
				spriteRenderer.sortingLayerName = spriteSortLayerName;
			
			if (spriteSortOrder.HasValue)
				spriteRenderer.sortingOrder = spriteSortOrder.Value;

			if (spriteOpacity.HasValue)
				go.SetSpriteOpacity(spriteOpacity.Value);
		}

		return go;
	}
}

That’s it. It’s not something complex but has helped a lot in maintaining the code clean and simple. You can now use this to create GameObjects as in the below example:

public class Example : MonoBehaviour
{
	public Sprite sprite1;

	void Start()
	{
		var go1 = UnityHelpers.CreateGameObject();

		var go2 = 
			UnityHelpers.CreateGameObject(
				name: "GO 2", 
				position: Vector3.up
			);

		var go3 = 
			UnityHelpers.CreateGameObject(
				name: "GO 3",
				position: Vector3.one,
				rotation: Quaternion.AngleAxis(15f, Vector3.up),
				parent: go2,
				sprite: sprite1,
				spriteSortLayerName: "SomeLayerName",
				spriteSortOrder: 1,
				spriteOpacity: .5f
			);
	}
}

Please, let me know if you like this solution, have a refactoring suggestion or would do everything completely differently in the comments.

Cheers!


Viewing latest article 1
Browse Latest Browse All 3

Trending Articles