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实现简单的地图编辑器,实现跑酷地图编辑器 2d地图编辑器,导出地图json数据,导入地图json数据 -> 正文阅读

[游戏开发]unity实现简单的地图编辑器,实现跑酷地图编辑器 2d地图编辑器,导出地图json数据,导入地图json数据

这里使用的是unity2020.1

对于unity编辑器开发也不是很了解,这方面的教程也不多,也是慢慢摸索的

效果显示

?

首先简单

介绍下Unity编辑器开发

1:Editor下打开新窗口需要继承EditorWindow,然后使用获取窗口即可,注意放在Editor文件夹下

public class DrawGameLevel : EditorWindow
{
    [MenuItem("Maps/Create Map &M")]
    public static void OpenMapCreate()
    {
        DrawGameLevel window = EditorWindow.GetWindow<DrawGameLevel>("地图编辑器");
        window.Show();
        window.minSize = new Vector2(500, 800);
        window.maxSize = new Vector2(600, 1200);

    }
}

2:因为是在Scene视图下进行操作,所以注册SceneView.duringSceneGui事件,在OnEnable中

void OnEnable()
 2     {
 3         SceneView.duringSceneGui += OnSceneGUI;
 4         //初始化一些东西
 5     }
 6 
 7     void OnDestroy()
 8     {
 9         SceneView.duringSceneGui -= OnSceneGUI;
10     }

3:unity?编辑器开发,需要在GUI中写,使用EditorGUILayout或者GUILayout来显示ui,基本的组件都是有的

