Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 12 Next capture
2021 2022 2023
1 capture
12 Jun 22 - 12 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 NathanJSmith · Aug 04, 2018 at 09:44 AM · assettutoriallodbillboard

Unity LOD billboard asset example?

I see that the SpeedTree in Standard Asset has billboard LOD, but I can't extract the SpeedTree asset in Standard Asset as FBX to learn.

I just can see 2 things of this billboard asset:

  1. The texture of the billboard contains the angles of the tree: UnityBillboardTexture.PNG

  2. The model of the billboard is a simple plane: UnityBillboardModel.PNG

Also according to the BillboardAsset manual, the billboard is like this: BillboardAsset manual

I create this question to ask for a billboard asset example (as FBX file). Does anyone know a (free) billboard asset example that I can study?

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
1
Best Answer

Answer by NathanJSmith · Nov 29, 2018 at 08:10 AM

I got it, billboard asset can be created with C# script. I can open the billboard asset with Notepad, here is the content of a Billboard Asset file:

Billboard.asset

 %YAML 1.1
 %TAG !u! tag:unity3d.com,2011:
 --- !u!226 &22600000
 BillboardAsset:
   m_ObjectHideFlags: 0
   m_CorrespondingSourceObject: {fileID: 0}
   m_PrefabInternal: {fileID: 0}
   m_Name: Billboard_Original
   serializedVersion: 2
   width: 10.350581
   bottom: -0.2622106
   height: 7.172371
   imageTexCoords:
   - {x: 0.230981, y: 0.33333302, z: 0.230981, w: -0.33333302}
   - {x: 0.230981, y: 0.66666603, z: 0.230981, w: -0.33333302}
   - {x: 0.33333302, y: 0, z: 0.33333302, w: 0.23098099}
   - {x: 0.564314, y: 0.23098099, z: 0.23098099, w: -0.33333302}
   - {x: 0.564314, y: 0.564314, z: 0.23098099, w: -0.33333403}
   - {x: 0.66666603, y: 0, z: 0.33333302, w: 0.23098099}
   - {x: 0.89764804, y: 0.23098099, z: 0.230982, w: -0.33333302}
   - {x: 0.89764804, y: 0.564314, z: 0.230982, w: -0.33333403}
   vertices:
   - {x: 0.47093, y: 0.020348798}
   - {x: 0.037790697, y: 0.498547}
   - {x: 0.037790697, y: 0.976744}
   - {x: 0.52906996, y: 0.020348798}
   - {x: 0.95930207, y: 0.498547}
   - {x: 0.95930207, y: 0.976744}
   indices: 040003000000010004000000050004000100020005000100
   material: {fileID: 2100000, guid: 6e680dda9368db5418f19388474277a2, type: 2}
 

Here is the C# code that I use to generate the file above

 using System.Collections;
 using System.Collections.Generic;
 using UnityEditor;
 using UnityEngine;
 
     public class BillboardBaker : MonoBehaviour
     {
 #if UNITY_EDITOR
         public BillboardAsset m_outputFile;
         public Material m_material;
 
         [ContextMenu("Bake Billboard")]
         void BakeBillboard()
         {
             BillboardAsset billboard = new BillboardAsset();
 
             billboard.material = m_material;
             Vector4[] texCoords = new Vector4[8];
             ushort[] indices = new ushort[12];
             Vector2[] vertices = new Vector2[6];
             texCoords[0].Set(0.230981f, 0.33333302f, 0.230981f, -0.33333302f);
             texCoords[1].Set(0.230981f, 0.66666603f, 0.230981f,-0.33333302f);
             texCoords[2].Set(0.33333302f, 0.0f, 0.33333302f,0.23098099f);
             texCoords[3].Set(0.564314f, 0.23098099f, 0.23098099f,-0.33333302f);
             texCoords[4].Set(0.564314f, 0.564314f, 0.23098099f,-0.33333403f);
             texCoords[5].Set(0.66666603f, 0.0f, 0.33333302f,0.23098099f);
             texCoords[6].Set(0.89764804f, 0.23098099f, 0.230982f,-0.33333302f);
             texCoords[7].Set(0.89764804f, 0.564314f, 0.230982f,-0.33333403f);
 
             indices[0] = 4;
             indices[1] = 3;
             indices[2] = 0;
             indices[3] = 1;
             indices[4] = 4;
             indices[5] = 0;
             indices[6] = 5;
             indices[7] = 4;
             indices[8] = 1;
             indices[9] = 2;
             indices[10] = 5;
             indices[11] = 1;
 
             vertices[0].Set(0.47093f, 0.020348798f);
             vertices[1].Set(0.037790697f, 0.498547f);
             vertices[2].Set(0.037790697f, 0.976744f);
             vertices[3].Set(0.52906996f, 0.020348798f);
             vertices[4].Set(0.95930207f, 0.498547f);
             vertices[5].Set(0.95930207f, 0.976744f);
 
             billboard.SetImageTexCoords(texCoords);
             billboard.SetIndices(indices);
             billboard.SetVertices(vertices);
 
             billboard.width = 10.35058f;
             billboard.height = 7.172371f;
             billboard.bottom = -0.2622106f;
 
             if (m_outputFile != null)
             {
                 EditorUtility.CopySerialized(billboard, m_outputFile);
             }
             else
             {
                 string path;
                 path = AssetDatabase.GetAssetPath(m_material) + ".asset";
                 AssetDatabase.CreateAsset(billboard, path);
             }
         }
 #endif
     }
 

