地图刷新+小地图+摄像机跟随

初始化地图的代码如下:

using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

[RequireComponent(typeof(MeshFilter))]
[RequireComponent(typeof(MeshRenderer))]
[RequireComponent(typeof(MeshCollider))]
public class PerlinNoiseMap : MonoBehaviour
{
    int w, h;//宽,高
    float row, col;//行,列

    VertexHelper vh;
    [SerializeField]
    Texture2D texture2D;//地图的材质

    public void Init(int r, int c)
    {
        row = r;
        col = c;
        w = 100;
        h = 100;
        vh = new VertexHelper();
        Mesh mesh = new Mesh();
        for (int i = 0; i <= w; i++)
        {
            for (int j = 0; j <= h; j++)
            {
                //用PerlinNoise计算地图的高度
                float y = Mathf.PerlinNoise((i + row * w) * 0.02f, (j + col * h) * 0.02f) * 30;
                //计算u,v值从而确定贴图
                float u = i * 1.0f / w;
                float v = j * 1.0f / h;
                if (y <= 10)//设置最低高度
                {
                    y = 0;
                }
                //解决边界有痕的问题
                if (row % 2 == 0)
                {
                    u = 1 - u;
                }
                if (col % 2 == 0)
                {
                    v = 1 - v;
                }
                //绘制地图
                vh.AddVert(new Vector3(i, y, j), Color.white, new Vector2(u, v));
                if (i < w && j < h)
                {
                    vh.AddTriangle(i * (h + 1) + j, i * (h + 1) + j + 1, (i + 1) * (h + 1) + j + 1);
                    vh.AddTriangle(i * (h + 1) + j, (i + 1) * (h + 1) + j + 1, (i + 1) * (h + 1) + j);
                }
            }
        }
        vh.FillMesh(mesh);
        GetComponent<MeshFilter>().mesh = mesh;
        Material mat = new Material(Shader.Find("Standard"));
        mat.mainTexture = texture2D;
        GetComponent<MeshRenderer>().material = mat;
        GetComponent<MeshCollider>().sharedMesh = mesh;
    }

    List<Vector3> vertics = new List<Vector3>();//顶点的集合
    public void Refresh(int r, int c)
    {
        row = r;
        col = c;
        vertics.Clear();
        GetComponent<MeshFilter>().mesh.GetVertices(vertics);
        for (int i = 0; i <= w; i++)
        {
            for (int j = 0; j <= h; j++)
            {
                float y = Mathf.PerlinNoise((i + w * r) * 0.02f, (j + h * c) * 0.02f) * 30;
                if (y <= 10)
                {
                    y = 0;
                }
                float u, v;
                if (row % 2 == 0)
                {
                    u = 1 - (i * 1.0f) / w;
                }
                else
                {
                    u = (i * 1.0f) / w;
                }
                if (col % 2 == 0)
                {
                    v = 1 - (j * 1.0f) / h;
                }
                else
                {
                    v = (j * 1.0f) / h;
                }
                Vector3 point = vertics[i * (h + 1) + j];
                point.y = y;
                vertics[i * (h + 1) + j] = point;
            }
        }
        GetComponent<MeshFilter>().mesh.vertices = vertics.ToArray();
    }
}

下面是地图刷新和玩家移动的代码

using System.Collections.Generic;
using UnityEngine;

public class RefreshMap : MonoBehaviour
{

    [SerializeField]
    GameObject tield;//地图模板

    [SerializeField]
    GameObject player;//玩家

    public List<TieldData> tieldDatas = new List<TieldData>();//地图数据的集合
    List<GameObject> tislds = new List<GameObject>();//地图模块的集合

    float orgX, orgY;//地图的初始位置

    int[,] tieldIndex = new int[9, 2];//地图下标的集合

    int curX, curZ;//地图的初始下标

    public int tieldSize = 100;//地图的大小(宽,高)

    Dictionary<string, GameObject> dicTield = new Dictionary<string, GameObject>();//缓存地图的字典



    // Start is called before the first frame update
    void Start()
    {
        orgX = -tieldSize;
        orgY = -tieldSize;

        //生成九宫格地图
        for (int i = 0; i < 3; i++)
        {
            for (int j = 0; j < 3; j++)
            {
                GameObject item;
                if (i == 0 && j == 0)
                {
                    item = tield;
                }
                else
                {
                    item = Instantiate(tield);

                }

                item.name = i.ToString() + "," + j.ToString();
                tislds.Add(item);
                item.GetComponent<PerlinNoiseMap>().Init(i, j);

                item.transform.SetParent(transform);
                item.transform.localPosition = new Vector3(i * tieldSize + orgX, 0, j * tieldSize + orgY);
                TieldData tieldData = new TieldData();
                tieldData.r = i;
                tieldData.c = j;
                tieldData.go = item;
                tieldDatas.Add(tieldData);
            }
        }
    }

