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 Overcast · May 18, 2013 at 04:53 PM · prefabsmaterials

Approach for showing a building template before placement

Hi Everyone,

I can't seem to find any discussion of what I am trying to do here, so perhaps someone here can help me.

I need to display building templates (think a 50% opacity 1 material version of the building) under the mouse before it is placed.

I'm not sure the best way to approach this, the options I've considered seem messy and I am wondering if I might be missing something obvious.

I've considered just instantiating the prefabs of the actual building and holding them in a certain state. This would require me to push out the materials to a temporary array, replace them all with one material, then swap them back if the building was placed, it seems a bit cumbersome.

The other solution which seemed obvious was to have an object which just rendered the relevant mesh, with one material instead of the correct ones, but many of the prefabs contain multiple meshes, so it would also be a lot of config.

Perhaps there isn't an easier way, but I would be glad for any opinions/help.

Thanks for your time

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

3 Replies

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

Answer by Bunny83 · May 18, 2013 at 06:18 PM

I would use something like this:

 // C#
 public Transform prefab;
 public Material PreviewMaterial;
 
 public Transform CreatePreview (Transform aPrefab)
 {
     Transform obj = (Transform)Instantiate(prefab);
     foreach (var renderer in obj.GetComponentsInChildren<Renderer>(true))
         renderer.sharedMaterial = PreviewMaterial;
     // If the building / object has some scripts or other components
     // which shouldn't be on the preview, remove them here:
     foreach (var script in obj.GetComponentsInChildren<MonoBehaviour>(true))
         Destroy(script);
     return obj;
 }

That way you can easily create a preview version of any prefab and have always the same "preview look". When it comes to creating the actual building, just Instantiate the prefab normally.

You can also add a script to the preview which can hold the prefab reference from which it has been created, so it's easier to Instantiate the actual building / object

 public class PreviewObject : MonoBehaviour
 {
     public Transform prefah;
     public Transform Place()
     {
         Transform obj = (Transform)Instantiate(prefab, transform.position, transform.rotation);
         Destroy(gameObject);
         return obj;
     }
 }

In this case your CreatePreview function should look like this:

 public PreviewObject CreatePreview (Transform aPrefab)
 {
     Transform obj = (Transform)Instantiate(prefab);
     foreach (var renderer in obj.GetComponentsInChildren<Renderer>(true))
         renderer.sharedMaterial = PreviewMaterial;
     foreach (var script in obj.GetComponentsInChildren<MonoBehaviour>(true))
         Destroy(script);
     PreviewObject po = obj.AddComponent<PreviewObject>();
     po.prefab = aPrefab;
     return po;
 }

The returned PreviewObject can be used to move / place the preview and when done, just call Place() and the preview will be replaced be a real object

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 Overcast · May 18, 2013 at 07:29 PM 0
Share

Thanks, this looks like a pretty complete solution. I'll go away and see if I have any issues, then come back and mark this answered.

Particularly I like the fact it contains the entire process coherently in one place.

avatar image
0

Answer by sotirosn · May 18, 2013 at 05:09 PM

I have a game where I do this very thing. When I place the object I instantiate the template and broadcast "OnPlacement" on the clone which causes all the renderes to change material and sets the building up with the environment. Maybe if you don't want to change materials you could have 2 prefabs, the template and the actual, and clone the actual even though you show the template.

Comment
Add comment · 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
0

Answer by hiddenspring81 · May 18, 2013 at 05:59 PM

I implemented a similar system for my game. While the player was placing their units on a map, each unit would appear transparent, and upon placing them, they'd become opaque. I did this by creating a new component, which was attached to each prefab instance of my unit type,

 public class TransparencyController : MonoBehaviour
 {
   const float TRANSPARENT_AMOUNT = 0.5f;
 
   public void ToggleTransparency (bool transparent)
   {
     float desiredTransparency = transparent ? TRANSPARENT_AMOUNT : 1.0f;
     // Find all the renderers on the object, including the children
     var renderers = GetComponentsInChildren<Renderer>(true);
     foreach (var renderer in renderers)
     {
       var color = renderer.material.color;
       renderer.material.color = new Color(color.r, color.g, color.b, desiredTransparency.a);
     }
   }
 }

Before placing my units, I'd call ToggleTransparency(true) on each unit, making them appear transparent. Then upon placing them on the map, I'd call ToggleTransparency(false), which would render them opaque. This a very clean, very simple way of achieving the effect that you described.

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 Overcast · May 18, 2013 at 07:28 PM 0
Share

Thanks for this, I'm still getting used to Unity's workflow and this makes sense now that I read it.

This one doesn't address stopping scripts running however, so I'm inclined to go with Bunny83's in terms of most complete.

Thanks for you help though - I've learnt something form this :)

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

16 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

Related Questions

best practices for importing and updating models 0 Answers

How to change a prefab's color before instantiating (with code) 1 Answer

When creating a 2D array as a grid of cubes they are all the same colour,My array of gameObjects are all the same colour, even when I set them differently 2 Answers

New prefab system problem 1 Answer

Models in prefab are broken after updating .fbx file 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