'How to fix distorted image shown on Unity UI?

I'm doing a project which will be used on projection. I want to display image in quadrilateral composed of given vertices on Unity UI. I created a class inheriting from Raw Image. Although it works for given vertices, color and uv mapping, the image appears distorted on the screen. I tried to build quad directly and build two triangles to compose a quad but the image looked weird. Should I split the quad into more triangles or is there any better way to solve this problem? Thank you.

Here is my code for drawing quad,

using UnityEngine;
using UnityEngine.UI;

[DisallowMultipleComponent]
[RequireComponent(typeof(RectTransform))]
[RequireComponent(typeof(CanvasRenderer))]
[ExecuteInEditMode]

public class LeftScreen : RawImage
{ 
    private UIVertex[] leftVertices;
    private Vector2[] leftuvs;

    public int[,] defaultPositions = new int[4, 2] { { 85, 43 },  { 80, 1016 }, { 962, 23 }, { 950, 605 } };

    protected override void Start()
    {
        leftVertices = new UIVertex[4];
        leftuvs = new Vector2[4];
        leftuvs[0] = new Vector2(0, 0);
        leftuvs[1] = new Vector2(0, 1);
        leftuvs[2] = new Vector2(1, 1);
        leftuvs[3] = new Vector2(1, 0);
        SetLeftVertices(defaultPositions);
    }

    protected override void OnPopulateMesh(VertexHelper helper)
    {
        base.OnPopulateMesh(helper);
        helper.Clear();
        
        // Draw quad
        helper.AddUIVertexQuad(leftVertices);
        /*
        // Draw triangles to compose quad
        foreach (UIVertex v in leftVertices)
        {
            helper.AddVert(v);
        }
        helper.AddTriangle(0, 1, 2);
        helper.AddTriangle(0, 2, 3);
        */
    }

    /**
     * Assign new positions to UI vertices
     */
    public void SetLeftVertices(int[,] vertices)
    {
        SetAllDirty();
        leftVertices[0].position = new Vector2(vertices[1, 0] - 960, -(vertices[1, 1] - 540));
        leftVertices[0].color = color;
        leftVertices[0].uv0 = leftuvs[0];
        leftVertices[1].position = new Vector2(vertices[0, 0] - 960, -(vertices[0, 1] - 540));
        leftVertices[1].color = color;
        leftVertices[1].uv0 = leftuvs[1];
        leftVertices[2].position = new Vector2(vertices[2, 0] - 960, -(vertices[2, 1] - 540));
        leftVertices[2].color = color;
        leftVertices[2].uv0 = leftuvs[2];
        leftVertices[3].position = new Vector2(vertices[3, 0] - 960, -(vertices[3, 1] - 540));
        leftVertices[3].color = color;
        leftVertices[3].uv0 = leftuvs[3];
    }
}

And the output of my code:

enter image description here



Solution 1:[1]

I think the issue here is with your defaultPositions. When I got to paint and place vertices at your defaultPositions, I get the following graphic:

defaultPositions

I thought it was unusual that you were subtracting what looks like pixel values in your SetLeftVertices method, and you're subtracting what looks like uniform values for x and y. Then I looked back at what you're subtracting from and was surprised that it wasn't square - two pair of x values, two pair of y values. I drew them and got the figure above.

Try setting the default values to something else, and remember that your field is public so Unity may have serialized your values in the inspector if you just change them in the script.

For example, I think the following values will get you more what you want:

public class LeftScreen : RawImage
{ 
    // ...
    private const int xMin = 80;
    private const int xMax = 950;
    private const int yMin = 23;
    private const int yMax = 1016;
    public int[,] defaultPositions = new int[4, 2] { { xMin, yMin },  { xMin, yMax }, { xMax, yMin }, { xMax, yMax } };
    // ...
}

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Chuck