    //缓存地图模块的下标
    void TieldIndex(int x, int z)
    {
        tieldIndex[0, 0] = x - 1;
        tieldIndex[0, 1] = z - 1;

        tieldIndex[1, 0] = x - 1;
        tieldIndex[1, 1] = z;

        tieldIndex[2, 0] = x - 1;
        tieldIndex[2, 1] = z + 1;

        tieldIndex[3, 0] = x;
        tieldIndex[3, 1] = z - 1;

        tieldIndex[4, 0] = x;
        tieldIndex[4, 1] = z;

        tieldIndex[5, 0] = x;
        tieldIndex[5, 1] = z + 1;

        tieldIndex[6, 0] = x + 1;
        tieldIndex[6, 1] = z - 1;

        tieldIndex[7, 0] = x + 1;
        tieldIndex[7, 1] = z;

        tieldIndex[8, 0] = x + 1;
        tieldIndex[8, 1] = z + 1;

        dicTield.Clear();
        for (int i = 0; i < tieldIndex.GetLength(0); i++)
        {
            string key = tieldIndex[i, 0].ToString() + "," + tieldIndex[i, 1].ToString();
            dicTield.Add(key, null);
        }
    }

    List<GameObject> temobj = new List<GameObject>();
    // Update is called once per frame
    void Update()
    {
        Move();
        //计算玩家的位置
        Vector3 off = player.transform.position - new Vector3(orgX, 0, orgY);

        //计算玩家在九宫格地图上的比例
        int x = Mathf.FloorToInt(off.x / tieldSize);
        int z = Mathf.FloorToInt(off.z / tieldSize);

        //计算玩家在小地图上的比例
        Vector3 leftBottom = new Vector3(orgX + (x - 1) * tieldSize, 0, orgY + (z - 1) * tieldSize);
        Vector3 tempPos = player.transform.localPosition - leftBottom;
        float pivotX = tempPos.x / (3 * tieldSize);
        float pivotY = tempPos.z / (3 * tieldSize);

        //设置小地图的中心点和位置
        GameObject.Find("Canvas/Panel/Mask/MiniMap").GetComponent<RectTransform>().pivot = new Vector2(pivotX,pivotY);
        GameObject.Find("Canvas/Panel/Mask/MiniMap").GetComponent<RectTransform>().localPosition = Vector3.zero;

        if (x == curX && z == curZ) return;
        TieldIndex(x, z);

        for (int i = 0; i < tislds.Count; i++)
        {
            string key = tislds[i].name;
            if (dicTield.ContainsKey(key))
            {
                dicTield[key] = tislds[i];
            }
            else
            {
                temobj.Add(tislds[i]);
            }
        }

        for (int i = 0; i < tieldIndex.GetLength(0); i++)
        {
            string key = tieldIndex[i, 0].ToString() + "," + tieldIndex[i, 1].ToString();

            TieldData tieldData = tieldDatas[i];
            tieldData.r = tieldIndex[i, 0];
            tieldData.c = tieldIndex[i, 1];
            if (dicTield[key] == null)
            {
                GameObject item = temobj[0];
                item.transform.localPosition = new Vector3(tieldIndex[i, 0] * tieldSize + orgX, 0,
                    tieldIndex[i, 1] * tieldSize + orgY);
                item.name = key;
                dicTield[key] = item;
                item.GetComponent<PerlinNoiseMap>().Refresh(tieldIndex[i, 0], tieldIndex[i, 1]);
                temobj.RemoveAt(0);
            }
            tieldData.go = dicTield[key];
        }

        tieldDatas.Sort((a, b) =>
        {
            return (int)(a.r - b.r);
        });
        tieldDatas.Sort((a, b) =>
        {
            return (int)(a.c - b.c);
        });

        GameObject.Find("Canvas/Panel/Mask").GetComponent<MiniMap>().RefreshMap(tieldDatas);
        curX = x;
        curZ = z;
    }

    private void Move()//玩家移动
    {
        float x = Input.GetAxis("Horizontal");
        float y = Input.GetAxis("Vertical");
        player.transform.Translate(new Vector3(0, 0, y) * Time.deltaTime * 10);
        player.transform.Rotate(new Vector3(0, x, 0) * Time.deltaTime * 100);

    }
}
//地图模块的数据类
public class TieldData
{
    public int r;
    public int c;
    public GameObject go;
}

下面是小地图刷新的代码:

using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class MiniMap : MonoBehaviour
{
    public List<Image> images; //小地图图片的集合
    List<Texture2D> texture2Ds = new List<Texture2D>();//小地图贴图的集合

    public RectTransform miniMap;//小地图的父物体

    //每块小地图的大小(宽,高)
    int w = 100;
    int h = 100;
    private void Awake()
    {
        for (int i = 0; i < images.Count; i++)
        {
            Texture2D texture = new Texture2D(w, h);
            texture2Ds.Add(texture);
        }
    }

    public void RefreshMap(List<TieldData> tieldDatas)
    {
        for(int i =0;i<images.Count;i++)
        {
            Texture2D texture2D = tieldDatas[i].go.GetComponent<MeshRenderer>().material.mainTexture as Texture2D;
            List<Vector3> points = new List<Vector3>();
             tieldDatas[i].go.GetComponent<MeshFilter>().mesh.GetVertices(points);
            int row = tieldDatas[i].r;
            int col = tieldDatas[i].c;
            for (int x = 0;x<=100;x++)
            {
                for (int z = 0; z <= 100; z++)
                {

                    float y = points[x * 101 + z].y;
                    if (y > 10)
                    {
                        int u, v;
                        if (row % 2 == 0)
                        {
                            u = w - x;
                        }
                        else
                        {
                            u = x;
                        }
                        if (col % 2 == 0)
                        {
                            v = h - z;
                        }
                        else
                        {
                            v = z;
                        }
                        texture2Ds[i].SetPixel(x, z,texture2D.GetPixel(u,v));
                    }
                    else
                    {
                        texture2Ds[i].SetPixel(x, z, Color.blue);
                    }
                }
            }
            texture2Ds[i].Apply();
            images[i].sprite = Sprite.Create(texture2Ds[i],new Rect(0,0,w,h),new Vector2(0.5f,0.5f));
        }
    }
    float scale = 1.0f;
    // Update is called once per frame
    void Update()
    {
        //鼠标滚轮控制地图缩放
        if (Input.GetAxis("Mouse ScrollWheel") != 0)
        {
            scale += Input.GetAxis("Mouse ScrollWheel");
            miniMap.localScale = new Vector3 (scale,scale,scale);
        }
    }
}

相机丝滑跟随的代码:

using UnityEngine;
/// <summary>
/// 挂载在相机上
/// </summary>
public class CameraMove : MonoBehaviour
{
    public GameObject player;//玩家
    Vector3 pos;//相对位置
    // Start is called before the first frame update
    void Start()
    {
        pos = new Vector3(0,12,-8);
    }

    // Update is called once per frame
    void Update()
    {
        //设置相机的位置和朝向
        transform.position = Vector3.Lerp(transform.position,player.transform.position + pos,Time.deltaTime / 2);
        Quaternion qua = Quaternion.LookRotation(player.transform.position - transform.position);
        transform.rotation = Quaternion.Slerp(transform.rotation,qua,Time.deltaTime);
    }
}

注意事项:

需要添加一个Mask组件

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
信息数据从传统到当代,是一直在变革当中,突如其来的互联网让传统的信息管理看到了革命性的曙光,因为传统信息管理从时效性,还是安全性,还是可操作性等各个方面来讲,遇到了互联网时代才发现能补上自古以来的短板,有效的提升管理的效率和业务水平。传统的管理模式,时间越久管理的内容越多,也需要更多的人来对数据进行整理,并且数据的汇总查询方面效率也是极其的低下,并且数据安全方面永远不会保证安全性能。结合数据内容管理的种种缺点,在互联网时代都可以得到有效的补充。结合先进的互联网技术,开发符合需求的软件,让数据内容管理不管是从录入的及时性,查看的及时性还是汇总分析的及时性,都能让正确率达到最高,管理更加的科学和便捷。本次开发的医院后台管理系统实现了病房管理、病例管理、处方管理、字典管理、公告信息管理、患者管理、药品管理、医生管理、预约医生管理、住院管理、管理员管理等功能。系统用到了关系型数据库中王者MySql作为系统的数据库,有效的对数据进行安全的存储,有效的备份,对数据可靠性方面得到了保证。并且程序也具备程序需求的所有功能,使得操作性还是安全性都大大提高,让医院后台管理系统更能从理念走到现实,确确实实的让人们提升信息处理效率。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值