国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

【Unity】運(yùn)行時(shí)創(chuàng)建曲線(貝塞爾的運(yùn)用)

這篇具有很好參考價(jià)值的文章主要介紹了【Unity】運(yùn)行時(shí)創(chuàng)建曲線(貝塞爾的運(yùn)用)。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問。

[Unity]運(yùn)行時(shí)創(chuàng)建線(貝塞爾的運(yùn)用)

1. 實(shí)現(xiàn)的目標(biāo)

在運(yùn)行狀態(tài)下創(chuàng)建一條可以使用貝塞爾方法實(shí)時(shí)編輯的網(wǎng)格曲線。

2. 原理介紹

2.1 曲線的創(chuàng)建

unity建立網(wǎng)格曲線可以參考Unity程序化網(wǎng)格體的實(shí)現(xiàn)方法。主要分為頂點(diǎn),三角面,UV和法線。筆者有類似的文章unity 線繩管道純代碼創(chuàng)建方法_,詳細(xì)的講解了網(wǎng)格線的創(chuàng)建方法,這次的不同點(diǎn)在于法線的確立方法上。

2.2貝塞爾曲線點(diǎn)的確立

筆者有文章Unity 貝塞爾曲線的創(chuàng)建_描述了貝塞爾的創(chuàng)建方法。

3. 實(shí)現(xiàn)過程

3.1曲線的創(chuàng)建方法

線的組成原理
曲線由橫截面圓和中心軸線組成。橫截面的法線方向?yàn)榍昂髢牲c(diǎn)向量差,如下圖綠色線為中心軸線,A點(diǎn)為橫截面所在點(diǎn),橫截面的法線方法為向量 A D ? \vec{AD} AD 既向量 C B ? \vec{CB} CB 的單位向量;終點(diǎn)和起點(diǎn)的法線方向?yàn)樽陨砗颓包c(diǎn)或者后一點(diǎn)的向量。

【Unity】運(yùn)行時(shí)創(chuàng)建曲線(貝塞爾的運(yùn)用),Unity,unity,游戲引擎

代碼源碼

3.1.1 橫截圓的創(chuàng)建
           #region 橫切圓創(chuàng)建
           /// <summary>
           /// 得到管線橫切圓
           /// </summary>
           /// <param name="Count">段數(shù)</param>
           /// <param name="R">半徑</param>
           /// <returns></returns>
           Vector3[] CircularSection(int Count, float R)
           {
               Vector3[] vector3s = new Vector3[Count];
               float angle = 360 / Count;
               Vector3 vector3 = new Vector3(R, 0, 0);
               for (int i = 0; i < Count; i++)
               {
                   //根據(jù)角度得到圓的分布點(diǎn)
                   vector3s[i] = vector3.ToAngle(angle * i, Vector3.zero, Vector3.forward);
               }
               return vector3s;
           }
           #endregion
          

? vector3旋轉(zhuǎn)擴(kuò)展方法

        /// <summary>
        /// 角度旋轉(zhuǎn)
        /// </summary>
        /// <param name="vector3"></param>
        /// <param name="angle">旋轉(zhuǎn)角度</param>
        /// <param name="center">旋轉(zhuǎn)中心點(diǎn)</param>
        /// <param name="direction">旋轉(zhuǎn)軸</param>
        /// <returns></returns>
        public static Vector3 ToAngle(this Vector3 vector3, float angle, Vector3 center, Vector3 direction)
        {
            Vector3 pos = center;
            Quaternion quaternion = Quaternion.AngleAxis(angle, direction);
            Matrix4x4 matrix = new Matrix4x4();
            matrix.SetTRS(pos, quaternion, Vector3.one);
            vector3 = matrix.MultiplyPoint3x4(vector3);
            return vector3;
        }