Note that the metrics I hard-code is the metrics of Palm tree Billboard from SpeedTree sample (that included in standard asset of Unity)

Billboard Asset


Some may ask: Why the billboard get cut off so perfectly? I don't see that cutoff information in the Billboard.asset file. Answer: the cutoff definition is in the image file (as Alpha channel), and Unity recognize the cutoff through shader code

Palm Transparency


palmbillboard.png (126.6 kB)
palmtransparency.png (132.8 kB)
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 plingativator · Feb 16, 2019 at 01:38 AM 0
Share

This was really helpful. I also found information on how the texcoord values work in the SpeedTree documentation. This enabled me to map my own textures out. https://docs.speedtree.com/doku.php?id=accessing_billboard_geometry

avatar image
1

Answer by BarShiftGames · Jan 18, 2020 at 06:50 AM

Using their code above, I have made a custom billboard asset maker, the script should be able to auto-render out a billboard asset and texture atlas, though I'm not sure about normals, how would one make a camera render normals?

The three slider values allow you to pinch the top, middle, and bottom width to cut off areas you won't normally render, like how they pinch the top of it for triangular trees, 1 is full width and 0 is it turns into a single point at the middle.

Basically, the "toRotateCamera" object (name it will try to auto-find is: BillboardCameraArm) is what rotates to take the pictures, and the camera is the camera that should be on the +x axis as a child of that rotator, kindof like an arm with a camera on the end that will spin to take pictures from all angles. The camera should only see the object/s you want to picture though, not everything in the scene, and have a background of transparent colors, with clear flags set to solid color. This was to allow complex objects to be easily baked into billboards, rather than only one mesh allowed, and scene lighting/post-processing is easy to customize.

The only special thing is you need to assign it a material from the nature/speedtree billboard shader thing, under the standard assets of unity, it saves everything in the same location as that material.

