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 haimmoshe · Jun 28, 2018 at 01:55 PM · c#scripting problemscript.

How can I add/remove squad members from the FormationSquare when changing the number of members value ?

 using System;
 using System.Collections;
 using System.Collections.Generic;
 using System.Linq;
 using UnityEngine;
 
 public class SquadFormation : MonoBehaviour
 {
     enum Formation
     {
         Square, Circle, Triangle
     }
 
     [Header("Main Settings")]
     [Space(5)]
     public Transform squadMemeberPrefab;
     [Range(4, 100)]
     public int numberOfSquadMembers = 20;
     [Range(1, 20)]
     public int numberOfSquads = 1;
     [Range(0, 4)]
     public int columns = 4;
     public int gaps = 10;
     public int circleRadius = 10;
     public float yOffset = 0;
     [Range(3, 50)]
     public float moveSpeed = 3;
     [Range(3, 50)]
     public float rotateSpeed = 1;
     public float threshold = 0.1f;
     public bool randomSpeed = false;
     [Range(1, 100)]
     public int randSpeedMin = 1;
     [Range(1, 100)]
     public int randSpeedMax = 1;
     public bool startRandomFormation = false;
     public string currentFormation;
 
     private Formation formation;
     private List<Quaternion> quaternions = new List<Quaternion>();
     private List<Vector3> newpositions = new List<Vector3>();
     private bool move = false;
     private bool squareFormation = false;
     private List<GameObject> squadMembers = new List<GameObject>();
     private float[] step;
     private int[] randomSpeeds;
     private int index = 0;
     private int numofobjects = 0;
 
     // Use this for initialization
     void Start()
     {
         numofobjects = numberOfSquadMembers;
         if (startRandomFormation)
         {
             formation = (Formation)UnityEngine.Random.Range(0, Enum.GetNames(typeof(Formation)).Length);
         }
         else
         {
             formation = Formation.Square;
         }
         currentFormation = formation.ToString();
         ChangeFormation();
 
         foreach (Transform child in gameObject.transform)
         {
             if (child.tag == "Squad Member")
                 squadMembers.Add(child.gameObject);
         }
 
         randomSpeeds = RandomNumbers(randSpeedMin, randSpeedMax, squadMembers.Count);
         step = new float[squadMembers.Count];
     }
 
     // Update is called once per frame
     void Update()
     {
         if (numofobjects != numberOfSquadMembers)
         {
             numofobjects = 0;
 
             numofobjects = numberOfSquadMembers;
             squadMembers = new List<GameObject>();
 
             FormationSquare();
         }
 
         if (Input.GetKeyDown(KeyCode.F))
         {
             randomSpeeds = RandomNumbers(randSpeedMin, randSpeedMax, squadMembers.Count);
             foreach (int speedV in randomSpeeds)
             {
                 if (index == randomSpeeds.Length)
                     index = 0;
 
                 step[index] = speedV * Time.deltaTime;
                 index++;
             }
 
             ChangeFormation();
         }
 
         if (move == true)
         {
             MoveToNextFormation();
         }
     }
 
     private void ChangeFormation()
     {
         switch (formation)
         {
             case Formation.Square:
                 FormationSquare();
                 break;
 
             case Formation.Circle:
                 FormationCircle();
                 break;
         }
     }
 
     private Vector3 FormationSquarePositionCalculation(int index) // call this func for all your objects
     {
         float posX = (index % columns) * gaps;
         float posY = (index / columns) * gaps;
         return new Vector3(posX, posY);
     }
 
     private void FormationSquare()
     {
         //newpositions = new List<Vector3>();
         quaternions = new List<Quaternion>();
 
         Transform go = squadMemeberPrefab;
 
         for (int i = 0; i < numofobjects; i++)
         {
             if (squadMembers.Count == 0)
                 go = Instantiate(squadMemeberPrefab);
 
             Vector3 pos = FormationSquarePositionCalculation(i);
 
             if (newpositions.Count > 0)
             {
                 go.position = new Vector3(newpositions[newpositions.Count -1].x + pos.x, 0, newpositions[newpositions.Count - 1].y + pos.y);
             }
             else
             {
                 go.position = new Vector3(transform.position.x + pos.x, 0, transform.position.y + pos.y);
             }
             go.Rotate(new Vector3(0, -90, 0));
             go.tag = "Squad Member";
             go.transform.parent = gameObject.transform;
             newpositions.Add(go.transform.position);
         }
         move = true;
         squareFormation = true;
         formation = Formation.Circle;
     }
 
     private Vector3 FormationCirclePositionCalculation(Vector3 center, float radius, int index, float angleIncrement)
     {
         float ang = index * angleIncrement;
         Vector3 pos;
         pos.x = center.x + radius * Mathf.Sin(ang * Mathf.Deg2Rad);
         pos.z = center.z + radius * Mathf.Cos(ang * Mathf.Deg2Rad);
         pos.y = center.y;
         return pos;
     }
 
     private void FormationCircle()
     {
         newpositions = new List<Vector3>();
         quaternions = new List<Quaternion>();
 
         Vector3 center = transform.position;
         float radius = (float)circleRadius / 2;
         float angleIncrement = 360 / (float)numberOfSquadMembers;
         for (int i = 0; i < numberOfSquadMembers; i++)
         {
             Vector3 pos = FormationCirclePositionCalculation(center, radius, i, angleIncrement);
 
             var rot = Quaternion.LookRotation(center - pos);
             pos.y = Terrain.activeTerrain.SampleHeight(pos);
             pos.y = pos.y + yOffset;
             newpositions.Add(pos);
             quaternions.Add(rot);
         }
         move = true;
         squareFormation = false;
         formation = Formation.Square;
     }
 
     private void MoveToNextFormation()
     {
         if (randomSpeed == false)
         {
             step[0] = moveSpeed * Time.deltaTime;
         }
 
         for (int i = 0; i < squadMembers.Count; i++)
         {
             squadMembers[i].transform.LookAt(newpositions[i]);
             if (randomSpeed == true)
             {
                 squadMembers[i].transform.position =
             Vector3.MoveTowards(squadMembers[i].transform.position, newpositions[i], step[i]);
             }
             else
             {
                 squadMembers[i].transform.position =
                 Vector3.MoveTowards(squadMembers[i].transform.position, newpositions[i], step[0]);
             }
             if (Vector3.Distance(squadMembers[i].transform.position, newpositions[i]) < threshold)
             {
                 if (squareFormation == true)
                 {
                     Vector3 degrees = new Vector3(0, 0, 0);
                     Quaternion quaternion = Quaternion.Euler(degrees);
                     squadMembers[i].transform.rotation = Quaternion.Slerp(squadMembers[i].transform.rotation, quaternion, rotateSpeed * Time.deltaTime);
                 }
                 else
                 {
                     squadMembers[i].transform.rotation = Quaternion.Slerp(squadMembers[i].transform.rotation, quaternions[i], rotateSpeed * Time.deltaTime);
                 }
             }
         }
     }
 
     private static int[] RandomNumbers(int min, int max, int howMany)
     {
         int[] myNumbers = new int[howMany];
 
         for (int i = 0; i < howMany; i++)
         {
             myNumbers[i] = UnityEngine.Random.Range(min, max);
         }
 
         return myNumbers;
     }
 }
 

Since the code is a bit long I will also show the places where the problem is: In the Update:

 if (numofobjects != numberOfSquadMembers)
         {
             numofobjects = 0;
 
             numofobjects = numberOfSquadMembers;
             squadMembers = new List<GameObject>();
 
             FormationSquare();
         }

For example numberOfSquadMembers value is 7 Now I change it to 8 Now numofobjects is 8 And it's going to the FormationSquare method:

 private Vector3 FormationSquarePositionCalculation(int index) // call this func for all your objects
     {
         float posX = (index % columns) * gaps;
         float posY = (index / columns) * gaps;
         return new Vector3(posX, posY);
     }
 
     private void FormationSquare()
     {
         //newpositions = new List<Vector3>();
         quaternions = new List<Quaternion>();
 
         Transform go = squadMemeberPrefab;
 
         for (int i = 0; i < numofobjects; i++)
         {
             if (squadMembers.Count == 0)
                 go = Instantiate(squadMemeberPrefab);
 
             Vector3 pos = FormationSquarePositionCalculation(i);
 
             if (newpositions.Count > 0)
             {
                 go.position = new Vector3(newpositions[newpositions.Count -1].x + pos.x, 0, newpositions[newpositions.Count - 1].y + pos.y);
             }
             else
             {
                 go.position = new Vector3(transform.position.x + pos.x, 0, transform.position.y + pos.y);
             }
             go.Rotate(new Vector3(0, -90, 0));
             go.tag = "Squad Member";
             go.transform.parent = gameObject.transform;
             newpositions.Add(go.transform.position);
         }
         move = true;
         squareFormation = true;
         formation = Formation.Circle;
     }