这是我实现的界面和代码??

 #region GUI显示
    private string brushY = "";// 刷新的y坐标
    private string brushX = "";// 刷新的x坐标
    private string brushDisY = "0";// 刷新的y坐标间距
    private string brushDisX = "0";// 刷新的x坐标间距
    private string zIndex = "-0.2";// 显示的层级
    private string fixCount = "0";// 固定生成个数,设置0,一直生成

    private float _lastBrushY = -10000;// 保持Y合理间距 上次刷的y的坐标
    private float _lastBrushX = -10000;// 保持X合理间距 上一个刷的x的坐标
    private int _curImgIndex = -1;//当前正在使用的图
    private int _curFixCount = 0;// 当前已经生成的个数

    private bool _drag = false;// 鼠标拖拽?
    private int _select = 0;// 当前选择的图片 index
    private string ck = "1";// 关卡
    private Texture[] _items = null;// 地形基础图 要使用的地块
    private GameObject parentMap = null;// 地图节点的父节点
    private GameObject bgParent = null;// 背景图挂点
    private string[] bgNames = { "Forest", "Night", "Winter" };// 背景图名字
    private int selectMapIndex = 0;// 选择的地图背景图index
    private int lastSelectMapIndex = -1;// 上次选择的地图背景图index

    private int funcTypeIndex = 0;//  功能类型的index
    private string[] funcTypeArry = { "无","橡皮擦","选中单个物体"};// 选择单个物体
    private int selectTypeIndex = 0;
    private int lastSelectTypeIndex = 0;// 上次选择的类型
    private string[] typeArry = {"不显示选图", "地形图","障碍物",};
    // Update is called once per frame
    void OnGUI()
    {
        GUI.skin.label.normal.textColor = Color.yellow;
        GUI.skin.label.fontSize = 15;

        GUIStyle popStyle = new GUIStyle("Popup");
        popStyle.fontSize = 15;
        // 选择地图
        EditorGUILayout.Space();
        EditorGUILayout.BeginHorizontal();
        GUILayout.Label("1.选择地图", GUILayout.Width(200));
        this.selectMapIndex = EditorGUILayout.Popup(this.selectMapIndex, bgNames, popStyle, GUILayout.MaxWidth(100));
        EditorGUILayout.EndHorizontal();
        EditorGUILayout.Space();
        LoadBg(); 

        ck = EditorGUILayout.TextField("2.设置关卡", ck);
        // 输入数据
        EditorGUILayout.Space();

        GUILayout.Label("设置坐标,批量坐标保持一致的时候使用,不输入是按照鼠标位置刷新");
        brushY = EditorGUILayout.TextField("3.固定Y的坐标(从左到右刷)", brushY);
        brushX = EditorGUILayout.TextField("4.固定X的坐标(从上到下刷)", brushX);
        brushDisY = EditorGUILayout.TextField("5.固定Y间距(从左到右刷)", brushDisY);
        brushDisX = EditorGUILayout.TextField("6.固定X间距(从上到下刷)", brushDisX);
        fixCount = EditorGUILayout.TextField("7.固定生成的个数", fixCount);
        EditorGUILayout.Space(10);
        zIndex = EditorGUILayout.TextField("8.物体显示层级,小的靠前显示", zIndex);

        EditorGUILayout.Space();
        EditorGUILayout.BeginHorizontal();
        GUILayout.Label("9.选择橡皮擦 或者 选中一个场景物体", GUILayout.Width(250));
        this.funcTypeIndex = EditorGUILayout.Popup(this.funcTypeIndex, funcTypeArry, popStyle, GUILayout.MaxWidth(100));
        EditorGUILayout.EndHorizontal();
        EditorGUILayout.Space();

        EditorGUILayout.BeginHorizontal("box");
        GUIStyle btnStyle = new GUIStyle("Button");
        btnStyle.fontSize = 15;
        btnStyle.padding = new RectOffset(10, 10, 10, 10);
        if (GUILayout.Button("10.清除当前地图数据",btnStyle))
        {
            RemoveParentChild(parentMap);
            _lastBrushY = -10000;// 防止后面刷新跟着这个位置
            _lastBrushX = -10000;
            _curFixCount = 0;
        }
        if (GUILayout.Button("11.导出json数据",btnStyle))
        {
            DataMgr.Instance.OutFile(parentMap,ck);
            EditorUtility.DisplayDialog("导出数据成", "导出关卡数据成功"+ck, "确定");
        }
        if (GUILayout.Button("12.导入json数据",btnStyle))
        {
            DataMgr.Instance.ImportFile(parentMap,ck);
            EditorUtility.DisplayDialog("导入数据成功","导入关卡数据成功"+ck,"确定");
        }
        EditorGUILayout.EndHorizontal();
        // 选择图片类型
        GUILayout.Label("13.显示选图", GUILayout.Width(200));
        this.selectTypeIndex = EditorGUILayout.Popup(this.selectTypeIndex,typeArry, popStyle, GUILayout.MaxWidth(100));

        if (selectTypeIndex>0)  LoadChooseImg();// 加载选图
    }
    #endregion

?4:unity?编辑器开发,资源加载可以使用Resources,前提是需要把资源放到Editor->Resources中

5:地图文件导出和导入,通过FileStream和LitJson的解析实现的

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using LitJson;
using UnityEngine;
using UnityEditor;


// 障碍物
public class Obstacle
{
    public int id;
    public string name;
    public int type;
}
// 导出的地图json文件数据格式
public class DataFile
{
    public int id;
    public string name; // 预制体名字
    public string path; // 加载路径
    public string tag;// 预制体的tag
    public string posX;// 坐标x
    public string posY;// 坐标y
    public string posZ;// 坐标z
    public string scaX;//  scale x
    public string scaY;//  scale y
    public string scaZ;// scale z
    public string rotX;//  rotate x
    public string rotY;//  rotate y  
    public string rotZ;// rotate z
   // Todo,后面还可以加障碍物id,用于实现障碍物的功能
    public DataFile() { }
    public DataFile(int id1,string path1,string tag1, float px, float py, float pz, float sx, float sy, float sz, float rx, float ry, float rz)
    {
        id = id1;
        path = path1;
        string[] p = path.Split('/');
        name = p[p.Length - 1];
        tag = tag1;
        posX = px.ToString();
        posY = py.ToString();
        posZ = pz.ToString(); // 使用string类型,是因为转json不识别float和double 
        scaX = sx.ToString();
        scaY = sy.ToString();
        scaZ = sz.ToString();
        rotX = rx.ToString();
        rotY = ry.ToString();
        rotZ = rz.ToString();
    }
}
 public class DataMgr:Editor
{
    private static DataMgr instance = null;
    public static DataMgr Instance
    {
        get
        {
            if (null == instance) instance = new DataMgr();
            return instance;
        }
    }
    public readonly List<Obstacle> m_table = null;
    public  DataMgr()
    {
        // 注册json类型转换方法
        LitJson.JsonMapper.RegisterImporter<int, string>((int input) => { return input.ToString(); });
        LitJson.JsonMapper.RegisterImporter<string, int>((string input) => { return Convert.ToInt32(input); });
        
        // 加载障碍物表 
        //TextAsset ts = Resources.Load<TextAsset>("jsonTable/config_obstacle");
        //m_table = JsonMapper.ToObject<List<Obstacle>>(ts.text);

    }
    // 导出文件json
    // ck 关卡id
    public void OutFile(GameObject parent,string ck)
    {
        int childCount = parent.transform.childCount;
        if (childCount <= 0)
        {
            Debug.Log("没有可以导出的数据节点");
        }
        List<DataFile> list = new List<DataFile>();
        for (int i = 0; i < childCount; i++)
        {
            GameObject obj = parent.transform.GetChild(i).gameObject;
            DataFile file = new DataFile(i+1,obj.name,obj.tag,obj.transform.localPosition.x, obj.transform.localPosition.y, obj.transform.localPosition.z, obj.transform.localScale.x, obj.transform.localScale.y,
                 obj.transform.localScale.z, obj.transform.localRotation.x, obj.transform.localRotation.y,obj.transform.localRotation.z);
            list.Add(file);
        }
        string jsons = JsonMapper.ToJson(list);
        FileStream fs = new FileStream(Application.dataPath + "/OutMap/mapCk_"+ck+".json", FileMode.Create);
        //存储时时二进制,所以这里需要把我们的字符串转成二进制
        byte[] bytes = new UTF8Encoding().GetBytes(jsons);
        fs.Write(bytes, 0, bytes.Length);
        //每次读取文件后都要记得关闭文件
        fs.Close();
        Debug.Log("导出成功"+ "/OutMap/mapCk_"+ck +".json");
    }
    // 导入文件 实例化数据
    public void ImportFile(GameObject parent,string ck)
    {
        if (!parent) return;
        FileStream fs = new FileStream(Application.dataPath + "/OutMap/mapCk_" + ck + ".json", FileMode.Open);
        byte[] bytes = new byte[fs.Length];
        fs.Read(bytes, 0, bytes.Length);
        //将读取到的二进制转换成字符串
        string s = new UTF8Encoding().GetString(bytes);
        List<DataFile> list = JsonMapper.ToObject<List<DataFile>>(s);
        if (list.Count <= 0)
        {
            Debug.Log("没有可导入的数据" + "/OutMap/mapCk_" + ck + ".json");
            return;
        }
        UnityEngine.Object a = Resources.Load<GameObject>(list[0].path);
        for (int i = 0; i < list.Count; i++)
        {
            if (a.name != list[i].path)
            {// 实例化新的
                a = Resources.Load<GameObject>(list[i].path);
            }
            GameObject obj = Instantiate(a) as GameObject;
            obj.tag = list[i].tag;
            obj.name = list[i].path;
            obj.transform.parent = parent.transform;
            obj.transform.localPosition = new Vector3(Convert.ToSingle(list[i].posX), Convert.ToSingle(list[i].posY), Convert.ToSingle(list[i].posZ));
            obj.transform.localRotation = Quaternion.Euler(Convert.ToSingle(list[i].rotX), Convert.ToSingle(list[i].rotY), Convert.ToSingle(list[i].rotZ));
            obj.transform.localScale = new Vector3(Convert.ToSingle(list[i].scaX), Convert.ToSingle(list[i].scaY), Convert.ToSingle(list[i].scaZ));
        }

        Debug.Log("导入成功" + "/OutMap/mapCk_" + ck + ".json");
    }
}

6:地图编辑器面版的全部代码

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
using UnityEditor.SceneManagement;
using System;

public class DrawGameLevel : EditorWindow
{
    [MenuItem("Maps/Create Map &M")]
    public static void OpenMapCreate()
    {
        DrawGameLevel window = EditorWindow.GetWindow<DrawGameLevel>("地图编辑器");
        window.Show();
        window.minSize = new Vector2(500, 800);
        window.maxSize = new Vector2(600, 1200);

    }
    #region 初始化和关闭界面
    private void OnEnable()
    {
        // 在scene下操作,所以要注册,屏蔽scene原有事件
        SceneView.duringSceneGui += OnSceneGUI;
        InitUI();
    }
    private void OnDestroy()
    {
        // 取消事件,恢复scene
        SceneView.duringSceneGui -= OnSceneGUI;
        EndUI();
    }
    //初始化ui,判断是否需要创建挂点
    private void InitUI()
    {
        bgParent = GameObject.Find("BgCamera");
        // 判断有没有quad平面
        GameObject pa = GameObject.Find("Quad");
        if (!pa)
        {
            GameObject obj = GameObject.CreatePrimitive(PrimitiveType.Quad);
            obj.transform.localScale = new Vector3(1000, 10, 1);
            obj.transform.position = new Vector3(0, 0, 0);
            pa = obj;
        }
        pa.tag = "Plane";

        // 判断地图的父节点 要刷的地形的父节点
        GameObject map = GameObject.Find("MapInfo");
        if (!map)
        {
            map = new GameObject("MapInfo");
            map.transform.position = Vector3.zero;
        }
        parentMap = map;
    }
    // 关闭界面的时候
    private void EndUI()
    {
        // 删除背景图
        RemoveParentChild(bgParent);
        // 保存数据道json  再
        //DataMgr.Instance.OutFile(parentMap,ck);
        // 删除parentMap下的
        RemoveParentChild(parentMap);
        // 保存场景 原始场景
        EditorSceneManager.SaveScene(UnityEngine.SceneManagement.SceneManager.GetActiveScene());
    }
    #endregion
    #region 点击事件和射线检测刷地形
   private void OnSceneGUI(SceneView sceneView)
    {
        // 替换Scene视图以前的相应事件,发射线检测要绘制的地图,射线必须要要有碰撞体,所以在场景中准备一个plane,整对着屏幕,只要射线碰撞到plane才进行绘制
        HandleUtility.AddDefaultControl(GUIUtility.GetControlID(FocusType.Passive));// 添加默认响应,来屏蔽以前的
        if (Event.current.type == EventType.MouseDown && Event.current.button == 0)// 点击
        {
        }
        else if (Event.current.type == EventType.MouseUp && Event.current.button == 0)// 抬起
        {
            if (!_drag)
            {
                OnMouseEvent();
            }
            _drag = false;
            // 清楚上次记录的 拖动位置,上次记录的刷出数量
            _lastBrushY = -10000;
            _lastBrushX = -10000;
            _curFixCount = 0;
        }
        else if (Event.current.type == EventType.MouseDrag && Event.current.button == 0)
        {
            OnMouseEvent();
            _drag = true;
        }
    }
    // 检测射线
    private void OnMouseEvent()
    {
        Vector2 mousePos = Event.current.mousePosition;
        mousePos.y = Camera.current.pixelHeight - mousePos.y;// 这里的鼠标原点在左上,而屏幕空间原点在左下,翻转他
        Ray ray = Camera.current.ScreenPointToRay(mousePos);
        RaycastHit hit;
        if (Physics.Raycast(ray, out hit, 3000f))
        {
            //  检测是不是要选中一个已经铺设的物体 
            if (this.funcTypeIndex == 2)
            {// 选择了铺设的地图点
                if (hit.transform.parent == parentMap.transform)
                {// 选中场景中物体
                    EditorGUIUtility.PingObject(hit.transform);
                    Selection.activeGameObject = hit.transform.gameObject;
                }
                return ;
            }
            // 固定生成的个数够了,不生成了
            if (Convert.ToInt32(fixCount) > 0 && Convert.ToInt32(fixCount) <= _curFixCount) return;
            // 
            if ((hit.transform.tag == "Plane" || hit.transform.tag == "Ground") && this.funcTypeIndex!=1)
            {// 实例化图 点击的是地面,或者点击的是ground
                GameObject obj = GetBrushName();
                float x = 0;// 这里使用临时的,是为了防止引用变量带来的错误
                float y = 0;
                Vector3 pos = Camera.current.ScreenToWorldPoint(mousePos);

                if (brushX != "")
                {// x一致 刷的物体 ,记录本次的y坐标,下次方便调整间距
                    pos.x = Convert.ToSingle(brushX);
                    if (_lastBrushY != -10000)
                    {// 前面有刷的同物体,计算本次位置
                        var box = obj.GetComponent<BoxCollider>();
                        if (box)
                        {// 必须从上往下刷
                            _lastBrushY -= (box.size.y * obj.transform.localScale.y) + Convert.ToSingle(brushDisY);
                            y = _lastBrushY;
                        }
                    }
                    else _lastBrushY = pos.y;
                }
                else if (brushY != "")
                {// 刷的物体y一致 ,记录本次的x坐标,下次方便调整间距
                    pos.y = Convert.ToSingle(brushY);
                    if (_lastBrushX != -10000)
                    {// 前面有刷的同物体,计算本次位置
                        var box = obj.GetComponent<BoxCollider>();
                        if (box)
                        {// 必须从左往右刷
                            _lastBrushX += box.size.x * obj.transform.localScale.x + Convert.ToSingle(brushDisX);
                            x = _lastBrushX;
                        }
                    }
                    else _lastBrushX = pos.x;
                }
                obj.transform.localPosition = new Vector3(x != 0 ? x : pos.x, y != 0 ? y : pos.y,Convert.ToSingle(zIndex));
                if (Convert.ToInt32(fixCount) > 0 && (brushY != "" || brushX != ""))
                {// 有刷x或者y,并且固定个数,数量加
                    _curFixCount++;
                }
            }
            else if ((hit.transform.tag == "Ground" || hit.transform.tag == "Obstacle") && this.funcTypeIndex == 1)
            {// 选择了橡皮擦,擦除地面 或者 障碍物
                UnityEngine.Object.DestroyImmediate(hit.transform.gameObject);
            }
        }
    }
    #endregion
    #region GUI显示
    private string brushY = "";// 刷新的y坐标
    private string brushX = "";// 刷新的x坐标
    private string brushDisY = "0";// 刷新的y坐标间距
    private string brushDisX = "0";// 刷新的x坐标间距
    private string zIndex = "-0.2";// 显示的层级
    private string fixCount = "0";// 固定生成个数,设置0,一直生成