Access the wizard under Window / Rendering / Generate Billboard of Object. Huge thanks to SomeGuy22, and the original hard-coded example by NathanJSmith.

 using UnityEditor;
 using UnityEngine;
 
 
 //Credits:
 //Original hard-coded solution by NathanJSmith: https://answers.unity.com/questions/1538195/unity-lod-billboard-asset-example.html?childToView=1692072#answer-1692072
 //Cutomization to script by BarShiftGames on above link, and below link
 //Inspiration/Feedback/More coding optimization by SomeGuy22 : https://answers.unity.com/questions/1692296/unable-to-save-generatedrendered-texture2d-to-use.html
 
 #if UNITY_EDITOR
 public class GenerateBillboard : ScriptableWizard
 {
     [Header("")]
     [Tooltip("This should be a Nature/Speedtree billboard material")]
     public Material m_material;
     [Tooltip("How much to pinch the mesh at a certain point, to cut off extra pixels off the mesh that won't be needed.")]
     [Range(0, 1)]
     public float topWidth = 1;
     [Tooltip("How much to pinch the mesh at a certain point, to cut off extra pixels off the mesh that won't be needed.")]
     [Range(0, 1)]
     public float midWidth = 1;
     [Tooltip("How much to pinch the mesh at a certain point, to cut off extra pixels off the mesh that won't be needed.")]
     [Range(0, 1)]
     public float botWidth = 1;
 
     [Tooltip("Units in height of the object, roughly, this can be fine-tuned later on the final asset")]
     public float objectHeight = 0;
     [Tooltip("Units in width of the object, roughly, this can be fine-tuned later on the final asset")]
     public float objectWidth = 0;
     [Tooltip("Usually negative and small, to make it sit in the ground slightly, can be modifed on final asset")]
     public float bottomOffset = 0;
 
     [Tooltip("The amount of rows in the texture atlas")]
     [Min(1)]
     public int atlasRowImageCount = 3;
     [Tooltip("The amount of columns in the texture atlas")]
     [Min(1)]
     public int atlasColumnImageCount = 3;
     [Tooltip("The total number of images to bake, ALSO decides how many angles to view from")]
     [Min(1)]
     public int totalImageCount = 8;
 
     [Header("-")]
     [Tooltip("This dictates the rotational center of the render for the billboard, and what is rotated to get different angles.\nThis also checks once for an object with named \"BillboardCameraArm\"")]
     public GameObject toRotateCamera;
     [Tooltip("This should be child of toRotateCamera, and on the local +x axis from it, facing center with a complete view of the object")]
     public Camera renderCamera;
 
     [Header("Dimensios of atlas")]
     public int atlasPixelWidth = 1024;
     public int atlasPixelHeight = 1024;
 
     [Header("Optional renderer to set in")]
     public BillboardRenderer optionalBillboardRenderer;
 
     private bool doOnce = true;
     private bool checkArmOnce = true;
 
     void OnWizardUpdate()
     {
         string helpString = "";
         bool isValid = (m_material != null && objectHeight != 0 && objectWidth != 0 && renderCamera != null && toRotateCamera != null);
 
         if (doOnce)
         {
             //this will get activated once
             doOnce = false;
             toRotateCamera = GameObject.Find("BillboardCameraArm");
 
         }
 
         if (toRotateCamera != null && checkArmOnce)
         {
             //this will check for a camera under toRotateCamera once
             checkArmOnce = false;
             Camera cam = toRotateCamera.GetComponentInChildren<Camera>();
             if (cam != null) { renderCamera = cam; }
         }
     }
 
 
 
     void OnWizardCreate()
     {
         //function to execute on submit
 
         BillboardAsset billboard = new BillboardAsset();
 
         billboard.material = m_material;
         Vector4[] texCoords = new Vector4[totalImageCount];
 
         ushort[] indices = new ushort[12];
         Vector2[] vertices = new Vector2[6];
 
         //make texture to save at end
         var texture = new Texture2D(atlasPixelWidth, atlasPixelHeight, TextureFormat.ARGB32, false);
         //make render texture to copy to texture and assign it to camera
         //renderCamera.targetTexture = RenderTexture.GetTemporary(atlasPixelWidth / atlasColumnImageCount, atlasPixelHeight / atlasRowImageCount, 16);
         renderCamera.targetTexture = RenderTexture.GetTemporary(atlasPixelWidth, atlasPixelHeight, 16);
         var renderTex = renderCamera.targetTexture;
         renderCamera.targetTexture = renderTex;
 
         //reset rotation, but camera should be on local +x axis from rotating object
         toRotateCamera.transform.eulerAngles = Vector3.zero;
         int imageAt = 0;
         for (int j = 0; j < atlasRowImageCount; j++)
         {
             for (int i = 0; i < atlasColumnImageCount; i++)
             {
                 //i is x, j is y
                 if (imageAt < totalImageCount)
                 {
                     //atla them left-right, top-bottom, 0,0 is bottom left
                     float xRatio = (float)i / atlasColumnImageCount;
                     float yRatio = (float)(atlasRowImageCount - j - 1) / atlasRowImageCount;
 
                     //starts at viewing from +x, and rotates camera clockwise around object, uses amount of vertices set (later down) to tell how many angles to view from
                     texCoords[imageAt].Set(xRatio, yRatio, 1f / atlasColumnImageCount, 1f / atlasRowImageCount);
                     imageAt++;
 
                     //set rect of where to render texture to
                     renderCamera.rect = new Rect(xRatio, yRatio, 1f / atlasColumnImageCount, 1f / atlasRowImageCount);
                     renderCamera.Render();
 
                     //read pixels on rec
                     //Rect rec = new Rect(xRatio * atlasPixelWidth, yRatio * atlasPixelHeight, (float)1 / atlasColumnImageCount * atlasPixelWidth, (float)1 / atlasRowImageCount * atlasPixelHeight);
                     //texture.ReadPixels(rec, i / atlasColumnImageCount * atlasPixelWidth, (atlasRowImageCount - j - 1) / atlasRowImageCount * atlasPixelHeight);
 
                     toRotateCamera.transform.eulerAngles -= Vector3.up * (360 / totalImageCount);
                 }
             }
         }
         toRotateCamera.transform.eulerAngles = Vector3.zero;
         renderCamera.rect = new Rect(0, 0, 1, 1);
 
         RenderTexture pastActive = RenderTexture.active;
         RenderTexture.active = renderTex;
         texture.ReadPixels(new Rect(0, 0, atlasPixelWidth, atlasPixelHeight), 0, 0);
         RenderTexture.active = pastActive;
         texture.Apply();
 
         //texCoords[0].Set(0.230981f, 0.33333302f, 0.230981f, -0.33333302f);
         //texCoords[1].Set(0.230981f, 0.66666603f, 0.230981f, -0.33333302f);
         //texCoords[2].Set(0.33333302f, 0.0f, 0.33333302f, 0.23098099f);
         //texCoords[3].Set(0.564314f, 0.23098099f, 0.23098099f, -0.33333302f);
         //texCoords[4].Set(0.564314f, 0.564314f, 0.23098099f, -0.33333403f);
         //texCoords[5].Set(0.66666603f, 0.0f, 0.33333302f, 0.23098099f);
         //texCoords[6].Set(0.89764804f, 0.23098099f, 0.230982f, -0.33333302f);
         //texCoords[7].Set(0.89764804f, 0.564314f, 0.230982f, -0.33333403f);
 
         //make basic box out of four trinagles, to be able to pinch the top/bottom/middle to cut extra transparent pixels
         //still not sure how this works but it connects vertices to make the mesh
         indices[0] = 4;
         indices[1] = 3;
         indices[2] = 0;
         indices[3] = 1;
         indices[4] = 4;
         indices[5] = 0;
         indices[6] = 5;
         indices[7] = 4;
         indices[8] = 1;
         indices[9] = 2;
         indices[10] = 5;
         indices[11] = 1;
 
         //set vertices positions on mesh
         vertices[0].Set(-botWidth / 2 + 0.5f, 0);
         vertices[1].Set(-midWidth / 2 + 0.5f, 0.5f);
         vertices[2].Set(-topWidth / 2 + 0.5f, 1);
         vertices[3].Set(botWidth / 2 + 0.5f, 0);
         vertices[4].Set(midWidth / 2 + 0.5f, 0.5f);
         vertices[5].Set(topWidth / 2 + 0.5f, 1);
 
         //assign data
         billboard.SetImageTexCoords(texCoords);
         billboard.SetIndices(indices);
         billboard.SetVertices(vertices);
 
         billboard.width = objectWidth;
         billboard.height = objectHeight;
         billboard.bottom = bottomOffset;
 
         //save assets
         string path;
         int nameLength = AssetDatabase.GetAssetPath(m_material).Length;
         //take out ".mat" prefix
         path = AssetDatabase.GetAssetPath(m_material).Substring(0, nameLength - 4) + ".asset";
         AssetDatabase.CreateAsset(billboard, path);
         path = AssetDatabase.GetAssetPath(m_material).Substring(0, nameLength - 4) + ".png";
         byte[] byteArray = texture.EncodeToPNG();
         System.IO.File.WriteAllBytes(path, byteArray);
         Debug.Log("BILLBOARD ASSET COMPLETED: File saved to " + path + ",\n if pressing save in editor breaks billboard, manually assign texture to material");
 
         if (optionalBillboardRenderer != null)
         {
             optionalBillboardRenderer.billboard = billboard;
         }
 
         //cleanup / qol things
         RenderTexture.ReleaseTemporary(renderTex);
         renderCamera.targetTexture = null;
         m_material.SetTexture("_MainTex", texture);
 
         AssetDatabase.Refresh();
     }
 
     [MenuItem("Window/Rendering/Generate Billboard of Object")]
     static void MakeBillboard()
     {
         ScriptableWizard.DisplayWizard<GenerateBillboard>(
             "Make Billboard from object", "Create");
     }
 }
 #endif


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 SomeGuy22 · Jan 21, 2020 at 08:27 PM 0
Share

