我怎样才能掩盖这个CanvasRenderer?

我创建了一个文本框,允许基于Unity的InputField的可选文本。 我现在面临的一个问题是,select突出显示不响应掩码(父对象具有掩码,但只是被忽略)深度也被忽略,这似乎通过任何其他UI元素进行渲染。 :

在这里输入图像描述

我完全失去了如何去掩盖它,所以它没有显示过去的框的边界。 我用来生成代码的代码很大程度上是基于Unity的,现在这个代码有点长,并且被一些黑客攻击了,我把它包括在内以供参考。

生成.gif中突出显示的vert的方法是GenerateHighlight

  private void UpdateGeometry() { if(caretCanvasRenderer == null && textBacker != null) { GameObject caret = new GameObject(transform.name + "Caret"); caret.hideFlags = HideFlags.DontSave; caret.transform.SetParent(textBacker.transform); caret.transform.SetAsFirstSibling(); caret.layer = gameObject.layer; caretRectTransform = caret.AddComponent<RectTransform>(); caretCanvasRenderer = caret.AddComponent<CanvasRenderer>(); caretCanvasRenderer.SetMaterial(Graphic.defaultGraphicMaterial, null); //caretCanvasRenderer.isMask = true; caret.AddComponent<LayoutElement>().ignoreLayout = true; AssignPositioningIfNeeded(); } if (caretCanvasRenderer == null) return; OnFillVBO(VBO); if (VBO.Count == 0) caretCanvasRenderer.SetVertices(null, 0); else caretCanvasRenderer.SetVertices(VBO.ToArray(), VBO.Count); VBO.Clear(); } private void OnFillVBO(List<UIVertex> vbo) { //if (!isFocused) // return; Rect inputRect = textBacker.rectTransform.rect; Vector2 extents = inputRect.size; // get the text alignment anchor point for the text in local space Vector2 textAnchorPivot = Text.GetTextAnchorPivot(textBacker.alignment); Vector2 refPoint = Vector2.zero; refPoint.x = Mathf.Lerp(inputRect.xMin, inputRect.xMax, textAnchorPivot.x); refPoint.y = Mathf.Lerp(inputRect.yMin, inputRect.yMax, textAnchorPivot.y); // Ajust the anchor point in screen space Vector2 roundedRefPoint = textBacker.PixelAdjustPoint(refPoint); // Determine fraction of pixel to offset text mesh. // This is the rounding in screen space, plus the fraction of a pixel the text anchor pivot is from the corner of the text mesh. Vector2 roundingOffset = roundedRefPoint - refPoint + Vector2.Scale(extents, textAnchorPivot); roundingOffset.x = roundingOffset.x - Mathf.Floor(0.5f + roundingOffset.x); roundingOffset.y = roundingOffset.y - Mathf.Floor(0.5f + roundingOffset.y); if (!hasSelection) GenerateCursor(vbo, roundingOffset); else GenerateHightlight(vbo, roundingOffset); } private void GenerateCursor(List<UIVertex> vbo, Vector2 roundingOffset) { if (!caretVisible) return; if(cursorVerts == null) CreateCursorVerts(); float width = 1f; float height = textBacker.fontSize; int adjustedPosition = Mathf.Max(0, caretPositionInternal - drawStart); TextGenerator generator = textBacker.cachedTextGenerator; if(generator == null) return; if (textBacker.resizeTextForBestFit) height = generator.fontSizeUsedForBestFit / textBacker.pixelsPerUnit; Vector2 startPosition = Vector2.zero; // Calculate startPosition if (generator.characterCountVisible + 1 > adjustedPosition || adjustedPosition == 0) { UICharInfo cursorChar = generator.characters[adjustedPosition]; startPosition.x = cursorChar.cursorPos.x; startPosition.y = cursorChar.cursorPos.y; } startPosition.x /= textBacker.pixelsPerUnit; // TODO: Only clamp when Text uses horizontal word wrap. if (startPosition.x > textBacker.rectTransform.rect.xMax) startPosition.x = textBacker.rectTransform.rect.xMax; cursorVerts[0].position = new Vector3(startPosition.x, startPosition.y - height, 0.0f); cursorVerts[1].position = new Vector3(startPosition.x + width, startPosition.y - height, 0.0f); cursorVerts[2].position = new Vector3(startPosition.x + width, startPosition.y, 0.0f); cursorVerts[3].position = new Vector3(startPosition.x, startPosition.y, 0.0f); if (roundingOffset != Vector2.zero) { for (int i = 0; i < cursorVerts.Length; i++) { UIVertex uiv = cursorVerts[i]; uiv.position.x += roundingOffset.x; uiv.position.y += roundingOffset.y; vbo.Add(uiv); } } else { for (int i = 0; i < cursorVerts.Length; i++) { vbo.Add(cursorVerts[i]); } } startPosition.y = Screen.height - startPosition.y; Input.compositionCursorPos = startPosition; } private void GenerateHightlight(List<UIVertex> vbo, Vector2 roundingOffset) { int startChar = Mathf.Max(0, caretPositionInternal - drawStart); int endChar = Mathf.Max(0, caretSelectPositionInternal - drawStart); // Ensure pos is always less then selPos to make the code simpler if (startChar > endChar) { int temp = startChar; startChar = endChar; endChar = temp; } endChar -= 1; TextGenerator generator = textBacker.cachedTextGenerator; int currentLineIndex = DetermineCharacterLine(startChar, generator); float height = textBacker.fontSize; if (textBacker.resizeTextForBestFit) height = generator.fontSizeUsedForBestFit / textBacker.pixelsPerUnit; if (generator != null && generator.lines.Count > 0) { // TODO: deal with multiple lines with different line heights. height = generator.lines[0].height; } if (textBacker.resizeTextForBestFit && generator != null) { height = generator.fontSizeUsedForBestFit; } int nextLineStartIdx = GetLineEndPosition(generator, currentLineIndex); UIVertex vert = UIVertex.simpleVert; vert.uv0 = Vector2.zero; vert.color = selectionColor; int currentChar = startChar; while (currentChar <= endChar && currentChar < generator.characterCountVisible) { if (currentChar + 1 == nextLineStartIdx || currentChar == endChar) { UICharInfo startCharInfo = generator.characters[startChar]; UICharInfo endCharInfo = generator.characters[currentChar]; Vector2 startPosition = new Vector2(startCharInfo.cursorPos.x / textBacker.pixelsPerUnit, startCharInfo.cursorPos.y); Vector2 endPosition = new Vector2((endCharInfo.cursorPos.x + endCharInfo.charWidth) / textBacker.pixelsPerUnit, startPosition.y - height / textBacker.pixelsPerUnit); // Checking xMin as well due to text generator not setting possition if char is not rendered. if (endPosition.x > textBacker.rectTransform.rect.xMax || endPosition.x < textBacker.rectTransform.rect.xMin) endPosition.x = textBacker.rectTransform.rect.xMax; vert.position = new Vector3(startPosition.x, endPosition.y, 0.0f) + (Vector3)roundingOffset; vbo.Add(vert); vert.position = new Vector3(endPosition.x, endPosition.y, 0.0f) + (Vector3)roundingOffset; vbo.Add(vert); vert.position = new Vector3(endPosition.x, startPosition.y, 0.0f) + (Vector3)roundingOffset; vbo.Add(vert); vert.position = new Vector3(startPosition.x, startPosition.y, 0.0f) + (Vector3)roundingOffset; vbo.Add(vert); startChar = currentChar + 1; currentLineIndex++; nextLineStartIdx = GetLineEndPosition(generator, currentLineIndex); } currentChar++; } } 

它的主旨是创造一个新的游戏物体。 添加canvas渲染器,并进行直接变换。 调用生成顶点的适当方法,然后将其分配给CanvasRenderer。

看看UI.Graphic和UI.MaskableGraphic

你需要编写一个派生自[MaskableGraphic]的类,然后在用户界面要求的时候实现这个方法来填充VBO。