///<summary> /// When called, fills all the lists and does a ManualUnFocus to deactivate all useless mesh renderers. ///</summary> ///<param name="e">The event's instance</param> private void OnImportFinished(ImportFinishedEvent e) { if (isDeleted) { return; } InitHandler(); if (GameManager.gm.currentItems.Contains(gameObject)) { UpdateChildMeshRenderers(true, true); transform.GetChild(0).GetComponent <Renderer>().enabled = true; return; } OObject selectionReferent = GameManager.gm.currentItems.Count > 0 ? GameManager.gm.currentItems[0].GetComponent <OObject>()?.referent : null; if (GetComponent <OObject>().category != "device" && selectionReferent != GetComponent <OObject>().referent) { UpdateChildMeshRenderersRec(false); } else if (selectionReferent == GetComponent <OObject>().referent) { if (!GameManager.gm.currentItems.Contains(gameObject) && !GameManager.gm.currentItems.Contains(transform.parent.gameObject)) { ToggleCollider(gameObject, false); UpdateOwnMeshRenderers(false); UpdateChildMeshRenderers(false); } if (GameManager.gm.currentItems.Contains(transform.parent.gameObject)) { print("##" + name); UpdateChildMeshRenderers(false); } } }
///<summary> /// Add selected object to currentItems if not in it, else remove it. ///</summary> public async Task UpdateCurrentItems(GameObject _obj) { previousItems = currentItems.GetRange(0, currentItems.Count); if (currentItems[0].GetComponent <OgreeObject>().category != _obj.GetComponent <OgreeObject>().category || currentItems[0].transform.parent != _obj.transform.parent) { AppendLogLine("Multiple selection should be same type of objects and belong to the same parent.", true, eLogtype.warning); return; } if (currentItems.Contains(_obj)) { AppendLogLine($"Remove {_obj.name} from selection.", true, eLogtype.success); currentItems.Remove(_obj); if (currentItems.Count == 0) { OObject oObject = _obj.GetComponent <OObject>(); if (oObject != null) { await oObject.LoadChildren("0"); } } else { bool unloadChildren = true; OObject currentDeselected = _obj.GetComponent <OObject>(); //Checking all of the previously selected objects foreach (GameObject previousObj in currentItems) { OObject previousSelected = previousObj.GetComponent <OObject>(); //Are the previous and current selection both a rack or smaller and part of the same rack ? if (previousSelected != null && currentDeselected != null && previousSelected.referent != null && previousSelected.referent == currentDeselected.referent) { unloadChildren = false; } } //if no to the previous question and previousSelected is a rack or smaller, unload its children if (unloadChildren) { await currentDeselected.LoadChildren("0"); } } } else { await _obj.GetComponent <OgreeObject>().LoadChildren("1"); AppendLogLine($"Select {_obj.name}.", true, eLogtype.success); currentItems.Add(_obj); } EventManager.Instance.Raise(new OnSelectItemEvent()); }
///<summary> /// When called checks if he is the GameObject focused on and if true activates all of his child's mesh renderers. ///</summary> ///<param name="e">The event's instance</param> private void OnSelectItem(OnSelectItemEvent e) { if (isDeleted) { return; } if (GameManager.gm.currentItems.Contains(gameObject)) { // We manage all collider and renderer changes due to the selection isSelected = true; ToggleCollider(gameObject, false); UpdateParentRenderers(gameObject, false); if (GetComponent <OObject>().category == "rack") { UpdateOwnMeshRenderers(false); } UpdateChildMeshRenderers(true, true); transform.GetChild(0).GetComponent <Renderer>().enabled = true; return; } // If this one is part of it and is in a rack which is not the parent of a selected object we display it again if (GameManager.gm.previousItems.Contains(gameObject)) { isSelected = false; // Parent racks of previously selected objects OObject selectionParentRack = GameManager.gm.currentItems.Count > 0 ? GameManager.gm.currentItems[0].GetComponent <OObject>()?.referent : null; OObject parentRack = GetComponent <OObject>().referent; if (selectionParentRack != parentRack) { ToggleCollider(gameObject, false); ResetToRack(); } else { if (!GameManager.gm.currentItems.Contains(transform.parent.gameObject)) { UpdateOwnMeshRenderers(false); UpdateChildMeshRenderers(false); } else { UpdateChildMeshRenderers(false); } } } // if (GameManager.gm.currentItems.Contains(transform.parent.gameObject) && transform.parent.GetComponent<OObject>()) // GetComponent<OgreeObject>().SetBaseTransform(transform.localPosition, transform.localRotation, transform.localScale); }
///<summary> /// Move the camera in front of given _target. ///</summary> ///<param name="_target">The object to look at</param> private void MoveToObject(Transform _target) { transform.position = _target.position; float offset = 3f; OObject obj = _target.GetComponent <OObject>(); if (obj && obj.category == "rack") { offset = JsonUtility.FromJson <Vector2>(obj.attributes["size"]).y / 45; } else if (obj && obj.category == "device") { offset = JsonUtility.FromJson <Vector2>(obj.attributes["size"]).y / 450; } switch ((int)_target.eulerAngles.y) { case 0: // Debug.Log("0"); transform.position += new Vector3(0, 0, offset); transform.eulerAngles = new Vector3(0, 180, 0); break; case 90: // Debug.Log("90"); transform.position += new Vector3(offset, 0, 0); transform.eulerAngles = new Vector3(0, 270, 0); break; case 180: // Debug.Log("180"); transform.position += new Vector3(0, 0, -offset); transform.eulerAngles = new Vector3(0, 0, 0); break; case 270: // Debug.Log("270"); transform.position += new Vector3(-offset, 0, 0); transform.eulerAngles = new Vector3(0, 90, 0); break; default: Debug.Log("default: " + _target.rotation.y); break; } }
public override void Process(NetMessage msg) { LoadNetworkObject(msg.dissectible); List <uint> NetIDs = JsonConvert.DeserializeObject <List <uint> >(msg.JsonData); LoadMultipleObjects(NetIDs.ToArray()); List <BodyPart> BodyParts = new List <BodyPart>(); foreach (var OObject in NetworkObjects) { if (OObject == null) { continue; } BodyParts.Add(OObject.GetComponent <BodyPart>()); } NetworkObject.GetComponent <Dissectible>().ReceivedSurgery(BodyParts); }
///<summary> /// Update the OObject attributes with given SApiObject. ///</summary> ///<param name="_src">The SApiObject used to update attributes</param> public override void UpdateFromSApiObject(SApiObject _src) { name = _src.name; id = _src.id; parentId = _src.parentId; category = _src.category; if (domain != _src.domain) { domain = _src.domain; UpdateColorByTenant(); } description = _src.description; if (attributes.ContainsKey("temperature") && _src.attributes.ContainsKey("temperature") && attributes["temperature"] != _src.attributes["temperature"]) { SetTemperature(_src.attributes["temperature"]); } else if (!attributes.ContainsKey("temperature") && _src.attributes.ContainsKey("temperature")) { SetTemperature(_src.attributes["temperature"]); } else if (attributes.ContainsKey("temperature") && !_src.attributes.ContainsKey("temperature")) { Destroy(transform.Find("sensor").gameObject); } attributes = _src.attributes; if (transform.parent?.GetComponent <OgreeObject>().category == "room") { referent = this; } else if (transform.parent.GetComponent <OObject>().referent != null) { referent = transform.parent.GetComponent <OObject>().referent; } else { referent = null; } }
///<summary> /// Save current object and change the CLI idle text. ///</summary> ///<param name="_obj">The object to save. If null, set default text</param> public async Task SetCurrentItem(GameObject _obj) { try { previousItems = currentItems.GetRange(0, currentItems.Count); ////////////////////////////////////////////////////////// //Should the previous selection's children be unloaded ?// ////////////////////////////////////////////////////////// //if we are selecting, we don't want to unload children in the same rack as the selected object if (_obj != null) { OObject currentSelected = _obj.GetComponent <OObject>(); //Checking all of the previously selected objects foreach (GameObject previousObj in currentItems) { bool unloadChildren = true; OObject previousSelected = previousObj.GetComponent <OObject>(); //Are the previous and current selection both a rack or smaller and part of the same rack ? if (previousSelected != null && currentSelected != null && previousSelected.referent != null && previousSelected.referent == currentSelected.referent) { unloadChildren = false; } //if no to the previous question and previousSelected is a rack or smaller, unload its children if (unloadChildren && previousSelected != null) { if (previousSelected.referent) { await previousSelected.referent.LoadChildren("0"); } if (previousSelected.category != "rack") { previousItems.Remove(previousObj); if (previousSelected.referent && !previousItems.Contains(previousSelected.referent.gameObject)) { previousItems.Add(previousSelected.referent.gameObject); } } } } } else { foreach (GameObject previousObj in currentItems) { OObject oObject = previousObj.GetComponent <OObject>(); if (oObject != null) { await oObject.LoadChildren("0"); } } } //Clear current selection currentItems.Clear(); if (_obj) { await _obj.GetComponent <OgreeObject>().LoadChildren("1"); AppendLogLine($"Select {_obj.name}.", true, eLogtype.success); currentItems.Add(_obj); } else { AppendLogLine("Empty selection.", true, eLogtype.success); } EventManager.Instance.Raise(new OnSelectItemEvent()); } catch (System.Exception _e) { Debug.LogError(_e); } }
///<summary> /// Deserialize a SInteract command and run it. ///</summary> ///<param name="_data">The serialized command to execute</param> private void InteractWithObject(string _data) { List <string> usableParams; SInteract command = JsonConvert.DeserializeObject <SInteract>(_data); OgreeObject obj = Utils.GetObjectById(command.id).GetComponent <OgreeObject>(); switch (obj.category) { case "room": Room room = (Room)obj; usableParams = new List <string>() { "tilesName", "tilesColor" }; if (usableParams.Contains(command.param)) { room.SetAttribute(command.param, command.value); } else { Debug.LogWarning("Incorrect room interaction"); } break; case "rack": Rack rack = (Rack)obj; usableParams = new List <string>() { "label", "labelFont", "alpha", "slots", "localCS", "U" }; if (usableParams.Contains(command.param)) { rack.SetAttribute(command.param, command.value); } else { Debug.LogWarning("Incorrect rack interaction"); } break; case "device": OObject device = (OObject)obj; usableParams = new List <string>() { "label", "labelFont", "alpha", "slots", "localCS" }; if (usableParams.Contains(command.param)) { device.SetAttribute(command.param, command.value); } else { Debug.LogWarning("Incorrect device interaction"); } break; default: GameManager.gm.AppendLogLine("Unknown category to interact with", true, eLogtype.warning); break; } }
///<summary> /// Deserialize given SApiObject and apply modification to corresponding object. ///</summary> ///<param name="_input">The SApiObject to deserialize</param> private void ModifyObject(string _input) { SApiObject newData = JsonConvert.DeserializeObject <SApiObject>(_input); OgreeObject obj = Utils.GetObjectById(newData.id).GetComponent <OgreeObject>(); // Case domain for all OgreeObjects bool tenantColorChanged = false; if (newData.category == "tenant" && obj.attributes["color"] != newData.attributes["color"]) { tenantColorChanged = true; } // Case color/temperature for racks & devices if (newData.category == "rack" || newData.category == "device") { OObject item = (OObject)obj; if (newData.attributes.ContainsKey("color")) { if ((obj.attributes.ContainsKey("color") && obj.attributes["color"] != newData.attributes["color"]) || !item.attributes.ContainsKey("color")) { item.SetColor(newData.attributes["color"]); } } if (newData.attributes.ContainsKey("temperature")) { if ((obj.attributes.ContainsKey("temperature") && obj.attributes["temperature"] != newData.attributes["temperature"]) || !item.attributes.ContainsKey("temperature")) { item.SetTemperature(newData.attributes["temperature"]); } } } // Case of a separator/areas modification in a room if (newData.category == "room") { Room room = (Room)obj; if (newData.attributes.ContainsKey("separators")) { if ((room.attributes.ContainsKey("separators") && room.attributes["separators"] != newData.attributes["separators"]) || !room.attributes.ContainsKey("separators")) { foreach (Transform wall in room.walls) { if (wall.name.Contains("separator")) { Object.Destroy(wall.gameObject); } } List <ReadFromJson.SSeparator> separators = JsonConvert.DeserializeObject <List <ReadFromJson.SSeparator> >(newData.attributes["separators"]); foreach (ReadFromJson.SSeparator sep in separators) { room.AddSeparator(sep); } } } if (newData.attributes.ContainsKey("reserved")) { if ((room.attributes.ContainsKey("reserved") && room.attributes["reserved"] != newData.attributes["reserved"]) || !room.attributes.ContainsKey("reserved")) { SMargin reserved = JsonUtility.FromJson <SMargin>(newData.attributes["reserved"]); SMargin technical = JsonUtility.FromJson <SMargin>(newData.attributes["technical"]); room.SetAreas(reserved, technical); } } } obj.UpdateFromSApiObject(newData); if (tenantColorChanged) { EventManager.Instance.Raise(new UpdateTenantEvent { name = newData.name }); } }
///<summary> /// Generate a corridor (from GameManager.labeledBoxModel) with defined corners and color. ///</summary> ///<param name="_co">The corridor data to apply</param> ///<param name="_parent">The parent of the created corridor. Leave null if _co contains the parendId</param> ///<returns>The created corridor</returns> public OObject CreateCorridor(SApiObject _co, Transform _parent = null) { Transform parent = Utils.FindParent(_parent, _co.parentId); if (!parent || parent.GetComponent <OgreeObject>().category != "room") { GameManager.gm.AppendLogLine($"Parent room not found", true, eLogtype.error); return(null); } string hierarchyName = $"{parent.GetComponent<OgreeObject>().hierarchyName}.{_co.name}"; if (GameManager.gm.allItems.Contains(hierarchyName)) { GameManager.gm.AppendLogLine($"{hierarchyName} already exists.", true, eLogtype.warning); return(null); } string roomHierarchyName = parent.GetComponent <OgreeObject>().hierarchyName; string[] rackNames = _co.attributes["content"].Split(','); Transform lowerLeft = GameManager.gm.FindByAbsPath($"{roomHierarchyName}.{rackNames[0]}")?.transform; Transform upperRight = GameManager.gm.FindByAbsPath($"{roomHierarchyName}.{rackNames[1]}")?.transform; if (lowerLeft == null || upperRight == null) { GameManager.gm.AppendLogLine($"{rackNames[0]} or {rackNames[1]} doesn't exist", true, eLogtype.error); return(null); } float maxHeight = lowerLeft.GetChild(0).localScale.y; if (upperRight.GetChild(0).localScale.y > maxHeight) { maxHeight = upperRight.GetChild(0).localScale.y; } GameObject newCo = Instantiate(GameManager.gm.labeledBoxModel); newCo.name = _co.name; newCo.transform.parent = parent; float x = upperRight.localPosition.x - lowerLeft.localPosition.x; float z = upperRight.localPosition.z - lowerLeft.localPosition.z; if (lowerLeft.GetComponent <Rack>().attributes["orientation"] == "front" || lowerLeft.GetComponent <Rack>().attributes["orientation"] == "rear") { x += (upperRight.GetChild(0).localScale.x + lowerLeft.GetChild(0).localScale.x) / 2; z -= (upperRight.GetChild(0).localScale.z + lowerLeft.GetChild(0).localScale.z) / 2; } else { x += (upperRight.GetChild(0).localScale.z + lowerLeft.GetChild(0).localScale.z) / 2; z -= (upperRight.GetChild(0).localScale.x + lowerLeft.GetChild(0).localScale.x) / 2; } newCo.transform.GetChild(0).localScale = new Vector3(x, maxHeight, z); newCo.transform.localEulerAngles = new Vector3(0, 180, 0); newCo.transform.localPosition = new Vector3(lowerLeft.localPosition.x, maxHeight / 2, lowerLeft.localPosition.z); float xOffset = (newCo.transform.GetChild(0).localScale.x - lowerLeft.GetChild(0).localScale.x) / 2; float zOffset = (newCo.transform.GetChild(0).localScale.z + lowerLeft.GetChild(0).localScale.z) / 2; newCo.transform.localPosition += new Vector3(xOffset, 0, zOffset); OObject co = newCo.AddComponent <OObject>(); co.UpdateFromSApiObject(_co); newCo.transform.GetChild(0).GetComponent <Renderer>().material = GameManager.gm.alphaMat; Material mat = newCo.transform.GetChild(0).GetComponent <Renderer>().material; mat.color = new Color(mat.color.r, mat.color.g, mat.color.b, 0.5f); if (_co.attributes["temperature"] == "cold") { co.SetAttribute("color", "000099"); } else { co.SetAttribute("color", "990000"); } newCo.GetComponent <DisplayObjectData>().PlaceTexts("top"); newCo.GetComponent <DisplayObjectData>().SetLabel("#name"); string hn = co.UpdateHierarchyName(); GameManager.gm.allItems.Add(hn, newCo); return(co); }
///<summary> /// Instantiate a deviceModel or a deviceTemplate (from GameManager) and apply given data to it. ///</summary> ///<param name="_dv">The device data to apply</param> ///<param name="_parent">The parent of the created device. Leave null if _dv contains the parendId</param> ///<returns>The created Device</returns> public OObject CreateDevice(SApiObject _dv, Transform _parent = null) { // Check parent & parent category Transform parent = Utils.FindParent(_parent, _dv.parentId); if (!parent || parent.GetComponent <OObject>() == null) { GameManager.gm.AppendLogLine($"Device must be child of a Rack or another Device", true, eLogtype.error); return(null); } // Check parent for subdevice if (parent.GetComponent <Rack>() == null && (string.IsNullOrEmpty(_dv.attributes["slot"]) || string.IsNullOrEmpty(_dv.attributes["template"]))) { GameManager.gm.AppendLogLine("A sub-device needs to be declared with a parent's slot and a template", true, eLogtype.error); return(null); } // Check if parent not hidden in a group if (parent.gameObject.activeSelf == false) { GameManager.gm.AppendLogLine("The parent object must be active (not hidden in a group)", true, eLogtype.error); return(null); } // Check if unique hierarchyName string hierarchyName = $"{parent.GetComponent<OgreeObject>().hierarchyName}.{_dv.name}"; if (GameManager.gm.allItems.Contains(hierarchyName)) { GameManager.gm.AppendLogLine($"{hierarchyName} already exists.", true, eLogtype.warning); return(null); } // Check template if (!string.IsNullOrEmpty(_dv.attributes["template"]) && !GameManager.gm.objectTemplates.ContainsKey(_dv.attributes["template"])) { GameManager.gm.AppendLogLine($"Unknown template \"{_dv.attributes["template"]}\"", true, eLogtype.error); return(null); } // Check slot Transform slot = null; if (!string.IsNullOrEmpty(_dv.attributes["slot"])) { List <Slot> takenSlots = new List <Slot>(); int i = 0; float max; if (string.IsNullOrEmpty(_dv.attributes["template"])) { max = float.Parse(_dv.attributes["sizeU"]); } else { max = float.Parse(GameManager.gm.objectTemplates[_dv.attributes["template"]].GetComponent <OgreeObject>().attributes["height"]) / 1000 / GameManager.gm.uSize; } foreach (Transform child in parent) { if ((child.name == _dv.attributes["slot"] || (i > 0 && i < max)) && child.GetComponent <Slot>()) { takenSlots.Add(child.GetComponent <Slot>()); i++; } } if (takenSlots.Count > 0) { foreach (Slot s in takenSlots) { s.SlotTaken(true); } slot = takenSlots[0].transform; } else { GameManager.gm.AppendLogLine($"Slot {_dv.attributes["slot"]} not found in {parent.name}", true, eLogtype.error); return(null); } } // Generate device GameObject newDevice; Vector2 size; float height; if (string.IsNullOrEmpty(_dv.attributes["template"])) { newDevice = GenerateBasicDevice(parent, Utils.ParseDecFrac(_dv.attributes["height"]), slot); Vector3 boxSize = newDevice.transform.GetChild(0).localScale; size = new Vector2(boxSize.x, boxSize.z); height = boxSize.y; } else { newDevice = GenerateTemplatedDevice(parent, _dv.attributes["template"]); OgreeObject tmp = newDevice.GetComponent <OgreeObject>(); size = JsonUtility.FromJson <Vector2>(tmp.attributes["size"]) / 1000; height = float.Parse(tmp.attributes["height"]) / 1000; } // Place the device if (!string.IsNullOrEmpty(_dv.attributes["slot"])) { newDevice.transform.localEulerAngles = slot.localEulerAngles; newDevice.transform.localPosition = slot.localPosition; if (height > slot.GetChild(0).localScale.y) { newDevice.transform.localPosition += new Vector3(0, height / 2 - GameManager.gm.uSize / 2, 0); } float deltaZ = slot.GetChild(0).localScale.z - size.y; switch (_dv.attributes["orientation"]) { case "front": newDevice.transform.localPosition += new Vector3(0, 0, deltaZ / 2); break; case "rear": newDevice.transform.localPosition -= new Vector3(0, 0, deltaZ / 2); newDevice.transform.localEulerAngles += new Vector3(0, 180, 0); break; case "frontflipped": newDevice.transform.localPosition += new Vector3(0, 0, deltaZ / 2); newDevice.transform.localEulerAngles += new Vector3(0, 0, 180); break; case "rearflipped": newDevice.transform.localPosition -= new Vector3(0, 0, deltaZ / 2); newDevice.transform.localEulerAngles += new Vector3(180, 0, 0); break; } // if slot, color Material mat = newDevice.transform.GetChild(0).GetComponent <Renderer>().material; Color slotColor = slot.GetChild(0).GetComponent <Renderer>().material.color; mat.color = new Color(slotColor.r, slotColor.g, slotColor.b); newDevice.GetComponent <OObject>().color = mat.color; } else { newDevice.transform.localEulerAngles = Vector3.zero; newDevice.transform.localPosition = new Vector3(0, (-parent.GetChild(0).localScale.y + height) / 2, 0); if (_dv.attributes.ContainsKey("posU")) { newDevice.transform.localPosition += new Vector3(0, (float.Parse(_dv.attributes["posU"]) - 1) * GameManager.gm.uSize, 0); } float deltaZ = parent.GetChild(0).localScale.z - size.y; newDevice.transform.localPosition += new Vector3(0, 0, deltaZ / 2); newDevice.GetComponent <OObject>().color = Color.white; } // Fill OObject class newDevice.name = _dv.name; OObject dv = newDevice.GetComponent <OObject>(); dv.UpdateFromSApiObject(_dv); // Set labels if (string.IsNullOrEmpty(dv.attributes["slot"])) { newDevice.GetComponent <DisplayObjectData>().PlaceTexts("frontrear"); } else { newDevice.GetComponent <DisplayObjectData>().PlaceTexts(slot?.GetComponent <Slot>().labelPos); } newDevice.GetComponent <DisplayObjectData>().SetLabel("#name"); string hn = dv.UpdateHierarchyName(); GameManager.gm.allItems.Add(hn, newDevice); if (!string.IsNullOrEmpty(_dv.attributes["template"])) { OObject[] components = newDevice.transform.GetComponentsInChildren <OObject>(); foreach (OObject comp in components) { if (comp.gameObject != newDevice) { comp.domain = dv.domain; string compHn = comp.UpdateHierarchyName(); GameManager.gm.allItems.Add(compHn, comp.gameObject); comp.referent = dv.referent; } } } return(dv); }
///<summary> /// Create a child Slot or Component object. ///</summary> ///<param name="_isSlot">Device if it's a slot or a component to create</param> ///<param name="_data">Data for Slot/Component creation</param> ///<param name="_parent">The parent of the Slot/Component</param> ///<param name="_customColors">Custom colors to use</param> private void PopulateSlot(bool _isSlot, STemplateChild _data, OgreeObject _parent, Dictionary <string, string> _customColors) { GameObject go = MonoBehaviour.Instantiate(GameManager.gm.labeledBoxModel); Vector2 parentSizeXZ = JsonUtility.FromJson <Vector2>(_parent.attributes["size"]); Vector3 parentSize = new Vector3(parentSizeXZ.x, float.Parse(_parent.attributes["height"]), parentSizeXZ.y); if (_parent.attributes["sizeUnit"] == "mm") { parentSize /= 1000; } else if (_parent.attributes["sizeUnit"] == "cm") { parentSize /= 100; } go.name = _data.location; go.transform.parent = _parent.transform; go.transform.GetChild(0).localScale = new Vector3(_data.elemSize[0], _data.elemSize[2], _data.elemSize[1]) / 1000; go.transform.localPosition = parentSize / -2; go.transform.localPosition += new Vector3(_data.elemPos[0], _data.elemPos[2], _data.elemPos[1]) / 1000; if (_data.elemOrient == "vertical") { go.transform.localEulerAngles = new Vector3(0, 0, 90); go.transform.localPosition += new Vector3(go.transform.GetChild(0).localScale.y, go.transform.GetChild(0).localScale.x, go.transform.GetChild(0).localScale.z) / 2; } else { go.transform.localEulerAngles = Vector3.zero; go.transform.localPosition += go.transform.GetChild(0).localScale / 2; } if (_isSlot) { Slot s = go.AddComponent <Slot>(); s.orient = _data.elemOrient; if (_data.attributes != null && _data.attributes.ContainsKey("factor")) { s.formFactor = _data.attributes["factor"]; } s.labelPos = _data.labelPos; go.transform.GetChild(0).GetComponent <Collider>().enabled = false; } else { OObject obj = go.AddComponent <OObject>(); obj.name = go.name; // obj.id // ?? obj.parentId = _parent.id; obj.category = "device"; obj.domain = _parent.domain; obj.description = new List <string>(); obj.attributes = new Dictionary <string, string> { ["deviceType"] = _data.type }; if (_data.attributes != null) { foreach (KeyValuePair <string, string> kvp in _data.attributes) { obj.attributes[kvp.Key] = kvp.Value; } } obj.UpdateHierarchyName(); } DisplayObjectData dod = go.GetComponent <DisplayObjectData>(); dod.PlaceTexts(_data.labelPos); dod.SetLabel("#name"); go.transform.GetChild(0).GetComponent <Renderer>().material = GameManager.gm.defaultMat; Renderer rend = go.transform.GetChild(0).GetComponent <Renderer>(); Color myColor; if (_data.color != null && _data.color.StartsWith("@")) { ColorUtility.TryParseHtmlString($"#{_customColors[_data.color.Substring(1)]}", out myColor); } else { ColorUtility.TryParseHtmlString($"#{_data.color}", out myColor); } if (_isSlot) { rend.material = GameManager.gm.alphaMat; rend.material.color = new Color(myColor.r, myColor.g, myColor.b, 0.33f); } else { rend.material.color = new Color(myColor.r, myColor.g, myColor.b, 1f); go.GetComponent <OObject>().color = rend.material.color; } }