在场景视图中编辑
我们现在确实有一个漂亮的检视面板,但要是我们能够在场景中直接编辑这些点是不是更好?我们可以通过向检视面板添加Unity事件系统中OnSceneGUI方法实现。一旦场景中的物体被选中,这个方法将被调用,调用过程中同时分配一个target变量给场景中相应的物体,这儿我们不应该用SerializedObject。实际上当场景中某物体需要完全从编辑器中独立出来时,我们最好考虑这个方法。
让我们放一个正方形的小控制柄在星形的最上面的点上。由于频率的原因不针对所有的点,第一次,我们只需要将其放在那些显示出来的点(就是就是星形的所有顶点)上。放置了这些顶点后,我们就产生了星形的网格。另外我们工作时在世界坐标系下面进行的,而不是在本地坐标系下进行的。因此我们需要对星形应用变换。
我们将利用Handles.FreeMoveHandle方法来描绘我们的控制柄,这个控制柄有两个参数。第一个是控制柄在世界坐标系下的位置参数。另外还需要旋转这个控制手柄,这里我们省略了这个旋转参数。另外一个是控制手柄的尺寸大小参数(就是控制缩放的),这里我们设置一个较小值,让控制手柄好看些。这时找一个向量用于它的原始尺寸大小,我们将这个向量设置为(0.1,0.1,0.1)。这个最后的参数(就是第二个参数)用来定义控制手柄的形状。
1
2
3
4
5
6
7
8
9
10
11
12
|
private static Vector3 pointSnap = Vector3.one * 0.1f;
void OnSceneGUI () {
Star star = (Star)target;
Transform starTransform = star.transform;
float angle = -360f / (star.frequency * star.points.Length);
for (int i = 0; i < star.points.Length; i++){
Quaternion rotation = Quaternion.Euler(0f, 0f, angle * i);
Vector3 oldPoint = starTransform.TransformPoint(rotation * star.points[i].position);
Handles.FreeMoveHandle(oldPoint, Quaternion.identity, 0.02f, pointSnap, Handles.DotCap);
}
|
场景中其他的顶点
我们并没有对控制手柄做太多的工作,但目前看起来挺不错的。你能点击其中一个,它就会变成黄色。我们需要做的就是比较我们放入控制手柄是的位置参数和控制手柄返回的位置参数是否一致。如果他们有不同,用户拖动这个控制手柄,我们就应该修正这个星形的位置。在将位置参数赋值给星形前,我们不应该忘记将控制手柄返回过来的新的位置参数转换成本地坐标系下的位置参数,从而修改这个顶点的偏移量并且更新星形的参数。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
void OnSceneGUI () {
Star star = (Star)target;
Transform starTransform = star.transform;
float angle = -360f / (star.frequency * star.points.Length);
for (int i = 0; i < star.points.Length; i++){
Quaternion rotation = Quaternion.Euler(0f, 0f, angle * i);
Vector3
oldPoint = starTransform.TransformPoint(rotation * star.points[i].position),
newPoint = Handles.FreeMoveHandle(
oldPoint, Quaternion.identity, 0.02f, pointSnap, Handles.DotCap);
if (oldPoint != newPoint){
star.points[i].position = Quaternion.Inverse(rotation) *
starTransform.InverseTransformPoint(newPoint);
star.UpdateMesh();
}
}
}
|
好了,它(星形)开始工作了。等等,目前它并没有支持撤销操作。这里我们不能依靠SerializedObject,但幸运的是,控制手柄能够为我们处理撤销这样的操作。我们需要做的是告诉它们那个物体将被编辑,怎样命名撤销的步骤。我们可以通过Undo.SetSnapshotTarget这样的方法。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
void OnSceneGUI () {
Star star = (Star)target;
Transform starTransform = star.transform;
Undo.SetSnapshotTarget(star, "Move Star Point" );
float angle = -360f / (star.frequency * star.points.Length);
for (int i = 0; i < star.points.Length; i++){
Quaternion rotation = Quaternion.Euler(0f, 0f, angle * i);
Vector3
oldPoint = starTransform.TransformPoint(rotation * star.points[i].position),
newPoint = Handles.FreeMoveHandle(
oldPoint, Quaternion.identity, 0.02f, pointSnap, Handles.DotCap);
if (oldPoint != newPoint){
star.points[i].position = Quaternion.Inverse(rotation) *
starTransform.InverseTransformPoint(newPoint);
star.UpdateMesh();
}
}
}
|
这个工程就完成了。
下载地址
star.unitypackage
原文链接:http://catlikecoding.com/unity/tutorials/editor/star/
建议使用电驴(eMule)下载分享的资源。
说明:本教程来源互联网或网友分享或出版商宣传分享,仅为学习研究或媒体推广,wanshiok.com不保证资料的完整性。
|