You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Unity中创建非矩形UI?基于运行时数值生成人格图表

Got it, let's walk through exactly how to create that personality chart using Unity's RectTransform and vertex manipulation—perfect for visualizing those 0-10 scores after a quiz. Here's a practical, step-by-step implementation:

Core Idea

We'll treat the target Panel as a bounding rectangle where each of the four personality attributes corresponds to a direction (e.g., top, right, bottom, left). Each score (0-10) translates to a distance from the panel's center to that direction's edge—so a score of 10 means the vertex hits the panel's edge, 5 is halfway, etc. We'll then generate a custom mesh connecting these four vertices to form the personality shape.

Step 1: Set Up Your Canvas and Base Panel
  • Create a new Canvas (use Screen Space - Overlay for simplicity, though World Space works too).
  • Add a Panel as the chart's container: set its size to something like 400x400, center it on the canvas, and give it a light background color so the chart stands out.
  • Optional: Add four text labels around the panel (e.g., "Openness" at top, "Conscientiousness" at right, "Extraversion" at bottom, "Neuroticism" at left) to label each attribute.
Step 2: Create a Custom Graphic Component

We'll make a reusable script that inherits from MaskableGraphic (Unity's base class for custom 2D graphics) to handle mesh generation. Create a new C# script called PersonalityChart:

using UnityEngine;
using UnityEngine.UI;

[RequireComponent(typeof(RectTransform))]
public class PersonalityChart : MaskableGraphic
{
    // Public fields to assign scores (0-10) in Inspector or via code
    [Range(0, 10)] public float scoreTop = 5;
    [Range(0, 10)] public float scoreRight = 5;
    [Range(0, 10)] public float scoreBottom = 5;
    [Range(0, 10)] public float scoreLeft = 5;

    // Color of the chart fill
    public Color chartColor = new Color(0.2f, 0.6f, 1f, 0.7f);

    protected override void OnPopulateMesh(VertexHelper vh)
    {
        vh.Clear();
        RectTransform rectTransform = GetComponent<RectTransform>();
        Vector2 center = rectTransform.rect.center;
        Vector2 halfSize = rectTransform.rect.size / 2;

        // Calculate vertex positions based on scores
        Vector2 topVertex = center + new Vector2(0, halfSize.y * (scoreTop / 10f));
        Vector2 rightVertex = center + new Vector2(halfSize.x * (scoreRight / 10f), 0);
        Vector2 bottomVertex = center + new Vector2(0, -halfSize.y * (scoreBottom / 10f));
        Vector2 leftVertex = center + new Vector2(-halfSize.x * (scoreLeft / 10f), 0);

        // Convert local positions to UI space for VertexHelper
        Vector3[] uiVertices = new Vector3[] { topVertex, rightVertex, bottomVertex, leftVertex };
        for (int i = 0; i < uiVertices.Length; i++)
        {
            uiVertices[i] = rectTransform.TransformPoint(uiVertices[i]);
            uiVertices[i] = transform.root.InverseTransformPoint(uiVertices[i]);
        }

        // Add vertices to the mesh
        UIVertex vertex = UIVertex.simpleVert;
        vertex.color = chartColor;

        vertex.position = uiVertices[0];
        vh.AddVert(vertex);

        vertex.position = uiVertices[1];
        vh.AddVert(vertex);

        vertex.position = uiVertices[2];
        vh.AddVert(vertex);

        vertex.position = uiVertices[3];
        vh.AddVert(vertex);

        // Add triangles to form a quad (two triangles make up the four-sided shape)
        vh.AddTriangle(0, 1, 2);
        vh.AddTriangle(0, 2, 3);
    }

    // Call this to update the chart after quiz completion
    public void UpdateScores(float top, float right, float bottom, float left)
    {
        scoreTop = Mathf.Clamp(top, 0, 10);
        scoreRight = Mathf.Clamp(right, 0, 10);
        scoreBottom = Mathf.Clamp(bottom, 0, 10);
        scoreLeft = Mathf.Clamp(left, 0, 10);
        SetVerticesDirty(); // Trigger mesh refresh
    }
}
Step 3: Hook Up the Script to Your Panel
  • Attach the PersonalityChart script to your base Panel.
  • In the Inspector, you can tweak the default scores to see the shape update in real-time.
Step 4: Update Scores After Quiz Completion

When the user finishes their quiz, calculate the four attribute totals (each between 0-10), then call the UpdateScores method from your quiz logic:

// Example: After calculating quiz scores
float opennessScore = 8;
float conscientiousnessScore = 6;
float extraversionScore = 4;
float neuroticismScore = 7;

PersonalityChart chart = FindObjectOfType<PersonalityChart>();
chart.UpdateScores(opennessScore, conscientiousnessScore, extraversionScore, neuroticismScore);
Bonus: Polish the Chart
  • Add an outline: Create a child Image under the Panel, set its color to a dark shade, and use a RectMask2D on the parent to clip it to the chart shape.
  • Add animation: Tween the scores from 0 to their final values over 1-2 seconds for a satisfying reveal after the quiz.
  • Adjust the shape: If you want a smoother look, you can add more vertices between the four main points, or use a bezier curve to round the edges.

This approach is lightweight, uses Unity's built-in UI system, and updates dynamically based on your runtime scores. Let me know if you need help tweaking any part!

内容的提问来源于stack exchange,提问作者Dtb49

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 11:50:35