Unity3D combines the grid to draw an arc rotation diagram

I introduced the principle of drawing earlier. You can draw some simple graphics through grids, but it is difficult to get started. The purpose of this article is to combine rotation graphics and drawing arc grids through vertices.

First, you need to get the arc-shaped grid drawn. The code and comments are as follows:

float n = 15; //定义一个变量n表示图形的个数
float l; //定义一个变量l表示周长
float r; //定义一个变量r表示半径

void Start()
{
    
    
    l = 150 * n; //计算周长
    r = l / (2 * Mathf.PI); //计算半径
    float ang = 2 * Mathf.PI / n; //计算角度
    float sunang = 2 * Mathf.PI / (n * 10); 
    VertexHelper vh = new VertexHelper(); //创建顶点帮助器

    for (int i = -5; i <= 5; i++) 
    {
    
    
        float x = Mathf.Sin(i * sunang) * r - Mathf.Sin(0) * r; //计算x坐标
        float z = Mathf.Cos(i * sunang) * r - Mathf.Cos(0) * r; //计算z坐标
        float y = 113; //可替换
        float y0 = -113; 

        float uvx = (float)(i + 5) / 10; //计算纹理坐标x值

        vh.AddVert(new Vector3(x, y, z), Color.white, new Vector2(uvx, 1)); 
        vh.AddVert(new Vector3(x, y0, z), Color.white, new Vector2(uvx, 0)); 

        if (i < 5) 
        {
    
    
            int j = i + 5; 
            vh.AddTriangle(j * 2 + 1, j * 2, (j + 1) * 2); 
            vh.AddTriangle(j * 2 + 1, (j + 1) * 2, (j + 1) * 2 + 1); 
        }
    }

    Mesh mesh = new Mesh();
    vh.FillMesh(mesh); //填充到网格

    GetComponent<MeshFilter>().mesh = mesh; //用于显示模型
    GetComponent<MeshCollider>().sharedMesh = mesh; 
}

First, establish the total number of drawn graphics. The l radius, y and y0 are all calculated proportionally based on the resolution of the picture at that time. They can be replaced. The number of vertices drawn can also be based on the required graphics. Vertex formulation.
This script can also be displayed separately, and you can see the generated arc Mash mesh.
An independent arc mesh has been solved. It’s time to use carousel images. Carousel images are different from carousel images. Carousel images are more used for cyclic display of images on web pages

Mount the arc-shaped Mash generated above to the prefabricated body. At the same time, you need to respond to the events of the rotation graph. Here you can use the event system of or to solve the problem. The event system can also be used for 3D rotation diagrams, while the trigger conditions for the OnMouse drag event are relatively loose. Both methods have their own advantagesUnity IDragHandler, IBeginDragHandler, IEndDragHandlerOnMouseDrag() OnMouseUp()

The script mounted here uses the OnMouse() method

private void OnMouseDrag()
    {
    
    
        Vector3 pos = Camera.main.WorldToScreenPoint(transform.position);
        Vector3 next = Camera.main.ScreenToWorldPoint(new Vector3(Input.mousePosition.x, Input.mousePosition.y, pos.z));
        float dis = next.x - transform.position.x;
        cyclogram.OnDrag(dis);
    }

    private void OnMouseUp()
    {
    
    
        Vector3 pos = Camera.main.WorldToScreenPoint(transform.position);
        Vector3 next = Camera.main.ScreenToWorldPoint(new Vector3(Input.mousePosition.x, Input.mousePosition.y, pos.z));
        float dis = next.x - transform.position.x;
        cyclogram.Inertia(dis);

    }

Here we also use the method of world coordinates and screen coordinates to obtain the mouse position, and then pass it to the rotation method of the rotation diagram and the processing after the movement.

Finally, the Control script

public Texture[] textures; // 纹理数组

public GameObject prefab; 

public int num; // 数量

