Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

How to set transition condition to >=, <= or ==

Discussion in 'Animation' started by ywq, Oct 20, 2016.

  1. ywq

    ywq

    Joined:
    Aug 22, 2012
    Posts:
    15
    I have a animation controller set to:
    Code (CSharp):
    1.  
    2. [any state] => [run]   when speed<5.0
    3. [any state] => [fastRun] when speed>5.0
    4.  
    But when speed is exactly 5.0,then it will not transit to any run state.
     
  2. Mecanim-Dev

    Mecanim-Dev

    Unity Technologies

    Joined:
    Nov 26, 2012
    Posts:
    1,675
    The usual workaround for this is to find the maximum speed and change your condition like this, in this case the ordering of the transition do matter

    Code (CSharp):
    1.  
    2. [any state] => [run]   when speed<5.0
    3. [any state] => [fastRun] when speed<10.0
    4.  
    The first transition in the list is the first one to be evaluated, and then we go down the list.
    transitionordering.png
     
  3. ywq

    ywq

    Joined:
    Aug 22, 2012
    Posts:
    15
    It doesn't work. Because it is AnyState. When speed<5.0 , it will repeatedly transit to run and fastRun.
     
  4. Mecanim-Dev

    Mecanim-Dev

    Unity Technologies

    Joined:
    Nov 26, 2012
    Posts:
    1,675
    Oh right, sorry

    Code (CSharp):
    1.  
    2. [any state] => [run]   when speed<5.0
    3. [any state] => [fastRun] when speed>4.9
    4.  
    Since the order of transition matter, fastRun will be triggered as soon as the speed is higher than 5.0

    Also make sure that 'Can Transition to Self' is not checked

    CanTransitionToSelf.png
     
  5. ywq

    ywq

    Joined:
    Aug 22, 2012
    Posts:
    15
    I doesn't try this, because I'm at home.
    But I think if unchecked 'Can Transition to Self', then condition will become:
    Code (CSharp):
    1.  
    2. [any state] => [run]   when speed<5.0 && current state != 'run'
    3. [any state] => [fastRun] when speed>4.9 && current state !='fastRun'
    4.  

    Then, when speed=4.95. If current state is 'run', then it will transit to 'fastRun'. because current state=='run', it will ignore the first transition. And the same as 'fastRun'. And the repeatedly transition occur again.
     
  6. SomeGuy22

    SomeGuy22

    Joined:
    Jun 3, 2011
    Posts:
    722
    Yeah that sounds about right. You'll be stuck in a loop if the speed is greater than 4.9 and less than 5.0.

    So what I typically do when I need || operators in Mecanim is I make two transitions that lead to the same place. So you would end up with 3 transitions that look like this:

    Code (CSharp):
    1. [any state] => [run]   when speed<5.0 && current state != 'run'
    2. [any state] => [run]   when speed > 4.99 && speed < 5.01 && current state != 'run'
    3. [any state] => [fastRun] when speed>5.0
    That way, when speed is < 5, we can get to 'run'. When speed is 5.0, we also go to run, but we ensure that we're not already there with "Can Transition To Self." (If we didn't do this, two transitions to the same place wouldn't know when not to fire) Finally if speed is > 5.0, we go to 'fast run'.

    If speed is 4.999 (or 4.999999) we will correctly transition to 'run'. The only error I can see is if speed is 5.00000001, then it would be less than 5.01 and still greater than 5.0--I'm not sure how precise you need to be, or how many decimal places the floating point values can go before it becomes ridiculous. But if you're only setting the speed directly, you can just ensure it's never > 5 and < 5.01. If you are adding/multiplying the speed, you could clamp to the nearest 5th decimal place, and then change the transition to be 5.000001, which would produce little visual error and that would make sure it's never less than that value.

    EDIT: Just realized that the second transition is redundant. At this rate, just use transitions 1 and 3, and edit 1 to be this:

    Code (CSharp):
    1. [any state] => [run]   when speed<5.000001 && current state != 'run'
    Combine that with the decimal clamp and you're good to go :)
     
    gaolei_nls likes this.
  7. ywq

    ywq

    Joined:
    Aug 22, 2012
    Posts:
    15
    Since I can write C# code, ensure speed != 5.0 is much simpler. But I don't like this. Because I have to place the number '5.0' in two places, C# code and Animator Controller. This break the DRY principle.
     
  8. SomeGuy22

    SomeGuy22

    Joined:
    Jun 3, 2011
    Posts:
    722
    How many of these do you need? If it's just a few, surely you can make a public variable for this stuff in your script and just change it if necessary. But if you truly wanted the code to be independent from what you input to the Animator, you could use the UnityEngine class to retrieve the transition's condition and read the threshold value. Then your script would just match whatever you input to Mecanim.