您的位置:首页 > 移动开发 > Unity3D

Creating a Vertex Painter in Unity 3D教学视频学习

2015-11-25 17:01 447 查看
    这个视频主要介绍了unity编辑器关于EditorWindow、SceneGUI以及点绘制的知识。

    EditorWindow的知识很普通,看官方教程就够了。这里不做特别记录。

    SceneGUI主要用到了Handles、HandleUtility、GUIUtility这三个类:

    1、Handles在教程中用于绘制控制手柄,如下图:

    


    2、HandleUtility在教程中通过HandleUtility.AddDefaultControl(GUIUtility.GetControlID(FocusType.Passive))这样的函数,达到绘图时避免误选择对象的效果。如果想要获得View视图中鼠标从屏幕发出的射线的话还可以用这句HandleUtility.GUIPointToWorldRay(MousePos),MousePos是鼠标在View视图屏幕中的位置。

    以下贴出核心类Gatu_VTXPainter_Window:

using UnityEngine;
using UnityEditor;
using System.Collections;

public class Gatu_VTXPainter_Window : EditorWindow
{
#region Variable
GUIStyle boxStyle;
public Vector2 MousePos;
public RaycastHit CurHit;
public bool AllowPainting;
public bool IsPainting;

public float BrushSize = 1f;
public float BrushMinSize = 0.01f;
public float BrushMaxSize = 10f;
public float BrushOpacity = 1f;
public float BrushFalloff = 1f;
public bool ChangingBrushValue;

public GameObject curGO;
public GameObject lastGO;
public Mesh curMesh;

public Color ForeBackgourndColor = Color.white;

#endregion

#region MainMethod
public static void LaunchVertexPainter()
{
var win = EditorWindow.GetWindow<Gatu_VTXPainter_Window>(false, "绘图窗口", true);
win.GenerateStyles();
}

void Update()
{
//Debug.Log("update");
if (AllowPainting)
{
Selection.activeGameObject = null;

}
else
{
curGO = null;
curMesh = null;
lastGO = null;
}

if (CurHit.transform != null)
{
//Debug.Log(CurHit.transform.name);
if (CurHit.transform.gameObject != lastGO)
{
curGO = CurHit.transform.gameObject;
curMesh = Gatu_VTXPainter_Utils.GetMesh(curGO);
lastGO = curGO;

if (curGO != null && curMesh != null)
{
Debug.Log(curGO.name + ":" + curMesh.name);
}
}
}
}

void OnEnable()
{
SceneView.onSceneGUIDelegate -= OnSceneGUI;
SceneView.onSceneGUIDelegate += OnSceneGUI;

}

void OnDestroy()
{
SceneView.onSceneGUIDelegate -= OnSceneGUI;

}
#endregion

#region GUIMethod

void OnGUI()
{
//Header
GUILayout.Box("Vertex Painter", boxStyle, GUILayout.ExpandWidth(true), GUILayout.Height(60));

//Body
GUILayout.BeginVertical(boxStyle);
GUILayout.Space(10);
{

//GUILayout.BeginHorizontal();
//GUILayout.Button("Button", GUILayout.Height(40));
//GUILayout.Button("Button", GUILayout.Height(40));
//GUILayout.EndHorizontal();
AllowPainting = GUILayout.Toggle(AllowPainting, "Allow Painter", GUI.skin.button, GUILayout.Height(60));
}

GUILayout.Button("Button", GUILayout.Height(40));
GUILayout.Space(5);
ForeBackgourndColor = EditorGUILayout.ColorField("ForeBackgroundColor:", ForeBackgourndColor);

GUILayout.FlexibleSpace();
GUILayout.EndVertical();

//Footer
GUILayout.Box("Box", boxStyle, GUILayout.ExpandWidth(true), GUILayout.Height(60));

//Update and Repainter UI in real time
Repaint();
}

void OnSceneGUI(SceneView sceneView)
{
//Handles.Label( Vector3.up,"Vextex Painter Access!");
/*
Handles.BeginGUI();
GUILayout.BeginArea(new Rect(10, 10, 200, 150), boxStyle);
GUILayout.Button("Button", GUILayout.Height(30));
GUILayout.Button("Button", GUILayout.Height(30));

GUILayout.EndArea();
Handles.EndGUI();
*/
if (AllowPainting)
{
if (CurHit.transform != null)
{

Handles.color = new Color(ForeBackgourndColor.r, ForeBackgourndColor.g, ForeBackgourndColor.b, BrushOpacity);
Handles.DrawSolidDisc(CurHit.point, CurHit.normal, BrushSize);
Handles.color = Color.red;
Handles.DrawWireDisc(CurHit.point, CurHit.normal, BrushSize);
Handles.DrawWireDisc(CurHit.point, CurHit.normal, BrushFalloff);

}

HandleUtility.AddDefaultControl(GUIUtility.GetControlID(FocusType.Passive));

Ray worldRay = HandleUtility.GUIPointToWorldRay(MousePos);

if (!ChangingBrushValue)
{

if (Physics.Raycast(worldRay, out CurHit, 500f))
{
//Debug.Log("Begein vertex painting here");
if (IsPainting)
PaintVertexColor();
}
}

}
else
{
//HandleUtility.AddDefaultControl(GUIUtility.GetControlID(FocusType.Native));

}

ProcessInput();

sceneView.Repaint();

}
#endregion

#region Temp Painter Method
void PaintVertexColor()
{
if (curMesh)
{
Vector3[] verts = curMesh.vertices;
Color[] colors = new Color[0];
if (curMesh.colors.Length > 0)
{
colors = curMesh.colors;
}
else
{
colors = new Color[verts.Length];
}
for (int i = 0; i < verts.Length; i++)
{
Vector3 v = curGO.transform.TransformPoint(verts[i]);
float dis = (v - CurHit.point).sqrMagnitude;
if (dis > BrushSize)
continue;
//float falloff = Gatu_VTXPainter_Utils.LinerFalloff(Mathf.Clamp(dis - BrushFalloff, 0, 10), BrushSize - BrushFalloff);
float falloff = Gatu_VTXPainter_Utils.LinerFalloff(dis, BrushSize);

falloff = Mathf.Pow(falloff, BrushFalloff* 3f) * BrushOpacity; //这里是以falloff为变量的幕函数.
//colors[i] = ForeBackgourndColor * falloff * BrushOpacity;
colors[i] = Gatu_VTXPainter_Utils.VtxLerpColor(colors[i],ForeBackgourndColor,falloff) ;

}

curMesh.colors = colors;
}
}

#endregion

#region Utility Method

void ProcessInput()
{
Event e = Event.current;
MousePos = e.mousePosition;
if (e.type == EventType.KeyDown && e.isKey)
{
if (e.keyCode == KeyCode.Y)
{
// Debug.Log("Press Y");
AllowPainting = !AllowPainting;
if (!AllowPainting)
{
Tools.current = Tool.View;
}
else
{
Tools.current = Tool.None;
}
}

if (e.keyCode == KeyCode.Space)
{
// Debug.Log("Press space");
}
}

if (e.type == EventType.MouseDown)
{
if (e.button == 0)
{
//Debug.Log("Left mouse button downs!");
}

if (e.button == 1)
{
//Debug.Log("Right mouse button downs!");
}

if (e.button == 2)
{
// Debug.Log("Middle mouse button downs!");
}
}
if (e.type == EventType.MouseUp)
{
ChangingBrushValue = false;
IsPainting = false;
}

if (AllowPainting)
{
if (e.ty
4000
pe == EventType.MouseDrag && e.button == 0 && e.control && !e.shift)
{
BrushSize += e.delta.x * 0.005f;
BrushSize = Mathf.Clamp(BrushSize, BrushMinSize, BrushMaxSize);
ChangingBrushValue = true;
if (BrushFalloff > BrushSize)
BrushFalloff = BrushSize;
}

if (e.type == EventType.MouseDrag && e.button == 0 && !e.control && e.shift)
{
BrushOpacity += e.delta.x * 0.005f;
BrushOpacity = Mathf.Clamp01(BrushOpacity);
ChangingBrushValue = true;

}

if (e.type == EventType.MouseDrag && e.button == 0 && e.control && e.shift)
{
BrushFalloff += e.delta.x * 0.005f;
BrushFalloff = Mathf.Clamp(BrushFalloff, BrushMinSize, BrushSize);
ChangingBrushValue = true;

}

if (e.type == EventType.MouseDrag && e.button == 0 && !e.control && !e.shift && !e.alt)
{
IsPainting = true;

}
}
}
void GenerateStyles()
{
boxStyle = new GUIStyle();
boxStyle.normal.background = Resources.Load<Texture2D>("Textures/defalt_box_bg");
boxStyle.normal.textColor = Color.white;
boxStyle.border = new RectOffset(4, 4, 4, 4);
boxStyle.margin = new RectOffset(2, 2, 2, 2);
boxStyle.fontSize = 30;
boxStyle.alignment = TextAnchor.MiddleCenter;
}
#endregion
}


       
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  Unity Editor