Unity - HasExitTime用法


本文詳細分析了AnimatorController中動畫切換過渡問題,即Translation過渡及hasExitTime的問題。方法為對實際項目中的所有情況進行分類,規划邏輯圖,可視化分析解決這些問題。

AnimatorController 動畫機控制器

  • 功能:對已有的Animation片進行邏輯連接,連接過渡方式為Translation有向線段,其切換方法包括啟用hasExitTime關閉hasExitTime
  • Translation:通過設置Parameters的參數進行切換過渡,可單線上有多條件,也可單方向上有多單條件線。選中任意Translation可在Inspecter窗口看到兩個動畫片段和區間的窗口,及Setting參數表
  • hasExitTime:是否有退出時間。簡單理解:開啟表示等待當前動畫進行完才可進行下一個動畫;關閉表示可以立即打斷當前動畫並播放下一個動畫

項目實戰

  • 背景:存在idle、idle_2、attack_1、attack_2、attack_3動畫片段實現三連擊的攻擊效果,根據attack值切換。我們僅關注幾個attack的切換,其中
    • attack_1->attack_2:關閉hasExitTime,切換條件attack=2,Translation未超
    • attack_2->attack_3:開啟hasExitTime,切換條件attack=3,Translation未超
    • attack_1、attack_2、attack_3切換到idle_2:切換條件attack=0,代碼控制判斷任意動畫播放完畢則attack=0

AnimatorController:

attack_1->attack_2(左)、attack_2->attack_3(右)的Translation:

1. 關閉 has exit time

關閉has Exit Time:無退出等待時間,立即開啟下一動畫

  • 情況一:當attack_1正常運轉,在左標記前達成轉行條件
    • 立即開啟Translation(而不是等待運行到左標記)和attack_2,三者並行運轉
      • 若Translation還在運行中,attack_1卻先運行完,代表當前動畫片attack_1運行完(代碼:(stateInfo.IsName("attack_1") && stateInfo.normalizedTime > 1)) == true ),會對邏輯上的判斷造成影響,這種情況非常容易出錯
      • 若attack_1還在運行,Translation卻先運行完,則立即停止attack_1片段。邏輯正常
    • 此后整體動畫全權由attack_2運轉
  • 情況二:當attack_1正常運轉,在左邊標記后(左右標記中或是右標記后)達成轉換條件
    • 立即開啟Translation和attack_2,三者並行運轉
      • 若Translation還在運行中,attack_1卻先運行完,代表當前動畫片attack_2運行完,結果同上
      • 若attack_1還在運行中,Translation卻先運行完,則立即停止attack_2片段。邏輯正常
    • 此后整體動畫全權由attack_2運轉

邏輯圖:(修正:count=0 表示attack=0)

項目實例圖:左標前達成(先),左標后達成且Translation后完成(后)

2. 開啟 has exit time

當has exit time:有退出等待時間,需等待目前動畫完成到一定階段才可切換至下一動畫。過程:

  • 情況一:attack_2正常運轉,若在左標記前達成轉換條件
    • 等待attack_2中動畫片進行到左標記,開啟Translation過渡和attack_3動畫,,三者動畫並行運轉
      • 若Translation還在運行中,attack_2卻先運行完,代表當前動畫片attack_2運行完(代碼:(stateInfo.IsName("attack_1") && stateInfo.normalizedTime > 1)) == true ),會對邏輯上的判斷造成影響,這種情況非常容易出錯
      • 若attack_2還在運行,Translation卻先運行完,則立即停止attack_2片段。邏輯正常
    • 此時整體動畫全權由attack_3運轉;
  • 情況二:attack_2正常運轉,若在左標記后達成條件
    • 無論是在標記期間或是右標記后達成條件,再也無法觸發Translation轉換,因為可過渡時間片已經錯過了

邏輯圖:(修正:count=0 表示attack=0)

項目實例圖:左標前達成(先),左標后達成(后)

總結

Translation內左右標記問題:

  • 左右標記范圍含義
    • Translation時長,兩個動畫的過渡時間長度
  • 左右標記位置含義
    • 對於當前Animation:左標記表示開啟Translation和下一Animation的時間點;右標記表示當前動畫片所能進行到的最晚時間點
    • 對於下一Animation:左標記為當前動畫開啟時間點,右標記為當前動畫全權運轉時間點
    • 通俗解釋:何時轉換、轉換多久、轉換時兩動畫所占比例
  • 區間意義
    • 例如attack_1和attack_2過渡的時間片段,過渡期的動畫由Unity根據attack_1和attack_2動畫混合而成,因此所謂三動畫並行執行,本質為執行Translation的混合動畫。其外需要注意:過渡期間仍處於attack_1,代碼就是:stateInfo.IsName("attack_1")==true,僅當Translation結束才算處於attack_2

Translation后於Animation錯誤問題:

該錯誤直觀上看就是兩動畫和Translation時間先后問題,數字上看就是Translation首尾點、區間大小、條件達成時機。因此解決辦法就圍繞這幾點,此處給出幾點建議:

  • Translation右標記最好 <= 前Animation末端,也就是說Translation不要超出動畫長度
  • 最好在左標記點前達成轉換條件,以便我們對轉換過程進行掌控
  • AnimatorController的設置不是唯一途徑,代碼操控、動畫內插入事件等,都可以較好輔助我們實現安全的動畫切換

參考


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM