Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 14 Next capture
2021 2022 2023
2 captures
13 Jun 22 - 14 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 keil_unity · Jun 11, 2021 at 04:14 PM · c#uisupportscritpinguitoolkit

UI Toolkit screen reader

hey all,

my team is currently using the new unity UIToolkit and loving it 10/10. But we are trying to make our games more accessible and found we can write our own UXML. Is it possible to labels and screen reader support for our UI using UXML? I have tried many things but when I turn on screen reader it does not seem to be able to read any of our onscreen Text.

Example:

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

Answer by Stealcase · Mar 19 at 06:53 PM

Hey, answering because this still shows up high in search results.

Yes, it's possible but...

Unity has no built in support for screen readers: It would be natural to assume it could because the new UXML and USS system seems so similar to HTML and CSS, and all web browsers support Screen Readers. It's also not really that far of a stretch to expect one of the biggest engines in the world with a worth of 13~ Billion dollars to support Screen Readers in SOME way.

But it doesn't, at all, for Runtime or Editor.


In order to support it across all platforms, Unity would have to make an API Layer that that can send UI navigation events to the screenreader on the platform, and do this automatically when using UI Toolkit. Unity would have to manage the drivers for each (Android, Iphone, Xbox, PS5, PC) so that developers only had to deal with the Unity internal API, no matter what platform they are targeting.

This is what Tolk does for Windows screen readers.


Here's an abridged history of Unity threads asking about Screen readers

and Unity sometimes answering perhaps-maybe-at-some-point-thinking-about it:


August 2014: "Is the new UI system going to support screenreaders?" (No answer from Unity)

Context: this is back when the old UI system was "new". History has since repeated itself with the new UI Toolkit system. https://forum.unity.com/threads/screen-reader-access.264938/


May 2015, Visually Impaired player says Unity would be accessible to blind players if only the Editor windows could be selected properly and read to screenreader. (No Answer) https://forum.unity.com/threads/screen-reader-accessibility.328623/


June 2015 Newly visually impaired developer asks if there is some way to navigate Unity Editor UI with screenreader. (No Answer) https://forum.unity.com/threads/ui-accessible-via-keyboard-and-screen-reader.334751/


March 2017, blind programmer asks if Unity editor is blind accessible. (No Answer) https://forum.unity.com/threads/screen-reader-support-of-unity-engine.462689/


  • I've cut away a lot of threads with no answer


Jan 2018, Developer asks about Editor and Screenreader accessibility, says Unity is not in compliance with CVAA (No Answer) https://forum.unity.com/threads/any-updates-on-accessibility-becoming-a-first-class-citizen-in-unity.512669/


March 2018 Student accuses Unity of breaking the Americans with dissability act, and quote:

"the americans with disabilities section 508 act, which in part, says that apps, products, services must be accessible for the blind."

(Unity answers 2 years later after thread is bumped twice) https://forum.unity.com/threads/screen-reader-accessibility-for-unity.521432/?gq=screen%20reader


Sep 2018, developer asks if the new UI Toolkit will be blind accessible, since it will be XML Based. (FINALLY Unity Answers in 2018! but their answer is vague and non-promising: Quote: "

It is indeed out intention to increase overall Accessibility in both the Editor and at Runtime, and you're right to say that adding support for it in UIElements makes a lot of sense. The how and when is still not defined though.

) https://forum.unity.com/threads/uielements-step-towards-screen-readers.563017/

June 2019, Hackathon Accessibility test, some Unity devs add engine-level Screen Reader support to unity as part of a Hackathon, is never published or released anywhere. https://twitter.com/superpig/status/1145381804389666976


June 2019-December 2021: (Last response from Unity as of now was May 2021): Accessibility and inclusion Thread. https://forum.unity.com/threads/accessibility-and-inclusion.694477/


In the meantime, if you want implement some sort of UI Toolkit TTS Support yourself for UI Toolkit for runtime, here is the simplest implementation I could get to work. This ONLY works on Windows (as far as I know, because I think the TTS drivers included in Tolk are Windows only).

