- Home /
Change a prefab sprite using Random.range instantiate in a script
Hello! Here is what I want to be able to do:
I want an attack to have different types of sprites, but using the same prefab for the projectile. I realize I could just copy the projectile prefab and call each different one if my random hits a specific number, but I'm wondering if I could do it in a bit neater way. So I don't have to declare 8 (my amount of sprites) different prefabs both in my script and my prefab folder.
Right now, I have a sprite that is spliced up. And I just want to apply a different splice to the projectile prefab if my Random.Range hits a specific number that is assigned to a splice. So I guess there has to be something about changing the sprite renderer on instantiate, but I have no idea how to go about that.
This is my current projectile instantatiation in my script:
public GameObject bulletPrefab;
public void FireBullet() {
float rightHorizontal = Input.GetAxis("RightStickHorizontalP1");
float rightVertical = Input.GetAxis("RightStickVerticalP1");
Vector2 shootDir = new Vector2(-rightHorizontal,-rightVertical);
GameObject Clone;
Clone = (Instantiate(bulletPrefab, transform.position,transform.rotation)) as GameObject;
Clone.rigidbody2D.AddRelativeForce(new Vector2(-bulletSpeed,0));
}
Any help or pointers in the right direction is highly appreciated.
Answer by Stealthygolem · Nov 16, 2014 at 04:05 PM
Rather than deleting, I will add my own answer, so other people can get help if needed in the future:
First off, in the script i instantiate my projectile, I made this array variable:
public Sprite[] projectileAttackSprite;
In the inspector, you now have a drop-down list, where you can add your specific sprites, or even slices from a sprite! First you choose your array size, and then you can drag-and-drop them in.
After I added all my 8 sliced up sprites, I return to my script. Now, I added a randomizer and a specific assignment for each. This is what my method now looks like:
public void FireBullet() {
float rightHorizontal = Input.GetAxis("RightStickHorizontalP1");
float rightVertical = Input.GetAxis("RightStickVerticalP1");
Vector2 shootDir = new Vector2(-rightHorizontal,-rightVertical);
int projectileAttackRandomizer = Random.Range (1,9);
GameObject Clone;
Clone = (Instantiate(bulletPrefab, transform.position,transform.rotation)) as GameObject;
Clone.rigidbody2D.AddRelativeForce(new Vector2(-bulletSpeed,0));
if(projectileAttackRandomizer == 1) {
Clone.GetComponent<SpriteRenderer>().sprite = projectileAttackSprite[0];
}
if(projectileAttackRandomizer == 2) {
Clone.GetComponent<SpriteRenderer>().sprite = projectileAttackSprite[1];
}
if(projectileAttackRandomizer == 3) {
Clone.GetComponent<SpriteRenderer>().sprite = projectileAttackSprite[2];
}
if(projectileAttackRandomizer == 4) {
Clone.GetComponent<SpriteRenderer>().sprite = projectileAttackSprite[3];
}
if(projectileAttackRandomizer == 5) {
Clone.GetComponent<SpriteRenderer>().sprite = projectileAttackSprite[4];
}
if(projectileAttackRandomizer == 6) {
Clone.GetComponent<SpriteRenderer>().sprite = projectileAttackSprite[5];
}
if(projectileAttackRandomizer == 7) {
Clone.GetComponent<SpriteRenderer>().sprite = projectileAttackSprite[6];
}
if(projectileAttackRandomizer == 8) {
Clone.GetComponent<SpriteRenderer>().sprite = projectileAttackSprite[7];
}
}
This was a lot neater than what I had in mind previously. Hope this can help someone in the future, cheers.
Thank you!
Note that you can get rid of your long set of conditions, with something like the following:
int i = Random.Range(0, projectileAttackSprite.Length);
Clone.GetComponent<SpriteRenderer>().sprite = projectileAttackSprite[i];
where i
is just what you'd previously called projectileAttackRandomizer
.
This will work regardless of how many sprites you put in your array (provided you put in at least one).
Also, in the Unity GUI there's no need to first set your array size. You can drag and drop a multiple selection of sprites onto the array and it'll auto-populate itself and set its size accordingly. You may have to lock the inspector open on the relevant panel in order to make the multiple-selection from the assets without the inspector's focus changing.
Hmm. Thanks for the extra info! I'll try it out next time I bump into the code, or what would be a similar one, haha!
Answer by thesagarlee · Nov 14, 2016 at 09:31 PM
Hey,
I did something similar, thought to share the solution-->
I have one EnemyCarSpawner Class which is instantiating enemyCar Object. I have around 5 different sprites for enemy cars.
In Start() function of enemyCarSpawner, i wrote this-->
Sprite[] EnemyCarSprites;
public void start()
{
EnemyCarSprites = Resources.LoadAll<Sprite>("LOCATION OF ENEMY CAR SPRITES IN RESOURCES FOLDER");
new Assets.Resources.Scripts.EnemyCarArrayHolder(EnemyCarSprites);
}
I also created a HELPER CLASS to hold the sprites array-->
namespace Assets.Resources.Scripts
{
class EnemyCarArrayHolder
{
static Sprite[] _EnemyCarSprites;
static int _EnemyCarSpritesCount=1;
public EnemyCarArrayHolder(Sprite[] EnemyCarSprites)
{
_EnemyCarSprites = EnemyCarSprites;
_EnemyCarSpritesCount = _EnemyCarSprites.Length;
Debug.Log("All Enemy Car Sprites loaded");
}
public static Sprite[] GetEnemyCarSprites()
{
return _EnemyCarSprites;
}
public static int GetEnemyCarSpritesCount()
{
return _EnemyCarSpritesCount;
}
public static Sprite GetRandomSprite()
{
return _EnemyCarSprites[Random.Range(0, _EnemyCarSpritesCount - 1)];
}
}
}
Finally, in my enemyCarObjectScript, i can change the sprites of the same object and get it by below method-->
void Awake() { %|168955743_39|% %|-1327520366_40|% // Debug.Log("Sprite added"); }
Answer by ewanhutchison1997 · Apr 18, 2018 at 11:57 AM
This is the array setup I have, different from what you're trying to achieve but it might be helpful to someone looking at this post. it spawns different looking asteroids in my side scrolling space shooter project for collage.
using System.Collections; using System.Collections.Generic; using UnityEngine;
public class AsteroidSpawn : MonoBehaviour { GameObject Asteroids; public Vector3 SpawnValues; public int AsteroidCount; public float SpawnWait; public GameObject[] Rocks; void Start() { StartCoroutine (SpawnWave()); }
IEnumerator SpawnWave()
{
for (int i = 0;i < AsteroidCount; i++)
{
int R = Random.Range(0, Rocks.Length);
Asteroids = Rocks[R];
Vector3 SpawnPosition = new Vector3(10, Random.Range(-SpawnValues.y, SpawnValues.y), -2);
Quaternion SpawnRotation = Quaternion.identity;
Instantiate(Asteroids, SpawnPosition, SpawnRotation);
yield return new WaitForSeconds(SpawnWait);
}
}
}