3.1.2 中心線的確立
           class LinePoint
             {
                 Vector3 location;
                 Vector3 direction;
     
                 public Vector3 Location { get => location; set => location = value; }
                 public Vector3 Direction { get => direction; set => direction = value; }
             }
             /// <summary>
             /// 中心線的確立
             /// </summary>
             /// <param name="createPoint">曲線點(diǎn)</param>
             /// <returns></returns>
             List<LinePoint> SetLinePoint(Vector3[] createPoint)
             {
                 List<LinePoint> pipePoints = new List<LinePoint>();
                 int length = createPoint.Length;
                 for (int i = 0; i < length; i++)
                 {
                     if (i == 0)
                     {
                         Vector3 tangent = (createPoint[i + 1] - createPoint[i]).normalized;//法線
                         AddPipePoints(createPoint[i], tangent, ref pipePoints);
                     }
                     else if (i == length - 1)
                     {
                         Vector3 tangent = (createPoint[i] - createPoint[i - 1]).normalized;//法線
                         AddPipePoints(createPoint[i], tangent, ref pipePoints);
                     }
                     else
                     {
                         Vector3 tangent = (createPoint[i+1] - createPoint[i - 1]).normalized;//法線
                         AddPipePoints(createPoint[i], tangent, ref pipePoints);
                     }
                 }
                 return pipePoints;
             }
     /// <summary>
             /// 增加中心軸線點(diǎn)
             /// </summary>
             /// <param name="location">位置</param>
             /// <param name="direction">法線</param>
             void AddPipePoints(Vector3 location, Vector3 direction,  ref List<LinePoint> pipePoints)
             {
                 LinePoint pipePoint = new LinePoint();
                 pipePoint.Location = location;
                 pipePoint.Direction = direction;
                 pipePoints.Add(pipePoint);
             }
3.1.3網(wǎng)格創(chuàng)建
        /// <summary>
        /// 立體網(wǎng)格創(chuàng)建
        /// </summary>
        /// <param name="createPoint">創(chuàng)建的點(diǎn)數(shù)據(jù)</param>
        /// <param name="circularCount">圓的段數(shù)</param>
        /// <param name="circularR">圓的半徑</param>
        /// <returns></returns>
        public Mesh CreateLine3D(Vector3[] createPoint, int circularCount, float circularR)
        {
            //截面圓
            Vector3[] circul = CircularSection(circularCount, circularR);
            //中心線
            List<LinePoint> centreLine = SetLinePoint(createPoint);
            //網(wǎng)格點(diǎn)數(shù)據(jù)
            Vector3[] meshPoint = CreateMeshPoint(centreLine, circul);
            float uvX = Vector3.Distance(circul[0], circul[1]);
            //返回網(wǎng)格
            return CreatMesh(centreLine, meshPoint, circul.Length, uvX);
        }
