Unity简单地图循环长箭头实现

作者: 玄猫大人 | 来源:发表于2017-05-17 20:02 被阅读379次

最近在做大地图,行军导航过程中会试用到导向箭头,这里整理下实现的过程。

最终效果

箭头实例图

思路分解

1 地图上会有很多这种指向的箭头,同时长度是不固定的,需要根据不同的起始点和终点进行计算角度和方向
2 长度在Unity中可以通过scale进行控制
3 需要重复的箭头,要实现图片平铺的效果,这里就有一个Tiling的概念
4 如果需要移动,可以使用材质的Offset属性
5 选择角度计算过程中,需要考虑到四个象限的不同情况
6 箭头显示要在最上层,不能被地表的物体遮挡

看到这些思路你们能实现的出来吗?不卖官司,接着往下看。

具体实现

原料:

Plane一只,做2D的时候用Sprite原理也是一样的;
箭头图片一张;
Shader文件一个;
材质球一枚;
CS文件一个;

操作步骤:

1 先处理材质球,新建一个Shader,命名为TransparentOverlay,具体代码如下:

Shader "Custom/TransparentOverlay"  
{  
    Properties   
    {  
        _MainTex ("MainTex(RGBA)", 2D) = "white" {}  
    }

    SubShader   
    {  
        LOD 100
        Cull Off Lighting Off ZWrite Off ZTest Always
        Blend SrcAlpha OneMinusSrcAlpha
        
        Tags
        {
            "Queue" = "Overlay"
            "IgnoreProjector" = "True"
            "RenderType" = "Transparent"
        }

        Pass
        {
            SetTexture[_MainTex]
        }
    } 
}

2 利用该Shader创建一个材质球,将箭头图片赋给材质球

箭头和对应的材质球

3 在场景中新建一个Plane,将材质球赋个Plane,调整Plane到你需要的尺寸,做成预制件

我所用的参数,根据场景自行修改

4 新建一个C#脚本,代码有点长,直接看注释咯,需要额外说的是,计算长度和角度公式大致如下,在其他地方使用的时候还是要根据当前场景的相机,地图大小等等进行相应的微调。

using UnityEngine;

/// <summary>
/// 行军路线
/// </summary>
public class MapLine : MonoBehaviour {
    private Vector3 startPos = Vector3.one;
    private Vector3 endPos = Vector3.one;
    private Vector3 rotation = Vector3.zero;

    private Material material;
    private bool isMove;
    private Vector2 moveDir;
    private Vector2 resetOffset;

    void Awake()
    {
        isMove = false;
        moveDir = new Vector2(0, 0.01f);
        resetOffset = new Vector2(0, 100);
        material = GetComponent<Renderer>().material;
    }
    
    /// <summary>
    /// 设置材质的Offset的属性,让箭头移动起来
    /// </summary>
    private void Update()
    {
        if(isMove)
        {
            if (material.mainTextureOffset == resetOffset)
                material.mainTextureOffset = moveDir;
            material.mainTextureOffset += moveDir;
        }
    }

    public void SetLine(Vector3 startPos, Vector3 endPos)
    {
        this.startPos = startPos;
        this.endPos = endPos;
        transform.localScale = Vector3.one * 0.05f;
        transform.position = startPos;
        transform.eulerAngles = Vector3.zero;

        var scale = transform.localScale;
        var lineLong = CalLineLong() * 2;
        scale.z = scale.z * lineLong;
        transform.localScale = scale;
        rotation.y = CalLineAngle();
        transform.eulerAngles = rotation;
        material.mainTextureScale = new Vector2(1, lineLong);
        transform.Translate(0,0,lineLong / 4, Space.Self);
        isMove = true;
    }

    /// <summary>
    /// 计算行军路线长度
    /// </summary>
    private float CalLineLong()
    {
        return Mathf.Sqrt(Mathf.Pow(startPos.x - endPos.x, 2) + Mathf.Pow(startPos.z - endPos.z, 2));
    }

    /// <summary>
    /// 计算行军路线角度
    /// </summary>
    private float CalLineAngle()
    {
        //斜边长度
        float length = Mathf.Sqrt(Mathf.Pow((startPos.x - endPos.x), 2) + Mathf.Pow((startPos.z - endPos.z), 2));
        //对边比斜边 sin
        float hudu = Mathf.Asin(Mathf.Abs(startPos.z - endPos.z) / length);
        float ag = hudu * 180 / Mathf.PI;

        //第一象限
        if ((endPos.x - startPos.x) >= 0 && (endPos.z - startPos.z >= 0))
            ag = -ag + 90;
        //第二象限
        else if ((endPos.x - startPos.x) <= 0 && (endPos.z - startPos.z >= 0))
            ag = ag - 90;
        //第三象限
        else if ((endPos.x - startPos.x) <= 0 && (endPos.z - startPos.z) <= 0)
            ag = -ag +270;
        //第四象限
        else if ((endPos.x - startPos.x) >= 0 && (endPos.z - startPos.z) <= 0)
            ag = ag + 90;
        return ag;
    }
}

5 将脚本附加到预制件中,通过设置SetLine方法设置起点和终点就可以在地图上画箭头了。

PS:写代码还是要学好数学呀,不做都不知道象限是个啥,顺路复习初中数学

相关文章

  • Unity简单地图循环长箭头实现

    最近在做大地图,行军导航过程中会试用到导向箭头,这里整理下实现的过程。 最终效果 思路分解 1 地图上会有很多这种...

  • Unity循环长箭头加强版

    需求变更 我哩个天天,需求这东西就是你做完一个又回有新的一个,做了个普通的,就会让你做高级的。这不之前做了循环长箭...

  • 游戏小地图方案

    Unity小地图的实现 游戏,特别是RPG类型,基本都需要添加小地图功能来辅助玩家。 实现小地图需解决的问题: 小...

  • Unity-UGUI无限循环列表

    Unity版本:2017.4 简介:UGUI使用ScrollView、GridLayoutGroup实现无限循环列...

  • 每日小结

    2020/5/14 参考资料 文章:老师!我想用Tilemap做元气骑士款地图!文章:用Unity实现元气骑士地图...

  • Code Snippet

    中文对齐 Unity3D 中 dotween 实现: 箭头向上跳动效果(见图1) 标准正态分布函数 sin函数的近...

  • 辨别方向的方法

    1、看地图辨别方向是最简单的办法。地图上有指向标指示方向,指向标箭头的指向就是北方。 2、有的地图没有指向标,通常...

  • 自定义拖拽View

    封装简单拖拽视图view,效果如下: 实现思路: 通过箭头的滑动事件坐标动态变化改变容器的高度 上面在箭头Imag...

  • unity A*算法简单实现

    项目要用A算法做运算所以边学边练。http://edu.manew.com/course/44/task/432/...

  • [Unity] 在Unity中实现小地图(Minimap)

    小地图的基本概念 众所周知,小地图(或雷达)是用于显示周围环境信息的。首先,小地图是以主角为中心的。其次,小地图上...

网友评论

本文标题:Unity简单地图循环长箭头实现

本文链接:https://www.haomeiwen.com/subject/wboxxxtx.html