Hi all
I know that I'm not the first person who has wanted to create a map with multi-storey buildings. My search for how to do so has evolved into a Holy Grail-like quest since there are hints and tips scattered across dozens of threads, but no one definitive resource.
What I want to do with this thread is identify all of the problems associated with multi-storey buildings and their potential solutions. Having done so, I will then collate all of the information into a definitive guide that I am sure will help many current and aspiring mapmakers.
What features must a multi-storey building have?
1. Two (or more) floors, vertically separated, with their own doodads, destructibles, and/or units.
2. Units (especially player-controlled units) must be capable of entering each floor.
3. Floors that a player-controlled unit is not on must either be transparent or not visible to the player-controlled unit.
4. Units (especially player-controlled units) must be capable of co-existing on different floors in the same 2D location simultaneously.
5. Units (especially player-controlled units) must not interact with each other (i.e. attack each other; give items; cast spells or use abilities on each other) across different floors.
What are the problems?
1. We need to be able to track which floor units are on.
2. Unit vision on a particular floor will be obscured by higher floors.
3. Unit movement on a particular floor will be obstructed by collisions with units, doodads, and destructibles on other floors.
4. Units can interact with each other across floors provided they are within sufficient 2D proximity of each other.
What are the possible solutions?
1a. Create small regions near the entrance and exit point(s) for each floor to track whether a unit is entering it. Create an array to store the floor that each unit is on.
1b. Give every unit that you want to be capable of entering different floors the ability to fly. Track whether it enters a particular floor using regions per 1a, adjust it's flying height accordingly, and get it's current flying height whenever you need to check which floor it is on.
[Note: these solutions could fail for very complex multi-storey buildings if the regions used for tracking unit movement overlap across different floors. One way of possibly solving this would be to use the unit's last stored floor location to filter out overlapping regions.
For example, assume region A on floor 1 is the entrance point for floor 2, region B on floor 2 is the entrance point for floor 3, and both of these regions overlap each other. When a unit enters floor 1, we store its floor position accordingly. Then, when it enters those overlapping regions, we can correctly change its floor position to floor 2 - and not floor 3 - by using both the region as well as its last stored floor position.]
2. Hide units and destructibles using GetLocalPlayer() (see: http://www.hiveworkshop.com/forums/world-editor-help-zone-98/getlocalplayer-faq-224876/)
[Note: I am assuming additional problems may arise if a player controls more than one unit.]
3a. Remove pathing from all doodads and destructibles used to create buildings, and use pathing blockers to control pathing instead. Use ground pathing blockers for the ground floor and flying pathing blockers for the second storey. Give units that enter the second storey the ability to fly so that they aren't obstructed by ground level units or pathing blockers.
[Note: This won't work for more complex buildings with more than two storeys.]
3b. Remove pathing from all doodads and destructibles used to create buildings, and use pathing blockers to control pathing instead. Create regions near each pathing blocker to track whether a unit is approaching it. Disable collisions for units when they enter the building. Enable collisions when units enter a region indicating that they are approaching a pathing blocker. Disable collisions when they exit those same regions. Filter out regions from floors other than the one that a unit is on using the method described under 1b.
[Note: While this should work for complex buildings with more than two floors, it is not a guaranteed solution for unit collisions since two or more units might obstruct each other if they have collisions turned on having entered overlapping regions used to monitor their proximity to pathing blockers. However, it might be possible to circumvent this possibility by constructing buildings very strategically such that the pathing blocking regions on each floor don't overlap significantly or at all.]
3c. Combine 1b and 3a or 3b. Track every unit's 2D co-ordinates and compare their flying height when they are about to collide. If their flying heights are the same, then turn collisions off for them and turn them back on when they are no longer within 2D proximity of each other.
4. Hide units and destructibles using GetLocalPlayer() so that units on different floors can't interact.
[Note: I am assuming this won't work if a player controls more than one unit.]
Please help me with this guide!
I'm far from being an expert, so I would greatly appreciate suggestions and corrections from other mapmakers.
I know that I'm not the first person who has wanted to create a map with multi-storey buildings. My search for how to do so has evolved into a Holy Grail-like quest since there are hints and tips scattered across dozens of threads, but no one definitive resource.
What I want to do with this thread is identify all of the problems associated with multi-storey buildings and their potential solutions. Having done so, I will then collate all of the information into a definitive guide that I am sure will help many current and aspiring mapmakers.
What features must a multi-storey building have?
1. Two (or more) floors, vertically separated, with their own doodads, destructibles, and/or units.
2. Units (especially player-controlled units) must be capable of entering each floor.
3. Floors that a player-controlled unit is not on must either be transparent or not visible to the player-controlled unit.
4. Units (especially player-controlled units) must be capable of co-existing on different floors in the same 2D location simultaneously.
5. Units (especially player-controlled units) must not interact with each other (i.e. attack each other; give items; cast spells or use abilities on each other) across different floors.
What are the problems?
1. We need to be able to track which floor units are on.
2. Unit vision on a particular floor will be obscured by higher floors.
3. Unit movement on a particular floor will be obstructed by collisions with units, doodads, and destructibles on other floors.
4. Units can interact with each other across floors provided they are within sufficient 2D proximity of each other.
What are the possible solutions?
1a. Create small regions near the entrance and exit point(s) for each floor to track whether a unit is entering it. Create an array to store the floor that each unit is on.
1b. Give every unit that you want to be capable of entering different floors the ability to fly. Track whether it enters a particular floor using regions per 1a, adjust it's flying height accordingly, and get it's current flying height whenever you need to check which floor it is on.
[Note: these solutions could fail for very complex multi-storey buildings if the regions used for tracking unit movement overlap across different floors. One way of possibly solving this would be to use the unit's last stored floor location to filter out overlapping regions.
For example, assume region A on floor 1 is the entrance point for floor 2, region B on floor 2 is the entrance point for floor 3, and both of these regions overlap each other. When a unit enters floor 1, we store its floor position accordingly. Then, when it enters those overlapping regions, we can correctly change its floor position to floor 2 - and not floor 3 - by using both the region as well as its last stored floor position.]
2. Hide units and destructibles using GetLocalPlayer() (see: http://www.hiveworkshop.com/forums/world-editor-help-zone-98/getlocalplayer-faq-224876/)
[Note: I am assuming additional problems may arise if a player controls more than one unit.]
3a. Remove pathing from all doodads and destructibles used to create buildings, and use pathing blockers to control pathing instead. Use ground pathing blockers for the ground floor and flying pathing blockers for the second storey. Give units that enter the second storey the ability to fly so that they aren't obstructed by ground level units or pathing blockers.
[Note: This won't work for more complex buildings with more than two storeys.]
3b. Remove pathing from all doodads and destructibles used to create buildings, and use pathing blockers to control pathing instead. Create regions near each pathing blocker to track whether a unit is approaching it. Disable collisions for units when they enter the building. Enable collisions when units enter a region indicating that they are approaching a pathing blocker. Disable collisions when they exit those same regions. Filter out regions from floors other than the one that a unit is on using the method described under 1b.
[Note: While this should work for complex buildings with more than two floors, it is not a guaranteed solution for unit collisions since two or more units might obstruct each other if they have collisions turned on having entered overlapping regions used to monitor their proximity to pathing blockers. However, it might be possible to circumvent this possibility by constructing buildings very strategically such that the pathing blocking regions on each floor don't overlap significantly or at all.]
3c. Combine 1b and 3a or 3b. Track every unit's 2D co-ordinates and compare their flying height when they are about to collide. If their flying heights are the same, then turn collisions off for them and turn them back on when they are no longer within 2D proximity of each other.
4. Hide units and destructibles using GetLocalPlayer() so that units on different floors can't interact.
[Note: I am assuming this won't work if a player controls more than one unit.]
Please help me with this guide!
I'm far from being an expert, so I would greatly appreciate suggestions and corrections from other mapmakers.