/// <summary>
        /// 創(chuàng)建網(wǎng)格點(diǎn)數(shù)據(jù)
        /// </summary>
        /// <param name="linePoint"></param>
        /// <param name="circular"></param>
        /// <returns></returns>
        Vector3[] CreateMeshPoint(List<LinePoint> linePoint, Vector3[] circular)
        {
            int length = linePoint.Count;
            int circularCount = circular.Length;
            Vector3[] meshPoint = new Vector3[length * circularCount];
            for (int i = 0; i < length; i++)
            {
                for (int j = 0; j < circularCount; j++)
                {
                    meshPoint[(i * circularCount) + j] = circular[j].FromToMoveRotation(linePoint[i].Location, linePoint[i].Direction);
                }
            }
            return meshPoint;
        }
        /// <summary>
        /// 網(wǎng)格創(chuàng)建
        /// </summary>
        /// <param name="linePoints">線的軸心線組</param>
        /// <param name="meshPoint">網(wǎng)格點(diǎn)</param>
        /// <param name="count">段數(shù)</param>
        /// <param name="uvX">uv寬度</param>
        /// <returns></returns>
        Mesh CreatMesh(List<LinePoint> linePoints, Vector3[] meshPoint, int count, float uvX)
        {
            Mesh mesh = new Mesh();
            mesh.vertices = meshPoint;
            mesh.triangles = GetTriangles(linePoints.Count, count);
            mesh.uv = GetUV(linePoints, count, uvX);
            mesh.RecalculateNormals();
            mesh.RecalculateBounds();
            return mesh;
        }
   /// <param name="length">線段段數(shù)</param>
        /// <param name="count">橫截面段數(shù)(也就是圓的段數(shù))</param>
        /// <returns></returns>
        int[] GetTriangles(int length, int count)
        {
            int[] triangles = new int[(count * (length - 1)) * 6];
            int k = 0;
            if (count == 1)
            {
                for (int i = 0; i < length-1; i++)
                {
                    int a = i * 2;
                    triangles[k] = a;
                    triangles[k + 1] = a + 1;
                    triangles[k + 2] = a + 3;
                    triangles[k + 3] = a;
                    triangles[k + 4] = a + 3;
                    triangles[k + 5] = a + 2;
                    k += 6;
                }
            }
            else
            {
                for (int i = 0; i < length - 1; i++)
                {
                    
                    for (int j = 0; j < count; j++)
                    {
                        if (j == count - 1)
                        {
                           // Debug.Log("k=" + k);
                            triangles[k] = (i * count) + j;
                            triangles[k + 1] = (i * count) + 0;
                            triangles[k + 2] = ((i + 1) * count) + 0;
                            triangles[k + 3] = (i * count) + j;
                            triangles[k + 4] = ((i + 1) * count) + 0;
                            triangles[k + 5] = ((i + 1) * count) + j;
                        }
                        else
                        {
                            triangles[k] = (i * count) + j;
                            triangles[k + 1] = (i * count) + j + 1;
                            triangles[k + 2] = ((i + 1) * count) + j + 1;
                            triangles[k + 3] = (i * count) + j;
                            triangles[k + 4] = ((i + 1) * count) + j + 1;
                            triangles[k + 5] = ((i + 1) * count) + j;
                        }
                        k += 6;
                    }
                }
            }
            return triangles;
        }
  /// <summary>
        /// 創(chuàng)建uv
        /// </summary>
        /// <param name="linePoints"></param>
        /// <param name="count"></param>
        /// <param name="uvX"></param>
        /// <returns></returns>
        Vector2[] GetUV(List<LinePoint> linePoints,int count, float uvX)
        {
            int length = linePoints.Count;
            if (count == 1) { count = 2; }
            Vector2[] uvs = new Vector2[(count * length)];
            float lineDis = 0;
            int k = 0;
            for (int i = 0; i < length; i ++)
            {
                
                if (i != 0)
                {
                    lineDis += Vector3.Distance(linePoints[i].Location, linePoints[i - 1].Location);
                }
                for (int j = 0; j < count; j++)
                {
                    Vector2 vector2;
                    if (j % 2 != 0)
                    {
                        vector2 = new Vector2(uvX, lineDis);
                    }
                    else
                    {
                        vector2 = new Vector2(0, lineDis);
                    }
                    uvs[k] = vector2;
                    k += 1;
                }
            }
            return uvs;
        }
3.2貝塞爾曲線的建立方法

源碼

 /// <summary>
    /// 獲取繪制點(diǎn)
    /// </summary>
    /// <param name="controlPoints"></param>
    /// <param name="segmentsPerCurve"></param>
    /// <returns></returns>
    public List<Vector3> GetDrawingPoints(List<Vector3> controlPoints, int segmentsPerCurve)
    {
        List<Vector3> points = new List<Vector3>();
        // 下一段的起始點(diǎn)和上段終點(diǎn)是一個(gè),所以是 i+=3
        for (int i = 0; i <= controlPoints.Count - 4; i += 3)
        {

            var p0 = controlPoints[i];
            var p1 = controlPoints[i + 1];
            var p2 = controlPoints[i + 2];
            var p3 = controlPoints[i + 3];
            float dis = Vector3.Distance(p0, p3);
            int count = Mathf.CeilToInt(segmentsPerCurve * dis);
            if (count < segmentsPerCurve)
            {
                count = segmentsPerCurve;
            }

            for (int j = 0; j <= count; j++)
            {
                var t = j / (float)count;
                points.Add(CalculateBezierPoint(t, p0, p1, p2, p3));
            }
        }
        return points;
    }
    // 三階公式
    Vector3 CalculateBezierPoint(float t, Vector3 p0, Vector3 p1, Vector3 p2, Vector3 p3)
    {
        Vector3 result;

        Vector3 p0p1 = (1 - t) * p0 + t * p1;
        Vector3 p1p2 = (1 - t) * p1 + t * p2;
        Vector3 p2p3 = (1 - t) * p2 + t * p3;

        Vector3 p0p1p2 = (1 - t) * p0p1 + t * p1p2;
        Vector3 p1p2p3 = (1 - t) * p1p2 + t * p2p3;

        result = (1 - t) * p0p1p2 + t * p1p2p3;
        return result;
    }

