我们需要让我们的编辑器支持两种模式,一种是Draw模式,一种是Erase模式

添加编辑模式

我们使用枚举来指定模式

修改LevelEditor脚本

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
using System;
using UnityEngine;

namespace ShootingEditor2D
{
public class LevelEditor : MonoBehaviour
{
public enum OperateMode
{
Draw,
Erase
}
OperateMode mCurrentOperateMode;
//...
Lazy<GUIStyle> mModeLableStyle = new Lazy<GUIStyle>(() =>
{
return new GUIStyle(GUI.skin.label)
{
fontSize = 30,
alignment = TextAnchor.MiddleCenter
};
});
private void OnGUI()
{
var modeLabelRect = RectHelper.RectForAnchorCenter(Screen.width * 0.5f, 35, 300, 50);
GUI.Label(modeLabelRect,mCurrentOperateMode.ToString(),mModeLableStyle.Value);
}
//...

}

我们再添加两个Button,用来切换绘制模式

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
using System;
using UnityEngine;

namespace ShootingEditor2D
{
public class LevelEditor : MonoBehaviour
{
public enum OperateMode
{
Draw,
Erase
}
OperateMode mCurrentOperateMode;
//...

Lazy<GUIStyle> mModeLableStyle = new Lazy<GUIStyle>(() =>
{
return new GUIStyle(GUI.skin.label)
{
fontSize = 30,
alignment = TextAnchor.MiddleCenter,
};
});
Lazy<GUIStyle> mButtonStyle = new Lazy<GUIStyle>(() =>
{
return new GUIStyle(GUI.skin.button)
{
fontSize = 30,
};
});
private void OnGUI()
{
var modeLabelRect = RectHelper.RectForAnchorCenter(Screen.width * 0.5f, 35, 300, 50);
GUI.Label(modeLabelRect,mCurrentOperateMode.ToString(),mModeLableStyle.Value);

var drawButtonRect = new Rect(10, 10, 150, 50);
if (GUI.Button(drawButtonRect, "Draw", mButtonStyle.Value))
{
mCurrentOperateMode = OperateMode.Draw;
}
var eraseButtonRect = new Rect(10, 60, 150, 50);
if (GUI.Button(eraseButtonRect, "Erase", mButtonStyle.Value))
{
mCurrentOperateMode = OperateMode.Erase;
}
}
//...
}
}

实现模式切换功能

首先修改高亮块的颜色提示部分

修改LevelEditor脚本的Update里面的部分代码块

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
if (Mathf.Abs(EmptyHighlight.transform.position.x - mouseWorldPos.x) < 0.1f && 
Mathf.Abs(EmptyHighlight.transform.position.y - mouseWorldPos.y) < 0.1f)
{

}
else
{
EmptyHighlight.transform.position = mouseWorldPos - new Vector3(0,0,1);
Ray ray = Camera.main.ScreenPointToRay(mousePosition);

RaycastHit2D hit = Physics2D.Raycast(ray.origin, Vector2.zero,20);

if (hit.collider)
{
if (mCurrentOperateMode == OperateMode.Draw)
{
EmptyHighlight.color = new Color(1, 0, 0,0.5f);
}else if (mCurrentOperateMode == OperateMode.Erase)//橡皮擦模式下显示橙色
{
EmptyHighlight.color = new Color(1, 0.5f, 0, 0.5f);
}

mCanDraw = false;
}
else
{
if (mCurrentOperateMode == OperateMode.Draw)
{
EmptyHighlight.color = new Color(1, 1, 1, 0.5f);
}else if(mCurrentOperateMode == OperateMode.Erase)//橡皮擦模式下显示蓝色
{
EmptyHighlight.color = new Color(0, 0, 1, 0.5f);
}
mCanDraw = true;
}
}

然后修改绘制逻辑

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
using System;
using UnityEngine;

namespace ShootingEditor2D
{
public class LevelEditor : MonoBehaviour
{

//...

private GameObject mCurrentObjectMouseOn;//缓存当前鼠标下的物体

//...

void Update()
{
//...
if (Mathf.Abs(EmptyHighlight.transform.position.x - mouseWorldPos.x) < 0.1f &&
Mathf.Abs(EmptyHighlight.transform.position.y - mouseWorldPos.y) < 0.1f)
{

}
else
{
//...
if (hit.collider)
{
//...
mCurrentObjectMouseOn = hit.collider.gameObject;//获得物体
}
else
{
//...
mCurrentObjectMouseOn = null;
}
}
if (Input.GetMouseButtonDown(0))
{
if (mCanDraw && mCurrentOperateMode == OperateMode.Draw)
{
var groundPrefab = Resources.Load<GameObject>("Ground");
var groundGameObj = Instantiate(groundPrefab,transform);
groundGameObj.transform.position = mouseWorldPos;
groundGameObj.name = "Ground";
mCanDraw = false;
}else if(mCurrentObjectMouseOn && mCurrentOperateMode == OperateMode.Erase)//擦除物体
{
Destroy(mCurrentObjectMouseOn);
mCurrentObjectMouseOn = null;
}
}
}
}
}

防止点选GUI按钮时发生绘制

使用GUIUtility.hotControl来判断当前鼠标是否和GUI发生了交互,它返回一个int值,代表交互数量。

修改LevelEditor脚本,

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
void Update()
{
//...
mouseWorldPos.y = Mathf.Floor(mouseWorldPos.y + 0.5f);

if(GUIUtility.hotControl == 0)//鼠标在GUI上时,高亮块就不显示
{
EmptyHighlight.gameObject.SetActive(true);
}
else
{
EmptyHighlight.gameObject.SetActive(false);
}

//...
if (Input.GetMouseButtonDown(0) && GUIUtility.hotControl == 0)//增加判断GUI交互的条件
{
if (mCanDraw && mCurrentOperateMode == OperateMode.Draw)
{
var groundPrefab = Resources.Load<GameObject>("Ground");
var groundGameObj = Instantiate(groundPrefab,transform);
groundGameObj.transform.position = mouseWorldPos;
groundGameObj.name = "Ground";
mCanDraw = false;
}else if(mCurrentObjectMouseOn && mCurrentOperateMode == OperateMode.Erase)
{
Destroy(mCurrentObjectMouseOn);
mCurrentObjectMouseOn = null;
}
}
}

实现拖拽绘制

方法很简单,我们在绘制的时候加上鼠标长按状态的判断即可

修改LevelEditor脚本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
if ((Input.GetMouseButtonDown(0) || Input.GetMouseButton(0)) && GUIUtility.hotControl == 0)//在前面的括号内添加判断
{
if (mCanDraw && mCurrentOperateMode == OperateMode.Draw)
{
var groundPrefab = Resources.Load<GameObject>("Ground");
var groundGameObj = Instantiate(groundPrefab,transform);
groundGameObj.transform.position = mouseWorldPos;
groundGameObj.name = "Ground";
mCanDraw = false;
}else if(mCurrentObjectMouseOn && mCurrentOperateMode == OperateMode.Erase)
{
Destroy(mCurrentObjectMouseOn);
mCurrentObjectMouseOn=null;
}
}