IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 游戏开发 -> Unity 贝塞尔曲线制作迁徙图 -> 正文阅读

[游戏开发]Unity 贝塞尔曲线制作迁徙图

效果图:

?实现该效果图所需的知识点:

1.贝塞尔曲线

? ? ? ? 贝塞尔曲线是图形学中非常重要的参数曲线,在此不做详细介绍,这里我们用到的是二次方公式:

using UnityEngine;
using System.Collections.Generic;

namespace SK.Framework
{
    public static class Vector3Extension 
    {
        /// <summary>
        /// 生成贝塞尔曲线
        /// </summary>
        /// <param name="self">控制点</param>
        /// <param name="startPoint">贝塞尔曲线起点</param>
        /// <param name="endPoint">贝塞尔曲线终点</param>
        /// <param name="count">贝塞尔曲线点个数</param>
        /// <returns>组成贝塞尔曲线的点集合</returns>
        public static Vector3[] GenerateBeizer(this Vector3 self, Vector3 startPoint, Vector3 endPoint, int count)
        {
            Vector3[] retValue = new Vector3[count];
            for (int i = 1; i <= count; i++)
            {
                float t = i / (float)count;
                float u = 1 - t;
                float tt = Mathf.Pow(t, 2);
                float uu = Mathf.Pow(u, 2);
                Vector3 point = uu * startPoint;
                point += 2 * u * t * self;
                point += tt * endPoint;
                retValue[i - 1] = point;
            }
            return retValue;
        }      
    }
}

2.LineRenderer光线渲染器

? ? ? ? LineRenderer在Unity中应用于线段的渲染,通过设置线段各个点的位置实现线段的绘制。

using UnityEngine;
using SK.Framework;

public class Foo : MonoBehaviour
{
    private void Start()
    {
        //通过起点(0,0,0)、控制点(0,7,5)、终点(0,0,10)生成贝塞尔曲线各点
        Vector3[] points = new Vector3(0f, 7f, 5f).GenerateBeizer(Vector3.zero, new Vector3(0f, 0f, 10f), 100);

        gameObject.AddComponent<LineRenderer>()
            //设置材质
            .SetMaterial(Resources.Load<Material>("Arrow"))
            //设置线段点个数
            .SetPositionCount(points.Length)
            //设置线段各点
            .SetLinePositions(points)
            //设置贴图为平铺模式
            .SetTextureMode(LineTextureMode.Tile)
            //设置起始宽度
            .SetStartWidth(.5f)
            //设置结束宽度
            .SetEndWidth(.5f);
    }
}

上述代码中用到对LineRenderer类的拓展函数

using UnityEngine;

namespace SK.Framework
{
    /// <summary>
    /// 光线渲染器相关拓展
    /// </summary>
    public static class LineRenderExtension
    {
        /// <summary>
        /// 设置起始宽度
        /// </summary>
        /// <param name="self">光线渲染器</param>
        /// <param name="width">起始宽度</param>
        /// <returns>光线渲染器</returns>
        public static LineRenderer SetStartWidth(this LineRenderer self, float width)
        {
            self.startWidth = width;
            return self;
        }
        /// <summary>
        /// 设置结束宽度
        /// </summary>
        /// <param name="self">光线渲染器</param>
        /// <param name="width">结束宽度</param>
        /// <returns>光线渲染器</returns>
        public static LineRenderer SetEndWidth(this LineRenderer self, float width)
        {
            self.endWidth = width;
            return self;
        }
        /// <summary>
        /// 设置起始颜色
        /// </summary>
        /// <param name="self">光线渲染器</param>
        /// <param name="color">起始颜色</param>
        /// <returns>光线渲染器</returns>
        public static LineRenderer SetStartColor(this LineRenderer self, Color color)
        {
            self.startColor = color;
            return self;
        }
        /// <summary>
        /// 设置结束颜色
        /// </summary>
        /// <param name="self">光线渲染器</param>
        /// <param name="color">结束颜色</param>
        /// <returns>光线渲染器</returns>
        public static LineRenderer SetEndColor(this LineRenderer self, Color color)
        {
            self.endColor = color;
            return self;
        }
        /// <summary>
        /// 设置点个数
        /// </summary>
        /// <param name="self">光线渲染器</param>
        /// <param name="count">点个数</param>
        /// <returns>光线渲染器</returns>
        public static LineRenderer SetPositionCount(this LineRenderer self, int count)
        {
            self.positionCount = count;
            return self;
        }
        /// <summary>
        /// 设置点位置
        /// </summary>
        /// <param name="self">光线渲染器</param>
        /// <param name="index">索引</param>
        /// <param name="position">位置</param>
        /// <returns>光线渲染器</returns>
        public static LineRenderer SetLinePosition(this LineRenderer self, int index, Vector3 position)
        {
            self.SetPosition(index, position);
            return self;
        }
        /// <summary>
        /// 设置点位置
        /// </summary>
        /// <param name="self">光线渲染器</param>
        /// <param name="positions">位置数组</param>
        /// <returns>光线渲染器</returns>
        public static LineRenderer SetLinePositions(this LineRenderer self, Vector3[] positions)
        {
            for (int i = 0; i < positions.Length; i++)
            {
                self.SetPosition(i, positions[i]);
            }
            return self;
        }
        /// <summary>
        /// 设置是否循环(终点是否连接起点)
        /// </summary>
        /// <param name="self">光线渲染器</param>
        /// <param name="loop">是否循环</param>
        /// <returns>光线渲染器</returns>
        public static LineRenderer SetLoop(this LineRenderer self, bool loop)
        {
            self.loop = loop;
            return self;
        }
        /// <summary>
        /// 设置CornerVertices属性
        /// </summary>
        /// <param name="self">光线渲染器</param>
        /// <param name="cornerVertices">conner vertices</param>
        /// <returns>光线渲染器</returns>
        public static LineRenderer SetCornerVertices(this LineRenderer self, int cornerVertices)
        {
            self.numCornerVertices = cornerVertices;
            return self;
        }
        /// <summary>
        /// 设置EndCapVertices属性
        /// </summary>
        /// <param name="self">光线渲染器</param>
        /// <param name="endCapVertices">end cap vertices</param>
        /// <returns>光线渲染器</returns>
        public static LineRenderer SetEndCapVertices(this LineRenderer self, int endCapVertices)
        {
            self.numCapVertices = endCapVertices;
            return self;
        }
        /// <summary>
        /// 设置Alignment属性
        /// </summary>
        /// <param name="self">光线渲染器</param>
        /// <param name="alignment">alignment</param>
        /// <returns>光线渲染器</returns>
        public static LineRenderer SetAlignment(this LineRenderer self, LineAlignment alignment)
        {
            self.alignment = alignment;
            return self;
        }
        /// <summary>
        /// 设置TextureMode
        /// </summary>
        /// <param name="self">光线渲染器</param>
        /// <param name="textureMode">texture mode</param>
        /// <returns>光线渲染器</returns>
        public static LineRenderer SetTextureMode(this LineRenderer self, LineTextureMode textureMode)
        {
            self.textureMode = textureMode;
            return self;
        }
        /// <summary>
        /// 设置材质球
        /// </summary>
        /// <param name="self">光线渲染器</param>
        /// <param name="material">材质球</param>
        /// <returns>光线渲染器</returns>
        public static LineRenderer SetMaterial(this LineRenderer self, Material material)
        {
            self.material = material;
            return self;
        }
        /// <summary>
        /// 烘焙网格
        /// </summary>
        /// <param name="self">光线渲染器</param>
        /// <param name="mesh">网格</param>
        /// <returns>光线渲染器</returns>
        public static LineRenderer BakeMesh(this LineRenderer self, out Mesh mesh)
        {
            mesh = new Mesh();
            self.BakeMesh(mesh);
            return self;
        }
    }
}

3.UV滚动

? ? ? ? 通过UV的滚动Shader实现箭头的移动,资源来源于他人博客:链接

?

Shader "Custom/Arrow"
{
    Properties
    {
        _MainTex ("Texture", 2D) = "white" {}
        _MSpeed("MoveSpeed", Range(1, 3)) = 2 //移动速度
    }
    SubShader
    {
        //贴图带透明通道 ,半透明效果设置如下:
        tags{"Queue" = "Transparent" "RenderType" = "Transparent" "IgnoreProjector" = "True"}
        LOD 100
        Blend  SrcAlpha OneMinusSrcAlpha           //Blend选值为: SrcAlpha 和1-SrcAlpha  //也可测试为 DstColor SrcColor    //one one    
        
        Pass
        {
            Name "Simple"
            Cull off //双面

            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            // make fog work
            #pragma multi_compile_fog

            #include "UnityCG.cginc"

            struct appdata
            {
                float4 vertex : POSITION;
                float2 uv : TEXCOORD0;
            };

            struct v2f
            {
                float2 uv : TEXCOORD0;
                UNITY_FOG_COORDS(1)
                float4 vertex : SV_POSITION;
            };

            sampler2D _MainTex;
            float4 _MainTex_ST;
            float _MSpeed;
            v2f vert (appdata v)
            {
                v2f o;
                o.vertex = UnityObjectToClipPos(v.vertex);
                o.uv = TRANSFORM_TEX(v.uv, _MainTex);
                UNITY_TRANSFER_FOG(o,o.vertex);
                return o;
            }

            half4 frag(v2f i) : SV_Target
            {
                float2 uv = float2(i.uv.x - _MSpeed * _Time.y,i.uv.y); //箭头移动的计算
                // sample the texture
                fixed4 col = tex2D(_MainTex, uv);
                // apply fog
                UNITY_APPLY_FOG(i.fogCoord, col);
                return col;
            }
            ENDCG
        }
    }
}

?

?最后通过该Shader创建材质Arrow放于Resources文件夹,创建物体挂载Foo脚本运行即可。

?

???欢迎关注公众号 “当代野生程序猿”

?

  游戏开发 最新文章
6、英飞凌-AURIX-TC3XX: PWM实验之使用 GT
泛型自动装箱
CubeMax添加Rtthread操作系统 组件STM32F10
python多线程编程:如何优雅地关闭线程
数据类型隐式转换导致的阻塞
WebAPi实现多文件上传,并附带参数
from origin ‘null‘ has been blocked by
UE4 蓝图调用C++函数(附带项目工程)
Unity学习笔记(一)结构体的简单理解与应用
【Memory As a Programming Concept in C a
上一篇文章      下一篇文章      查看所有文章
加:2021-09-27 14:26:05  更:2021-09-27 14:26:28 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/28 3:35:17-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码