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 /
  • Help Room /
avatar image
0
Question by KnightRiderGuy · Dec 26, 2015 at 05:16 PM · c#arduinoserialportbuttonstatescase

Add A Start Off State for Switch Case Scenario

I have some switch cases set up from reading that are sent through the Serial port from the Arduino into Unity. A Button Pressed state and Un pressed state. These states are then read by unity in order to trigger some animation on another canvas panel. What happens is that although the initial button functions are working just fine (See Video Demo) Because it starts off at a "case 0" for button up or un pressed my animation sounder gets activated. like this:

 void DirectionArrow(int buttonStatus)
     //void DirectionArrow(int Direction)
     {
         
     switch (buttonStatus)
     {
         //OFF Buttons  States
         case 0:
             //deactivate Left Direction Arrow
             SystemGuidanceManagerScript WAO = FindObjectOfType<SystemGuidanceManagerScript>();
             WAO.WestArrowOff ();
 
             SystemGuidanceManagerScript EAO = FindObjectOfType<SystemGuidanceManagerScript>();
             EAO.EastArrowOff();
 
             SystemGuidanceManagerScript SFXOff = FindObjectOfType<SystemGuidanceManagerScript>();
             SFXOff.TopIndicatorOff();
 
             SystemGuidanceManagerScript BGSOff = FindObjectOfType<SystemGuidanceManagerScript>();
             BGSOff.BarLEDsSounderOff();
             break;
         //LEFT BUTTON ON STATE
         case 4:
             //Activate Left Direction Arrow Indicator
             SystemGuidanceManagerScript WA = FindObjectOfType<SystemGuidanceManagerScript>();
             WA.WestArrow();
             SystemGuidanceManagerScript WBSOn = FindObjectOfType<SystemGuidanceManagerScript>();
             WBSOn.BarLEDsSounderOn();
             break;
         //RIGHT BUTTON ON STATE
         case 5:
             //Activate Right Direction Arrow Indicator
             SystemGuidanceManagerScript EA = FindObjectOfType<SystemGuidanceManagerScript>();
             EA.EastArrow();
             SystemGuidanceManagerScript EBSOn = FindObjectOfType<SystemGuidanceManagerScript>();
             EBSOn.BarLEDsSounderOn();
             break;
     }
             
     }

I was wondering if there is a way to add some sort of "Start Off" case where nothing happens until the buttons are pressed.?

Video Demo Of Arduino To Unity

Comment
Add comment · Show 2
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 gjf · Dec 27, 2015 at 07:50 PM 0
Share

what do you mean by "where nothing happens"?

you could add a default state to handle some case not explicitly handled by 0-5... for clarity, you might consider assigning some names to those too - use an enum and pass that as the button state or cast it to the enum

you can get rid of a lot of that code too - the object you're getting with every FindObjectOfType appears to be the same every time, so just get the reference before your switch statement...

edit: btw - looks like an interesting project ;)

avatar image KnightRiderGuy gjf · Dec 28, 2015 at 01:06 PM 0
Share

@gif, Thanks man, I'm all for cleaning up unnecessary confusing code, can you direct me more with what needs to stay and what can go?

P.S. I posted more information down below with updated codes.

2 Replies

· Add your reply
  • Sort: 
avatar image
0

Answer by NoseKills · Dec 28, 2015 at 11:46 AM

I'm not sure if I understand your problem right but in general I'd say that a switch case works as it works and there's no changing it:

You have your individual "cases" and the "default" that happens when no other case happens. But you can change what values you feed into it and change behavior that way.

If I understood correctly, the device outputs "0" all the time if no buttons are pressed and you'd like your code to only perform the "case 0:" when the button is released after pressing ? In that case you need to use other variables to control what goes into the switch-case

     private int lastbuttonStatus = 0;
     void DirectionArrow(int buttonStatus)
     {
         if (buttonStatus != lastbuttonStatus) {
             lastbuttonStatus = buttonStatus;
             switch (buttonStatus)
             {
                 //OFF Buttons  States
                 case 0:
                     //deactivate Left Direction Arrow
                     break;
                 //LEFT BUTTON ON STATE
                 case 4:
                     //Activate Left Direction Arrow Indicator
                     break;
                 //RIGHT BUTTON ON STATE
                 case 5:
                     //Activate Right Direction Arrow Indicator
                     break;
             }
         }
     }
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 KnightRiderGuy · Dec 28, 2015 at 01:04 PM 0
Share

