Unity3d 在Unity(2D)中连接具有不同纹理的规则平铺
我正在Unity中创建一个2D平台,我正在使用“2D Extras”附加组件中的ruletiles。我目前正在尝试让两个RuleTile相互连接,即使它们具有不同的纹理。在这里,您可以看到一个示例。我想连接浅色和深色的草砖。它们位于两个独立的ruletile文件中Unity3d 在Unity(2D)中连接具有不同纹理的规则平铺,unity3d,sprite,unity3d-2dtools,Unity3d,Sprite,Unity3d 2dtools,我正在Unity中创建一个2D平台,我正在使用“2D Extras”附加组件中的ruletiles。我目前正在尝试让两个RuleTile相互连接,即使它们具有不同的纹理。在这里,您可以看到一个示例。我想连接浅色和深色的草砖。它们位于两个独立的ruletile文件中 我如何管理这一点?有几种方法可以实现这一点,主要取决于您在视觉上希望如何连接有问题的磁贴。我通常处理这个问题的方法是修改ruletile,以便区分: 相同的瓷砖类型(此) 另一种磁贴类型(不是此) emtpy瓷砖(空) 我认为实现
我如何管理这一点?有几种方法可以实现这一点,主要取决于您在视觉上希望如何连接有问题的磁贴。我通常处理这个问题的方法是修改ruletile,以便区分:
- 相同的瓷砖类型(此)
- 另一种磁贴类型(不是此)
- emtpy瓷砖(空)
public enum Neighbor { DontCare, This, NotThis, Empty }
最重要的是:
// When this returns true, that means that the rule does not match
// IE this is testing if any of the rules are broken
// If the rule matches that means that the sprite associated to the rule will be the new main sprite
// These are the rules which are being checked if they are broken
// This - should only be triggered for the same tile type,
// which is not the case when the tile is not this
// NotThis - should only be triggered for another tile, which is not empty
// IE broken when it is this or null(empty)
// Empty - should only be triggered when there is no tile
// IE broken when it is this or not null(empty)
private bool RuleBroken(TilingRule rule, int index, TileBase tile)
{
return (rule.m_Neighbors[index] == TilingRule.Neighbor.This && tile != this)
|| (rule.m_Neighbors[index] == TilingRule.Neighbor.NotThis && (tile == this || tile == null))
|| (rule.m_Neighbors[index] == TilingRule.Neighbor.Empty && (tile == this || tile != null))
;
}
剩下的是对编辑器文件进行更改,以便您可以在4个而不是3个枚举状态之间切换,然后在网格中绘制所选图形
如果您想使用我的更改版本,您可以找到
注意:通过此实现,您的ruletile将需要更多的规则来描述每个tile。我也遇到了同样的问题,但我看到包代码已经更新,因此我将相同的解决方案应用于包的最新版本(适用于Unity 2019.2.0f1)。我把它放在这里,以防有人需要它: 添加代码的大部分相关部分: 在RuleTile.cs中,在第57行(类邻居)添加了新类型的邻居:
public const int Empty=3;
以及如何管理它(更基本的RuleMatch实现):
第413页改为:
case TilingRule.Neighbor.NotThis:return(tile!=m\u Self&&tile!=null);
并在以下字句之后加入:
case TilingRule.Neighbor.Empty:返回tile==null;
在ruletileditor.cs中,在第28行添加了图标:
private const string s_OtherTile="一个中国政府的一个中国政府的一个中国政府一个中国政府一个中国政府一个中国政府一个中国政府一个中国政府一个中国政府一个中国政府一个中国政府一个中国政府一个中国政府一个中国政府一个中国政府一个中国政府一个中国政府一个中国政府一个中国政府一个中国政府一个中国政府一个中国政府一个中国政府一个中国一个中国政府一个中国政府一个中国政府一个中国政府一个中国政府一个中国政府一个中国政府一个中国政府一个中国政府一个中国政府一个中国政府一个中国政府一个中国政府一个中国政府一个中国政府一个中国政府一个中国政府一个中国政府一个中国政府一个中国政府一个中国政府一个中国政府一个中国政府一个中国政府一个中国政府一个中国政府一个中国政府一个中国政府一个中国政府一个中国政府一个中国政府一个中国政府一个中国政府一个中国政府一个中国政府一个中国政府DDMA(2)QQQVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVXLTWWRGQ3G7KXE4BOYRCDGa7ABXH1An+zoOh3fgcAkVNC6ZGUg/8AAAAASUVORK5CYII=“;
添加到47处的纹理数组(并将第37行中的数组项目数更改为11):
s_Arrows[10]=Base64ToTexture(s_OtherTile);
最后,将“NotThis”GUI移动到数组中的项目10,这样我们就可以添加“Empty”并使用第198行的图标编号9,如下所示:
case RuleTile.TilingRule.Neighbor.NotThis:
DrawTexture(矩形,箭头[10]);
打破
大小写规则tile.TilingRule.Neighbor.Empty:
DrawTexture(矩形,箭头[9]);
打破
就这些:)
非常感谢您的解决方案,Alexander:)2d Tilemap Extras的贡献者包括对规则tile的选择性覆盖 示例如下: 特别是第1条 这将创建一个新的规则磁贴,其功能与规则磁贴相同,只是它还包括同样在可展开列表中的规则磁贴 我不想遍历我的150万条规则,将所有规则从绿色箭头“This”更改为#3“Sibling”,所以我只是用它覆盖“This”以包含“Sibling”
public类同级tile:RuleTile{
公共列表同级=新列表();
公共覆盖布尔规则匹配(int邻居,TileBase平铺){
//直接覆盖规则磁贴的“此”检查,并将其包含在同级列表中。
交换机(邻居){
case TilingRuleOutput.Neighbor.This:
return tile==此| |兄弟.包含(tile);
}
返回base.RuleMatch(邻居,平铺);
}
}
非常好而且简单。我使用了Kmsxkuse的解决方案,但我不得不对它进行一些修改,因为它对我不起作用
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Tilemaps;
using static UnityEngine.RuleTile.TilingRuleOutput;
namespace Assets.Scripts.Tiles
{
[CreateAssetMenu]
public class PathHighlightTile : IsometricRuleTile<Neighbor>
{
public List<TileBase> Siblings = new List<TileBase>();
public override bool RuleMatch(int neighbor, TileBase other)
{
switch (neighbor)
{
case Neighbor.This:
{
return other == this || Siblings.Contains(other);
}
case Neighbor.NotThis:
{
return other != this && !Siblings.Contains(other);
}
}
return base.RuleMatch(neighbor, other);
}
}
}
使用System.Collections.Generic;
使用UnityEngine;
使用UnityEngine.Tilemaps;
使用静态UnityEngine.RuleTile.TilingRuleOutput;
命名空间资产.Scripts.Tiles
{
[创建资产菜单]
公共类PathHighlightTile:IsometricRuleTile
{
公共列表同级=新列表();
公共覆盖布尔规则匹配(int邻居,TileBase其他)
{
交换机(邻居)
{
案例邻居。这是:
{
return other==此| |兄弟.包含(其他);
}
case Neighbor.NotThis:
{
return other!=此&&!兄弟.Contains(其他);
}
}
返回base.RuleMatch(邻居,其他);
}
}
}
谢谢你的回答。我检查了你的代码,我理解你的方法,但我不确定你是如何询问邻居是否为空的。这是怎么回事?如果你同意,我会使用你的代码,但我也想理解。是的,请随意使用。:)我花了一段时间才明白到底发生了什么我对这个类的理解是,每当网格中的ruletile得到刷新时,它都会检查它需要什么,方法是在每个tilingrules上循环,返回第一个实际符合的规则
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Tilemaps;
using static UnityEngine.RuleTile.TilingRuleOutput;
namespace Assets.Scripts.Tiles
{
[CreateAssetMenu]
public class PathHighlightTile : IsometricRuleTile<Neighbor>
{
public List<TileBase> Siblings = new List<TileBase>();
public override bool RuleMatch(int neighbor, TileBase other)
{
switch (neighbor)
{
case Neighbor.This:
{
return other == this || Siblings.Contains(other);
}
case Neighbor.NotThis:
{
return other != this && !Siblings.Contains(other);
}
}
return base.RuleMatch(neighbor, other);
}
}
}