• Listen to a special audio message from Bill Roper to the Hive Workshop community (Bill is a former Vice President of Blizzard Entertainment, Producer, Designer, Musician, Voice Actor) 🔗Click here to hear his message!
  • Read Evilhog's interview with Gregory Alper, the original composer of the music for WarCraft: Orcs & Humans 🔗Click here to read the full interview.

[General] Problem with collision and Replace Unit

Status
Not open for further replies.
Level 2
Joined
Feb 16, 2020
Messages
9
In my map you can deactivate and reactivate buildings (stops them from spawning units periodically). How this works is an ability is cast, then a trigger is fired that uses 'Replace Unit' to change to a Unit Type 'Deactivated Unit', and vice versa for Reactivate.

The problem is if there is an enemy unit standing on the building (common in this map) and you cast it, the building will move places to avoid collision.

Any ideas for a fix? Using upgrade unit instead of replace unit works but isn't feasible because of the number of buildings. There is no way to add a building upgrade using a trigger is there?
 
Level 15
Joined
Feb 7, 2020
Messages
398
When I encountered this problem I found the easiest solution was to pick units in a radius around the structure's center X/Y and move said units outside of its collision box with a projected point. There could be another, simpler solution, but I found simply trying to disable collision on nearby units, etc., didn't quite work.

I only have this in code but you could easily replicate in GUI:
Lua:
-- move units away so the outpost is centered properly
function FlightPathClearArea(x,y)
    local g = CreateGroup()
    local centerLoc = Location(x,y)

    GroupEnumUnitsInRange(g, x, y, 335.0, Condition( function() return IsUnitAliveBJ(GetFilterUnit()) and not IsUnitType(GetFilterUnit(),UNIT_TYPE_STRUCTURE) end ) )
    if (not IsUnitGroupEmptyBJ(g)) then
        local loc
        local newLoc
        local u = FirstOfGroup(g)
        local i = 0
        local angle
        repeat
            loc = GetUnitLoc(u)
            angle = AngleBetweenPoints(centerLoc, loc)
            newLoc = PolarProjectionBJ(centerLoc, 335.0, angle)
              i = i + 1
              SetUnitX(u,GetLocationX(newLoc))
            SetUnitY(u,GetLocationY(newLoc))
            RemoveLocation(loc)
            RemoveLocation(newLoc)
            GroupRemoveUnit(g, u)
            u = FirstOfGroup(g)
          until (u == nil or i == 64)
          u = nil
      end
    DestroyGroup(g)
    RemoveLocation(centerLoc)
end
 
Level 2
Joined
Feb 16, 2020
Messages
9
Moving nearby units away before I use Replace Unit is fixing part of the issue. However I want to move the units back to their original position afterwards. What's the best way to do this? I thought about using Hashtables to store the location for each unit, but I wasn't sure how leaks work with this. If I clear Child Hashtable will that prevent leaks?

They also lose their last order when I move them which is a problem.

The other part of the issue that hasn't been fixed is, although just having a unit on top of the building no longer causes it to move, if you have buildings next to each other with enough unit build up the buildings seem to get stuck on each other when you cast it. Sometimes they will move to the side, sometimes even on top of another building.
 
Last edited:
Status
Not open for further replies.
Top