首页 > 解决方案 > UI 按钮无法正确移动

问题描述

我有一个制作系统的代码,用于检查库存中是否有制作物品所需的成分,并添加一个按钮来制作它。问题是当我想定位我的按钮时,它会远离画布。我看到有人说它与矩形变换有关。我已经坚持了一个多小时。任何帮助表示赞赏。

我尝试删除 setparent() 函数,使用 anchoredPosition,使用 localPosition

我的代码

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Crafting : MonoBehaviour
{
    public List<recipe> recipes = new List<recipe>();
    public GameObject base_item, parent;
    List<GameObject> items = new List<GameObject>();
    public int y = 75;
    public int x = -45;
    public Inv inv;

    private void Start()
    {
        inv = GetComponent<Inv>();
    }

    private void Update()
    {
        if (Input.GetKeyDown(KeyCode.Tab))
        {
            checkitems();
            Debug.Log("y = " + y + " x = " + (x - 40));
        }
    }
    public void checkitems()
    {
        for (int i = 0; i < recipes.Count; i++)
        {
            recipe r = recipes[i];
            for (int x = 0; x < r.ingredients.Count; x++)
            {
                if (!inv.hasitem(r.ingredients[x])){
                    return;
                }
            }
            showitem(r.result);
        }
    }

    public void onClick(int _slot)
    {
        recipe r = recipes[_slot];
        for (int i = 0; i < r.ingredients.Count; i++)
        {
            inv.removeitem(inv.getitem(r.ingredients[i]));
        }
        inv.additem(inv.getFirstAvailable(), r.result, r.stack);
    }

    public void showitem(string name)
    {
        GameObject obj = Instantiate(base_item);
        if (items.Count != 0)
        {
            if (((items.Count) % 3) != 0)
            {
                Debug.Log("first thing");
                obj.GetComponent<RectTransform>().position = new Vector2(x, y);
                obj.transform.SetParent(parent.transform);
                obj.SetActive(true);
                items.Add(obj);
                x = x + 40;
                Debug.Log("x + 40");
            }
            else if (((items.Count + 1) % 3) == 0)
            {
                Debug.Log("second thing");
                x = -45;
                Debug.Log("x + 40");
                y = y + 40;
                Debug.Log(" y + 40");
                obj.GetComponent<RectTransform>().position = new Vector2(x, y);
                obj.transform.SetParent(parent.transform);
                obj.SetActive(true);
                items.Add(obj);
            }
        }else
        {
            obj.GetComponent<RectTransform>().position = new Vector2(x, y);
            obj.transform.SetParent(parent.transform);
            obj.SetActive(true);
            items.Add(obj);
            x = x + 40;
            Debug.Log("x + 40");
        }
    }
}

它产生的蓝色圆圈。我想要的红色圆圈

用户界面的图像

标签: c#unity3d

解决方案


似乎你混淆了一堆术语,因为你的问题是你的问题。首先,我想解决滚动条上的红色 X 问题。每当发生这种情况时,就意味着你RectTransform的这个 UI 对象已经从它的正顶点拖到负顶点,反之亦然,导致它几乎反转。我会纠正这一点,但这不是你的对象没有正确生成的原因。

一般来说,对于 UI 对象,我永远不会使用LocalPosition,只是AnchoredPosition. LocalPositionTransform我相信RectTransform继承自的领域。由于从、和RectTransforms对其位置进行了大量修改,因此很可能需要重新计算数据才能正确移动对象,而这些计算已经完成。pivotsanchorsanchored positionsLocalPositionAnchoredPosition

我相信您当前代码的问题在于您如何使用SetParent. 第二个参数SetParent控制对象在被子化后是否在世界空间中保持相同的位置。由于您没有bool为此参数传入新参数,因此默认为true. 由于您希望将对象作为父对象的子对象但不保留其世界空间位置,因此您需要传入false.

在您的情况下,看起来好像您想将对象设置为与 this 关联的网格状模式ScrollRect,我会将 a 附加GridLayoutGroupContent您的滚动条,并将新对象添加到该对象。您可以设置此网格的最大列数和间距,以提供您尝试在代码中实现的相同布局。

总而言之,我将删除您在代码中使用LocalPositionand进行的所有手部放置,AnchorPosition然后附加一个GridLayoutGroup. 要修复对象相对于父对象的当前位置,请将所有行更改obj.transform.SetParent(parent.transform);obj.transform.SetParent(parent.transform, false);。如果您想在代码中而不是布局元素中保持本地更改位置,SetParent请先使用,然后使用AnchoredPosition而不是,LocalPosition因为传入的SetParentwith将覆盖您设置的位置。false


推荐阅读