Unity的程序化刀光插件:X-WeaponTrail

Unity的程序化刀光插件:X-WeaponTrail

X-WeaponTrail是一個很古老的程序化刀光插件齿诞,很早以前買了一直放在倉庫沒用上雨膨。最近不知道特效同學抽什么瘋支救,突然不肯自己做刀光特效了幢泼,所以就把這個插件丟給他了渡嚣。

截圖.png

用法

該插件的用法很簡單渣淳,找到你的武器脾还,把X-WeaponTrail預設拖到武器節(jié)點下,調(diào)整StartPointEndPoint入愧,使其和武器對齊即可鄙漏。

X-WeaponTrail.png
起點和終點.png
X-WeaponTrail腳本.png

查看X Weapon Trail腳本,參數(shù)都比較直觀棺蛛,不過美術(shù)比較難理解的是Max Frame怔蚌,Granularity這2個參數(shù),作者在他的主頁給了如下說明:

參數(shù)說明.png

MaxFrame可以理解為刀光拖尾的生命周期(長度)旁赊,MaxFrame越大桦踊,拖尾越長。
Granularity可以理解為拖尾Mesh的頂點粒度终畅,Granularity越大籍胯,頂點數(shù)越多,越平滑离福。


實現(xiàn)細節(jié)

趁著給美術(shù)介紹參數(shù)杖狼,我把這個刀光的實現(xiàn)代碼看了一遍,有一些地方還是值得說一下妖爷。

首先蝶涩,作者維護了一個隊列mSnapshotList,用來保存刀光拖尾的位置信息赠涮。隊列的index越小子寓,則越接近當前武器的位置,index越大則越接近刀光的尾部笋除,隊列的長度由MaxFrame決定斜友。

  void RecordCurElem() 
  {
    //TODO: use element pool to avoid gc alloc.
    //Element elem = new Element(PointStart.position, PointEnd.position);

    Element elem = mElemPool.Get();
    elem.PointStart = PointStart.position;
    elem.PointEnd = PointEnd.position;

    if (mSnapshotList.Count < MaxFrame) 
    {
      mSnapshotList.Insert(1, elem);
    }
    else 
    {
      mElemPool.Release(mSnapshotList[mSnapshotList.Count - 1]);
      mSnapshotList.RemoveAt(mSnapshotList.Count - 1);
      mSnapshotList.Insert(1, elem);
    }
  }

上面代碼中的Element記錄了一幀的位置信息,包括一開始我們設置的StartPointEndPoint垃它,以及中間位置Pos鲜屏。

  public class Element 
  {
    public Vector3 PointStart;
    public Vector3 PointEnd;
    
    public Vector3 Pos 
    {
      get 
      {
        return (PointStart + PointEnd) / 2f;
      }
    }

    public Element(Vector3 start, Vector3 end) 
    {
      PointStart = start;
      PointEnd = end;
    }
    
    public Element() 
    {
    }
  }

有了MaxFrame幀的位置信息后烹看,我們就可以生成Mesh了。假設我們沒有做任何平滑處理洛史,只是簡單的根據(jù)每一幀的位置(StartPoint惯殊,Pos,EndPoint)補充頂點也殖,已經(jīng)可以生成刀光的Mesh了土思,但是會出現(xiàn)明顯的折痕:

折痕.png

這個時候,插值平滑就非常必要了忆嗜。作者采用的插值方式是CatmullRom己儒,關(guān)于CatmullRom的說明,網(wǎng)上很多捆毫,這里直接貼代碼:

        public static Vector3 CatmulRom(Vector3 T0, Vector3 P0, Vector3 P1, Vector3 T1, float f)
        {
            double DT1 = -0.5; 
            double DT2 = 1.5; 
            double DT3 = -1.5; 
            double DT4 = 0.5;

            double DE2 = -2.5; 
            double DE3 = 2; 
            double DE4 = -0.5;

            double DV1 = -0.5;
            double DV3 = 0.5;

            double FAX = DT1 * T0.x + DT2 * P0.x + DT3 * P1.x + DT4 * T1.x;
            double FBX = T0.x + DE2 * P0.x + DE3 * P1.x + DE4 * T1.x;
            double FCX = DV1 * T0.x + DV3 * P1.x;
            double FDX = P0.x;

            double FAY = DT1 * T0.y + DT2 * P0.y + DT3 * P1.y + DT4 * T1.y;
            double FBY = T0.y + DE2 * P0.y + DE3 * P1.y + DE4 * T1.y;
            double FCY = DV1 * T0.y + DV3 * P1.y;
            double FDY = P0.y;

            double FAZ = DT1 * T0.z + DT2 * P0.z + DT3 * P1.z + DT4 * T1.z;
            double FBZ = T0.z + DE2 * P0.z + DE3 * P1.z + DE4 * T1.z;
            double FCZ = DV1 * T0.z + DV3 * P1.z;
            double FDZ = P0.z;

            float FX = (float)(((FAX * f + FBX) * f + FCX) * f + FDX);
            float FY = (float)(((FAY * f + FBY) * f + FCY) * f + FDY);
            float FZ = (float)(((FAZ * f + FBZ) * f + FCZ) * f + FDZ);

            return new Vector3(FX, FY, FZ);
        }

