你正在做
LetterInputTile[i].transform.SetParent(null);
这会将您的对象设置为场景根级别。但他们似乎UI.Image
必须嵌套在 a 下的组件Canvas
以便被渲染。
还有你新创建的对象LetterInputTileParent
不嵌套在Canvas
但在场景根级别。
=> 你很可能更愿意维护
- the
LetterInputTileParent
- 和瓷砖本身
总是嵌套在Canvas
对于所有情况。
为此,您可以例如找到并做
// If possible it is always better to directly reference your objects via the Inspector
// In order to avoid any runtime issues and save some performance
[SerializeField] Canvas _canvas;
private void Awake()
{
// As a fallback find the canvas on runtime - assuming there is only one anyway
if(!_canvas) _canvas = FindObjectOfType<Canvas>();
// You could/should also rather create this one beforehand
// and reference this directly via the Inpector
if(!letterInputTileParent )
{
letterInputTileParent = new GameObject("LetterInputTileParent");
// Make sure it is under the Canvas
letterInputTileParent.AddComponent<RectTransform>();
letterInputTileParent.SetParent(_canvas.transform, false);
}
LetterInputTile = GameObject.FindGameObjectsWithTag("MLetterTile");
}
一般来说,我不完全理解你的组件背后的逻辑。但你似乎把它附加到每个LetterSlot
。然而你却发现all带有标签的对象MLetterTile
。它们不是同时运行吗?
我也不会这样做Update
和一个布尔标志一遍又一遍。
您已经有两个事件消息,所以为什么不处理那里的结果once.
另请注意你的循环foreach
然后是嵌套的for
循环是完全多余的并且迭代相同的项目
private void OnCollisionEnter2D(Collision2D other)
{
if(other.gameObject.CompareTag("MLetterTile"))
{
foreach (GameObject obj in LetterInputTile)
{
obj.transform.SetParent(letterInputTileParent.transform);
}
}
}
private void OnCollisionExit2D(Collision2D other)
{
if (other.gameObject.CompareTag("MLetterTile"))
{
foreach (GameObject obj in LetterInputTile)
{
obj.transform.SetParent(/*probably not null but something else see above*/);
}
}
}
很可能您甚至不想迭代at all- 考虑一下,您似乎要检查与数组中的对象完全相同的标签的碰撞=>您只想仅作为父对象this other
您碰撞的对象,甚至可能不需要创建新的父对象。
我怀疑你更想要实现的是
- 如果一个对象带有标签
MLetterTile
与槽碰撞
- 将此插槽设置为对象的新父级
- 如果它退出插槽
- 将其设置回其原始父级
所以我宁愿期待类似的东西
public class ParentSetter : MonoBehaviour
{
private readonly Dictionary<Transform, Transform> originalParents = new ();
private void OnCollisionEnter2D(Collision2D other)
{
if(!other.gameObject.CompareTag("MLetterTile")) return;
originalParents[other.transform] = other.transform.parent;
other.transform.SetParent(transform);
}
private void OnCollisionExit2D(Collision2D other)
{
if(!other.gameObject.CompareTag("MLetterTile")) return;
if(!originalParents.Remove(other.transform, out var originalParent)) return;
other.transform.SetParent(originalParent);
}
}
In the originalParents
你现在同时发现
- 当前位于此槽中的对象(
originalParents.Keys
)
- 原始父母在退出插槽时重置它们