private T AddOrReplaceAsset <T>(T asset, Node node, AgXUnity.IO.AssetType type) where T : UnityEngine.Object { var existingAsset = AssetDatabase.LoadAssetAtPath <T>(FileInfo.GetAssetPath(asset)); if (existingAsset == null) { FileInfo.AddAssetToDataDirectory(asset, type); existingAsset = asset; } else { EditorUtility.CopySerialized(asset, existingAsset); } return(existingAsset); }
private Node CreateNode(NodeType type, agx.Uuid uuid, bool isRoot) { Node node = new Node() { Type = type, Uuid = uuid }; if (isRoot) { if (type == NodeType.Constraint) { m_constraintRoot.AddChild(node); } else if (type == NodeType.Material) { m_materialRoot.AddChild(node); } else if (type == NodeType.ContactMaterial) { m_contactMaterialRoot.AddChild(node); } else if (type == NodeType.Wire) { m_wireRoot.AddChild(node); } else if (type == NodeType.Cable) { m_cableRoot.AddChild(node); } else if (m_roots.FindIndex(n => n.Uuid == uuid) >= 0) { Debug.LogError("Node already present as root."); } else { m_roots.Add(node); } } m_nodeCache.Add(uuid, node); return(node); }
private void Parse(agxCollide.Geometry geometry, Node parent) { var geometryNode = GetOrCreateGeometry(geometry, parent == null); if (parent != null) { parent.AddChild(geometryNode); } foreach (var shape in geometry.getShapes()) { var shapeNode = GetOrCreateShape(shape.get()); geometryNode.AddChild(shapeNode); } if (geometry.getMaterial() != null) { var materialNode = GetOrCreateMaterial(geometry.getMaterial()); geometryNode.AddReference(materialNode); } var groupsCollection = geometry.findGroupIdCollection(); foreach (var name in groupsCollection.getNames()) { geometryNode.AddReference(new Node() { Type = NodeType.GroupId, Object = name }); } foreach (var id in groupsCollection.getIds()) { geometryNode.AddReference(new Node() { Type = NodeType.GroupId, Object = id.ToString() }); } }
private GameObject GetOrCreateGameObject(Node node) { if (node.GameObject != null) { return(node.GameObject); } node.GameObject = FileInfo.ObjectDb.GetGameObject(node.Uuid) ?? new GameObject(); node.GameObject.GetOrCreateComponent <AgXUnity.IO.Uuid>().Native = node.Uuid; // Is it safe to exit if the node has a parent? // I.e., the node has been read from an existing prefab. if (FileInfo.PrefabInstance.HasChild(node.GameObject)) { return(node.GameObject); } // Passing parents with null game objects - e.g., shapes // has geometry as parent but we're not creating objects // for geometries. Node localParent = node.Parent; while (localParent != null && localParent.GameObject == null) { localParent = localParent.Parent; } if (localParent != null) { localParent.GameObject.AddChild(node.GameObject); } else { FileInfo.PrefabInstance.AddChild(node.GameObject); } return(node.GameObject); }
private bool CreateCable(Node node) { var nativeCable = m_tree.GetCable(node.Uuid); if (nativeCable == null) { Debug.LogWarning("Unable to find native instance of cable: " + node.GameObject.name + " (UUID: " + node.Uuid.str() + ")"); return(false); } var cable = node.GameObject.GetOrCreateComponent <Cable>(); var route = cable.Route; route.Clear(); cable.RestoreLocalDataFrom(nativeCable); cable.RouteAlgorithm = Cable.RouteType.Identity; var properties = CableProperties.Create <CableProperties>().RestoreLocalDataFrom(nativeCable.getCableProperties(), nativeCable.getCablePlasticity()); properties.name = cable.name + "_properties"; cable.Properties = properties = AddOrReplaceAsset(properties, node, AgXUnity.IO.AssetType.CableProperties); for (var it = nativeCable.getSegments().begin(); !it.EqualWith(nativeCable.getSegments().end()); it.inc()) { var segment = it.get(); route.Add(segment, attachment => { if (attachment == null || attachment.getRigidBody() == null) { return(FileInfo.PrefabInstance); } var rbNode = m_tree.GetNode(attachment.getRigidBody().getUuid()); if (rbNode == null) { Debug.LogWarning("Unable to find rigid body in cable attachment."); return(FileInfo.PrefabInstance); } return(rbNode.GameObject); }); } var materials = node.GetReferences(Node.NodeType.Material); if (materials.Length > 0) { cable.Material = materials[0].Asset as ShapeMaterial; } cable.GetComponent <CableRenderer>().InitializeRenderer(); cable.GetComponent <CableRenderer>().Material = null; // Adding collision group from restored instance since the disabled pair // will be read from Space (cable.setEnableCollisions( foo, false ) will // work out of the box). var collisionGroups = cable.gameObject.GetOrCreateComponent <CollisionGroups>(); collisionGroups.AddGroup(nativeCable.getUniqueId().ToString(), false); var referencedGroups = node.GetReferences(Node.NodeType.GroupId); foreach (var group in referencedGroups) { if (group.Object is string) { collisionGroups.AddGroup(group.Object as string, false); } } return(true); }
private bool CreateWire(Node node) { var nativeWire = m_tree.GetWire(node.Uuid); if (nativeWire == null) { Debug.LogWarning("Unable to find native instance of wire: " + node.GameObject.name + " (UUID: " + node.Uuid.str() + ")"); return(false); } Func <agx.RigidBody, GameObject> findRigidBody = (nativeRb) => { if (nativeRb == null) { return(FileInfo.PrefabInstance); } // Do not reference lumped nodes! if (agxWire.Wire.isLumpedNode(nativeRb)) { return(FileInfo.PrefabInstance); } Node rbNode = m_tree.GetNode(nativeRb.getUuid()); if (rbNode == null) { Debug.LogWarning("Unable to find reference rigid body: " + nativeRb.getName() + " (UUID: " + nativeRb.getUuid().str() + ")"); return(FileInfo.PrefabInstance); } if (rbNode.GameObject == null) { Debug.LogWarning("Referenced native rigid body hasn't a game object: " + nativeRb.getName() + " (UUID: " + rbNode.Uuid.str() + ")"); return(FileInfo.PrefabInstance); } return(rbNode.GameObject); }; var wire = node.GameObject.GetOrCreateComponent <Wire>(); var route = wire.Route; route.Clear(); wire.RestoreLocalDataFrom(nativeWire); var nativeIt = nativeWire.getRenderBeginIterator(); var nativeEndIt = nativeWire.getRenderEndIterator(); var nativeBeginWinch = nativeWire.getWinchController(0u); var nativeEndWinch = nativeWire.getWinchController(1u); if (nativeBeginWinch != null) { route.Add(nativeBeginWinch, findRigidBody(nativeBeginWinch.getRigidBody())); } // Connecting nodes will show up in render iterators. else if (nativeIt.get().getNodeType() != agxWire.Node.Type.CONNECTING && nativeWire.getFirstNode().getNodeType() == agxWire.Node.Type.BODY_FIXED) { route.Add(nativeWire.getFirstNode(), findRigidBody(nativeWire.getFirstNode().getRigidBody())); } while (!nativeIt.EqualWith(nativeEndIt)) { var nativeNode = nativeIt.get(); // Handing ContactNode and ShapeContactNode parenting. GameObject nodeParent = null; if (nativeNode.getType() == agxWire.Node.Type.CONTACT) { var nativeGeometry = nativeNode.getAsContact().getGeometry(); var geometryNode = m_tree.GetNode(nativeGeometry.getUuid()); if (geometryNode != null && geometryNode.GetChildren(Node.NodeType.Shape).Length > 0) { nodeParent = geometryNode.GetChildren(Node.NodeType.Shape)[0].GameObject; } } else if (nativeNode.getType() == agxWire.Node.Type.SHAPE_CONTACT) { var nativeShape = nativeNode.getAsShapeContact().getShape(); var shapeNode = m_tree.GetNode(nativeShape.getUuid()); if (shapeNode != null) { nodeParent = shapeNode.GameObject; } } if (nodeParent == null) { nodeParent = findRigidBody(nativeNode.getRigidBody()); } route.Add(nativeNode, nodeParent); nativeIt.inc(); } // Remove last node if we should have a winch or a body fixed node there. if (route.Last().Type == Wire.NodeType.FreeNode && nativeWire.getLastNode().getNodeType() == agxWire.Node.Type.BODY_FIXED) { route.Remove(route.Last()); } if (nativeEndWinch != null) { route.Add(nativeEndWinch, findRigidBody(nativeEndWinch.getRigidBody())); } else if (nativeIt.prev().get().getNodeType() != agxWire.Node.Type.CONNECTING && nativeWire.getLastNode().getNodeType() == agxWire.Node.Type.BODY_FIXED) { route.Add(nativeWire.getLastNode(), findRigidBody(nativeWire.getLastNode().getRigidBody())); } var materials = node.GetReferences(Node.NodeType.Material); if (materials.Length > 0) { wire.Material = materials[0].Asset as ShapeMaterial; } wire.GetComponent <WireRenderer>().InitializeRenderer(); // Reset to assign default material. wire.GetComponent <WireRenderer>().Material = null; // Adding collision group from restored instance since the disabled pair // will be read from Space (wire.setEnableCollisions( foo, false ) will // work out of the box). var collisionGroups = wire.gameObject.GetOrCreateComponent <CollisionGroups>(); collisionGroups.AddGroup(nativeWire.getGeometryController().getDisabledCollisionsGroupId().ToString(), false); foreach (var id in nativeWire.getGeometryController().getGroupIds()) { collisionGroups.AddGroup(id.ToString(), false); } return(true); }
private bool CreateConstraint(Node node) { var nativeConstraint = m_tree.GetConstraint(node.Uuid); if (nativeConstraint == null) { Debug.LogWarning("Unable to find native constraint instance with name: " + node.GameObject.name + " (UUID: " + node.Uuid.str() + ")"); return(false); } var bodyNodes = node.GetReferences(Node.NodeType.RigidBody); if (bodyNodes.Length < 1 || bodyNodes.Length > 2) { Debug.LogWarning("Unsupported number of body references to constraint with name: " + node.GameObject.name + " (#bodies: " + bodyNodes.Length + ")"); return(false); } var constraintType = Constraint.FindType(nativeConstraint); if (constraintType == ConstraintType.Unknown) { Debug.LogWarning("Unknown/unsupported constraint type of constraint with name: " + node.GameObject.name + " (UUID: " + node.Uuid.str() + ")"); return(false); } Constraint constraint = node.GameObject.GetOrCreateComponent <Constraint>(); constraint.SetType(constraintType, true); try { constraint.TryAddElementaryConstraints(nativeConstraint); constraint.VerifyImplementation(); } catch (System.Exception e) { Debug.LogException(e); return(false); } // Scaling damping to our (sigh) hard coded time step. float fixedStepTime = AgXUnity.Simulation.DefaultTimeStep; float readTimeStep = Convert.ToSingle(Simulation.getTimeStep()); float timeStepRatio = fixedStepTime / readTimeStep; if (!Mathf.Approximately(timeStepRatio, 1.0f)) { foreach (var ec in constraint.ElementaryConstraints) { foreach (var rowData in ec.RowData) { if (rowData.Compliance < -float.Epsilon) { Debug.LogWarning("Constraint: " + constraint.name + " (ec name: " + rowData.ElementaryConstraint.NativeName + ")," + " has too low compliance: " + rowData.Compliance + ". Setting to zero."); rowData.Compliance = 0.0f; } else if (rowData.Compliance > float.MaxValue) { Debug.LogWarning("Constraint: " + constraint.name + " (ec name: " + rowData.ElementaryConstraint.NativeName + ")," + " has too high compliance: " + rowData.Compliance + ". Setting to a large value."); rowData.Compliance = 0.5f * float.MaxValue; } rowData.Damping *= timeStepRatio; } } } constraint.AttachmentPair.ReferenceFrame.SetParent(bodyNodes[0].GameObject); constraint.AttachmentPair.ReferenceFrame.LocalPosition = nativeConstraint.getAttachment(0ul).getFrame().getLocalTranslate().ToHandedVector3(); constraint.AttachmentPair.ReferenceFrame.LocalRotation = nativeConstraint.getAttachment(0ul).getFrame().getLocalRotate().ToHandedQuaternion(); if (bodyNodes.Length > 1) { constraint.AttachmentPair.ConnectedFrame.SetParent(bodyNodes[1].GameObject); } else { constraint.AttachmentPair.ConnectedFrame.SetParent(FileInfo.PrefabInstance); } constraint.AttachmentPair.ConnectedFrame.LocalPosition = nativeConstraint.getAttachment(1ul).getFrame().getLocalTranslate().ToHandedVector3(); constraint.AttachmentPair.ConnectedFrame.LocalRotation = nativeConstraint.getAttachment(1ul).getFrame().getLocalRotate().ToHandedQuaternion(); constraint.AttachmentPair.Synchronized = constraintType != ConstraintType.DistanceJoint; return(true); }
private bool CreateRenderData(Node node) { var nativeShape = m_tree.GetShape(node.Uuid); var renderData = nativeShape.getRenderData(); if (renderData == null || !renderData.getShouldRender()) { return(false); } var nativeGeometry = m_tree.GetGeometry(node.Parent.Uuid); var shape = node.GameObject.GetComponent <AgXUnity.Collide.Shape>(); var toWorld = nativeGeometry.getTransform(); var toLocal = shape.transform.worldToLocalMatrix; var meshes = new Mesh[] { }; if (renderData.getVertexArray().Count > UInt16.MaxValue) { Debug.LogWarning("Render data contains more than " + UInt16.MaxValue + " vertices. Splitting it into smaller meshes."); var splitter = MeshSplitter.Split(renderData.getVertexArray(), renderData.getIndexArray(), v => toLocal.MultiplyPoint3x4(toWorld.preMult(v).ToHandedVector3())); meshes = splitter.Meshes; } else { var mesh = new Mesh(); mesh.name = shape.name + "_Visual_Mesh"; // Assigning and converting vertices. // Note: RenderData vertices assumed to be given in geometry coordinates. mesh.SetVertices((from v in renderData.getVertexArray() select toLocal.MultiplyPoint3x4(toWorld.preMult(v).ToHandedVector3())).ToList()); // Assigning and converting colors. mesh.SetColors((from c in renderData.getColorArray() select c.ToColor()).ToList()); // Unsure about this one. mesh.SetUVs(0, (from uv in renderData.getTexCoordArray() select uv.ToVector2()).ToList()); // Converting counter clockwise -> clockwise. var triangles = new List <int>(); var indexArray = renderData.getIndexArray(); for (int i = 0; i < indexArray.Count; i += 3) { triangles.Add(Convert.ToInt32(indexArray[i + 0])); triangles.Add(Convert.ToInt32(indexArray[i + 2])); triangles.Add(Convert.ToInt32(indexArray[i + 1])); } mesh.SetTriangles(triangles, 0, false); mesh.RecalculateBounds(); mesh.RecalculateNormals(); mesh.RecalculateTangents(); meshes = new Mesh[] { mesh }; } var shader = Shader.Find("Standard") ?? Shader.Find("Diffuse"); if (shader == null) { Debug.LogError("Unable to find standard shaders."); } var renderMaterial = renderData.getRenderMaterial(); var material = new Material(shader); material.name = shape.name + "_Visual_Material"; if (renderMaterial.hasDiffuseColor()) { var color = renderMaterial.getDiffuseColor().ToColor(); color.a = 1.0f - renderMaterial.getTransparency(); material.SetVector("_Color", color); } if (renderMaterial.hasEmissiveColor()) { material.SetVector("_EmissionColor", renderMaterial.getEmissiveColor().ToColor()); } material.SetFloat("_Metallic", 0.3f); material.SetFloat("_Glossiness", 0.8f); if (renderMaterial.getTransparency() > 0.0f) { material.SetBlendMode(BlendMode.Transparent); } material = AddOrReplaceAsset(material, node, AgXUnity.IO.AssetType.Material); foreach (var mesh in meshes) { AddOrReplaceAsset(mesh, node, AgXUnity.IO.AssetType.RenderMesh); } var shapeVisual = ShapeVisual.Find(shape); if (shapeVisual != null) { // Verify so that the meshes matches the current configuration? } else { ShapeVisual.CreateRenderData(shape, meshes, material); } return(true); }
private bool CreateShape(Node node) { var nativeGeometry = m_tree.GetGeometry(node.Parent.Uuid); var nativeShape = m_tree.GetShape(node.Uuid); var nativeShapeType = (agxCollide.Shape.Type)nativeShape.getType(); if (nativeShapeType == agxCollide.Shape.Type.BOX) { node.GameObject.GetOrCreateComponent <AgXUnity.Collide.Box>().HalfExtents = nativeShape.asBox().getHalfExtents().ToVector3(); } else if (nativeShapeType == agxCollide.Shape.Type.CYLINDER) { var cylinder = node.GameObject.GetOrCreateComponent <AgXUnity.Collide.Cylinder>(); cylinder.Radius = Convert.ToSingle(nativeShape.asCylinder().getRadius()); cylinder.Height = Convert.ToSingle(nativeShape.asCylinder().getHeight()); } else if (nativeShapeType == agxCollide.Shape.Type.CAPSULE) { var capsule = node.GameObject.GetOrCreateComponent <AgXUnity.Collide.Capsule>(); capsule.Radius = Convert.ToSingle(nativeShape.asCapsule().getRadius()); capsule.Height = Convert.ToSingle(nativeShape.asCapsule().getHeight()); } else if (nativeShapeType == agxCollide.Shape.Type.SPHERE) { var sphere = node.GameObject.GetOrCreateComponent <AgXUnity.Collide.Sphere>(); sphere.Radius = Convert.ToSingle(nativeShape.asSphere().getRadius()); } else if (nativeShapeType == agxCollide.Shape.Type.CONVEX || nativeShapeType == agxCollide.Shape.Type.TRIMESH || nativeShapeType == agxCollide.Shape.Type.HEIGHT_FIELD) { var mesh = node.GameObject.GetOrCreateComponent <AgXUnity.Collide.Mesh>(); var collisionData = nativeShape.asMesh().getMeshData(); var nativeToWorld = nativeShape.getTransform(); var meshToLocal = mesh.transform.worldToLocalMatrix; if (collisionData.getVertices().Count > UInt16.MaxValue) { var nativeVertices = collisionData.getVertices(); var nativeIndicies = collisionData.getIndices(); var splitter = MeshSplitter.Split(nativeVertices, nativeIndicies, v => meshToLocal.MultiplyPoint3x4(nativeToWorld.preMult(v).ToHandedVector3())); var subMeshes = splitter.Meshes; for (int i = 0; i < subMeshes.Length; ++i) { subMeshes[i].name = "Mesh_" + mesh.name + (i == 0 ? "" : "_Sub_" + i.ToString()); mesh.AddSourceObject(AddOrReplaceAsset(subMeshes[i], node, AgXUnity.IO.AssetType.CollisionMesh)); } } else { var source = new Mesh(); source.name = "Mesh_" + mesh.name; source.SetVertices((from v in collisionData.getVertices() select meshToLocal.MultiplyPoint3x4(nativeToWorld.preMult(v).ToHandedVector3())).ToList()); // Converting counter clockwise -> clockwise. var triangles = new List <int>(); var indexArray = collisionData.getIndices(); triangles.Capacity = indexArray.Count; for (int i = 0; i < indexArray.Count; i += 3) { triangles.Add(Convert.ToInt32(indexArray[i + 0])); triangles.Add(Convert.ToInt32(indexArray[i + 2])); triangles.Add(Convert.ToInt32(indexArray[i + 1])); } source.SetTriangles(triangles, 0, false); source.RecalculateBounds(); source.RecalculateNormals(); source.RecalculateTangents(); source = AddOrReplaceAsset(source, node, AgXUnity.IO.AssetType.CollisionMesh); mesh.SetSourceObject(source); } } else { Debug.LogWarning("Unsupported shape type: " + nativeShapeType); return(false); } var shape = node.GameObject.GetComponent <AgXUnity.Collide.Shape>(); if (nativeGeometry.getMaterial() != null) { var shapeMaterial = m_tree.GetNode(nativeGeometry.getMaterial().getUuid()).Asset as ShapeMaterial; if (shapeMaterial == null) { Debug.LogWarning("Shape material from geometry: " + nativeGeometry.getName() + " isn't found in UUID database."); } shape.Material = shapeMaterial; } shape.CollisionsEnabled = nativeGeometry.getEnableCollisions(); // Groups referenced in geometry node. var groups = node.Parent.GetReferences(Node.NodeType.GroupId); if (groups.Length > 0) { var groupsComponent = shape.gameObject.GetOrCreateComponent <CollisionGroups>(); foreach (var group in groups) { if (group.Object is string) { groupsComponent.AddGroup(group.Object as string, false); } } } CreateRenderData(node); return(true); }
private void Generate(Node node) { if (node == null) { return; } // TODO: Skip if node.GameObject != null means "use Unity configuration". switch (node.Type) { case Node.NodeType.Assembly: agx.Frame frame = m_tree.GetAssembly(node.Uuid); node.GameObject = GetOrCreateGameObject(node); node.GameObject.name = FindName("", node.Type.ToString()); node.GameObject.transform.position = frame.getTranslate().ToHandedVector3(); node.GameObject.transform.rotation = frame.getRotate().ToHandedQuaternion(); node.GameObject.GetOrCreateComponent <Assembly>(); break; case Node.NodeType.RigidBody: agx.RigidBody nativeRb = m_tree.GetRigidBody(node.Uuid); node.GameObject = GetOrCreateGameObject(node); node.GameObject.name = FindName(nativeRb.getName(), node.Type.ToString()); node.GameObject.transform.position = nativeRb.getPosition().ToHandedVector3(); node.GameObject.transform.rotation = nativeRb.getRotation().ToHandedQuaternion(); node.GameObject.GetOrCreateComponent <RigidBody>().RestoreLocalDataFrom(nativeRb); break; case Node.NodeType.Geometry: // Ignoring geometries - handling Shape == Geometry. // The shapes are children to this node. break; case Node.NodeType.Shape: var nativeGeometry = m_tree.GetGeometry(node.Parent.Uuid); var nativeShape = m_tree.GetShape(node.Uuid); var nativeShapeType = (agxCollide.Shape.Type)nativeShape.getType(); node.GameObject = GetOrCreateGameObject(node); node.GameObject.name = FindName(nativeGeometry.getName() + "_" + nativeShapeType.ToString().ToLower().FirstCharToUpperCase(), node.Type.ToString()); node.GameObject.transform.position = nativeShape.getTransform().getTranslate().ToHandedVector3(); node.GameObject.transform.rotation = nativeShape.getTransform().getRotate().ToHandedQuaternion(); if (!CreateShape(node)) { GameObject.DestroyImmediate(node.GameObject); } break; case Node.NodeType.Material: var nativeMaterial = m_tree.GetMaterial(node.Uuid); node.Asset = ScriptAsset.Create <ShapeMaterial>().RestoreLocalDataFrom(nativeMaterial); node.Asset.name = FindName(nativeMaterial.getName(), node.Type.ToString()); node.Asset = AddOrReplaceAsset(node.Asset as ShapeMaterial, node, AgXUnity.IO.AssetType.ShapeMaterial); break; case Node.NodeType.ContactMaterial: var nativeContactMaterial = m_tree.GetContactMaterial(node.Uuid); var nativeFrictionModel = nativeContactMaterial.getFrictionModel(); var contactMaterial = ScriptAsset.Create <ContactMaterial>().RestoreLocalDataFrom(nativeContactMaterial); contactMaterial.name = FindName("ContactMaterial_" + nativeContactMaterial.getMaterial1().getName() + "_" + nativeContactMaterial.getMaterial2().getName(), node.Type.ToString()); var materials = node.GetReferences(Node.NodeType.Material); if (materials.Length == 0) { Debug.LogWarning("No materials referenced to ContactMaterial node."); } else if (materials.Length == 1) { contactMaterial.Material1 = contactMaterial.Material2 = materials[0].Asset as ShapeMaterial; } else if (materials.Length > 1) { contactMaterial.Material1 = materials[0].Asset as ShapeMaterial; contactMaterial.Material2 = materials[1].Asset as ShapeMaterial; if (materials.Length > 2) { Debug.LogWarning("More than two materials referenced to ContactMaterial (" + node.Asset.name + "). First two are used."); } } if (nativeFrictionModel != null) { var frictionModelAsset = ScriptAsset.Create <FrictionModel>().RestoreLocalDataFrom(nativeFrictionModel); frictionModelAsset.name = "FrictionModel_" + contactMaterial.name; contactMaterial.FrictionModel = AddOrReplaceAsset(frictionModelAsset, node, AgXUnity.IO.AssetType.FrictionModel); } node.Asset = contactMaterial = AddOrReplaceAsset(contactMaterial, node, AgXUnity.IO.AssetType.ContactMaterial); break; case Node.NodeType.Constraint: var nativeConstraint = m_tree.GetConstraint(node.Uuid); node.GameObject = GetOrCreateGameObject(node); node.GameObject.name = FindName(nativeConstraint.getName(), "AgXUnity." + Constraint.FindType(nativeConstraint)); if (!CreateConstraint(node)) { GameObject.DestroyImmediate(node.GameObject); } break; case Node.NodeType.Wire: var nativeWire = m_tree.GetWire(node.Uuid); node.GameObject = GetOrCreateGameObject(node); node.GameObject.name = FindName(nativeWire.getName(), "AgXUnity.Wire"); if (!CreateWire(node)) { GameObject.DestroyImmediate(node.GameObject); } break; case Node.NodeType.Cable: var nativeCable = m_tree.GetCable(node.Uuid); node.GameObject = GetOrCreateGameObject(node); node.GameObject.name = FindName(nativeCable.getName(), "AgXUnity.Cable"); if (!CreateCable(node)) { GameObject.DestroyImmediate(node.GameObject); } break; } foreach (var child in node.Children) { Generate(child); } }