Okay, this was a huge coincidence since I've been searching for something exactly like what you wrote and realized you made this answer only a few days ago! So, I took a look at your code and was able to modify it using a different approach. $$anonymous$$y updated version of your code is now able to:

  • Render the snapshots with alpha background by overriding the clear color in post

  • $$anonymous$$anually adjust scaling/snapshot position

  • No more error messages about reading out of range

The biggest change is basically that I've simplified the approach somewhat. Ins$$anonymous$$d of rendering individual segments of camera react subspaces and copying the render texture using hack magic, I've ins$$anonymous$$d opted to just make a small rect to render to and use the ReadPixels() source destination to just output to a different position on the final atlas. However, in shifting to this approach I encountered new issues:

  • ReadPixels actually captures the Editor UI based on your aspect ratio. Solution: Set the aspect ratio to free aspect and manually align the snapshot position using the new cameraShift variables I included. You can also scale the camera rect to get a fuller/smaller view of the object you want to capture using cameraScale. There's probably a way to automatically detect this stuff but manual is fine for now.

  • ReadPixels doesn't get new info until the end of frame, so you only end up with one snapshot. Solution: Import the EditorCoroutines package. Now I can use the IEnumerator to yield during an Editor function and thus I can take snapshots in several steps.

Also a few small things:

  • I'm now calling AssetDatabase.Refresh() so that new assets always appear

  • You shouldn't set the material's texture to "texture" because it's temporary and not linked to the PNG asset which is created. That now has to be done manually.

  • I'm now calling texture.Apply() so that changes are properly saved

