- Home /
Can I create a sprite at runtime?
I was wondering if it was possible to create a new sprite at runtime. I'm basicly trying to slice a Sprite in 2 pieces (similar to Metal Gear Rising but in 2D)
In this example, i'm creating a copy of the current object and i'm trying to create a new sprite for it's SpriteRenderer. I'm able to create the new sprite and the new texture but when I assign them to the SpriteRenderer, it does not display anything. The result is an invisible object (since the SpriteRenderer is not diplaying). The strange part is that when I select the sprite in the SpriteRenderer component of the new object, the preview is showing the part of the texture I wanted...
It is possible that I am not using these components the intended way, so feel free to make suggestions. Thanks.
Texture2D tex = new Texture2D(100,100);
tex.SetPixels(0,0,100,100,this.GetComponent<SpriteRenderer>().sprite.texture.GetPixels(0,0,100,100));
tex.Apply();
GameObject newObj = Instantiate(gameObject) as GameObject;
SpriteRenderer renderer = newObj.GetComponent<SpriteRenderer>();
Sprite sprite = new Sprite();
sprite = Sprite.Create(tex,new Rect(0, 0, 100, 100),new Vector2(50,50));
renderer.sprite = sprite;
Did you figure out what the problem was/is? It sound like some of the same troubles I'm having (http://forum.unity3d.com/threads/219939-Prefab-created-at-runtime-is-missing-sprite-reference-(original-object-is-not)) So if you have found out anything, I would very much like to know. Thanks. - Henning
Sprite sprite = new Sprite();
found at line 8 should be removed. You are instantiating a sprite, then replacing it with Sprite.Create
two lines later, and you don't want to instantiate Sprites with "new" anyway, since it doesn't properly initialize the object. You should, in s$$anonymous$$d, use "Sprite.Create" (as you did).
Answer by Peaj · Jan 05, 2014 at 11:39 AM
I'm trying to achieve the same sprite splicing effect and I think i resolved your problem. You used "new Vector2(50,50)" for the pivot but the pivot is in 0,1 range. Just replace it with new "Vector2(0.5f,0.5f)". Your sprite should even be displayed atm but its far away from where you expect it to be. Although this fixed it for me I had problems with the scaling. It works using 40 for the texels per unit which is really strange. So here is my code:
Texture2D old = renderer.sprite.texture;
Texture2D left = new Texture2D((int)(old.width), old.height, old.format, false);
Color[] colors = old.GetPixels(0, 0, (int)(old.width), old.height);
left.SetPixels(colors);
left.Apply();
Sprite sprite = Sprite.Create(left,
new Rect(0, 0, left.width, left.height),
new Vector2(0.5f,0.5f),
40);
Debug.Log("Old Bounds: " + renderer.sprite.bounds + " Rect: " + renderer.sprite.rect + " TexRect: " + renderer.sprite.textureRect);
Debug.Log("Bounds: " + sprite.bounds+" Rect: "+sprite.rect+" TexRect: "+sprite.textureRect);
renderer.sprite = sprite;
If this will help you it would be nice to share your result with me.
Peaj, thanks a lot, this solved a similar problem I had!
Indeed, the sprite was there but far away from where it should have been. Also, when trying to scale it via the Editor, the sprite did not scale properly as the bounds were off.
Answer by Drachenfels · Nov 02, 2014 at 09:14 PM
Hi guys,
I tried to achieve the same using UnityScript, after googling for this and some other similar question, that is what works for me:
for (var key in data) {
ui_texture = Resources.Load(images[key], Texture2D);
ui_sprite = Sprite.Create(ui_texture, Rect(0f, 0f, 48f, 48f), new Vector2(0f, 0f), 128f);
new_sprite = GameObject();
new_sprite.name = key;
new_sprite.AddComponent(SpriteRenderer);
ui_renderer = new_sprite.GetComponent(SpriteRenderer);
ui_renderer.sprite = ui_sprite;
}
Hopefully it will happen to be useful for someone else as well. :)
thanks! This worked for me
// create sprite
Texture2D tex = Resources.Load<Texture2D>("texture2") as Texture2D;
Sprite sprite = new Sprite();
sprite = Sprite.Create(tex, new Rect(64, 0, 64, 64), new Vector2(0.5f, 0.5f));
// create gameobject
newSprite = new GameObject();
newSprite.AddComponent<SpriteRenderer>();
SpriteRenderer SR = newSprite.GetComponent<SpriteRenderer>();
SR.sprite = sprite;
Answer by Thonbo · Nov 16, 2014 at 07:19 PM
C#
public Sprite AddSprite (Texture2D tex) {
Texture2D _texture = tex;
Sprite newSprite = Sprite.Create(_texture, new Rect(0f, 0f, _texture.width, _texture.height), new Vector2(0.5f, 0.5f),128f);
GameObject sprGameObj = new GameObject();
sprGameObj.name = "something";
sprGameObj.AddComponent<SpriteRenderer>();
SpriteRenderer sprRenderer = sprGameObj.GetComponent<SpriteRenderer>();
sprRenderer.sprite = newSprite;
return sprGameObj;
}
For me it doesn't work. C# complains that it can not convert a gameobject to a sprite in the last line. Can you help?
It is because this code has a return type Sprite but returns a GameObject. You could just change "public Sprite" to "public GameObject" and it will work