1

【Unity3D】动态路径特效 - little_fat_sheep

 11 months ago
source link: https://www.cnblogs.com/zhyan8/p/17760926.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

​ 本文通过导航系统(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>();
        navMeshAgent.speed = 100;
        navMeshAgent.angularSpeed = 10000;
        navMeshAgent.acceleration = 10000;
        path = new NavMeshPath();
    }

    private void AddLineRenderer() { // 添加线段渲染器
        lineRenderer = gameObject.AddComponent<LineRenderer>();
        lineRenderer.textureMode = LineTextureMode.Tile;
        lineRenderer.material = Resources.Load<Material>("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】动态路径特效


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK