1. The effect to be achieved
- Storage function: Click [Step Name] to pop up [Detailed Steps Page], click again to store this page
- More self-adaptive steps: [Detailed steps page] The small steps in it can be added at will, and the layout is equidistant along the vertical direction
- Drag and slide to display: [Detailed steps page] You can drag and drop with the mouse, slide up and down to browse
2. Implementation process
The difficulty of this step: the detailed steps can be more or less, and these steps are arranged equidistantly along the vertical direction
function to be implemented | what components to use | ||
---|---|---|---|
1 | How to implement window scrolling | ScrollView | |
2 | Automatic vertical arrangement after detailed steps are dynamically added | Vertical Layout Group | |
3* | Why [Tect Transform of the Content component] will not stretch in the vertical direction | Content Size Fitter | vertical adaptation |
Step 3 above is critical
[Vertical Layout Group] and [Content Size Fitter] parameter settings:
/// <summary>
/// 设置VerticalLayoutGroup与ContentSizeFitter组件的属性
/// </summary>
public void InitContentComponent()
{
//添加 Vertical Layout Group 组件,并设置为自动布局
if (content.GetComponent<VerticalLayoutGroup>() == null) content.gameObject.AddComponent<VerticalLayoutGroup>();
VerticalLayoutGroup layoutGroup = content.GetComponent<VerticalLayoutGroup>();
layoutGroup.childControlHeight = true;
layoutGroup.childForceExpandHeight = false;
layoutGroup.spacing = spacing; // 设置新的 Text 对象的间距
//添加ContentSizeFitter组件,内容自适应
if (content.GetComponent<ContentSizeFitter>() == null) content.gameObject.AddComponent<ContentSizeFitter>();
var contentFiter = content.GetComponent<ContentSizeFitter>();
contentFiter.verticalFit = ContentSizeFitter.FitMode.PreferredSize; // 将 Vertical Fit 设置为 Preferred Size
}
3. Script and code
using TMPro;
using UnityEngine;
using UnityEngine.UI;
public class ScrollViewTexts : MonoBehaviour
{
/// <summary>
/// scrollView的Content对象
/// </summary>
[Header("scrollView的Content对象")]
[SerializeField]
public RectTransform content;
/// <summary>
/// 用来实例化的text对象
/// </summary>
[Header("用来实例化的text对象")]
[SerializeField]
public GameObject textPrefab;
/// <summary>
/// 垂直布局时,item之间的间距
/// </summary>
[Header("文本的行间距")]
[SerializeField]
public float spacing = 1f;
void Start()
{
InitContentComponent();
}
/// <summary>
/// 设置VerticalLayoutGroup与ContentSizeFitter组件的属性
/// </summary>
public void InitContentComponent()
{
//添加 Vertical Layout Group 组件,并设置为自动布局
if (content.GetComponent<VerticalLayoutGroup>() == null) content.gameObject.AddComponent<VerticalLayoutGroup>();
VerticalLayoutGroup layoutGroup = content.GetComponent<VerticalLayoutGroup>();
layoutGroup.childControlHeight = true;
layoutGroup.childForceExpandHeight = false;
layoutGroup.spacing = spacing; // 设置新的 Text 对象的间距
//添加ContentSizeFitter组件,内容自适应
if (content.GetComponent<ContentSizeFitter>() == null) content.gameObject.AddComponent<ContentSizeFitter>();
var contentFiter = content.GetComponent<ContentSizeFitter>();
contentFiter.verticalFit = ContentSizeFitter.FitMode.PreferredSize; // 将 Vertical Fit 设置为 Preferred Size
}
/// <summary>
/// 添加新的Text文本
/// </summary>
/// <param name="text">文本的内容</param>
/// <returns>text对象</returns>
public GameObject AddText(string text)
{
// 创建新的 Text 对象
GameObject newText = Instantiate(textPrefab, content);
// 设置 Text 组件的文本内容
newText.GetComponent<TMP_Text>().text = text;
// 添加 ContentSizeFitter 组件,并设置为 VerticalFitMode.PreferredSize
ContentSizeFitter sizeFitter = newText.AddComponent<ContentSizeFitter>();
sizeFitter.verticalFit = ContentSizeFitter.FitMode.PreferredSize;
// 重新计算布局
LayoutRebuilder.ForceRebuildLayoutImmediate(content);
return newText;
}
[Header("文本内容-测试用")]
[SerializeField]
public string text;
#if UNITY_EDITOR
[ContextMenu("测试")]
#endif
void Test()
{
AddText(text);
}
}