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
0
Question by gilgada · Jan 09, 2014 at 05:14 PM · instantiateprefabrandomproperty

How to access property of a prefab before Instantiating.

I am randomly generating instances of a group of prefabs. Currently this means there is an equal chance of generating each one. I would like to place a 'weight' on each prefab for its chance on being picked. I have setup a simple script to hold this property and placed it on each prefab. How can I access this property in my code? The prefabs count as Object datatypes and not GameObject so it isn't as easy as GetComponent. I want to do this before creating GameObjects with them.

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

1 Reply

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

Answer by HappyMoo · Jan 09, 2014 at 05:38 PM

Putting the weights on the prefabs is so global.. why don't you put it on your prefab list? Seems to make more sense that way... Then one prefab could be instantiated with different weights in different situations.

 public List<WeightedPrefab> prefabPickList;
 
 ...
 ...
 
 [System.Serializable]
 public class WeightedPrefab
 {
     public Transform prefab;
     public float weight;
 }


EDIT: Some Example code:

 using UnityEngine;
 using System.Collections;
 using System.Collections.Generic;
 
 [System.Serializable]
 public class WeightedTile {
     public Transform tile;
     public float weight;
 }
 
 public class MapGenerator : MonoBehaviour {
 
     public List<WeightedTile> floorTiles;
     public List<WeightedTile> wallTiles;
     public float tileWidth = 1f;
     public float tileLength = 1f;
 
 
     void Start () {
         createARoom();
     }
 
     void createARoom()
     {
         int width = Random.Range(4,8);
         int length = Random.Range(4,8);
 
         for(int x = 0; x<width; x++) for(int z = 0; z<length; z++)
         {
             Transform tile;
             if (x==0 || x==width-1 || z==0 || z==length-1)
             {
                 tile = pickWeightedOne(wallTiles);
             }else{
                 tile = pickWeightedOne(floorTiles);
             }
             Instantiate(tile, new Vector3(x*tileWidth, 0, z*tileLength), Quaternion.identity);
         }
     }
 
     Transform pickWeightedOne(List<WeightedTile> tiles)
     {
         float weightSum = 0f;
         foreach(WeightedTile tile in tiles)
         {
             if (tile != null && tile.tile != null)
             {
                 weightSum += tile.weight;
             } else {
                 Debug.LogWarning("Warning. Found empty tile");
             }
         }
         
         float runningWeight = 0f;
         float pick = Random.Range(0f, weightSum);
         foreach(WeightedTile tile in tiles)
         {
             if (tile != null && tile.tile != null)
             {
                 runningWeight += tile.weight;
                 if (runningWeight>=pick) return tile.tile;
             }
         }
         Debug.LogError("OMG. We shouldn't be here");
         return null; // this should never be reached!
     }
 
 }


Example Image

Comment
Add comment · Show 30 · 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 HappyMoo · Jan 09, 2014 at 05:46 PM 1
Share

Yes, you place this on your Generator...

Should you then later have another Generator, you can have a completely different list and other weights on that one.

avatar image HappyMoo · Jan 09, 2014 at 05:57 PM 1
Share

yes :D

 using System.Collections.Generic;
avatar image semiessessi · Jan 09, 2014 at 06:02 PM 1
Share

doesn't this assume that he already has a list of prefabs and isn't doing something more data driven, like loading all prefabs under a path, or a path defined in data somewhere? what is a 'Generator' in this context?

also, for the record, nothing actually wrong with global state - just everything wrong with lazy common abuse of it - is C# where I can't produce a free standing function any better? It encourages a different set of bad habits... like using singletons which are horrible at compile/run-time for things which genuinely are global state and should be treated as such. (just my 2 cents on that)

avatar image HappyMoo · Jan 09, 2014 at 06:06 PM 1
Share

Yes, you can define classes in your Generator class, but don't have to. Depending on what makes sense in your Design.

You can also move it to the front of your file and define it in the same File as your Generator or move it in its own file.

avatar image HappyMoo · Jan 09, 2014 at 06:14 PM 1
Share

The class is public. Not out of scope.

you don't need to define object, you can drag a prefab on a Transform... which would also allow you to call GetComponent, but that's still bad design.

Just replace your current list of objects with a list of WeightedPrefabs

Show more comments

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

20 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

Can't set the random position for an Instance. 1 Answer

Can't access enum property of an instantiated prefab. 1 Answer

Random.value sometimes doesn't instantiate my prefab(pic included) 1 Answer

instantiating vertically 2 Answers

How can I align instantiated prefabs randomly on runtime #C 0 Answers


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