Unity3D-我们是否有插件,或者是否有人在Tag collection输入视图上工作过,请参见屏幕截图

Unity3D-我们是否有插件,或者是否有人在Tag collection输入视图上工作过,请参见屏幕截图,unity3d,plugins,android-chips,Unity3d,Plugins,Android Chips,我需要一个具有以下功能的Unity插件(例如): 用户将从列表中搜索标签,列表中的选定项目将显示为标签。标记将包含带有十字的文本。移动设备宽度将是最大水平空间,如果已满,下一个标签将放在下一行 注意!在花太多时间回答这个问题之前,一定要检查一下 这方面没有现成的好方案。但是使用UnityUI做这件事相当容易。您必须熟悉HorizontalLayoutGroup等,以及如何在代码中添加UI项。从…开始。享受吧 我继续做了一个演示项目,展示了如何做到这一点 链条是这样的:它有四个深度 All

我需要一个具有以下功能的Unity插件(例如):

用户将从列表中搜索标签,列表中的选定项目将显示为标签。标记将包含带有十字的文本。移动设备宽度将是最大水平空间,如果已满,下一个标签将放在下一行


注意!在花太多时间回答这个问题之前,一定要检查一下


这方面没有现成的好方案。但是使用UnityUI做这件事相当容易。您必须熟悉HorizontalLayoutGroup等,以及如何在代码中添加UI项。从…开始。享受吧


我继续做了一个演示项目,展示了如何做到这一点

链条是这样的:它有四个深度