public float r; // 半径
float ang;
public float dec = 5f; 
List<GameObject> list = new List<GameObject>(); 
List<Transform> sortList = new List<Transform>(); 

void Start()
{
    
    
    ang = 2 * Mathf.PI / num; // 根据数量计算角度
    Move(); 
  
}

float allAng = 0;

public void OnDrag(float dis)
{
    
    
    float moveang = dis / r; 
    allAng -= moveang; 
    Move(); 
    
}

public void Move()
{
    
    
    for (int i = 0; i < num; i++)
    {
    
    
        float x = Mathf.Sin(i * ang + allAng) * r; 
        float z = Mathf.Cos(i * ang + allAng) * r; // 根据角度和半径计算z坐标值
        if (list.Count <= i)
        {
    
    
            GameObject sphere = Instantiate(prefab); 
            sphere.transform.parent = transform; 
            sphere.GetComponent<CyclogramItem>().cyclogram = this; // 获取并设置CyclogramItem组件的cyclogram属性为当前对象
            
            sphere.GetComponent<MeshRenderer>().material.mainTexture = textures[i];
            list.Add(sphere); 
            sortList.Add(sphere.transform); 
        }
        list[i].transform.localPosition = new Vector3(x, 0, z); /
        list[i].transform.localEulerAngles = Vector3.up * ((i * ang + allAng) * Mathf.Rad2Deg); 
        
    }
  

public void Inertia(float dis)
{
    
    
    float time = Mathf.Abs(dis / dec); // 计算惯性
    DT.To((a) =>
    {
    
    
        OnDrag(a);
        
    }, dis, 0, time).OnComplete(() =>
    {
    
    
        sortList.Sort((a, b) =>
        {
    
    
            if (a.position.z < b.position.z)
            {
    
    
                return -1;
            }
            else if (a.position.z == b.position.z)
            {
    
    
                return 0;
            }
            else
            {
    
    
                return 1;
            }
        }); // 排序
        float aligning = Mathf.Asin(sortList[0].localPosition.x / r); // 对齐
        float aligntimer = Mathf.Abs(aligning * r / 200);
        DT.To((a) =>
        {
    
    
            allAng = a;
            Move();
            
        }, allAng, allAng + aligning, aligntimer).OnComplete(() =>
        {
    
    
         
            //这一部分可以添加对齐后的代码,比如对齐后会显示角色立绘,角色的详情面板以及模型等,
            //可以使用脚本也可以直接添加

        });
    });
}

The alignment and offset in the code are all implemented by the self-made Dotween class. You can also directly use the Dotween animation plug-in for animation effects to avoid reinventing the wheel, -——
The following For some applications of self-made DotWeen, the start and end time of animation are defined, and the corresponding trigger delegation and timing

 public Action<float> action;
    public float bagin;
    public float end;
    public float time;
    public Action complete;

    float nowtime;
    public static DotweenHuan To(Action<float> action, float bagin, float end, float time)
    {
    
    
        GameObject dt = new GameObject("DotweenHuan");
        DotweenHuan dotween = dt.AddComponent<DotweenHuan>();
        dotween.action = action;
        dotween.bagin = bagin;
        dotween.end = end;
        dotween.time = time;
        dotween.nowtime = Time.time;

        return dotween;
    }

    private void Update()
    {
    
    
        if (Time.time - nowtime < time)
        {
    
    
            float t = Time.time - nowtime;
            float p = t / time;
            float a = bagin * (1 - p) + end * p;
            action(a);

        }
        else
        {
    
    
            action(end);
            if (complete !=null)
            {
    
    
                complete();
            }
            Destroy(gameObject);
        }
    }

    public void OnComplete(Action complete)
    {
    
    
        this.complete = complete;
    }

After completing the above preparations, you can achieve the corresponding opening mention effect. The mention effect is not perfect due to OnMouse and other reasons and can be improved.Imperfect carousel chart

Guess you like

Origin blog.csdn.net/m0_57252175/article/details/132310158