Known limitations:

  • if you don't have NVDA or something else installed, this sollution will use Windows SAPI. This WILL lag your game when navigating UI.

  • If your UI often changes (if you dynamically add elements to a UI List or something) then you need to call the EnableTTSForMenus() method on the Visual Element container to grab them.

  • If you update a label or button text, you need to register the event again, or else it will read the old text.

    How to Implement

  1. Download the Tolk DLLs and include the drivers, drop them in the Assets/Plugins folder

  2. Add the script component below to a gameobject in the scene.

  3. Drag your UI DocumentComponent into it.

  4. Play the game.


 using System.Collections;
 using System.Collections.Generic;
 using UnityEngine;
 using DavyKager;
 using UnityEngine.UIElements;
 namespace Stealcase.TTS
 {
 
 
     public class TTSManager : MonoBehaviour
     {
         public UIDocument document;
         public bool useSAPI = true;
         /// <summary>
         /// Whether the player wants to use TTS.
         /// </summary>
         public bool useTTS = true;
         /// <summary>
         /// The actual STATE of the TTS.
         /// </summary>
         private bool ttsEnabled = false;
         public int MaxQueueCount = 10;
         public bool TTSEnabled { get => ttsEnabled; }
         private int currentIndex = 0;
         private string lastHeader = "";
         private Queue<string> SpokenSentences;
         private Coroutine shuttingDownTTS;
 
         public static TTSManager instance;
         void Awake()
         {
             SpokenSentences = new Queue<string>(MaxQueueCount);
             if(instance != null)
             {
                 Destroy(this);
             }
             else
             {
                 instance = this;
                 if(useTTS)
                 {
                     EnableTTS();
                 }
                 DontDestroyOnLoad(this);
             }
         }
         public void ToggleEnabled()
         {
             useTTS = !useTTS;
             if(useTTS)
             {
                 EnableTTS();
             }
             else
             {
                 if(shuttingDownTTS == null)
                 {
                     Tolk.Speak("Shutting down TTS. Press T at any time to enable");
                     shuttingDownTTS = StartCoroutine(ShutDownTTS());
                 }
             }
         }
         void Start()
         {
             var root = document.rootVisualElement;
             EnableTTSForMenus(root);
         }
         IEnumerator ShutDownTTS()
         {
             yield return new WaitForSeconds(0.4f);
             while(Tolk.IsSpeaking())
             {
                 yield return new WaitForSeconds(1f);
             }
             DisableTTS();
         }
         void EnableTTS()
         {
             Debug.Log("Enabling TTS");
             if(!TTSEnabled)
             {
                 Tolk.Load();
                 Tolk.TrySAPI(useSAPI);
                 ttsEnabled = true;
                 Debug.Log("TTS ENabled");
                 Speak("Screen Reader Loaded",true);
             }
         }
         void ChangeTTS(bool enable)
         {
             if(enable)
             {
                 EnableTTS();
             }
             else
             {
                 DisableTTS();
             }
         }
         void DisableTTS()
         {
             if(TTSEnabled)
             {
                 Tolk.Unload();
                 ttsEnabled = false;
                 shuttingDownTTS = null;
                 Debug.Log("TTS SHUTDOWN");
             }
         }
         void OnDisable()
         {
             Debug.Log("Destroying Object");
             if(instance == this)
             {
                 DisableTTS();
                 instance = null;
             }
         }
         void OnEnable()
         {
             if(instance == this && useTTS)
             {
                 EnableTTS();
             }
         }
         public void Silence()
         {
             if(TTSEnabled)
             {
                 Tolk.Silence();
             }
         }
         public void Speak(string textToSpeak, bool interupt = false)
         {
             if(TTSEnabled)
             {
                 SpokenSentences.Enqueue(textToSpeak);
                 currentIndex = SpokenSentences.Count;
                 if(SpokenSentences.Count > MaxQueueCount)
                 {
                     SpokenSentences.Dequeue();
                 }
                 Tolk.Speak(textToSpeak, interupt);
             }
         }
         public void Speak(string header, string body, bool interupt = false, bool reverseOrder = false)
         {
             if(header == lastHeader)
             {
                 Speak(body, interupt);
             }
             else
             {
                 lastHeader = header;
                 if(reverseOrder)
                 {
                     string newLine_reversed = $"{body}. {header}";
                     Speak(newLine_reversed, interupt);
                 }
                 else
                 {
                     string newLine = $"{header}. {body}";
                     Speak(newLine, interupt);
                 }
             }
         }
         /// <summary>
         /// Grabs a Visual Element and queries it for elements that have USS with "tts" in them, then subscribes to navigationevents to trigger tts.  
         /// </summary>
         /// <param name="root"></param>
         public void EnableTTSForMenus(VisualElement root)
         {
             var tts = root.Q<Toggle>("text-to-speech");
             if(tts != null)
             {
                 tts.RegisterValueChangedCallback(e => ChangeTTS(e.newValue));
             }
             UQueryBuilder<Button> builder_buttons = root.Query<Button>(classes: new string[]{"unity-button"});
             builder_buttons.ForEach(RegisterButtonEvents);
 
             UQueryBuilder<Label> builder_labels = root.Query<Label>(classes: new string[]{"unity-label"});
             builder_labels.ForEach(RegisterLabelEvents);
 
             UQueryBuilder<SliderInt> builder_sliders = root.Query<SliderInt>(classes: new string[]{"unity-slider-int"});
             builder_sliders.ForEach(RegisterSliderEvents);
             builder_sliders.ForEach(v => v.RegisterCallback<NavigationMoveEvent, SliderTTS>(IncrementSlider,v)); //Allowing Slider to navigate with WASD
 
             UQueryBuilder<Toggle> builder_toggles = root.Query<Toggle>(classes: new string[]{"unity-toggle"});
             builder_toggles.ForEach(RegisterToggleEvents);
 
             UQueryBuilder<ImageTTS> builder_images = root.Query<ImageTTS>(classes: new string[]{"tts-image"}); //Custom class with Alt Text
             builder_images.ForEach(RegisterImageEvents);
         }
         /// <summary>
         /// Unsubscribe from all children elements.  
         /// </summary>
         /// <param name="root"></param>
         public void DisableTTSForMenus(VisualElement root)
         {
             UQueryBuilder<Button> builder_buttons = root.Query<Button>(classes: new string[]{"unity-button"});
             builder_buttons.ForEach(UnRegisterButtonEvents);
 
             UQueryBuilder<Label> builder_labels = root.Query<Label>(classes: new string[]{"unity-label"});
             builder_labels.ForEach(UnregisterLabelEvents);
 
             UQueryBuilder<SliderInt> builder_sliders = root.Query<SliderInt>(classes: new string[]{"unity-slider-int"});
             builder_sliders.ForEach(UnRegisterSliderEvents);
             builder_sliders.ForEach(v => v.UnregisterCallback<NavigationMoveEvent, SliderTTS>(IncrementSlider,v));
 
             UQueryBuilder<Toggle> builder_toggles = root.Query<Toggle>(classes: new string[]{"unity-toggle"});
             builder_toggles.ForEach(UnRegisterToggleEvents);
 
             UQueryBuilder<ImageTTS> builder_images = root.Query<ImageTTS>(classes: new string[]{"tts-image"});
             builder_images.ForEach(UnRegisterImageEvents);
         }
         #region subscribe events
         void RegisterButtonEvents(Button btn) => btn.RegisterCallback<FocusInEvent, string>(NavigateButton, btn.text);
         void UnRegisterButtonEvents(Button btn) => btn.UnregisterCallback<FocusInEvent, string>(NavigateButton);
         void RegisterLabelEvents(Label label)
         {
             label.focusable = true;
             label.RegisterCallback<FocusInEvent, string>(NavigateLabel, label.text);
         }
         void UnregisterLabelEvents(Label label)
         {
             label.focusable = false;
             label.UnregisterCallback<FocusInEvent, string>(NavigateLabel);
         } 
             
         void RegisterImageEvents(ImageTTS image)
         {
             image.focusable = true;
             image.RegisterCallback<FocusInEvent, string>(NavigateImage, image.Description);
         }
         void UnRegisterImageEvents(ImageTTS image)
         {
             image.focusable = true;
             image.UnregisterCallback<FocusInEvent, string>(NavigateImage);
         }
         void RegisterSliderEvents(SliderInt slider) => slider.RegisterCallback<FocusInEvent, SliderInt>(NavigateSlider, slider);
         void UnRegisterSliderEvents(SliderInt slider) => slider.UnregisterCallback<FocusInEvent, SliderInt>(NavigateSlider);
         void RegisterToggleEvents(Toggle toggle) => toggle.RegisterCallback<FocusInEvent, string>(NavigateToggle, toggle.label);
         void UnRegisterToggleEvents(Toggle toggle) => toggle.UnregisterCallback<FocusInEvent, string>(NavigateToggle);
         #endregion
         # region EventWrappers
         void NavigateButton(FocusInEvent e, string body) => Speak(TTSElementType.Button.ToString(), body, true, true);
         void NavigateLabel(FocusInEvent e, string body) => Speak(TTSElementType.Label.ToString(), body, true, true);
         void NavigateImage(FocusInEvent e, string body) => Speak(TTSElementType.Image.ToString(), body, true, true);
         void NavigateSlider(FocusInEvent e, SliderInt slider) => Speak(TTSElementType.Slider.ToString(), $"{slider.label}. {slider.value} percent. {slider.tooltip}", true, true);
         void NavigateToggle(FocusInEvent e, string body) => Speak(TTSElementType.Toggle.ToString(), body, true, true);
         #endregion
 
         /// <summary>
         /// Allowing Left and right UI navigation events to increment value. 
         // only Directional Arrows are supported automatically, this method allows WASD to be supported.
         /// </summary>
         /// <param name="root"></param>
 
         void IncrementSlider(NavigationMoveEvent m, SliderInt slider) {
             switch (m.direction)
             {
                     break;
                 case NavigationMoveEvent.Direction.Left:
                     slider.value -= 1;
                     break;
                 case NavigationMoveEvent.Direction.Right:
                     slider.value += 1;
                     break;
                 default:
                     break;
             }
         }
     }
     public enum TTSElementType
     {
         Button,
         Label,
         Slider,
         Input,
         Toggle,
         Image,
     }
     /// <summary>
     /// Image class that supports Alt Text for Images in unity. 
     /// Be sure to use this class when adding images to unity, or creating your own custom visual Elements. 
     /// </summary>
     public class ImageTTS : Image
     {
         public new class UxmlFactory : UxmlFactory<ImageTTS, UxmlTraits> { }
         public new class UxmlTraits : Image.UxmlTraits 
         {
                 UxmlStringAttributeDescription m_description = new UxmlStringAttributeDescription { name = "description", defaultValue = "Needs description!" };
                 public override IEnumerable<UxmlChildElementDescription> uxmlChildElementsDescription
                 {
                     get { yield break; }
                 }
 
                 public override void Init(VisualElement ve, IUxmlAttributes bag, CreationContext cc)
                 {
                     base.Init(ve, bag, cc);
                     var _l = ve as ImageTTS;
                     _l.Clear();
                     _l.Description = m_description.GetValueFromBag(bag, cc);
                 }
         }
         public string Description { get; set; }
         public ImageTTS() : base()
         {
             AddToClassList("tts-image");
         }
         public ImageTTS(string description) : this()
         {
             Description = description;
         }
 
     }
 }


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

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

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

UI Toolkit: Is it possible to modify USS custom properties (variables) with C#? 0 Answers

How do I set rectTransform properties of one image to another which differ in anchor and parent transforms (script)? 0 Answers

Multiple Cars not working 1 Answer

Distribute terrain in zones 3 Answers

UI Only Updates As Intended When Editing Through Scene 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