当前位置:   article > 正文

Unity3D-iOS中使用Tilemap问题研究以及解决方案_unityengine.setupcoroutine.invokemovenext

unityengine.setupcoroutine.invokemovenext

前不久刚刚研究了Unity3D的Tilemap,在编辑器里面捣鼓了半天,总算是弄明白怎么用了。

昨天想着可以上真机试试看,结果悲剧果然发生了。在iOS平台上无法显示Tilemap!准确来说,是在iOS平台,用代码初始化Tilemap没有效果,log里面你会看到下面的错误:

NullReferenceException: A null value was found where an object instance was required.

  at UnityEngine.Tilemaps.TileBase.RefreshTile (Vector3Int position, UnityEngine.Tilemaps.ITilemap tilemap) [0x00000] in <filename unknown>:0 

  at UnityEngine.Tilemaps.Tilemap.SetTile (Vector3Int position, UnityEngine.Tilemaps.TileBase tile) [0x00000] in <filename unknown>:0 

  at GameManager+<InitData>c__Iterator0.MoveNext () [0x00000] in <filename unknown>:0 

  at UnityEngine.SetupCoroutine.InvokeMoveNext (IEnumerator enumerator, IntPtr returnValueAddress) [0x00000] in <filename unknown>:0 

UnityEngine.Tilemaps.Tilemap:SetTile(Vector3Int, TileBase)

<InitData>c__Iterator0:MoveNext()

UnityEngine.SetupCoroutine:InvokeMoveNext(IEnumerator, IntPtr)


Error running RefreshTile for previous TileNullReferenceException: A null value was found where an object instance was required.

  at UnityEngine.Tilemaps.TileBase.RefreshTile (Vector3Int position, UnityEngine.Tilemaps.ITilemap tilemap) [0x00000] in <filename unknown>:0 

  at UnityEngine.Tilemaps.Tilemap.SetTile (Vector3Int position, UnityEngine.Tilemaps.TileBase tile) [0x00000] in <filename unknown>:0 

  at GameManager+<InitData>c__Iterator0.MoveNext () [0x00000] in <filename unknown>:0 

  at UnityEngine.SetupCoroutine.InvokeMoveNext (IEnumerator enumerator, IntPtr returnValueAddress) [0x00000] in <filename unknown>:0 

UnityEngine.Tilemaps.Tilemap:SetTile(Vector3Int, TileBase)

<InitData>c__Iterator0:MoveNext()

UnityEngine.SetupCoroutine:InvokeMoveNext(IEnumerator, IntPtr)

然后在网上找了很久,也没看见有人说解决方案,这是Unity官网上的问题,目前还没人解决掉。

点击打开链接

点击打开链接

在贴吧看到这个问题,也没人回答- -

点击打开链接

然后就自己各种尝试,看看是不是哪里写错了,或者要弄清楚,这个到底还可以用不?

最后我尝试了好几种方式,弄清楚是怎么回事了,下面是我测试代码:

  1. //下面测试,如果 i < 25,那么是已经在编辑器中存在的 tile 做的操作
  2. int len = 5;
  3. for(int i=0;i<len*len;i++){
  4. tempIntPoint = new Vector3Int(i%len, i/len, 0);
  5. // Tile tempTile = testMap.GetTile<Tile>(tempIntPoint);
  6. // tempTile.color = listColorData[Random.Range(0, listColorData.Count)].mColor;
  7. //这种可以利用同样的Tile设置不同的颜色
  8. // testMap.RefreshTile(tempIntPoint);
  9. //这种设置颜色之后,所有引用同一个Tile的方块都会变色
  10. // testMap.SetTile(tempIntPoint, tempTile);
  11. //这种方式同上面的,所有方块都变,但是我这里使用的 Tile 是从预制中加载的
  12. // baseTile.color = listColorData[Random.Range(0, listColorData.Count)].mColor;
  13. // testMap.SetTile(tempIntPoint, baseTile);
  14. //因为 baseTile 和 testMap 里面已存在的 tile 引用的是同一个,所以还是会变色
  15. // baseTile.color = listColorData[Random.Range(0, listColorData.Count)].mColor;
  16. // testMap.RefreshTile(tempIntPoint);
  17. //这种方式同上,但是使用 Tile 是动态生成的,无法使用,iOS 上报 null 的错误
  18. // testMap.SetTile(tempIntPoint, listColorData[Random.Range(0, listColorData.Count)].mTile);
  19. //预先设置好的Tile,可以设置,但是不能超过 testMap 已存在的 tile
  20. // testTile.color = listColorData[Random.Range(0, listColorData.Count)].mColor;
  21. // testMap.SetTile(tempIntPoint, testTile);
  22. }

最后得出两个结论:

1、在iOS平台,Tilemap必须要预先设置好,意思就是说一开始在编辑器中填充好一个Tilemap,可以用纯色的色块,设置最大的宽高;

2、Tile不能是有代码创建的,上面第五个尝试就说明了这个问题,就算Tilemap预先填充了Tile,但是Tile是由代码创建的,还是会报错;

所以,这个问题的暂时解决方案就是Tilemap预先填充,Tile可以用同一块,然后在设置时,使用RefreshTile,这样可以达到想要的目标,也不需要想着预先生成多个地图块了。

我现在做的方式是:

1、在编辑器填充 Tilemap,最大化处理;

2、在编辑器中设置好需要用到的Tile;

3、在初始化Tilemap时,可以将Tile的Color的透明度设置为0,然后调用Tilemap的RefreshAllTiles,可以达到清除所有Tile的目的(间接清楚,看不到而已);

4、然后根据数据需要,设置Tile的颜色,图块,调用Tilemap的RefreshTile,这样就可以做到不同图块的显示了;

5、在要点击Tilempa改变图块时,要注意Tilemap的边界问题;

6、完毕!

希望Unity以后可以把这个问题解决掉吧!如果有人觉得我这个方式麻烦,那么只有去找插件了,毕竟以前很多人都用过的。



声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/2023面试高手/article/detail/134815
推荐阅读
相关标签
  

闽ICP备14008679号