• 【Unity3D】动态路径特效


    1 前言

    ​ 本文通过导航系统(NavMeshAgent)和线段渲染器(LineRenderer)实现了角色走迷宫和绘制路径功能,同时实现动态路径特效。

    ​ 导航系统的介绍详见博客:导航系统分离路面导航动态路障导航。线段渲染器的介绍详见博客:线段渲染器LineRenderer

    ​ 动态路径特效的原理是:通过对顶点的 uv 纹理坐标平移实现路径节点的移动效果。

    ​ 本文完整资源见→Unity3D动态路径特效

    2 烘焙导航网格

    1)搭建场景

    ​ 搭建迷宫场景如下,红的胶囊体是角色。

    img

    2)设置导航静态对象

    ​ 选中地面和所有围墙,将它们设置为 Navigation Static,如下。

    img

    3)烘焙导航网格

    ​ 通过【Window→AI→Navigation】打开导航窗口。

    img

    ​ 调整参数后,点击 Bake 烘焙导航网格,如下,蓝色的区域是可以行走的区域。

    img

    3 导航及轨迹绘制

    ​ NavController.cs

    using UnityEngine;
    using UnityEngine.AI;
     
    public class NavController : MonoBehaviour {
        private NavMeshAgent navMeshAgent; // 导航网格代理
        private LineRenderer lineRenderer; // 线段渲染器
        private RaycastHit hit; // 碰撞信息
        private NavMeshPath path; // 导航路径
    
        private void Awake() {
            AddNavMeshAgent();
            AddLineRenderer();
        }
     
    	private void Update() {
            if (Input.GetMouseButtonUp(0) && navMeshAgent.remainingDistance < float.Epsilon) {
                Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
                if (Physics.Raycast(ray, out hit)) {
                    if (navMeshAgent.CalculatePath(hit.point, path)) {
                        DrawLine(path.corners);
                        navMeshAgent.SetDestination(hit.point);
                    } else {
                        lineRenderer.positionCount = 0;
                        lineRenderer.enabled = false;
                    }
                }
            }
        }
    
        private void AddNavMeshAgent() { // 添加导航网格代理
            navMeshAgent = gameObject.AddComponent();
            navMeshAgent.speed = 100;
            navMeshAgent.angularSpeed = 10000;
            navMeshAgent.acceleration = 10000;
            path = new NavMeshPath();
        }
    
        private void AddLineRenderer() { // 添加线段渲染器
            lineRenderer = gameObject.AddComponent();
            lineRenderer.textureMode = LineTextureMode.Tile;
            lineRenderer.material = Resources.Load("PathNodeMat");
            lineRenderer.positionCount = 0;
            lineRenderer.enabled = false;
        }
    
        private void DrawLine(Vector3[] points) { // 绘制顶点
            lineRenderer.positionCount = points.Length;
            lineRenderer.SetPositions(points);
            lineRenderer.enabled = true;
        }
    }
    

    ​ 说明:NavController 脚本组件挂在 Player 角色下。

    ​ PathNode.shader

    Shader "MyShader/PathNode"  { // 路径上的节点移动特效
        Properties {
            _MainTex("MainTex", 2D) = "white" {} // 节点贴图
            _Speed("Speed", Range(0.1, 3)) = 2 // 节点移动速度
            _Color("Color", Color) = (1, 1, 1, 1) // 节点颜色
        }
    
        SubShader {
            tags{"Queue" = "Transparent" "RenderType" = "Transparent" "IgnoreProjector" = "True"}
            Blend  SrcAlpha OneMinusSrcAlpha // 混合
            // Cull off // 双面
    
            Pass {
                CGPROGRAM
    
                #include "UnityCG.cginc"
                #pragma vertex vert
                #pragma fragment frag
    
                sampler2D _MainTex; // 节点贴图
                float _Speed; // 节点移动速度
                float4 _Color; // 节点颜色
    
                v2f_img vert(appdata_img v) {
                    v2f_img o;
                    o.pos = UnityObjectToClipPos(v.vertex); // 模型空间顶点坐标变换到裁剪空间, 等价于: mul(UNITY_MATRIX_MVP, v.vertex)
                    o.uv = v.texcoord;
                    o.uv.x -= _Speed * _Time.y; // 通过uv纹理坐标的移动实现节点的移动
                    return o;
                }
    
                fixed4 frag(v2f_img i) : SV_Target {
                    return tex2D(_MainTex, i.uv) * _Color;
                }
    
                ENDCG
            }
        }
    }
    

    ​ 说明:在 Assets 目录下面新建 Resources 目录,接着在 Resources 目录下面创建材质,重命名为 PathNodeMat,将 PathNode.shader 与 PathNodeMat 材质绑定,并将路径节点纹理拖拽到 PathNodeMat 的 Main Tex 中。节点纹理如下,它们都是 png 格式,方向朝右,颜色只有灰色和白色(方便在 Shader 中通过 _Color 控制节点颜色)。

    img

    4 运行效果

    1)路径导航效果

    img

    2)飞机路径节点效果

    img

    img

    3)火箭路径节点效果

    img

    img

    4)箭头路径节点效果

    img

    img

    img

    5)其他路径节点效果

    img

    img

    img

    ​ 声明:本文转自【Unity3D】动态路径特效

  • 相关阅读:
    C# 实现数独游戏
    网络基础知识
    pythonGUI(二)基本元素之一
    docker基础命令
    「面经分享」西北大学 | 字节 生活服务 | 一面二面三面 HR 面
    问题:vue2使用watch监视对象属性,但是这个监视只执行了第一次,后面就没反应了
    网络通信框架的完善
    Python分享之路径与文件 (os.path包, glob包)
    FRED应用:激光二极管的模拟
    4种 Redis 集群方案及优缺点对比
  • 原文地址:https://www.cnblogs.com/zhyan8/p/17760926.html