Staredit Network > Forums > SC2 Assistance > Topic: Drifting unit
Drifting unit
Mar 12 2014, 1:21 am
By: payne  

Mar 12 2014, 1:21 am payne Post #1

:payne:

I wasn't sure if it were to be done via Data or Triggers, so I'm posting this here.

How do I make a unit drift when it turns, like a race car?
And is there a way to make this toggle-able on a unit?



None.

Mar 12 2014, 1:46 am Roy Post #2

An artist's depiction of an Extended Unit Death

The easiest way would be to just give the unit a ridiculous turn radius, but that wouldn't give the visual effect you probably want.

There's probably a good way to do it with the Data Editor, but I'm more of a Trigger Editor guy. My general suggestion for the trigger approach would be to reduce the unit's speed and have a micro periodic event (every 0.05 seconds of the game) activated while the unit is moving. Record the facing direction of the unit, and then after a small delay (depending on how long you want the drift to happen, maybe 1 second) move the unit in that direction by a minuscule amount (the fact that this trigger runs so often will create a sliding effect). The only problem is you'll probably get weird results for people who spam different directions, but tuning the times can vary this effect. This would take care of things like trying to suddenly stop, though, and you'll have a neat effect where it takes some time to accelerate to full speed from a stationary position.

The other approach with triggers would be to detect a significant change in direction while the unit is moving. You can detect the event that the unit is issued an order, and then compare the angle from that unit to the new order to the angle of the unit's current facing direction, and if the change is significant enough, make a loop that slides the unit for however long you want the slide to last.

The only slightly annoying thing is figuring out when the unit is currently moving or not. The best you can do (to my knowledge) is to use the "Unit Is Issued Order" and "Unit Becomes Idle" events and keep track with a global variable.




Mar 12 2014, 3:23 am payne Post #3

:payne:

Code
   Events
       Timer - Every 0.0625 seconds of Game Time
   Local Variables
   Conditions
   Actions
       Unit Group - Pick each unit in _13 Racers and do (Actions)
           Actions
               General - If (Conditions) then do (Actions) else do (Actions)
                   If
                       _13 Drifting?[(Owner of (Picked unit))] == False
                   Then
                       Variable - Set _13 Drifting?[(Owner of (Picked unit))] = True
                       General - Wait 1.0 Game Time seconds
                       Unit - Order (Picked unit) to ( Move targeting ((Position of (Picked unit)) offset by 1.1 towards (Facing of (Picked unit)) degrees)) (Replace Existing Orders)
                       Variable - Set _13 Drifting?[(Owner of (Picked unit))] = False
                   Else

This is definitely not working.
The problem is that ordering the unit replaces the order, so it'll get in the way of the gameplay a lot. If the player wants to cast an ability while this thing runs, there is a chance the ability won't be cast. And if I don't set it to "Replace Existing Orders", a player that spams order will never be affected by the drifting effect (and all players, in this context, will be spamming orders).
As it is, it just makes the movement of my Probe racer unit all clunky.
I also haven't bothered with making an "Is Moving" detection trigger since all the racers will basically be moving all the time (though I would add this safe-proof later on, but for testing, I don't think it was necessary).



None.

Mar 12 2014, 12:33 pm Roy Post #4

An artist's depiction of an Extended Unit Death

As an ode to SC1 I'll remind you that "Move Unit" and "Order Unit" are two completely different actions.

Also, you need to store the facing angle of the picked unit into a variable before you do your wait; otherwise it will just get the direction they've been moving toward.

I don't have time to look through what else may be wrong with the trigger, but I'd work on those two issues first. Also, a distance of 1.1 is probably going to be too large a distance.




Mar 12 2014, 1:40 pm Ahli Post #5

I do stuff and thingies... Try widening and reducing the number of small nooks and crannies to correct the problem.

I would move it with blend & calculate a speed and a max facing change of the direction you are pushed into.




Mar 12 2014, 2:58 pm payne Post #6

:payne:

Quote from Roy
As an ode to SC1 I'll remind you that "Move Unit" and "Order Unit" are two completely different actions.

Also, you need to store the facing angle of the picked unit into a variable before you do your wait; otherwise it will just get the direction they've been moving toward.

I don't have time to look through what else may be wrong with the trigger, but I'd work on those two issues first. Also, a distance of 1.1 is probably going to be too large a distance.
Ah! That makes more sense.

Quote from Ahli
calculate a speed and a max facing change of the direction you are pushed into.
Sorry for not following, but I'm not sure I understand what is the purpose of calculating the max facing change.

Current trigger:
Code
   Events
       Timer - Every 0.0625 seconds of Game Time
   Local Variables
       Angle = 0.0 <Real>
       Position = No Point <Point>
   Conditions
   Actions
       Unit Group - Pick each unit in _13 Racers and do (Actions)
           Actions
               General - If (Conditions) then do (Actions) else do (Actions)
                   If
                       _13 Drifting?[(Owner of (Picked unit))] == False
                   Then
                       Variable - Set _13 Drifting?[(Owner of (Picked unit))] = True
                       Variable - Set Angle = (Facing of (Picked unit))
                       Variable - Set Position = (Position of (Picked unit))
                       General - Wait 0.1 Game Time seconds
                       Unit - Move (Picked unit) instantly to (Position offset by 0.5 towards Angle degrees) (Blend)
                       Variable - Set _13 Drifting?[(Owner of (Picked unit))] = False
                   Else

I've tried tweaking the numbers, but I just can't get the effect I want. I see the unit drifting slightly, but it's nothing ever near what I am expecting. I want a big sliding effect with decently high speed unit.
I wasn't sure about adding that "Position" variable, but it seemed to increase the sliding effect as long as certain parameters' values were kept within a certain range.
It seems like the solution could be to increase the Move value, but restrict it to when the players are not moving precisely forward, and thus to increase its value based on the Turn Angle compared to the last Forward Angle?



None.

Mar 13 2014, 3:54 am Roy Post #7

An artist's depiction of an Extended Unit Death

I quickly wrote up a little something that should be easy to use:
Drift Unit Action
Drift Unit
   Options: Action
   Return Type: (None)
   Parameters
       Unit = (Triggering unit) <Unit>
       Distance = 1.0 <Real>
       Angle <Real>
       Time = 1.0 <Real>
       TimeType = Game Time <Time Type>
   Grammar Text: Drift Unit by a distance of Distance toward Angle over Time TimeType
   Hint Text: (None)
   Custom Script Code
   Local Variables
       wait = 0.05 <Real (Constant)>
       repeat = (Integer((Time / wait))) <Integer>
       step = (Distance / repeat) <Real>
   Actions
       General - Repeat (Actions) repeat times
           Actions
               Unit - Move Unit instantly to ((Position of Unit) offset by step towards Angle degrees) (Blend)
               General - Wait wait TimeType seconds

And a simpler action definition to call it:
Slide Unit Action
Slide Unit
   Options: Action
   Return Type: (None)
   Parameters
       Unit = (Triggering unit) <Unit>
       Angle <Real>
   Grammar Text: Make Unit slide toward Angle based on its current speed
   Hint Text: (None)
   Custom Script Code
   Local Variables
       speed = ((Triggering unit) Movement Speed (Current)) <Real>
       time = (speed * 0.175) <Real>
       distance = (speed * 0.55) <Real>
   Actions
       Drift Unit by a distance of distance toward Angle over time Game Time

Here's an example of using these new action definitions:
CheckDrift
CheckDrift
   Events
       Unit - Any Unit is issued an order to  Move
   Local Variables
       faceAngle = (Facing of (Triggering unit)) <Real>
       orderAngle = (Angle from (Position of (Triggering unit)) to (Target point for (Triggering order))) <Real>
       racers = Racers <Unit Group>
   Conditions
       ((Triggering unit) is in racers) == True
   Actions
       General - If (Conditions) then do (Actions) else do (Actions)
           If
               (Abs((((faceAngle + 180.0) mod 320.0) - ((orderAngle + 180.0) mod 320.0)))) >= 40.0
           Then
               Make (Triggering unit) slide toward faceAngle based on its current speed
           Else