All Rows .. VerticalLayoutGroup, ContentSizeFitter
(EXPAND MUST BE "OFF")
(MUST BE HORIZONTAL >>UNCONSTRAINED<<, VERT PREFERRED)
 One Row ... HorizontalLayoutGroup, ContentSizeFitter  ** CFO OFF!
 (EXPAND MUST BE "OFF")
 (MUST BE HORIZONTAL PREFERRED, VERT PREFERRED)
  One Unit .... HorizontalLayoutGroup, ContentSizeFitter   **CFO ON!
  (EXPAND MUST BE "ON")
  (MUST BE HORIZONTAL PREFERRED, VERT PREFERRED)
    Text on the left (inherently sizes in Unity)
    The UI.Button ..... LayoutElement: choose and set "Min" Width/Height
      Text below button ...... nothing (probably won't need this)
 Another row...
 Another row...
 
 CFE means ChildForceExpand button, set correctly as shown!
 For all three ContentSizeFitters, select "Preferred" both ways

上面的软件包是关于Unity.UI的一个很好的教程。但是一定要看看这个奇妙的QA:

谢谢所有的解释,甚至感谢链接的unity项目。我试图在几个小时内完成所有这些工作。我可以轻松添加新项目,然后调用Flow()来调整布局。当新项目超出一点点空间时,它不会溢出。我试图访问芯片(型号单元)的标题,并将其从交叉按钮上移除。我在芯片上添加了一个脚本,并在那里编写了它的点击事件。调用Destroy(this)来移除它,我还从“所有行”游戏对象中引用了FattieFlow scrpit。销毁(this)之后,我调用Flow()。移除芯片仍然有一些问题。工作进行得很好!!现在,我正在尝试我的运气,用和我之前评论中相同的方法移除他们X按钮上的芯片。嗨@SyedAsadAli!更多好消息,看看我提出的这个问题和这里的答案。。。。。。。。。。。。。。。重要!下面我的答案是可以操纵行,但请检查以下内容:
// FattieFlow - flush left fitting for Unity reactive

// for simplicity, it does assume the only things under here
// are the relevant rows and items, and, the model row.

// NOTE ----
// this is deliberately programmed in the most illustrative manner.

// To use - just call Flow() any time to completely correct the layout.

// To put in a project: simply copy the "all rows" and the "model rows"
// in to your own scene.  That's it.

// To make your layout in editor. Just enable the model so you can see it.
// Just duplicate the model item/row a few times to see what you're doing.
// Change the colors/sizes/spacings in any way you wish.  Done.
// Eliminate the non-model items you used to layout.  Roll tide.

// To test.  Hit Play.  Literally add or delete "items" or rows,
// so that the flow is wrong.  Run the "Flow()" function and it
// will fix everything regardless.

using UnityEngine;
using UnityEngine.UI;
using System.Collections;

public class FattieFlow:MonoBehaviour
    {
    public GameObject modelRow;
    public GameObject modelItem;
    
    
    void Awake()
        {
        modelRow.SetActive(false);
        modelItem.SetActive(false);
        // (it's a little untidy having the model (which is inactive)
        // sibling to the real rows, so just be careful with it...)
        modelRow.transform.SetAsFirstSibling();
        
        // simple example of how you might add an item
        Invoke("_teste", 2f);
        }
    
    void _teste()
        {
        ExampleAddItem("added this");
        Flow();
        }
    public void ExampleAddItem(string label)
        {
        if (transform.childCount < 2) _addARow();
        GameObject nu = Instantiate(modelItem);
        nu.name = "dynamically created item.";
        nu.transform.SetParent(transform.GetChild(1),false);
        nu.SetActive(true);
        Canvas.ForceUpdateCanvases();
        }
    
    float screen;
    
    public void Flow()
        {
        screen = GetComponent<RectTransform>().rect.width;
        
        // move downwards any which need to be moved downwards
        int row = 0;
        while (row < transform.childCount)  // (dynamic)
            {
            if (transform.GetChild(row).gameObject.activeSelf) FlowRow(row);
            ++row;
            }
        
        // move upwards any which can be moved upwards
        row = 0;
        while (row < transform.childCount)
            {
            if (transform.GetChild(row).gameObject.activeSelf) UnflowRow(row);
            ++row;
            }
        
        // account perfectly for spacing, regardless of the user's layout
        // (the most elegant algorithm is to simply ABA)
        row = 0;
        while (row < transform.childCount)  // (dynamic)
            {
            if (transform.GetChild(row).gameObject.activeSelf) FlowRow(row);
            ++row;
            }
        
        // remove any dud rows
        }
    
    private void UnflowRow(int r)
        {
        // so where possible move any from below us, into this row
        
        if (r == transform.childCount-1) return;
        Transform thisRow = transform.GetChild(r);
        Transform nextRow = transform.GetChild(r+1);
        
        while (_nominalWidthOfFirst(nextRow) < _availableSpaceOnRight(thisRow))
            {
            Transform moveMeUp = nextRow.GetChild(0);
            moveMeUp.SetParent(thisRow, false);
            moveMeUp.SetAsLastSibling();
            Canvas.ForceUpdateCanvases();
            }
        }
    
    private float _availableSpaceOnRight(Transform someRow)
        {
        return screen - someRow.GetComponent<RectTransform>().rect.width;
        }
    
    private float _nominalWidthOfFirst(Transform someRow)
        {
        if (someRow.childCount == 0) return screen*2f;
        return someRow.GetChild(0).GetComponent<RectTransform>().rect.width;
        }
    
    private void FlowRow(int r)
        {
        Transform row = transform.GetChild(r);
        
        // it's worth noting this is an indeterminate algorithm.
        // if you're not into compsci, don't worry about this. much.
        
        while (row.GetComponent<RectTransform>().rect.width > screen)
            {
            int k = row.childCount;
            
            if (k<1) return;    // setup problem!
            if (k==1) return;   // one item is too wide for screen!
            
            Transform lastOnThisRow = row.GetChild(k-1);
            MoveToStartOf( lastOnThisRow, r+1 );
            }
        }
    
    private void MoveToStartOf(Transform item, int newRow)
        {
        while (newRow >= transform.childCount)  // may have to add a row
            _addARow();
        
        Transform moveToThisRow = transform.GetChild(newRow);
        
        item.SetParent(moveToThisRow, false);
        item.SetAsFirstSibling();
        Canvas.ForceUpdateCanvases();
        }
    
    private void _addARow()
        {
        GameObject r = Instantiate(modelRow);
        r.name = "dynamically created row.";
        r.SetActive(true);
        r.transform.SetParent(transform,false);
        Canvas.ForceUpdateCanvases();
        // just remove the model unit
        while(r.transform.childCount>0)
            {
            Debug.Log("Deleting model");
            DestroyImmediate(r.transform.GetChild(0).gameObject);
            Canvas.ForceUpdateCanvases();
            }
        }
    }