Roguelike随机地下城 | 三、建立墙Wall

本文详细介绍了如何在Unity3D中为Roguelike游戏构建随机地下城的墙系统。首先,通过创建十五种不同门组合的墙预制体,然后在代码中定义了一个名为`WallType`的类来存储这些预制体,以保持代码整洁。接着,利用`Physics2D.OverlapCircle`检测房间的开口,并根据房间的开口数量和方向,通过`switch`语句实例化相应的墙预制体。最后,作者强调了这种方法的可扩展性,便于未来素材更新。下一部分将介绍使用Unity的Tilemap功能来绘制场景并创建Player角色。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Roguelike随机地下城

建立墙Wall


建立墙Wall

现在我们有十五种上下左右门组合的墙的资源,我们分别命名设置十五个预制体,方便我们后续的使用。
我们只需要建立一个空的GameObject,然后将我们的资源放入作为子集即可。
在这里插入图片描述
接下来我们需要在代码中获得这些预制体。
如果我们都用Public GameObject来生成,这样显得我们代码很乱。
所以这里我定义了一个新的类,用来存放这些预制体。
这里为了让我们的Unity识别出来,我们需要在类上面加入**[System.Serializable]**,这样才能被Unity识别到。

[System.Serializable]
public class WallType
{
    public GameObject singleLeft, singleRight, singleUp, singleBottom,
                      doubleUL, doubleLR, doubleBL, doubleUR, doubleUB, doubleBR,
                      tripleULR, tripleUBL, tripleUBR, tripleBLR,
                      fourDoors;
}

这样回到Unity中就可以将预制体放入对应的框里。
在这里插入图片描述
接下来就要实现在每个房间生成对应的预制体。
之前在Room脚本中我们可以判断一个房间有上下左右那个门,有几个开口DoorNumber
所以我们就可以通过一个简单的Switch语句来判断有几个门就在对应的有几个门的预制体中直接挑选我们的预制体,比如DoorNumber为1,那么就在有一个门的预制体中找到对应有上下左右那个门的预制体。
通过我们定义的四个方向来判断有哪个方向的门。

        newRoom.roomUp = Physics2D.OverlapCircle(roomPosition + new Vector3(0, yOffset, 0), 0.2f, roomLayer);
        newRoom.roomDown = Physics2D.OverlapCircle(roomPosition + new Vector3(0, -yOffset, 0), 0.2f, roomLayer);
        newRoom.roomLeft = Physics2D.OverlapCircle(roomPosition + new Vector3(-xOffset, 0, 0), 0.2f, roomLayer);
        newRoom.roomRight = Physics2D.OverlapCircle(roomPosition + new Vector3(xOffset, 0, 0), 0.2f, roomLayer);

最后我们通过Instantiate方法来生成预制体即可。

    public void SetupRoom(Room newRoom,Vector3 roomPosition)
    {
        newRoom.roomUp = Physics2D.OverlapCircle(roomPosition + new Vector3(0, yOffset, 0), 0.2f, roomLayer);
        newRoom.roomDown = Physics2D.OverlapCircle(roomPosition + new Vector3(0, -yOffset, 0), 0.2f, roomLayer);
        newRoom.roomLeft = Physics2D.OverlapCircle(roomPosition + new Vector3(-xOffset, 0, 0), 0.2f, roomLayer);
        newRoom.roomRight = Physics2D.OverlapCircle(roomPosition + new Vector3(xOffset, 0, 0), 0.2f, roomLayer);

        newRoom.UpdateRoom();

        switch (newRoom.doorNumber)
        {
            case 1:
                if (newRoom.roomUp)
                    Instantiate(wallType.singleUp, roomPosition, Quaternion.identity);
                if (newRoom.roomDown)
                    Instantiate(wallType.singleBottom, roomPosition, Quaternion.identity);
                if (newRoom.roomLeft)
                    Instantiate(wallType.singleLeft, roomPosition, Quaternion.identity);
                if (newRoom.roomRight)
                    Instantiate(wallType.singleRight, roomPosition, Quaternion.identity);
                break;
            case 2:
                if (newRoom.roomUp && newRoom.roomDown)
                    Instantiate(wallType.doubleUB, roomPosition, Quaternion.identity);
                if (newRoom.roomUp && newRoom.roomLeft)
                    Instantiate(wallType.doubleUL, roomPosition, Quaternion.identity);
                if (newRoom.roomUp && newRoom.roomRight)
                    Instantiate(wallType.doubleUR, roomPosition, Quaternion.identity);
                if (newRoom.roomDown && newRoom.roomLeft)
                    Instantiate(wallType.doubleBL, roomPosition, Quaternion.identity);
                if (newRoom.roomDown && newRoom.roomRight)
                    Instantiate(wallType.doubleBR, roomPosition, Quaternion.identity);
                if (newRoom.roomLeft && newRoom.roomRight)
                    Instantiate(wallType.doubleLR, roomPosition, Quaternion.identity);
                break;
            case 3:
                if (newRoom.roomUp && newRoom.roomDown && newRoom.roomLeft)
                    Instantiate(wallType.tripleUBL, roomPosition, Quaternion.identity);
                if (newRoom.roomUp && newRoom.roomDown && newRoom.roomRight)
                    Instantiate(wallType.tripleUBR, roomPosition, Quaternion.identity);
                if (newRoom.roomDown && newRoom.roomLeft && newRoom.roomRight)
                    Instantiate(wallType.tripleBLR, roomPosition, Quaternion.identity);
                if (newRoom.roomUp && newRoom.roomLeft && newRoom.roomRight)
                    Instantiate(wallType.tripleULR, roomPosition, Quaternion.identity);
                break;
            case 4:
                if (newRoom.roomUp && newRoom.roomLeft && newRoom.roomRight && newRoom.roomDown)
                    Instantiate(wallType.fourDoors, roomPosition, Quaternion.identity);
                break;
        }

这里的代码可能比较繁琐,但是是为了我们之后更好的使用,如果有新的素材可以直接替换预制体即可。
最后回到我们的Unity运行一下。
在这里插入图片描述
这样我们要的效果就出现了。


总结

这节我们主要实现了Wall的建立,下次我们会通过Unity的组件Tilemap瓦片功能来绘制我们的场景,并且对我们的Player进行创建。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值