3.3貝塞爾曲線應(yīng)用

基于上述方法實(shí)現(xiàn)了貝塞爾創(chuàng)建,保存,讀取,在編輯功能。
案例下載地址

創(chuàng)建曲線

【Unity】運(yùn)行時(shí)創(chuàng)建曲線(貝塞爾的運(yùn)用),Unity,unity,游戲引擎

保存曲線

保存方法有兩種分別是,長(zhǎng)期保存和暫時(shí)保存。長(zhǎng)期保存是將保存數(shù)據(jù)寫入本地文件,項(xiàng)目重啟也可以讀?。粫簳r(shí)保存是在項(xiàng)目運(yùn)行期間保存數(shù)據(jù),重啟后丟失。demo使用暫時(shí)保存的方法

【Unity】運(yùn)行時(shí)創(chuàng)建曲線(貝塞爾的運(yùn)用),Unity,unity,游戲引擎

讀取再編輯

讀取曲線后可以繼續(xù)編輯當(dāng)前曲線

【Unity】運(yùn)行時(shí)創(chuàng)建曲線(貝塞爾的運(yùn)用),Unity,unity,游戲引擎

曲線瀏覽

【Unity】運(yùn)行時(shí)創(chuàng)建曲線(貝塞爾的運(yùn)用),Unity,unity,游戲引擎文章來源地址http://www.zghlxwxcb.cn/news/detail-760671.html

