Rather use components for the movement.
Assign two variables to each unit:
real dx (difference/delta x)
real dy (difference/delta y)
Each of these moves the unit along one axis (x and y respectively), so together these two numbers can represent any speed at any angle, instead of having a variable for speed and a variable for the angle.
The advantage of this approach is that it makes collisions very easy to do. If it is colliding horizontally, you change dx. If it is colliding vertically, you change dy.
Use a unit indexer to allow saving these variables per unit.
So the code will look like this:
set id = custom value of unit
Custom script: call SetUnitX(GetUnitX(picked unit) + udg_dx[udg_id])
Custom script: call SetUnitY(GetUnitY(picked unit) + udg_dy[udg_id])
For your starting conditions, just set dx and dy to some random values between -10 and 10.
Now for the fun part: collision detection. We can detect collision by checking pathing at a point, but how do we translate that into an angle?
We check all four directions around the unit.
set point = position of unit
set point2 = point1 offset by (30, 0)
(this will check to the right of the unit)
Now, if we detect point2 to be unpathable, we simply multiply dx (horizontal motion) by -1, and it will reflect.
Follow this method for the other 3 angles, and that's an accurate collision system. It will also work for corners, since you'll trigger both directions.
For reference:
North ... dy+ ... (0, 30) ... set dy = dy * -1
East ... dx+ ... (30, 0) ... set dx = dx * -1
South ... dy- ... (0, -30) ... set dy = dy * -1
West ... dx- ... (-30, 0) ... set dx = dx * -1