0 votes

Hello,

I have created an autotile for building a fence which is working fine (except when placing a 4x4 square, not a big deal but if someone has an idea about that too...).
I also have built a scene for the door which is a StaticBody2D with an AnimatedSprite and a CollisionShape2D. All my tiles are 16*16 and so is the door sprite.
My autotile fence

What I want is one of the following behaviour:
- Door is placed on an empty 16x16 grid slot between 2 fence slots: the fence re-adjust to connect to the door.
- Door is placed on a fence tile, the fence tile is deleted but the connected fences do not change their state so they stay connected to the door

Gate position behaviour

How can any of these solutions be implemented (the simplest as they both would work for my game)? Or may be there is another (better) way of doing this?

I would really appreciate if someone could point me to the right direction.

Thanks !

Godot version v3.3.2.stable.official
in Engine by (21 points)

2 Answers

0 votes
Best answer

I found a nice video explaining how to instantiate a scene from a TileMap which allowed me to do what I wanted.
Here it is for anyone looking: https://www.youtube.com/watch?v=CDwSTV0y9Rg

Based on that, I wrote this script for my fence tilemap, it will replace the tile of the fence by an actual fence scene I've created (that handle opened/closed state & animation):

extends TileMap

const wooden_gate = preload("res://WoodenGate.tscn")

func _ready():
    var gates_pos = get_used_cells_by_id(1)
    var tilePos
    for gate_pos in gates_pos:
        var gate = wooden_gate.instance()
        tilePos = map_to_world(gate_pos)
        gate.set_position(tilePos)
        set_cell(gate_pos.x, gate_pos.y, -1)
        self.add_child(gate)

And this small code I've seen multiple times comes very handy as it allows the AutoTile for the fence to match the door (which is not in the fence autotile set). It's a script to attach to the TileSet:

tool
extends TileSet

const WOODEN_FENCE = 0
const WOODEN_GATE = 1

var binds = {
    WOODEN_FENCE: [WOODEN_GATE],
    WOODEN_GATE: [WOODEN_FENCE]
}

func _is_tile_bound(drawn_id, neighbor_id):
    if drawn_id in binds:
        return neighbor_id in binds[drawn_id]
    return false

Then, I just need to create a tile for the door in the tileset and set the bitmap to match the expected left and right fences.
Here is the result:

Result of the code

by (21 points)
+1 vote

Well, the simplest way is to turn off auto-tiling and just place the tiles yourself. Unfortunately Godot 3 does not natively have the capability to auto-tile different between different types of tiles. You'll have to wait for Godot 4 with terrains in order to do that.

by (7,190 points)

Thanks for your answer. Of course this is the obvious solution, but I forgot to mention that I want the player to be able to place fences and doors, and it would not be very user friendly that way...

Then you will need to write a script that does conditional autotiling yourself for the player to place down fences.

Ok I'll do that then, thank you!

Welcome to Godot Engine Q&A, where you can ask questions and receive answers from other members of the community.

Please make sure to read How to use this Q&A? before posting your first questions.
Social login is currently unavailable. If you've previously logged in with a Facebook or GitHub account, use the I forgot my password link in the login box to set a password for your account. If you still can't access your account, send an email to webmaster@godotengine.org with your username.