Thanks @Nose$$anonymous$$ills, I posted some more information in an answer below, I changed the Arduino code so that the "0" is not being sent constantly, it's fixed part of the problem. I put a video link near the bottom too to demo what I mean better.

Video Demo

avatar image
0

Answer by KnightRiderGuy · Dec 28, 2015 at 01:01 PM

@gif thanks. I should point out that code is not really my strong suit but I kinda have no choice on this project ;) Glad you like the project, if I can ever get it done it should make a nice compliment to the knight Rider dash I have.... takes me all day to figure out nit picky stuff that some one who is way more code savvy would whip through in a matter of minutes... It's the biggest frustrating part about this project is the code stuff. ;)

I was on the Arduino forums and managed to change my Arduino code to this:

 int lightSensorPin = A0; //Define the Light Sensor Pin
 int lightSensorValue = 0;
 
 //int lightLevel = analogRead(0);
 //int threshold = 250;
 //int range = 50;
 
 //Defines Our Button Pins
 const int buttonRight = A1; 
 const int buttonLeft = A2;
 
 // Variable to hold the state of the buttons
 int bRS, bLS; //ButtonRight and ButtonLeft states status holders
 
 
 //Sets Pin number LED is conneted too
 const byte rLed = 12; 
 const byte rLed2 = 1;
 const byte yLed = 11;
 const byte gLed = 10;
 const byte gLed2 = 5;
 const byte gLed3 = 4;
 const byte wLed = 3;
 const byte bLed = 2;
 const byte bLed2 = 13;
 
 char myChar;         //changed the name of this variable because they are not all colurs now
 const byte pulsePins[] = {6, 7, 8, 9};  //pins for a pulse output
 char pulseTriggers[] = {'p', 'q','R','L'};
 const int NUMBER_OF_PULSE_PINS = sizeof(pulsePins);
 unsigned long pulseStarts[NUMBER_OF_PULSE_PINS];
 unsigned long pulseLength = 500;
 
 int buttonStateR = 0;       //Current State of the R button
 int lastButtonStateR = 0;   //Previous State of the R button
 
 int buttonStateL = 0;       //Current State of the L button
 int lastButtonStateL = 0;   //Previous State of the L button
 int buttonPushCounter = 0;  //Counter for number of button presses
 
 void setup()
 {
   //Serial.begin (9600);
   Serial.begin (115200);
   Serial.setTimeout(13); //Added today Sun Nov 22 ( not sure if this is needed? )
 
   pinMode(buttonRight, INPUT); //Defines Pin Mode
   pinMode(buttonLeft, INPUT);
 
   digitalWrite(buttonRight, HIGH);
   digitalWrite(buttonLeft, HIGH);
   
   pinMode(wLed, OUTPUT);
   pinMode(rLed, OUTPUT);
   pinMode(rLed2, OUTPUT);
   pinMode(yLed, OUTPUT);
   pinMode(gLed, OUTPUT);
   pinMode(gLed2, OUTPUT);
   pinMode(gLed3, OUTPUT);
   pinMode(bLed, OUTPUT);
   pinMode(bLed2, OUTPUT);
   digitalWrite(wLed, LOW);
   digitalWrite(rLed, LOW);
   digitalWrite(rLed2, LOW);
   digitalWrite(yLed, LOW);
   digitalWrite(gLed, LOW);
   digitalWrite(gLed2, LOW);
   digitalWrite(gLed3, LOW);
   digitalWrite(bLed, LOW);
   digitalWrite(bLed2, LOW);
   
   for (int p = 0; p < NUMBER_OF_PULSE_PINS; p++)
   {
     pinMode(pulsePins[p], OUTPUT);
     digitalWrite(pulsePins[p], LOW);
   }
 }
 
 void loop()
 {
   
    
   // read the new light value (in range 0..1023): 
      int sensorValue = analogRead(lightSensorPin);
      // if the value changed by 10
      if(lightSensorValue - sensorValue > 10 || sensorValue - lightSensorValue > 10){
          lightSensorValue = sensorValue; // save the new value
          float p = lightSensorValue * (100.0 / 1023.0);    // make the value to range 0..100
          // the Parentheses may be for compiler optimization idk  
          Serial.println(p); // send it to unity
      }
 
   
 
   
   if (Serial.available())              //if serial data is available
   {
 
     
     
     int lf = 10;
 
     myChar = Serial.read();             //read one character from serial
     if (myChar == 'r')                  //if it is an r
     {
       digitalWrite(rLed, !digitalRead(rLed));  //Oil Slick Toggle
     }
     
     if (myChar == 'b')
     {
       digitalWrite(bLed, !digitalRead(bLed)); //Surveillance Mode Toggle
     }
 
     if (myChar == 'y')
     {
       digitalWrite(yLed, !digitalRead(yLed)); //Movie Player Toggle
     }
 
     if (myChar == 'g')
     {
       digitalWrite(gLed, !digitalRead(gLed)); //Auto Phone Toggle
     }
 
     if (myChar == 's')
     {
       digitalWrite(bLed2, !digitalRead(bLed2)); //Scanner Toggle
     }
 
     if (myChar == 'f')
     {
       digitalWrite(gLed2, !digitalRead(gLed2)); //Fog Lights Toggle
     }
 
     if (myChar == 'h')
     {
       digitalWrite(gLed3, !digitalRead(gLed3)); //Head Lights Toggle
     }
 
     if (myChar == 'H')
     {
       digitalWrite(wLed, !digitalRead(wLed)); //High Beams Toggle
     }
 
 
     //Rear Hatch Popper
     for (int p = 0; p < NUMBER_OF_PULSE_PINS; p++)
     {
       if (myChar == pulseTriggers[p])
       {
         pulseStarts[p] = millis();  //save the time of receipt
         digitalWrite(pulsePins[p], HIGH);
       }
     }
 
 
     //Grappling Hook Launch
     for (int q = 0; q < NUMBER_OF_PULSE_PINS; q++)
     {
       if (myChar == pulseTriggers[q])
       {
         pulseStarts[q] = millis();  //save the time of receipt
         digitalWrite(pulsePins[q], HIGH);
       }
     }
 
 
     //Auto Doors Right Pulse
     for (int R = 0; R < NUMBER_OF_PULSE_PINS; R++)
     {
       if (myChar == pulseTriggers[R])
       {
         pulseStarts[R] = millis();  //save the time of receipt
         digitalWrite(pulsePins[R], HIGH);
       }
     }
 
 
     //Auto Doors Left Pulse
     for (int L = 0; L < NUMBER_OF_PULSE_PINS; L++)
     {
       if (myChar == pulseTriggers[L])
       {
         pulseStarts[L] = millis();  //save the time of receipt
         digitalWrite(pulsePins[L], HIGH);
       }
     }
   }
 
   //the following code runs each time through loop()
   for (int p = 0; p < NUMBER_OF_PULSE_PINS; p++)
   {
     if (millis() - pulseStarts[p] >= pulseLength)  //has the pin been HIGH long enough ?
     {
       digitalWrite(pulsePins[p], LOW);   //take the pulse pin LOW
     }
   }
 
   for (int q = 0; q < NUMBER_OF_PULSE_PINS; q++)
   {
     if (millis() - pulseStarts[q] >= pulseLength)  //has the pin been HIGH long enough ?
     {
       digitalWrite(pulsePins[q], LOW);   //take the pulse pin LOW
     }
   }
 
  
   // read the pushbutton input pin
   buttonStateR = digitalRead(buttonRight);
 
   //compare the buttonState to its previous state
   if (buttonStateR != lastButtonStateR){
     // if the state has changed, increment the counter
     if (buttonStateR == LOW){
       // if the current state is HIGH then the button went from off to on
       buttonPushCounter++;
       Serial.println(1);
       //Serial.print("number of button pushes: ");
       //Serial.println(buttonPushCounter);
     }else{
       // if the current state is LOW then the button went from on to off
       Serial.println(0);
     }
     // Delay  little bit to avoid bouncing
     delay(20);
   }
     // save the current state as the last state for the next time through loop
       lastButtonStateR = buttonStateR;
 
 
    // read the pushbutton input pin
   buttonStateL = digitalRead(buttonLeft);
 
   //compare the buttonState to its previous state
   if (buttonStateL != lastButtonStateL){
     // if the state has changed, increment the counter
     if (buttonStateL == LOW){
       // if the current state is HIGH then the button went from off to on
       buttonPushCounter++;
       Serial.println(2);
       //Serial.print("number of button pushes: ");
       //Serial.println(buttonPushCounter);
     }else{
       // if the current state is LOW then the button went from on to off
       Serial.println(0);
     }
     // Delay  little bit to avoid bouncing
     delay(20);
   }
   // save the current state as the last state for the next time through loop
   lastButtonStateL = buttonStateL;
     
 
 }


UNITY Code: I changed my unity code to this:

 using UnityEngine;
 using UnityEngine.UI;
 using System.Collections;
 using System.IO.Ports;
 using System.Threading;
 
 
 public class Sending : MonoBehaviour {
 
 
     //int sysHour = System.DateTime.Now.Hour;
     
     //Random Clips
     public AudioClip[] BrightnessAudioClips;
     public AudioClip[] DarknessAudioClips;
     public AudioClip[] AnnoyedAudioClips;
 
     //DTMF Tones
     public AudioClip DTMFtone01;
     public AudioClip DTMFtone02;
     public AudioClip DTMFtone06;
     public AudioClip DTMFtone08;
     public AudioSource source;
 
     //UI Text Reference
     //public Text MessageCentreText;
 
     //_isPlayingSound is true when a sound is currently playing - just as the name suggests.
     private bool _isPlayingSound;
 
     const float sliderChangeVelocity = 0.5f;
     private float desiredSliderValue;
 
     public GameObject LightSlider;
     public Slider slider;
     Slider lightSlider;
     public static Sending sending;
 
     //public static SerialPort sp = new SerialPort("COM4", 9600, Parity.None, 8, StopBits.One);
     public static SerialPort sp = new SerialPort("/dev/cu.wchusbserial1420", 115200, Parity.None, 8, StopBits.One); //115200
 
     public string message2;
 
     //Button States
     bool button01State = false;
 
 
 
     void Awake () {
         if (sending == null) {
             DontDestroyOnLoad (gameObject);
             sending = this;
         } else if (sending != this) {
             Destroy (gameObject);
         }
 }
 
 
     float timePassed = 0.0f;
     // Use this for initialization
     void Start () {
         StartCoroutine(OpenConnection());
         lightSlider = GetComponent<Slider> ();
         if(slider == null) slider = GetComponent<Slider>(); // search slider in this object if its not set in unity inspector
         if(source == null) source = GetComponent<AudioSource>(); // search audiosource in this object if its not set in unity inspector
 
         }
     
     // Update is called once per frame
     void Update () {
         /*string dataFromArduinoString = sp.ReadLine ();
         int dFAI = int.Parse (dataFromArduinoString);
         print (dFAI);
         DirectionArrow (dFAI);*/
 
         try
         {
             //DirectionArrow(sp.ReadByte());
             //print(sp.ReadByte());
             string dataFromArduinoString = sp.ReadLine ();
             int dFAI = int.Parse (dataFromArduinoString);
             print (dFAI);
             DirectionArrow (dFAI);
         }
         catch (System.Exception) {
 
         }
             //print("BytesToRead" +sp.BytesToRead);
             message2 = sp.ReadLine();
             
         string message = sp.ReadLine(); //get the message...
         if(message == "") return; //if its empty stop right here
         // parse the input to a float and normalize it (range 0..1) (we could do this already in the Arduino)
 
         float input =  1 -  float.Parse (message) / 100f;
         // set the slider to the value
         float oldValue = slider.value; // -------- this is new
         slider.value = input;
 
         // after the slider is updated, we can check for the other things for example play sounds:
 
         if (source.isPlaying) return; // if we are playing a sound stop here
 
         // else check if we need to play a sound and do it
         if (slider.value > 0.9f && oldValue <= 0.9f) // ---------this has changed
             source.PlayOneShot (BrightnessAudioClips [Random.Range (0, BrightnessAudioClips.Length)]);
 
         else if (slider.value < 0.15f && oldValue >= 0.15f) //----------this has changed
             source.PlayOneShot (DarknessAudioClips [Random.Range (0, DarknessAudioClips.Length)]);
         
 
     }
         
 
 
     //public void OpenConnection() {
     IEnumerator OpenConnection(){
         yield return new WaitForSeconds(1.9f); // wait time
        if (sp != null) 
        {
          if (sp.IsOpen) 
          {
           sp.Close();
           print("Closing port, because it was already open!");
          }
          else 
          {
           sp.Open();  // opens the connection
           sp.ReadTimeout = 16;  // sets the timeout value before reporting error
           print("Port Opened!");
         //        message = "Port Opened!";
          }
        }
        else 
        {
          if (sp.IsOpen)
          {
           print("Port is already open");
          }
          else 
          {
           print("Port == null");
          }
        }
     }
 
     void OnApplicationQuit() 
     {
        sp.Close();
     }
 
     //Movie Player Toggle
     public static void sendYellow(){
         sp.Write("y");
     }
 
     //Analyzer Toggle
     public static void sendYellow2(){
         sp.Write("A");
     }
 
     //Pod 7DLA Toggle
     public static void sendYellow3(){
         sp.Write("D");
     }
 
     //Pod PENG Toggle
     public static void sendYellow4(){
         sp.Write("P");
     }
 
     //Pod 6RM Toggle
     public static void sendYellow5(){
         sp.Write("6");
     }
 
     //Pod Laser Toggle
     public static void sendYellow6(){
         sp.Write("Z");
     }
 
 
     //Auto Phone Toggle
     public static void sendGreen(){
         sp.Write("g");
         //sp.Write("\n");
     }
     
     //Oil Slick Toggle
     public static void sendRed(){
         sp.Write("r");
     }
 
     //Surveillance Mode Toggle
     public static void sendBlue(){ 
         sp.Write("b");
     }
     
     //Scanner Toggle
     public static void sendRed2(){
         sp.Write("s");
     }
 
     //Fog Lights Toggle
     public static void sendGreen2(){
         sp.Write("f");
     }
 
     //Head Lights Toggle
     public static void sendGreen3(){
         sp.Write("h");
     }
 
     //Hight Beams Toggle
     public static void sendWhite(){
         sp.Write("H");
     }
 
     //Rear Hatch Popper
     public static void sendPulse1(){
         sp.Write("p");
     }
     
     //Grappling Hook Launch
     public static void sendPulse2(){
         sp.Write("q");
     }
 
     //Auto Doors Right Pulse
     public static void sendPulse3(){
         sp.Write("R");
     }
 
     //Auto Doors Left Pulse
     public static void sendPulse4(){
         sp.Write("L");
     }
 
     //Startup and Shutdown Pulse
     public static void sendPulse5(){
         sp.Write("S");
     }
         
 
     //System Guidance Close Button
     public void  GoDTMFtone02(){
         StartCoroutine(LoadT4());
         GetComponent<AudioSource>().PlayOneShot(DTMFtone02);
     }
 
     IEnumerator LoadT4(){
         yield return new WaitForSeconds(0.0f); // wait time
         CameraSwitcher cs1 = FindObjectOfType<CameraSwitcher>();
         cs1.EnableCamera1();
     }
         
     void DirectionArrow(int buttonStatus)
     //void DirectionArrow(int Direction)
     {
         
     switch (buttonStatus)
     {
         //OFF Buttons  States
         case 0:
             //deactivate Left Direction Arrow
             SystemGuidanceManagerScript WAOff = FindObjectOfType<SystemGuidanceManagerScript>();
             WAOff.WestArrowOff ();
 
             SystemGuidanceManagerScript EAOff = FindObjectOfType<SystemGuidanceManagerScript>();
             EAOff.EastArrowOff();
 
             SystemGuidanceManagerScript SFXOff = FindObjectOfType<SystemGuidanceManagerScript>();
             SFXOff.TopIndicatorOff();
 
             SystemGuidanceManagerScript BGSOff = FindObjectOfType<SystemGuidanceManagerScript>();
             BGSOff.BarLEDsSounderOff();
             break;
         //LEFT BUTTON ON STATE
         case 1:
             //Activate Left Direction Arrow Indicator
             SystemGuidanceManagerScript WAOn = FindObjectOfType<SystemGuidanceManagerScript>();
             WAOn.WestArrow();
 
             SystemGuidanceManagerScript WBSOn = FindObjectOfType<SystemGuidanceManagerScript>();
             WBSOn.BarLEDsSounderOn();
             break;
         //RIGHT BUTTON ON STATE
         case 2:
             //Activate Right Direction Arrow Indicator
             SystemGuidanceManagerScript EAOn = FindObjectOfType<SystemGuidanceManagerScript> ();
             EAOn.EastArrow ();
 
             SystemGuidanceManagerScript EBSOn = FindObjectOfType<SystemGuidanceManagerScript>();
             EBSOn.BarLEDsSounderOn();
             break;
     }
             
     }
 
 }
 


I think part of the problem now might be That because the Buttons read into Unity as 0, 1 & 2 that perhaps these values conflict with values of the LDR sensor. Someone on the Arduino forums suggested that I should try and call the button inputs or LDR reading inputs before each other in the Update.

Here is a vide link of how it's working with these updated codes. As you will see the LDR seems to work fine for the most part although right away on sat up the light sensor slider will often shoot right up to it's brightest level and the buttons for the turn signal indicators will often "Miss fire" for lack of a better word.

Video Link Demo Video Link

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

46 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

Related Questions

How Do I Activate The Switch Statement 1 Answer

Get Temperature Value and Prompt an Action 0 Answers

Convert an Int to a String 0 Answers

App - device connection in Android 0 Answers

Need Help With Arduino Code to Unity 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