/// <summary>Sets pointer origin to the current attachment node</summary> private static void UpdatePointerAttachNode() { var node = GetCurrentAttachNode(); pointerNodeTransform.localPosition = node.position; // HACK(ihsoft): For some reason Z orientation axis is get mirrored in the parts for the stack // nodes. It results in a weird behavior when aligning parts in "back" or "front" node attach // modes. It may be a KIS code bug but I gave up finding it. pointerNodeTransform.localRotation = KIS_Shared.GetNodeRotation(node, mirrorZ: node.nodeType != AttachNode.NodeType.Surface); }
public static void AssignAttachIcon(Part part, AttachNode node, Color iconColor, string name = null) { // Create NodeTransform if needed if (!node.nodeTransform) { node.nodeTransform = new GameObject("KISNodeTransf").transform; node.nodeTransform.parent = part.transform; node.nodeTransform.localPosition = node.position; node.nodeTransform.localRotation = KIS_Shared.GetNodeRotation(node); } if (!node.icon) { node.icon = GameObject.CreatePrimitive(PrimitiveType.Sphere); if (node.icon.GetComponent <Collider>()) { UnityEngine.Object.DestroyImmediate(node.icon.GetComponent <Collider>()); } var iconRenderer = node.icon.GetComponent <Renderer>(); if (iconRenderer) { iconRenderer.material = new Material(Shader.Find("Transparent/Diffuse")); iconColor.a = 0.5f; iconRenderer.material.color = iconColor; iconRenderer.material.renderQueue = HighlighedPartRenderQueue; } node.icon.transform.parent = part.transform; if (name != null) { node.icon.name = name; } double num; if (node.size == 0) { num = (double)node.size + 0.5; } else { num = (double)node.size; } node.icon.transform.localScale = Vector3.one * node.radius * (float)num; node.icon.transform.parent = node.nodeTransform; node.icon.transform.localPosition = Vector3.zero; node.icon.transform.localRotation = Quaternion.identity; } }
public void UpdatePointer() { // Stop pointer on map if (running && MapView.MapIsEnabled) { StopPointer(); } // Remove pointer if not running or if the raycast do not hit anything if (!running || pointerTarget == PointerTarget.Nothing) { if (pointer) { UnityEngine.Object.Destroy(pointer); } return; } //Create pointer if needed if (!pointer) { GameObject modelGo = partToAttach.FindModelTransform("model").gameObject; GameObject pointerModel = Mesh.Instantiate(modelGo, new Vector3(0, 0, 100), Quaternion.identity) as GameObject; foreach (Collider col in pointerModel.GetComponentsInChildren <Collider>()) { UnityEngine.Object.DestroyImmediate(col); } pointer = new GameObject("KISPointer"); pointerModel.transform.parent = pointer.transform; pointerModel.transform.localPosition = modelGo.transform.localPosition; pointerModel.transform.localRotation = modelGo.transform.localRotation; pointer.transform.localScale = new Vector3(scale, scale, scale); allModelMr = new List <MeshRenderer>(); // Remove attached tube mesh renderer if any List <MeshRenderer> tmpAllModelMr = new List <MeshRenderer>(pointerModel.GetComponentsInChildren <MeshRenderer>() as MeshRenderer[]); foreach (MeshRenderer mr in tmpAllModelMr) { if (mr.name == "KAStube" || mr.name == "KASsrcSphere" || mr.name == "KASsrcTube" || mr.name == "KAStgtSphere" || mr.name == "KAStgtTube") { Destroy(mr); continue; } allModelMr.Add(mr); mr.material = new Material(Shader.Find("Transparent/Diffuse")); } // Set pointer attach node pointerNodeTransform = new GameObject("KASPointerPartNode").transform; pointerNodeTransform.parent = pointer.transform; pointerNodeTransform.localPosition = GetCurrentAttachNode().position; pointerNodeTransform.localRotation = KIS_Shared.GetNodeRotation(GetCurrentAttachNode()); } // Custom rotation float rotDegree = 15; if (Input.GetKey(KeyCode.LeftShift)) { rotDegree = 1; } if (GameSettings.Editor_rollLeft.GetKeyDown()) { customRot -= new Vector3(0, -1, 0) * rotDegree; } if (GameSettings.Editor_rollRight.GetKeyDown()) { customRot += new Vector3(0, -1, 0) * rotDegree; } if (GameSettings.Editor_pitchDown.GetKeyDown()) { customRot -= new Vector3(1, 0, 0) * rotDegree; } if (GameSettings.Editor_pitchUp.GetKeyDown()) { customRot += new Vector3(1, 0, 0) * rotDegree; } if (GameSettings.Editor_yawLeft.GetKeyDown()) { customRot -= new Vector3(0, 0, 1) * rotDegree; } if (GameSettings.Editor_yawRight.GetKeyDown()) { customRot += new Vector3(0, 0, 1) * rotDegree; } if (GameSettings.Editor_resetRotation.GetKeyDown()) { customRot = new Vector3(0, 0, 0); } Quaternion rotAdjust = Quaternion.Euler(0, 0, customRot.z) * Quaternion.Euler(customRot.x, customRot.y, 0); // Move to position if (pointerTarget == PointerTarget.PartMount) { //Mount snap KIS_Shared.MoveAlign(pointer.transform, pointerNodeTransform, hoveredNode.nodeTransform); pointer.transform.rotation *= Quaternion.Euler(hoveredNode.orientation); } else if (pointerTarget == PointerTarget.PartNode) { //Part node snap KIS_Shared.MoveAlign(pointer.transform, pointerNodeTransform, hoveredNode.nodeTransform, rotAdjust); } else { KIS_Shared.MoveAlign(pointer.transform, pointerNodeTransform, hit, rotAdjust); } // Move above if (allowOffset) { if (pointerTarget != PointerTarget.PartMount) { if (Input.GetKeyDown(offsetUpKey)) { if (aboveDistance < maxOffsetDist) { aboveDistance += aboveOffsetStep; } } if (Input.GetKeyDown(offsetDownKey)) { if (aboveDistance > -maxOffsetDist) { aboveDistance -= aboveOffsetStep; } } if (GameSettings.Editor_resetRotation.GetKeyDown()) { aboveDistance = 0; } pointer.transform.position = pointer.transform.position + (hit.normal.normalized * aboveDistance); } } //Check distance bool isValidSourceDist = true; if (sourceTransform) { isValidSourceDist = Vector3.Distance(FlightGlobals.ActiveVessel.transform.position, sourceTransform.position) <= maxDist; } bool isValidTargetDist = Vector3.Distance(FlightGlobals.ActiveVessel.transform.position, hit.point) <= maxDist; //Set color Color color = colorNok; bool invalidTarget = false; bool notAllowedOnMount = false; bool cannotSurfaceAttach = false; bool invalidCurrentNode = false; bool itselfIsInvalid = false; switch (pointerTarget) { case PointerTarget.Static: if (allowStatic) { color = colorOk; } else { invalidTarget = true; } break; case PointerTarget.StaticRb: if (allowStatic) { color = colorOk; } else { invalidTarget = true; } break; case PointerTarget.KerbalEva: if (allowEva) { color = colorOk; } else { invalidTarget = true; } break; case PointerTarget.Part: if (allowPart) { if (hoveredPart == partToAttach && !allowPartItself) { itselfIsInvalid = true; } else { if (useAttachRules) { if (hoveredPart.attachRules.allowSrfAttach) { if (GetCurrentAttachNode().nodeType == AttachNode.NodeType.Surface) { color = colorOk; } else { invalidCurrentNode = true; } } else { cannotSurfaceAttach = true; } } else { color = colorOk; } } } else { invalidTarget = true; } break; case PointerTarget.PartMount: if (allowMount) { ModuleKISPartMount pMount = hoveredPart.GetComponent <ModuleKISPartMount>(); List <string> allowedPartNames = new List <string>(); pMount.GetMounts().TryGetValue(hoveredNode, out allowedPartNames); if (allowedPartNames.Contains(partToAttach.partInfo.name)) { color = colorMountOk; } else { color = colorMountNok; notAllowedOnMount = true; } } break; case PointerTarget.PartNode: if (allowStack) { color = colorStack; } else { invalidTarget = true; } break; default: break; } if (!isValidSourceDist || !isValidTargetDist) { color = colorDistNok; } color.a = 0.5f; foreach (MeshRenderer mr in allModelMr) { mr.material.color = color; } //On click if (Input.GetKeyDown(KeyCode.Mouse0)) { if (invalidTarget) { ScreenMessages.PostScreenMessage("Target object is not allowed !"); audioBipWrong.Play(); return; } else if (itselfIsInvalid) { ScreenMessages.PostScreenMessage("Cannot attach on itself !"); audioBipWrong.Play(); return; } else if (notAllowedOnMount) { ScreenMessages.PostScreenMessage("This part is not allowed on the mount !"); audioBipWrong.Play(); return; } else if (cannotSurfaceAttach) { ScreenMessages.PostScreenMessage("Target part do not allow surface attach !"); audioBipWrong.Play(); return; } else if (invalidCurrentNode) { ScreenMessages.PostScreenMessage("This node cannot be used for surface attach !"); audioBipWrong.Play(); return; } else if (!isValidSourceDist) { ScreenMessages.PostScreenMessage("Too far from source !"); audioBipWrong.Play(); return; } else if (!isValidTargetDist) { ScreenMessages.PostScreenMessage("Too far from target !"); audioBipWrong.Play(); return; } else { SendPointerClick(pointerTarget, pointer.transform.position, pointer.transform.rotation, hoveredPart, GetCurrentAttachNode().id, hoveredNode); } } }