到了這里,關(guān)于【Unity】運(yùn)行時(shí)創(chuàng)建曲線(貝塞爾的運(yùn)用)的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • 【游戲開發(fā)實(shí)戰(zhàn)】Unity實(shí)現(xiàn)類似GitHub地球射線的效果(LineRenderer | 貝塞爾曲線)

    【游戲開發(fā)實(shí)戰(zhàn)】Unity實(shí)現(xiàn)類似GitHub地球射線的效果(LineRenderer | 貝塞爾曲線)

    一、前言 嗨,大家伙,我是新發(fā)。 好久不見,這是2022年第一篇博客,今天有同學(xué)私信我,問我在 Unity 中如何實(shí)現(xiàn)這種地球輻射線的效果, 這一看,我就想到了 GitHub 主頁(yè)的地球射線, 那么,今天就來講講如何實(shí)現(xiàn)這個(gè)效果吧~ 本文最終效果如下: 本文工程源碼見文章末尾

    2024年02月06日
    瀏覽(30)
  • 【unity小技巧】使用貝塞爾曲線實(shí)現(xiàn)導(dǎo)彈隨機(jī)攻擊敵人,也可以用于平滑拾取物品

    參考原視頻鏈接: 【視頻】:https://www.bilibili.com/video/BV1aU4y1v7yM/ 注意 :本文為學(xué)習(xí)筆記記錄,推薦支持原作者,去看原視頻自己手敲代碼理解更加深入

    2024年02月13日
    瀏覽(25)
  • Unity實(shí)現(xiàn)殺戮尖塔出牌效果( 三. 貝塞爾曲線引導(dǎo)箭頭繪制,卡牌使用效果制作)

    Unity實(shí)現(xiàn)殺戮尖塔出牌效果( 三. 貝塞爾曲線引導(dǎo)箭頭繪制,卡牌使用效果制作)

    1. 攻擊類型卡牌 ①拖拽超過一定高度之后卡牌會(huì)移動(dòng)到手牌中心位置 ②出現(xiàn)攻擊引導(dǎo)箭頭 (塞貝爾曲線) ③成功指向目標(biāo)怪物后打出 2. 技能能力類型卡牌 ①可自由拖動(dòng) ②脫離手牌高度后打出 這里只展示此效果核心代碼內(nèi)容,重復(fù)代碼不做贅述,上期(二.鼠標(biāo)指向卡牌時(shí),

    2024年04月12日
    瀏覽(139)
  • 二階貝塞爾曲線生成弧線

    二階貝塞爾曲線生成弧線

    本文分享一個(gè)二階貝塞爾曲線曲線生成弧線的算法。 示例使用openlayers實(shí)現(xiàn)。

    2024年01月22日
    瀏覽(23)
  • 【LVGL筆記】-- 貝塞爾曲線繪制

    【LVGL筆記】-- 貝塞爾曲線繪制

    什么是貝塞爾曲線 貝塞爾曲線 (Bézier Curve,也被稱為貝塞爾多項(xiàng)式(Bézier Polynomial),是由一系列控制點(diǎn)(Control Point)所定義的一條平滑曲線。 Pierre Bézier 于1960年開始利用該曲線設(shè)計(jì)雷諾的車身線條,故命名為貝塞爾曲線。目前,貝塞爾曲線被廣泛應(yīng)用于圖形設(shè)計(jì)、路徑

    2024年02月02日
    瀏覽(27)
  • c++計(jì)算貝塞爾曲線(折線平滑為曲線)坐標(biāo)方法

    效果可查看上一篇博文: js手動(dòng)畫平滑曲線,貝塞爾曲線擬合 【代碼】js手動(dòng)畫平滑曲線,貝塞爾曲線擬合。 https://blog.csdn.net/qiufeng_xinqing/article/details/131711963?spm=1001.2014.3001.5502 代碼如下:

    2024年02月16日
    瀏覽(25)
  • CSS動(dòng)畫中的貝塞爾曲線

    CSS動(dòng)畫中的貝塞爾曲線

    最近在學(xué)習(xí)CSS動(dòng)畫,其中動(dòng)畫時(shí)間函數(shù)的部分涉及到了 貝塞爾曲線 的相關(guān)知識(shí)。對(duì)于這部分知識(shí),之前一直沒有好好學(xué)習(xí)過,正好借著這個(gè)機(jī)會(huì)學(xué)習(xí)下。 首先簡(jiǎn)單介紹下貝塞爾曲線。 貝塞爾曲線(Bézier curve),又稱貝茲曲線或貝濟(jì)埃曲線,是應(yīng)用于二維圖形應(yīng)用程序的數(shù)學(xué)曲

    2024年02月09日
    瀏覽(27)
  • 徹底搞懂貝塞爾曲線的原理

    徹底搞懂貝塞爾曲線的原理

    貝塞爾曲線介紹 我們?cè)谇懊嬷v了繪制自定義曲線,而實(shí)際開發(fā)過程還會(huì)遇到更復(fù)雜的圖形繪制,比如下面的這些圖形: 這時(shí)候就需要用到貝塞爾曲線了。下面是百科關(guān)于貝塞爾曲線的介紹。 貝塞爾曲線就是這樣的一條曲線,它是依據(jù)四個(gè)位置任意的點(diǎn)坐標(biāo)繪制出的一條光滑

    2024年02月20日
    瀏覽(23)
  • 貝塞爾曲線的python實(shí)現(xiàn)(簡(jiǎn)單易理解)

    貝塞爾曲線的python實(shí)現(xiàn)(簡(jiǎn)單易理解)

    貝塞爾曲線在計(jì)算機(jī)圖形學(xué)中被大量使用,通??梢援a(chǎn)生平滑的曲線。比如ps中的鋼筆工具,就是利用的這種原理。由于用計(jì)算機(jī)畫圖大部分時(shí)間是操作鼠標(biāo)來掌握線條的路徑,與手繪的感覺和效果有很大的差別。即使是一位精明的畫師能輕松繪出各種圖形,拿到鼠標(biāo)想隨心

    2024年02月16日
    瀏覽(24)
  • Godot插值、貝塞爾曲線和Astar尋路

    Godot插值、貝塞爾曲線和Astar尋路

    線性插值是采用一次多項(xiàng)式上進(jìn)行的插值計(jì)算,任意給定兩個(gè)值A(chǔ)和B,那么在A和B之間的任意值可以定義為: P(t) = A * (1 - t) + B * t,0 = t = 1。 數(shù)學(xué)中用于線性擬合,游戲應(yīng)用可以做出跟隨效果(寵物跟隨、npc跟隨) 貝塞爾是插值的應(yīng)用之一。貝塞爾曲線是為工業(yè)設(shè)計(jì),是圖形

    2024年04月14日
    瀏覽(27)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包