Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 13 Next capture
2021 2022 2023
1 capture
13 Jun 22 - 13 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
1
Question by Joshua · Apr 24, 2011 at 03:34 PM · texturearraymaterialfor-loop

for() loop skipping the first entry. Scripting error?

Hey guys - thanks for looking at my question.

I'm making a small cardgame. I have a script set up that 'deals' the card at the beginning. It's supposed to 1. place the cards in the start position (for solitaire) and 2. assign a random cardTexture to it.

This works perfectly, but the loop seems to skip the very first card, which gets dealt without any material applied.

I'll walk you through my code:

  • depending on number of the card, get instantiated at a certain place
  • pick a random element of the cardtypes array (Two of Spades, for instance. It has the same order as the textures array)
  • create a material, apply the texture that corresponds to the cardtype
  • apply the material to the card and apply the cardtype as the name
  • delete the material and cardtype from the arrays so they wont be re-used

All these steps work for all cards, except the very first card (i=0) skips the applying the material step for some reason.. If I check the arrays at the end they are empty though..

function Start () {

 for(i=0;i<52;i++){

     if(i<23) Instantiate(card,Vector3(0,i*0.01,3),Quaternion.identity);
     else if(i<30) Instantiate(card,Vector3((12-2*(i-23)),0.00,-0.0),Quaternion.identity);
     else if(i<36) Instantiate(card,Vector3((12-2*(i-30)),0.01,-0.3),Quaternion.identity);
     else if(i<41) Instantiate(card,Vector3((12-2*(i-36)),0.02,-0.6),Quaternion.identity);
     else if(i<45) Instantiate(card,Vector3((12-2*(i-41)),0.03,-0.9),Quaternion.identity);
     else if(i<48) Instantiate(card,Vector3((12-2*(i-45)),0.04,-1.2),Quaternion.identity);
     else if(i<50) Instantiate(card,Vector3((12-2*(i-48)),0.05,-1.5),Quaternion.identity);
     else if(i<51) Instantiate(card,Vector3((12-2*(i-50)),0.06,-1.8),Quaternion.identity);

     //pick a rendom element from the cardtypes array
     var randomPick = Random.Range(0,51-i);

     //create a material and apply a texture from the cardTextures array - which has the same order as cardtypes. Also rename the card.
     var cardMaterial : Material = new Material(Shader.Find("Diffuse Detail"));
     cardMaterial.mainTexture = cardTextures[randomPick];        
     card.renderer.material = cardMaterial;
     card.name = ""+cardTypes[randomPick];

     //remove the element from the arrays
     cardTypes.RemoveAt(randomPick); 
     cardTextures.RemoveAt(randomPick);  


     yield new WaitForFixedUpdate ();
 }

 Debug.Log(""+cardTextures); //this is EMPTY so all textures are selected and deleted, why not applied? :S

}

Many thanks in advance!

Comment
Add comment
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

4 Replies

· Add your reply
  • Sort: 
avatar image
2
Best Answer

Answer by Seregon · Apr 24, 2011 at 10:49 PM

I think the problem here is actually the order in which you create the card and apply the texture. You first instantiate a card from a prefab 'card' presumably declared elsewhere in the script:

if(i<23) Instantiate(card,Vector3(0,i*0.01,3),Quaternion.identity);

and then later change the material attached to the prefab:

card.renderer.material = cardMaterial;

whereas you really want to change the material attached to the card you just instantiated. What you are in effect doing is changing the prefab, so that the next time through the loop, this altered prefab is spawned. This explains why the first card doesn't get textured, but the rest do.

The easiest way to fix this is to swap the order in which you instantiate the card, and attach a texture, so that you attach the texture first. However, changing your prefab each iteration isn't an ideal method, and you would be better off saving a reference to the last spawned card and changing that material attached.

I've put the fixed code below. The changes are the definition of the SpawnCard var, and assigning the result of the instantiate calls to that var, this is the card which has just been created. Where you assigned the texture and name of the card, I've changed 'card' to 'SpawnedCard'. Hope this helps:

function Start () {

 for(i=0;i&lt;52;i++){

     var SpawnedCard;
     if(i&lt;23) SpawnedCard = Instantiate(card,Vector3(0,i*0.01,3),Quaternion.identity);
     else if(i&lt;30) SpawnedCard = Instantiate(card,Vector3((12-2*(i-23)),0.00,-0.0),Quaternion.identity);
     else if(i&lt;36) SpawnedCard = Instantiate(card,Vector3((12-2*(i-30)),0.01,-0.3),Quaternion.identity);
     else if(i&lt;41) SpawnedCard = Instantiate(card,Vector3((12-2*(i-36)),0.02,-0.6),Quaternion.identity);
     else if(i&lt;45) SpawnedCard = Instantiate(card,Vector3((12-2*(i-41)),0.03,-0.9),Quaternion.identity);
     else if(i&lt;48) SpawnedCard = Instantiate(card,Vector3((12-2*(i-45)),0.04,-1.2),Quaternion.identity);
     else if(i&lt;50) SpawnedCard = Instantiate(card,Vector3((12-2*(i-48)),0.05,-1.5),Quaternion.identity);
     else if(i&lt;51) SpawnedCard = Instantiate(card,Vector3((12-2*(i-50)),0.06,-1.8),Quaternion.identity);

     //pick a rendom element from the cardtypes array
     var randomPick = Random.Range(0,51-i);

     //create a material and apply a texture from the cardTextures array - which has the same order as cardtypes. Also rename the card.
     var cardMaterial : Material = new Material(Shader.Find("Diffuse Detail"));
     cardMaterial.mainTexture = cardTextures[randomPick];        
     SpawnedCard.renderer.material = cardMaterial;
     SpawnedCard.name = ""+cardTypes[randomPick];

     //remove the element from the arrays
     cardTypes.RemoveAt(randomPick); 
     cardTextures.RemoveAt(randomPick);  


     yield new WaitForFixedUpdate ();
 }

 Debug.Log(""+cardTextures); //this is EMPTY so all textures are selected and deleted, why not applied? :S

}

Comment
Add comment · Show 2 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image Joshua · Apr 24, 2011 at 10:55 PM 0
Share

Thank you SO $$anonymous$$UCH. You are absolutely one hundred percent right! Whow, I wish I could somehow repay you for this - I've been going insane over this all bloody day. Thank you!

avatar image Seregon · Apr 24, 2011 at 11:06 PM 0
Share

No worries, glad I could help.

avatar image
2

Answer by Peter G · Apr 24, 2011 at 09:13 PM

for(i=0;i<52;i++){

 if(i&lt;23) Instantiate(card,Vector3(0,i*0.01,3),Quaternion.identity);
 else if(i&lt;30) Instantiate(card,Vector3((12-2*(i-23)),0.00,-0.0),Quaternion.identity);
 else if(i&lt;36) Instantiate(card,Vector3((12-2*(i-30)),0.01,-0.3),Quaternion.identity);
 else if(i&lt;41) Instantiate(card,Vector3((12-2*(i-36)),0.02,-0.6),Quaternion.identity);
 else if(i&lt;45) Instantiate(card,Vector3((12-2*(i-41)),0.03,-0.9),Quaternion.identity);
 else if(i&lt;48) Instantiate(card,Vector3((12-2*(i-45)),0.04,-1.2),Quaternion.identity);
 else if(i&lt;50) Instantiate(card,Vector3((12-2*(i-48)),0.05,-1.5),Quaternion.identity);
 else if(i&lt;51) Instantiate(card,Vector3((12-2*(i-50)),0.06,-1.8),Quaternion.identity);

I don't know if this is your problem (it affects that last card) but your final iteration doesn't fit any of these specifications. i = 51 will be the last iteration and as you can see that doesn't meet any requirements.

And this line:

var randomPick = Random.Range(0,51-i);

if i = 51, then this will always equal 0. I'm not sure if that's what you wanted, but if another iteration happened to choose 0, then there will be no texture to go along with this.

Comment
Add comment · Show 2 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image Joshua · Apr 24, 2011 at 09:51 PM 0
Share

You're absolutely right about this, I also caught this but changing it doesn't actually fix it though o.O and when I don't fix the Random.Range the last iteration will pick the final name, so I can then catch it and fix it. So there must be even an other mistake somewhere o.O I'm just going to start over fresh and rethink every step of the way xD thanks though!

avatar image Joshua · Apr 24, 2011 at 09:55 PM 0
Share

You are absolutely genius for spotting these two errors though - I have been spending the entire day going crazy over this stupid script and I didn't spot it until an hour ago.

avatar image
1

Answer by Uzquiano · Apr 24, 2011 at 03:48 PM

Hi,

I would suggest you to do this line out of the for()

var cardMaterial : Material = new Material(Shader.Find("Diffuse Detail"));

I mean, before the for()

Comment
Add comment · Show 19 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image Joshua · Apr 24, 2011 at 04:04 PM 1
Share

That would create one material and assign 52 different textures to it throughout the loop - ending on the last one. All cards would be assigned this one material. The goal is 52 cards with 52 different textures (therefore, diff mat.). I do think you're right the issue is at/around that line - thanks for trying to help :)

avatar image Uzquiano · Apr 24, 2011 at 04:11 PM 0
Share

So, what you are trying is to show more than one card at the same time... well, sorry I though that only one card was shown at a time...

I will take a look to your code again.

Let me know if you solve it, and how :)

avatar image Uzquiano · Apr 24, 2011 at 04:13 PM 0
Share

I would say that the problem is in this line:

var randomPick = Random.Range(0,51-i);

Are you using the float version or the int version?

avatar image Uzquiano · Apr 24, 2011 at 04:14 PM 0
Share

could you define explicetly randomPick as an interger?

avatar image Uzquiano · Apr 24, 2011 at 11:10 PM 1
Share

Hei, yes I was following your issue al evening long... so I feel kind of stupid too ;) but Peter G and Statement are really good. I so much to learn still :)

Anyway, now it is over :)

Show more comments
avatar image
1

Answer by jahroy · Apr 24, 2011 at 08:28 PM

I don't see it in the code you have posted, but make sure you don't ever check anything like this:

if ( i ) {
  doSomething();
}

If i is equal to zero this will evaluate as false. I had a similar situation where one iteration of my loop was getting skipped because i represented an offset into an array that I looked up. I thought was making sure that the lookup function returned a valid result, but 0 was a valid result that was getting skipped.

Comment
Add comment · Show 1 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image Joshua · Apr 24, 2011 at 08:49 PM 0
Share

Heh thanks, I won't. But as you said, that can't be what's causing this :p

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

No one has followed this question yet.

Related Questions

How do i get texture from GUI box? 1 Answer

Texture2D to Texture3D 2 Answers

Attaching scripts to meshes with multiple materials 2 Answers

Quality loss on texture 1 Answer

How do I get a material to tile dynamically? 1 Answer


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges