static void ResearchPanelConstruction(GameObject source, Dictionary <DBClass, GameObject> unlockToGO, List <DBClass> sources, Advancement screen, string addFilter, float radiusMultiplier, float horizontalSpreadMultiplier) { int circleRadius = 160; float spreadAngleDistance = 360 / 20f; var r = sources; if (addFilter == "food items") { r = r.FindAll(o => FilterCooking(o)); } else if (addFilter == "nonfood items") { r = r.FindAll(o => FilterNonCooking(o)); } List <List <DBClass> > structure = new List <List <DBClass> >(); HashSet <DBClass> listed = new HashSet <DBClass>(); Dictionary <DBClass, Vector3> resourcePositions = new Dictionary <DBClass, Vector3>(); float layoutRadius = circleRadius * radiusMultiplier; float spreadDistance = spreadAngleDistance / horizontalSpreadMultiplier; int k = 0; while (listed.Count < r.Count) { k++; if (k > 10) { break; } List <DBClass> layer = new List <DBClass>(); structure.Add(layer); if (!SortingSources(r, listed, layer)) { break; } } for (var l = 0; l < structure.Count; l++) { if (l == 0) { float count = structure[l].Count; for (int i = 0; i < count; i++) { Quaternion q = Quaternion.Euler(0, 0, 360 * i / count); Vector3 dir = q * (new Vector3(0, 1, 0) * layoutRadius); DBClass res = structure[l][i]; GameObject s = GameObjectUtils.Instantiate(source, source.transform.parent); GameObject go = screen.PopulateNode(s, res); go.transform.localPosition = dir; resourcePositions[res] = dir; unlockToGO[res] = go; VectorLine vl = screen.DrawLink(go, go.transform.parent.gameObject); screen.RegisterLine(res, null, vl); DBClass resRef = Globals.GetInstanceFromDB(go.name); go.GetComponent <Button>().onClick.AddListener(delegate() { if (resRef is Resource) { screen.Click(resRef as Resource); } else if (resRef is ItemTech) { screen.Click(resRef as ItemTech); } else if (resRef is BuildingTech) { screen.Click(resRef as BuildingTech); } }); Image icon = GameObjectUtils.FindByNameGetComponent <Image>(go, "Bg"); icon.alphaHitTestMinimumThreshold = 0.5f; var st = GameObjectUtils.GetOrAddComponent <RolloverSimpleTooltip>(icon.gameObject); if (resRef is Resource) { var stRes = resRef as Resource; st.title = stRes.descriptionInfo.name; st.imageName = stRes.descriptionInfo.iconName; st.description = stRes.descriptionInfo.description; } else if (resRef is ItemTech) { var stIT = resRef as ItemTech; st.title = stIT.descriptionInfo.name; st.imageName = stIT.descriptionInfo.iconName; st.description = stIT.descriptionInfo.description; } else if (resRef is BuildingTech) { var stBT = resRef as BuildingTech; st.title = stBT.descriptionInfo.name; st.imageName = stBT.descriptionInfo.iconName; st.description = stBT.descriptionInfo.description; } } } else { List <DBClass> layer = structure[l]; while (layer.Count > 0) { DBClass res = layer[0]; if (GetParents(res) == null) { break; } List <DBClass> group = layer.FindAll(o => GetParents(o) != null && (o == res || ( GetParents(o).All(GetParents(res).Contains) && GetParents(res).All(GetParents(o).Contains) ) ) ); layer = layer.FindAll(o => !group.Contains(o)); Vector3 cumulativeOffset = Vector3.zero; int count = 0; foreach (var v in GetParents(res)) { cumulativeOffset += resourcePositions[v]; count++; } Vector3 groupDir = (cumulativeOffset / count).normalized; for (int i = 0; i < group.Count; i++) { res = group[i]; float steps = i - (group.Count - 1) * 0.5f; Quaternion q = Quaternion.Euler(0, 0, steps * spreadDistance); Vector3 dir = q * groupDir; //First radius is multiplied based on the extra settings to ensure this distance is set on screen basis //Second and further are spread by default distance dir = dir.normalized * layoutRadius + dir.normalized * circleRadius * l; GameObject s = GameObjectUtils.Instantiate(source, source.transform.parent); GameObject go = screen.PopulateNode(s, res); go.transform.localPosition = dir; resourcePositions[res] = dir; unlockToGO[res] = go; foreach (var v in GetParents(res)) { VectorLine vl = screen.DrawLink(unlockToGO[res], unlockToGO[v]); screen.RegisterLine(v, res, vl); } DBClass resRef = Globals.GetInstanceFromDB(go.name); go.GetComponent <Button>().onClick.AddListener(delegate() { if (resRef is Resource) { screen.Click(resRef as Resource); } else if (resRef is ItemTech) { screen.Click(resRef as ItemTech); } else if (resRef is BuildingTech) { screen.Click(resRef as BuildingTech); } }); Image icon = GameObjectUtils.FindByNameGetComponent <Image>(go, "Bg"); icon.alphaHitTestMinimumThreshold = 0.5f; var st = GameObjectUtils.GetOrAddComponent <RolloverSimpleTooltip>(icon.gameObject); if (resRef is Resource) { var stRes = resRef as Resource; st.title = stRes.descriptionInfo.name; st.imageName = stRes.descriptionInfo.iconName; st.description = stRes.descriptionInfo.description; } else if (resRef is ItemTech) { var stIT = resRef as ItemTech; st.title = stIT.descriptionInfo.name; st.imageName = stIT.descriptionInfo.iconName; st.description = stIT.descriptionInfo.description; } else if (resRef is BuildingTech) { var stBT = resRef as BuildingTech; st.title = stBT.descriptionInfo.name; st.imageName = stBT.descriptionInfo.iconName; st.description = stBT.descriptionInfo.description; } } } } } GameObject.Destroy(source); }