調(diào)大Granularity后闪湾,之前的折痕平滑了很多。

平滑刀光曲線.png

關(guān)于頂點的UV映射

最后想再說一下頂點的UV映射問題绩卤。如果不考慮特效貼圖途样,單純的看頂點生成,效果如下:

刪除特效貼圖.png
Scene視圖.png

注意上圖的紅色射線濒憋,射線的原點即StartPointEndPoint的中間點Pos何暇,射線方向從StartPoint指向EndPoint

查看頂點更新的代碼凛驮,我們發(fā)現(xiàn)頂點的UV設定如下:StartPoint的U是1赖晶,EndPoint的U是0,Pos的U是0.5辐烂。越接近刀光尾部的頂點,V越接近1捂贿。

                Vector3 pos = mSpline.InterpolateByLen(fadeT);
                Vector3 up = mSpline.InterpolateNormalByLen(fadeT);
                Vector3 pos0 = pos + (up.normalized * mTrailWidth * 0.5f);
                Vector3 pos1 = pos - (up.normalized * mTrailWidth * 0.5f);

                Debug.DrawRay(pos, up * 3, Color.red);

                // pos0
                pool.Vertices[baseIdx] = pos0;
                pool.Colors[baseIdx] = MyColor;
                uvCoord.x = 0f;
                uvCoord.y = uvSegment;
                pool.UVs[baseIdx] = uvCoord;

                //pos
                pool.Vertices[baseIdx + 1] = pos;
                pool.Colors[baseIdx + 1] = MyColor;
                uvCoord.x = 0.5f;
                uvCoord.y = uvSegment;
                pool.UVs[baseIdx + 1] = uvCoord;

                //pos1
                pool.Vertices[baseIdx + 2] = pos1;
                pool.Colors[baseIdx + 2] = MyColor;
                uvCoord.x = 1f;
                uvCoord.y = uvSegment;
                pool.UVs[baseIdx + 2] = uvCoord;

結(jié)合特效貼圖

slash02.png

越接近刀光頭部(武器)的頂點纠修,其UV映射的區(qū)域越接近貼圖的底部:

頭部的UV映射.png

越接近刀光尾部的頂點,其UV映射的區(qū)域越接近貼圖的上部:

尾部的UV映射.png

結(jié)合實際效果查看刀光的強弱厂僧,就更清晰了:

UV映射.png

好了扣草,拜拜。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末颜屠,一起剝皮案震驚了整個濱河市辰妙,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌甫窟,老刑警劉巖密浑,帶你破解...
    沈念sama閱讀 222,104評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異粗井,居然都是意外死亡尔破,警方通過查閱死者的電腦和手機街图,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,816評論 3 399
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來懒构,“玉大人餐济,你說我怎么就攤上這事〉ň纾” “怎么了絮姆?”我有些...
    開封第一講書人閱讀 168,697評論 0 360
  • 文/不壞的土叔 我叫張陵,是天一觀的道長秩霍。 經(jīng)常有香客問我篙悯,道長,這世上最難降的妖魔是什么前域? 我笑而不...
    開封第一講書人閱讀 59,836評論 1 298
  • 正文 為了忘掉前任辕近,我火速辦了婚禮,結(jié)果婚禮上匿垄,老公的妹妹穿的比我還像新娘移宅。我一直安慰自己,他們只是感情好椿疗,可當我...
    茶點故事閱讀 68,851評論 6 397
  • 文/花漫 我一把揭開白布漏峰。 她就那樣靜靜地躺著,像睡著了一般届榄。 火紅的嫁衣襯著肌膚如雪浅乔。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,441評論 1 310
  • 那天铝条,我揣著相機與錄音靖苇,去河邊找鬼。 笑死班缰,一個胖子當著我的面吹牛贤壁,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播埠忘,決...
    沈念sama閱讀 40,992評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼脾拆,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了莹妒?” 一聲冷哼從身側(cè)響起名船,我...
    開封第一講書人閱讀 39,899評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎旨怠,沒想到半個月后渠驼,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,457評論 1 318
  • 正文 獨居荒郊野嶺守林人離奇死亡运吓,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,529評論 3 341
  • 正文 我和宋清朗相戀三年渴邦,在試婚紗的時候發(fā)現(xiàn)自己被綠了疯趟。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,664評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡谋梭,死狀恐怖信峻,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情瓮床,我是刑警寧澤盹舞,帶...
    沈念sama閱讀 36,346評論 5 350
  • 正文 年R本政府宣布,位于F島的核電站隘庄,受9級特大地震影響踢步,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜丑掺,卻給世界環(huán)境...
    茶點故事閱讀 42,025評論 3 334
  • 文/蒙蒙 一获印、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧街州,春花似錦兼丰、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,511評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至面徽,卻和暖如春艳丛,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背趟紊。 一陣腳步聲響...
    開封第一講書人閱讀 33,611評論 1 272
  • 我被黑心中介騙來泰國打工氮双, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人霎匈。 一個月前我還...
    沈念sama閱讀 49,081評論 3 377
  • 正文 我出身青樓眶蕉,卻偏偏與公主長得像,于是被迫代替她去往敵國和親唧躲。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 45,675評論 2 359