    private float _lastBrushY = -10000;// 保持Y合理间距 上次刷的y的坐标
    private float _lastBrushX = -10000;// 保持X合理间距 上一个刷的x的坐标
    private int _curImgIndex = -1;//当前正在使用的图
    private int _curFixCount = 0;// 当前已经生成的个数

    private bool _drag = false;// 鼠标拖拽?
    private int _select = 0;// 当前选择的图片 index
    private string ck = "1";// 关卡
    private Texture[] _items = null;// 地形基础图 要使用的地块
    private GameObject parentMap = null;// 地图节点的父节点
    private GameObject bgParent = null;// 背景图挂点
    private string[] bgNames = { "Forest", "Night", "Winter" };// 背景图名字
    private int selectMapIndex = 0;// 选择的地图背景图index
    private int lastSelectMapIndex = -1;// 上次选择的地图背景图index

    private int funcTypeIndex = 0;//  功能类型的index
    private string[] funcTypeArry = { "无","橡皮擦","选中单个物体"};// 选择单个物体
    private int selectTypeIndex = 0;
    private int lastSelectTypeIndex = 0;// 上次选择的类型
    private string[] typeArry = {"不显示选图", "地形图","障碍物",};
    // Update is called once per frame
    void OnGUI()
    {
        GUI.skin.label.normal.textColor = Color.yellow;
        GUI.skin.label.fontSize = 15;

        GUIStyle popStyle = new GUIStyle("Popup");
        popStyle.fontSize = 15;
        // 选择地图
        EditorGUILayout.Space();
        EditorGUILayout.BeginHorizontal();
        GUILayout.Label("1.选择地图", GUILayout.Width(200));
        this.selectMapIndex = EditorGUILayout.Popup(this.selectMapIndex, bgNames, popStyle, GUILayout.MaxWidth(100));
        EditorGUILayout.EndHorizontal();
        EditorGUILayout.Space();
        LoadBg(); 

        ck = EditorGUILayout.TextField("2.设置关卡", ck);
        // 输入数据
        EditorGUILayout.Space();

        GUILayout.Label("设置坐标,批量坐标保持一致的时候使用,不输入是按照鼠标位置刷新");
        brushY = EditorGUILayout.TextField("3.固定Y的坐标(从左到右刷)", brushY);
        brushX = EditorGUILayout.TextField("4.固定X的坐标(从上到下刷)", brushX);
        brushDisY = EditorGUILayout.TextField("5.固定Y间距(从左到右刷)", brushDisY);
        brushDisX = EditorGUILayout.TextField("6.固定X间距(从上到下刷)", brushDisX);
        fixCount = EditorGUILayout.TextField("7.固定生成的个数", fixCount);
        EditorGUILayout.Space(10);
        zIndex = EditorGUILayout.TextField("8.物体显示层级,小的靠前显示", zIndex);

        EditorGUILayout.Space();
        EditorGUILayout.BeginHorizontal();
        GUILayout.Label("9.选择橡皮擦 或者 选中一个场景物体", GUILayout.Width(250));
        this.funcTypeIndex = EditorGUILayout.Popup(this.funcTypeIndex, funcTypeArry, popStyle, GUILayout.MaxWidth(100));
        EditorGUILayout.EndHorizontal();
        EditorGUILayout.Space();

        EditorGUILayout.BeginHorizontal("box");
        GUIStyle btnStyle = new GUIStyle("Button");
        btnStyle.fontSize = 15;
        btnStyle.padding = new RectOffset(10, 10, 10, 10);
        if (GUILayout.Button("10.清除当前地图数据",btnStyle))
        {
            RemoveParentChild(parentMap);
            _lastBrushY = -10000;// 防止后面刷新跟着这个位置
            _lastBrushX = -10000;
            _curFixCount = 0;
        }
        if (GUILayout.Button("11.导出json数据",btnStyle))
        {
            DataMgr.Instance.OutFile(parentMap,ck);
            EditorUtility.DisplayDialog("导出数据成", "导出关卡数据成功"+ck, "确定");
        }
        if (GUILayout.Button("12.导入json数据",btnStyle))
        {
            DataMgr.Instance.ImportFile(parentMap,ck);
            EditorUtility.DisplayDialog("导入数据成功","导入关卡数据成功"+ck,"确定");
        }
        EditorGUILayout.EndHorizontal();
        // 选择图片类型
        GUILayout.Label("13.显示选图", GUILayout.Width(200));
        this.selectTypeIndex = EditorGUILayout.Popup(this.selectTypeIndex,typeArry, popStyle, GUILayout.MaxWidth(100));

        if (selectTypeIndex>0)  LoadChooseImg();// 加载选图
    }
    #endregion
    #region 加载图片和删除
    // 加载地形需要图 选择使用
    private void LoadChooseImg()
    {
        // 根据类型,加载相应地形图,障碍,还是金币,还是基础地形
        string name = bgNames[this.selectMapIndex].ToLower();
        switch (selectTypeIndex)
        {
            case 2:name = "obstacle";break;
            case 3:name = "gold"; break;
        }
        Texture[] ts = Resources.LoadAll<Texture>("baseImg/" + name);
        if (ts.Length<=0) return;// 无图
        _items = ts;
        int sizeY = 100 * Mathf.CeilToInt(_items.Length / 5f);
        _select = GUI.SelectionGrid(new Rect(new Vector2(0, 385), new Vector2(100 * 5, sizeY)), _select, _items, 5); //可以给出grid选择框,需要传入贴图数组_items
        if (_select != _curImgIndex || lastSelectTypeIndex != selectTypeIndex)
        {// 切换图片了,清楚上次使用的同时刷的最后一个物体的x y  记录的刷出来的固定数量
            lastSelectTypeIndex = selectTypeIndex;
            _curImgIndex = _select;
            _lastBrushY = -10000;
            _lastBrushX = -10000;
            _curFixCount = 0;
        }
    }
    // 加载背景图
    private void LoadBg()
    {
        if (lastSelectMapIndex == selectMapIndex) return;
        if (!bgParent) return;
        lastSelectMapIndex = selectMapIndex;
        RemoveParentChild(bgParent);// 删除之前的背景
        RemoveParentChild(parentMap);// 删除之前铺设的
        int dis = 19;//间距 根据实际背景图算的
        UnityEngine.Object a = Resources.Load<GameObject>("Prefabs/" + bgNames[selectMapIndex]);

        for (int i = 0; i < 100; i++)
        {
            GameObject o1 = Instantiate(a) as GameObject;
            o1.transform.parent = bgParent.transform;
            o1.transform.localPosition = new Vector3(-488 + dis * i, o1.transform.position.y, o1.transform.position.z);
            // -488是根据实际的quad的长度一半得到的
        }
    }
    // 获取要刷的图片
    private GameObject GetBrushName()
    {
        string tag = "Ground";// 设置物体的tag
        string name = bgNames[this.selectMapIndex].ToLower();
        switch (selectTypeIndex)
        {
            case 2: name = "obstacle"; tag = "Obstacle"; break;
            case 3: name = "gold"; tag = "Gold"; break;
        }
        name = "Prefabs_block/" + name + "/" + _items[_select].name;
        UnityEngine.Object a = Resources.Load<GameObject>(name);
        GameObject obj = Instantiate(a) as GameObject;
        obj.tag = tag;
        obj.name = name;
        obj.transform.parent = parentMap.transform;
        return obj;
    }

    // 删除父节点的所有子
    private void RemoveParentChild(GameObject parent)
    {
        if (parent)
        {
            while (parent.transform.childCount > 0)
            {
                UnityEngine.Object.DestroyImmediate(parent.transform.GetChild(0).gameObject);
            }
        }
    }
    #endregion
    private void Update()
    {
        if (this.funcTypeIndex != 2)// 点击
        {// 不单独选择,那就把选择取消,取消编辑器的选中物体
            EditorGUIUtility.PingObject(null);
            Selection.activeGameObject = null;
        }
        // 修改鼠标样式
        //if(_items!=null) Cursor.SetCursor(_items[_select] as Texture2D, Vector2.zero, CursorMode.Auto);
    }
}

项目github地址:https://github.com/SuiFengErQu/unity----map-Editor

参考:https://www.cnblogs.com/wayneWy/p/13087940.html

  游戏开发 最新文章
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
上一篇文章      下一篇文章      查看所有文章
加:2022-03-13 22:09:00  更:2022-03-13 22:10:25 
 
开发: 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/18 22:56:27-

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