In the FormationSquare mode before I used to make new instance for newpositions List but now my logic say to keep the positions all the time and when creating new squad member/s to add it to the last position of the formation. But also to keep the formation shape.

But what it does now it first adding much more objects. If numofobjects is 8 it will not add new 8 but more. Second problem it's adding the new once on the old once positions so in the end there are places there is 2 or 3 objects at the same position. But I want it to add the new once to last position/s so the formation square will get bigger.

Same idea with the circle formation. I didn't do it yet not sure how but if it's in the circle formation mode make the circle bigger show the current objects moving a bit to the sides or backward and make the circle bigger for the new once.

The main goal is when changing the numberOfSquadMembers while the game is running to update the currently formation.

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
0

Answer by madks13 · Jun 28, 2018 at 02:32 PM

You forgot to clear the lists before adding. Also, you wrote :

              if (squadMembers.Count == 0)
                  go = Instantiate(squadMemeberPrefab);

Which means, if squadMembers.Count != 0, you keep using the prefab as "go".

Edit : i want to give a suggestion :

Given that the only thing changing between formations is poisitions + rotations, and that you can base the number of GameObjects on those, you might want to first only calculate position + rotation, then check if those changed, and if they did, update the game objects.

In pseudo-code :

 var newpos = List CalculateFormation(paramaters);
 If (newpos.count != pos.count || ComparePos(pos, newPos))
 {
     UpdateSquad(parameters);
 } 

The answer is too long with the code. Maybe in here it will work :

Here is an example of implementation. Keep in mind i removed anything unnecessary for the example, and the code is not optimised, it IS an example :

     using System;
     using System.Collections;
     using System.Collections.Generic;
     using System.Linq;
     using UnityEngine;
 
     public enum Formation
     {
         Unknown,
         Square,
         Circle,
         Triangle
     }
 
     public class SquadFormation : MonoBehaviour
     {
         [Header("Main Settings")]
         [Space(5)]
         public Transform squadMemeberPrefab;
         [Range(4, 100)]
         public int numberOfSquadMembers = 20;
         [Range(1, 20)]
         public int numberOfSquads = 1;
         [Range(0, 4)]
         public int columns = 4;
         public int gaps = 10;
         public int circleRadius = 10;
         public float yOffset = 0;
         [Range(3, 50)]
         public float moveSpeed = 3;
         [Range(3, 50)]
         public float rotateSpeed = 1;
         public float threshold = 0.1f;
         public bool randomSpeed = false;
         [Range(1, 100)]
         public int randSpeedMin = 1;
         [Range(1, 100)]
         public int randSpeedMax = 1;
         public bool startRandomFormation = false;
 
         //This will allow the field to be shown in editor while remaining private
         [SerializeField]
         private Formation formation;
         private List<PositionInformation> positionInformations = new List<PositionInformation>();
         private List<GameObject> squadMembers = new List<GameObject>();
 
         // Use this for initialization
         void Start()
         {
             if (startRandomFormation)
             {
                 formation = (Formation)UnityEngine.Random.Range(0, Enum.GetNames(typeof(Formation)).Length);
             }
             else
             {
                 formation = Formation.Square;
             }
             ChangeFormation();
 
             foreach (Transform child in gameObject.transform)
             {
                 if (child.tag == "Squad Member")
                     squadMembers.Add(child.gameObject);
             }
         }
 
         void Update()
         {
             if (Input.GetKeyDown(KeyCode.F))
             {
                 ChangeFormation();
             }
         }
 
         private void ChangeFormation()
         {
             switch (formation)
             {
                 case Formation.Square:
                     UpdateFormation(new SquareFormationParameters
                     {
                         Formation = formation,
                         SquadSize = numberOfSquadMembers
                     }.CalculateFormation());
                     break;
 
                 case Formation.Circle:
                     UpdateFormation(new CircleFormationParameters
                     {
                         Formation = formation,
                         SquadSize = numberOfSquadMembers,
                         Radius = circleRadius
                     }.CalculateFormation());
                     break;
             }
         }
 
         private void UpdateFormation(IEnumerable<PositionInformation> newPositions)
         {
             //Not checking a list with 0 elements in case all squad members are dead
             if (newPositions == null)
             {
                 return;
             }
 
             List<GameObject> updatedSquad = new List<GameObject>();
 
             foreach (var posInfo in newPositions)
             {
                 Transform sm = null;
                 //You can try to find squad members closest to the new position
                 //For the sake of simplicity, we simply assign squad members per new position
                 if (squadMembers.Count > 0)
                 {
                     sm = squadMembers.First().transform;
                     squadMembers.Remove(sm.gameObject);
                 }
                 else
                 {
                     sm = Instantiate(squadMemeberPrefab);
                 }
 
                 sm.position = posInfo.Position;
                 sm.rotation = posInfo.Rotation;
                 updatedSquad.Add(sm.gameObject);
             }
             //Cleanup in case updated squad size < old squad size
             if (squadMembers.Count > 0)
             {
                 GameObject sm = null;
                 while (squadMembers.Count > 0)
                 {
                     sm = squadMembers[0];
                     squadMembers.RemoveAt(0);
                     Destroy(sm);
                     sm = null;
                 }
             }
 
         }
     }
 
     public class PositionInformation
     {
         public Vector3 Position { get; set; }
         public Quaternion Rotation { get; set; }
 
         //Custom Equals methods for custom classes are good practice
         public override bool Equals(object obj)
         {
             var other = obj as PositionInformation;
 
             if (other == null) return false;
             if (other.GetType() != GetType()) return false;
 
             if (ReferenceEquals(this, null)) return false;
             if (ReferenceEquals(this, obj)) return true;
 
             return Position == other.Position && Rotation == other.Rotation;
         }
 
         //This is just an example, adapt to what you need or want
         public override int GetHashCode()
         {
             return (Rotation.GetHashCode() * Position.GetHashCode());
         }
     }
 
 
     public class FormationBaseParameters
     {
         public Formation Formation { get; set; }
         public int SquadSize { get; set; }
     }
 
     public class SquareFormationParameters : FormationBaseParameters
     {
         //Add square apecific parameters
     }
 
     public class CircleFormationParameters : FormationBaseParameters
     {
         public float Radius { get; set; }
         //Other circle specific parameters
     }
 
     public static class Formations
     {
         public static List<PositionInformation> CalculateFormation<T>(this T parameters) where T : FormationBaseParameters
         {
             List<PositionInformation> result = null;
             switch (parameters.Formation)
             {
                 case Formation.Unknown:
                     break;
                 case Formation.Square:
                     result = CalculateFormationSquare(parameters as SquareFormationParameters);
                     break;
                 case Formation.Circle:
                     result = CalculateFormationCircle(parameters as CircleFormationParameters);
                     break;
                 case Formation.Triangle:
                     //Same for all formations
                     break;
                 default:
                     break;
             }
 
             return result;
         }
 
         private static List<PositionInformation> CalculateFormationSquare(SquareFormationParameters parameters)
         {
             List<PositionInformation> result = null;
 
             if (parameters != null)
             {
                 result = new List<PositionInformation>();
                 //Calculate all squad members positions and rotations
             }
 
             return result;
         }
 
         private static List<PositionInformation> CalculateFormationCircle(CircleFormationParameters parameters)
         {
             List<PositionInformation> result = null;
 
             if (parameters != null)
             {
                 result = new List<PositionInformation>();
                 //Calculate all squad members positions and rotations
             }
 
             return result;
         }
     }
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 haimmoshe · Jun 28, 2018 at 08:18 PM 0
Share

Hi,

Thank you for the ideas and suggestions. $$anonymous$$aybe you can show me or give some leading about how to separate the code to some classes or scripts ?

For example all the Formations code in once class and the main engine the manager script will handle each formation. Something like that. So it will be much easier to access each formation.

avatar image madks13 haimmoshe · Jun 29, 2018 at 09:31 AM 0
Share

Since answering here has character number limitations, i answered in my main answer.

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

559 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

Related Questions

How can I check if a object in the hierarchy have been destroyed using EditorWindow type script ? 1 Answer

Can someone please help me find out what wrong with my code. 0 Answers

Enabling & Disabling Script via On Click 1 Answer

Reverse memcpy for NativeArray? 0 Answers

The laser problems 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