Unity自制地图地基生成插件
诞生于|更新于
|大约字数:1.5k|阅读量:
在上回书中说到,Boss给我分配了大富翁的制作,其中有一项地图的基础
其中要求是说需要建立很多很多cube,作为地图的地基
这样可以方便后期进行快速调节
但是问题来了,整个游戏的地图还算是很大的,如果生成100*200个cube的话,我能想到的就是一个一个地添加,然后点线面的方式进行增加
虽然可以一组一组的进行复制,但是还是一项很麻烦的工序
这时候我突然想到,之前在做2048的时候,可以通过代码去自动生成cube
那么我可不可以用代码这样生成呢
这样想之后,我发现了一个问题
一直以来所编写的所有C#Script都是在工程开始运行的时候执行的
也就是说,我的地基是在运行时候才能生成,这是绝对不行的
所以我又去询问了伟大的Google老师
Google老师告诉我,Unity有一个叫做MenuItem
的东西
以这种方式可以写出来一个菜单控件,并且可以生成组件
这就符合我的需求了
于是根据下方参考资料中的代码,我写出了符合自己需要的代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133
| using Microsoft.SqlServer.Server; using System.Collections; using System.Collections.Generic; using System.Linq; using UnityEditor; using UnityEngine;
public class MapCreater : EditorWindow { private int _width; private int _height; private int _number; private Vector3 _position;
private Vector3 _scale;
[MenuItem("rtmacha/创建地图")] public static void ShowWindow() { EditorWindow.GetWindow(typeof(MapCreater), false, "MapCreater"); } void OnGUI() {
_number = Mathf.Max(EditorGUILayout.IntField("复制的层数", _number), 0); _width = Mathf.Max(EditorGUILayout.IntField("水平长度", _width), 0); _height = Mathf.Max(EditorGUILayout.IntField("垂直长度长度", _height), 0); EditorGUILayout.Space();
_position = EditorGUILayout.Vector3Field("位移增量", _position);
_scale = EditorGUILayout.Vector3Field("Scale", _scale);
EditorGUILayout.Space();
EditorGUILayout.BeginHorizontal();
if (GUILayout.Button("Generate")) { Generate(); }
bool isCancel = GUILayout.Button("Cancel");
EditorGUILayout.EndHorizontal();
if (isCancel) { Cancel(); } }
private void Generate() { GameObject MapBase = new GameObject("MapBase"); MapBase.transform.position = new Vector3(0, 0, 0);
GameObject layerObj = new GameObject("Layer 1"); layerObj.transform.SetParent(MapBase.transform);
GameObject obj = new GameObject("cubeGroup 1"); obj.transform.SetParent(layerObj.transform);
for (int j = 0; j < _height; j++) { GameObject obj1 = GameObject.CreatePrimitive(PrimitiveType.Cube); obj1.transform.position = new Vector3(0, 0, 0); obj1.transform.SetParent(obj.transform); obj1.name = "cube " + (j + 1); obj1.transform.localScale = Vector3.Max(_scale, new Vector3(0.1f, 0.1f, 0.1f)); obj1.transform.localPosition = obj.transform.localPosition + Vector3.right * _position.x * j * obj1.transform.localScale.x; }
for (int i = 0; i < _width; i++) { GameObject gameObject = Instantiate(obj); gameObject.transform.name = "cubeGroup " + (i + 2); gameObject.transform.SetParent(layerObj.transform); gameObject.transform.localScale = Vector3.Max(_scale, new Vector3(0.1f, 0.1f, 0.1f)); gameObject.transform.localPosition = obj.transform.localPosition + Vector3.forward * _position.z * i * gameObject.transform.localScale.z; }
for (int i = 0; i < _number; i++) { GameObject gameObject = Instantiate(layerObj); gameObject.transform.name = "Layer " + (i + 2); gameObject.transform.SetParent(MapBase.transform); gameObject.transform.localScale = Vector3.Max(_scale, new Vector3(0.1f, 0.1f, 0.1f)); gameObject.transform.localPosition = layerObj.transform.localPosition + Vector3.up * _position.y * i * gameObject.transform.localScale.y; } }
private void Cancel() { Undo.PerformUndo(); } }
|
在我写完这些代码之后,我开始测试代码
最开始是使用双重循环嵌套逐一生成的
比如我需要生成一个 100*200的cube组,我就需要生成2w次
后来改成了分组复制,这样做的好处就是,首先生成100次的一行,然后将这行作为整体进行复制,复制200次即可
这样总体的生成为300次,生成速度会比原来快很多
于是,在写完最后一个功能(生成多层)之后,我不知道为什么脑抽生成了一个100*100*100的cube,也就是说我一下子生成了100w个cube组合成了一个大的cube。。
结果可想而知,稍微动一下地图整个unity就卡死了hhhhhh
仔细看那一大坨绿色的东西,就是那100w个cube组合成的一个大号的cube啦
点了删除之后,unity又开始疯狂处理了
就酱,等着unity全部再说吧
于是我又水了一篇文章hhhhh
成功向独立游戏制作人迈进一步,因为开始自己写Unity组件了
参考资料
https://indienova.com/indie-game-development/unity3d-plugin-development-tutorial-02/