That complicated If/Then condition is just me being bad at math - all it's doing is checking to see that the angle change is greater than 40 degrees.

Basically, you can just call Slide Unit and give it the unit and its facing angle and it will automatically drift (distance and duration based on its speed), or if you want to fine tune it more, you can call the Drift Unit action instead and specify a distance over a period of time.

Note that without checking to see if the unit is already drifting, you can get interesting results by spamming different directions in rapid succession. But I'll leave that up to you on how you want to handle that (if at all).

Attached is the test map I made. You can just copy pastarino the Drift/Slide actions into your own map, and then use them like you would any other trigger action.

Attachments:
DriftTest.SC2Map
Hits: 2 Size: 28.49kb




Mar 13 2014, 4:26 am payne Post #8

:payne:

I ended up using a friend's work:

Code
[NYI] Apply Force
   Options: Action, Create Thread
   Return Type: (None)
   Parameters
       Unit = (Triggering unit) <Unit>
       Initial Force = 1.0 <Real>
       Direction = (Facing of (Triggering unit)) <Real>
       Duration = 1.0 <Real>
   Grammar Text: Apply Force(Unit, Initial Force, Direction, Duration)
   Hint Text: Custom "physics" function for basic pushing or pulling effects.
   Custom Script Code
   Local Variables
       force = Initial Force <Real>
       steps = (Duration * 16.0) <Real>
       temppoint = No Point <Point[2]>
       inta = 0 <Integer>
       skidstep = 0.0 <Real>
       distance = 0.0 <Real>
       forcemultiplier = 1.0 <Real>
   Actions
       General - If (Conditions) then do (Actions) else do (Actions)
           If
               Direction < 0.0
           Then
               Variable - Modify Direction: + 360.0
           Else
       General - While (Conditions) are true, do (Actions)
           Conditions
               force > 0.0
           Actions
               Variable - Set forcemultiplier = 1.0
               ------- things that might modify force effects go here; change forcemultiplier
               Unit - Move Unit instantly to ((Position of Unit) offset by (force * forcemultiplier) towards Direction degrees) (Blend)
               Variable - Modify force: - (Initial Force / steps)
               General - Wait 0.0625 Game Time seconds

Along with:
Code
_13 Drift
   Events
       Unit - Any Unit uses  Move at Generic1 - Any stage (Ignore shared abilities)
   Local Variables
   Conditions
   Actions
       Unit - [NYI] Apply Force((Triggering unit), 0.1, (Facing of (Triggering unit)), 1.25)


Works wonders.

Thanks for you work anyways, though. :cube:



None.

Options
  Back to forum
Please log in to reply to this topic or to report it.
Members in this topic: None.
[09:19 am]
Linekat -- cool
[01:56 am]
Oh_Man -- cool bit of history, spellsword creator talking about the history of EUD ^
[09:24 pm]
Moose -- denis
[05:00 pm]
lil-Inferno -- benis
[10:41 am]
v9bettel -- Nice
[2024-4-19. : 1:39 am]
Ultraviolet -- no u elky skeleton guy, I'll use em better
[2024-4-18. : 10:50 pm]
Vrael -- Ultraviolet
Ultraviolet shouted: How about you all send me your minerals instead of washing them into the gambling void? I'm saving up for a new name color and/or glow
hey cut it out I'm getting all the minerals
[2024-4-18. : 10:11 pm]
Ultraviolet -- :P
[2024-4-18. : 10:11 pm]
Ultraviolet -- How about you all send me your minerals instead of washing them into the gambling void? I'm saving up for a new name color and/or glow
Please log in to shout.


Members Online: IlyaSnopchenko, Linekat