基本实现
由于最近一个星期都比较魔怔《天际线》,突然开始要工作了,用Editor好像突然没了按键反而不习惯
就是要实现一个点击AWSD,能方便编辑地图的功能
其实大可不必自己写代码
本身Unity自带的,飞跃模式已经包含(按鼠标右键)AWSD
就是如下图,摄像机要有一点角度,肯定不是直角的移动
图片来自CSDN某小哥的贴图
protected virtual void OnScene(SceneView obj)
{
Event e = Event.current;
if (e.type == EventType.KeyDown)
{
if (e.keyCode == KeyCode.A || e.keyCode == KeyCode.S || e.keyCode == KeyCode.D ||
e.keyCode == KeyCode.W)
{
// obj is SceneView
float h = 0;
float v = 0;
if (e.keyCode == KeyCode.A)
h = -1;
else if (e.keyCode == KeyCode.D)
h = 1;
else if (e.keyCode == KeyCode.W)
v = 1;
else if (e.keyCode == KeyCode.S)
v = -1;
Vector3 targetDirection = new Vector3(h, 0, v);
float y = obj.camera.transform.rotation.eulerAngles.y;
targetDirection = Quaternion.Euler(0, y, 0) * targetDirection;
// //TODO:按Shift加速(e.control && e.keyCode == KeyCode.Z)
// //obj.camera.transform.Translate(targetDirection );//直接改camera 这句代码没用
//
obj.pivot += targetDirection * Time.deltaTime * 3;
}
}
}
//打开EditorWindow扩展时,需调用
protected virtual void OnEnable()
{
SceneView.duringSceneGui += OnScene;
}
protected virtual void OnDisable()
{
SceneView.duringSceneGui -= OnScene;
}
是不是就是这么简单?
写代码肯定就没这么简单
结果后来我又调试了两个小时
二次迭代
========== 如果你要的仅仅只是Hello World 代码 ======
上面代码够了,下面代码很乱不要看
原因就是
keyDown只能在GUI用,第一下和第二下还有延迟,为了更顺滑的响应,只能用上。Update了
protected virtual void OnEnable()
{
onRefreshWindow -= Refresh;
onRefreshWindow += Refresh;
SceneView.duringSceneGui += OnScene;
EditorApplication.update += OnSceneUpdate;
}
protected virtual void OnDisable()
{
onRefreshWindow -= Refresh;
BlockClicks(false);
SceneView.duringSceneGui -= OnScene;
EditorApplication.update -= OnSceneUpdate;
}
private int longPressCount;
private SceneView view;
private float longPressH = 0;
private float longPressV = 0;
private float longPressY = 0;//camera y Angle
private int longPressCountDown = 0;//允许多个按键AWSD多按 ,可以省几个变量了,不改了,睡觉
private void OnSceneUpdate()
{
if (view == null) return;
if (longPressCount > 0)
{
var targetDirection = new Vector3(longPressH, 0, longPressV);
// //xxxx判斷長按,跳過第一下按下xxxx
// //MD,第一下不能跳过,又需要马上有反应,。。。。。。。。longPressCount>0 逻辑就是为了这个
// // if (longPressCount == 1) return;
// // Debug.LogError("ffff key=" + e.keyCode + " pos>" + view.camera.transform.position);
// Vector3 targetDirection = new Vector3(longPressH, 0, longPressV);
// // float y = view.camera.transform.rotation.eulerAngles.y;
targetDirection = Quaternion.Euler(0, longPressY, 0) * targetDirection;
// //TODO:按Shift加速(e.control && e.keyCode == KeyCode.Z)
view.pivot += targetDirection * Time.deltaTime * 3;
}
}
protected virtual void OnScene(SceneView obj)
{
Event e = Event.current;
if (e.type == EventType.KeyDown)
{
if (e.keyCode == KeyCode.A || e.keyCode == KeyCode.S || e.keyCode == KeyCode.D ||
e.keyCode == KeyCode.W)
{
if (e.keyCode == KeyCode.A)
longPressCountDown |= 1 << 1;
else if (e.keyCode == KeyCode.W)
longPressCountDown |= 1 << 2;
else if (e.keyCode == KeyCode.S)
longPressCountDown |= 1 << 3;
else if (e.keyCode == KeyCode.D)
longPressCountDown |= 1 << 4;
Debug.LogError("longPressCount=" + longPressCountDown);
longPressCount++;
if (view == null)
view = obj;
longPressY = obj.camera.transform.rotation.eulerAngles.y;
longPressH = 0;
longPressV = 0;
if (e.keyCode == KeyCode.A)//注意,为了第一下,这下面几个逻辑也是改过的
longPressH = -1;
if (e.keyCode == KeyCode.D)
longPressH = 1;
if (e.keyCode == KeyCode.W)
longPressV = 1;
if (e.keyCode == KeyCode.S)
longPressV = -1;
}
}
else if (e.type == EventType.KeyUp)
{
if (e.keyCode == KeyCode.A)
longPressCountDown &= ~(1 << 1);
else if (e.keyCode == KeyCode.W)
longPressCountDown &= ~(1 << 2);
else if (e.keyCode == KeyCode.S)
longPressCountDown &= ~(1 << 3);
else if (e.keyCode == KeyCode.D)
longPressCountDown &= ~(1 << 4);
if(longPressCountDown==0)
//判斷長按,跳過第一下按下
longPressCount = 0;
}
}
}
最终结果
好了,谢谢阅读,下一篇会说下,SceneView的笔刷Brush吧