It's still a little messy, but it gets the job done. Here's my modified version: https://pastebin.com/0EHwuU0g

I think it gets pretty good results. On the left is the billboard render: https://i.imgur.com/zN$$anonymous$$bmk8.png

There's probably more QOL adjustments that can be made such as auto-detecting object position and saving assets in a more organized manner--overriding the billboard asset breaks links to renderers which sucks. But it works good enough for now and great for what I need to billboard my custom trees. Thanks a ton for your original version.

With your permission, would I be able to share this new code with the people down on the forums? There's practically no info on BillboardAsset online and I think this would be a great use case to take advantage of one of Unity's lesser known components. I'd also love to discuss it further if you have any more improvements. Thanks for sharing :)

EDIT: I should add that I spent 6 or 7+ hours on it so I hope it's useful for someone .-.

avatar image pankao SomeGuy22 · Jul 24, 2021 at 11:08 PM 0
Share

Man I definitely found this useful! Thanks for sharing really. I am going to implement top-down angle myself, seems pretty straightforward a syour code is actually quite readable. Great work dude thanks for your effort!

avatar image
0

Answer by dan_wipf · Aug 04, 2018 at 10:33 AM

might this is one could be a example you’re looking for..

https://github.com/danwipf/TreeShader

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 NathanJSmith · Aug 06, 2018 at 03:08 AM 0
Share

I have checked that asset out, it doesn't use the billboard asset but it use double-plane-mesh technique. (It doesn't have Billboard-render component)

avatar image dan_wipf · Aug 07, 2018 at 05:12 AM 0
Share

well I just googled around and tried inside of Unity to figuerout some Information.

  1. On Google, nobody figured it out how to make a Custom BillboardAsset and the $$anonymous$$anual dosent provide any useable Information. (might be real hard work to create a usable Script)

  2. I think it's a Speedtree "only" thing. Because it creates the BillBoardAsset inside of the SpeedTree $$anonymous$$odeler and if you have a look to the Shader of the $$anonymous$$aterial the only which Works with BillboardRenderer is the SpeedtreeBillboard shader..

to sum up my Opinion. I'd looking for an alternative Billboard Solution or try to create a Script which makes RendereTextures which you combine to one and then compile it to a BillboardAsset.

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

98 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 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 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 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 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

Tutorial Program will not Run (First time in Unity) 1 Answer

How to create billboard version of a tree? 3 Answers

Are there project files for a game like.... 0 Answers

Can someone provide an alternative source for downloading Robot Lab? 0 Answers

Help I Opened An Asset But Can't Get Back 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