/// <summary>Constructs a joint node for the requested config.</summary> /// <param name="modelName">Name of the model in the hierarchy.</param> /// <returns>Pipe's end node.</returns> protected virtual ModelPipeEndNode LoadJointNode(string modelName) { var node = new ModelPipeEndNode(partModelTransform.Find(modelName)); node.AlignTo(null); // Init mode objects state. return(node); }
/// <summary>Builds a model for the joint end basing on the configuration.</summary> /// <param name="node">The node to setup.</param> /// <param name="alignTo"> /// The object to align the conenctor to. If it's <c>null</c>, then the model will be parked. /// </param> protected virtual void UpdateJointNode(ModelPipeEndNode node, Transform alignTo) { var config = node.config; var makeProceduralModels = alignTo != null || !config.parkPrefabOnly; // Return the models back to the owner part to make the search working properly. if (node.rootModel != null) { node.AlignToTransform(null); } node.parkRootObject = partModelTransform; // Create basic setup. var nodeName = ModelBasename + "-pipeNode" + node.name; node.rootModel = partModelTransform.Find(nodeName) ?? new GameObject(nodeName).transform; node.rootModel.parent = partModelTransform; node.partAttach = node.rootModel.Find(PartJointTransformName) ?? new GameObject(PartJointTransformName).transform; Hierarchy.MoveToParent(node.partAttach, node.rootModel, newPosition: Vector3.zero, newRotation: Quaternion.LookRotation(Vector3.back)); node.pipeAttach = node.rootModel.Find(PipeJointTransformName) ?? new GameObject(PipeJointTransformName).transform; Hierarchy.MoveToParent(node.pipeAttach, node.rootModel, newPosition: Vector3.zero, newRotation: Quaternion.LookRotation(Vector3.forward)); // Add a pipe attachment sphere if set. const string sphereName = "pipeSphere"; var sphere = node.pipeAttach.Find(sphereName); if (config.sphereDiameter > float.Epsilon && makeProceduralModels) { if (sphere == null) { sphere = Meshes.CreateSphere(config.sphereDiameter, pipeMaterial, node.pipeAttach, colliderType: Colliders.PrimitiveCollider.Shape).transform; sphere.name = sphereName; sphere.rotation = Quaternion.LookRotation(node.partAttach.up, node.partAttach.forward); } sphere.GetComponent <Renderer>().sharedMaterial = pipeMaterial; // For performance. RescalePipeTexture(sphere, sphere.localScale.z * config.sphereDiameter * 2.0f); } else if (sphere != null) { Hierarchy.SafeDestory(sphere); } // Parking position, if defined. var parkObjectName = ModelBasename + "-park" + node.name; var parkAttach = partModelTransform.Find(parkObjectName); if (config.parkAttachAt != null) { node.parkAttach = parkAttach ?? new GameObject(parkObjectName).transform; Hierarchy.MoveToParent(node.parkAttach, partModelTransform, newPosition: config.parkAttachAt.pos, newRotation: config.parkAttachAt.rot); } else if (parkAttach != null) { Hierarchy.SafeDestory(parkAttach); } // Place prefab between the part and the pipe if specified. if (!string.IsNullOrEmpty(config.modelPath)) { // The prefab model can move to the part's model, so make a unique name for it. const string prefabName = "prefabConnector"; var prefabModel = node.rootModel.Find(prefabName) ?? Hierarchy.FindTransformByPath(partModelTransform, config.modelPath); if (prefabModel != null) { prefabModel.gameObject.SetActive(true); prefabModel.name = prefabName; prefabModel.parent = node.rootModel; prefabModel.rotation = node.partAttach.rotation * config.modelPartAttachAt.rot.Inverse(); prefabModel.position = node.partAttach.TransformPoint(config.modelPartAttachAt.pos); node.pipeAttach.rotation = prefabModel.rotation * config.modelPipeAttachAt.rot; node.pipeAttach.position = prefabModel.TransformPoint(config.modelPipeAttachAt.pos); } else { HostedDebugLog.Error(this, "Cannot find prefab model: {0}", config.modelPath); } } // The offset is intended for the sphere/arm models only. if (makeProceduralModels) { node.pipeAttach.localPosition += new Vector3(0, 0, config.sphereOffset); } // Add arm pipe. const string armName = "sphereArm"; var arm = node.pipeAttach.Find(armName); if (config.armDiameter > float.Epsilon && config.sphereOffset > float.Epsilon && makeProceduralModels) { if (arm == null) { arm = Meshes.CreateCylinder(config.armDiameter, config.sphereOffset, pipeMaterial, node.pipeAttach, colliderType: Colliders.PrimitiveCollider.Shape).transform; arm.name = armName; } arm.GetComponent <Renderer>().sharedMaterial = pipeMaterial; // For performance. arm.transform.localPosition = new Vector3(0, 0, -config.sphereOffset / 2); arm.transform.localRotation = Quaternion.LookRotation(Vector3.forward); RescalePipeTexture(arm.transform, arm.localScale.z * config.sphereOffset); } else if (arm != null) { Hierarchy.SafeDestory(arm); } // Adjust to the new target. node.AlignToTransform(alignTo); }
/// <inheritdoc/> public override void OnAwake() { base.OnAwake(); sourceJointNode = new ModelPipeEndNode(SourceNodeName, sourceJointConfig); targetJointNode = new ModelPipeEndNode(TargetNodeName, targetJointConfig); }