1.一楼测试…
[MenuItem("CustomTools/Test___K %K")]
public static void Test___K()
{
}
[MenuItem("CustomTools/Test___L %L")]
public static void Test___L()
{
}
[MenuItem("CustomTools/Test___J %J")]
public static void Test___J()
{
}
2.统计选中物体的子物体数量
[MenuItem("CustomTools/CalculationChildCount")]
public static void CalculationChildCount()
{
StatisticsChildCount scc = new StatisticsChildCount();
scc.FindObjectChild(Selection.activeTransform);
Debug.Log(scc.allObjCount);
}
public class StatisticsChildCount
{
public void FindObjectChild(Transform t)
{
Transform[] trans = FindChild(t);
if (trans == null)
return;
for (int i = 0; i < trans.Length; i++)
{
FindObjectChild(trans[i]);
}
}
public int allObjCount = 0;
Transform[] FindChild(Transform t)
{
Transform[] trans = new Transform[t.childCount];
if (t.childCount > 0)
{
for (int i = 0; i < t.childCount; i++)
{
allObjCount++;
trans[i] = t.GetChild(i);
}
return trans;
}
else
return null;
}
}
3. 将选中的物体包含的所有的这个类型的物体的子物体命名为:父物体的名字+前缀+子物体在当前父物体下的索引+1
[MenuItem("CustomTools/ResetChildName")]
public static void ResetChildName()
{
string prefix = "_Node:";
Roads[] games = Selection.activeGameObject.GetComponentsInChildren<Roads>();
for (int i = 0; i < games.Length; i++)
{
for (int j = 0; j < games[i].transform.childCount; j++)
{
games[i].transform.GetChild(j).name = games[i].name + prefix + (j + 1);
}
}
return;
}
4. 子物体不变,父物体的位置和旋转设置为子物体中间的位置
[MenuItem("CustomTools/ChangeTransformParentLocation ")]
public static void ChangeTransformParentLocation()
{
GameObject[] games = Selection.gameObjects;
for (int i = 0; i < games.Length; i++)
{
Transform[] trans = new Transform[games[i].transform.childCount];
Transform parent = games[i].transform;
Vector3[] local = new Vector3[trans.Length];
Quaternion[] lo = new Quaternion[trans.Length];
for (int j = 0; j < games[i].transform.childCount; j++)
{
local[j] = games[i].transform.GetChild(j).position;
lo[j] = games[i].transform.GetChild(j).rotation;
trans[j] = games[i].transform.GetChild(j);
}
int fa = (trans.Length / 2) + Random.Range(-5, 5);
if (fa >= trans.Length || fa < 0)
fa = trans.Length / 2;
parent.position = trans[fa].position;
for (int j = 0; j < trans.Length; j++)
{
trans[j].SetParent(parent);
trans[j].position = local[j];
trans[j].rotation = lo[j];
}
}
}
5. 创建一个新的mesh给选中的物体,mesh为烘焙好的导航网格
[MenuItem("CustomTools/DrawNavMesh")]
private static void DrawNavMesh()
{
NavMeshTriangulation triangulation = NavMesh.CalculateTriangulation();
Mesh mesh = new Mesh();
mesh.vertices = triangulation.vertices;
mesh.triangles = triangulation.indices;
mesh.RecalculateBounds();
Transform tran = Selection.activeTransform;
MeshFilter filter = tran.GetComponent<MeshFilter>();
if (filter != null)
{
filter.sharedMesh = mesh;
}
}
6. 查找选中物体的所有子物体,使所有有该类型的子物体处于选中状态
[MenuItem("CustomTools/SelctionObjs/Text")]
private static void SelectionTexts()
{
Text[] allButton = Selection.activeGameObject.GetComponentsInChildren<Text>();
GameObject[] allObj = new GameObject[allButton.Length];
for (int i = 0; i < allObj.Length; i++)
{
allObj[i] = allButton[i].gameObject;
}
Selection.objects = allObj;
}
PS:这里类型只是一个筛选的条件
7. 复制选中物体的名字到剪切板
[MenuItem("CustomTools/CopySelectionName %W")]
public static void CopySelectionName()
{
Object[] objs = Selection.GetFiltered(typeof(Object), SelectionMode.Deep); //Assets中的文件
Transform[] trans = Selection.GetTransforms(SelectionMode.DeepAssets); //Scene中的文件
TextEditor te = new TextEditor();
if (objs.Length > 0) //只能单选
{
PlayerPrefs.SetString("CopyName", objs[0].name); //存储到本地
te.text = objs[0].name;
Debug.Log("--------------" + objs[0].name + "--------------");
}
else if (trans.Length > 0)
{
PlayerPrefs.SetString("CopyName", trans[0].name); //从本地取出
te.text = trans[0].name;
Debug.Log("--------------" + trans[0].name + "--------------");
}
else //不支持一些特殊的对象,比如5.0之后Hierarchy中的Scene的name
Debug.Log("无法识别选中的目标!");
te.SelectAll();
te.Copy();
} //复制选中物体的名字到剪切板
8. 使选中的物体隐藏或显示
[MenuItem("CustomTools/SetObjectActive %Q")] //使选中的物体隐藏或显示
public static void SetActive()
{
Transform[] trans = Selection.GetTransforms(SelectionMode.DeepAssets);
GameObject[] allGame = new GameObject[trans.Length];
for (int i = 0; i < trans.Length; i++)
{
allGame[i] = trans[i].gameObject;
}
Undo.RecordObjects(allGame, "SetObjectActive");//注册撤销事件
int activeCount = trans.Length; //获取选中的物体数量
for (int i = trans.Length - 1; i >= 0; i--) //对选中的目标进行筛选,隐藏的数量>=1&&不等于选中的总数量则全部开启,否则关闭
{
if (trans[i].gameObject.activeInHierarchy) //得到隐藏的数量
activeCount--;
}
bool activeState = activeCount != 0;//列表中同时有显示和隐藏,优先把所有的设置为显示状态
for (int i = trans.Length - 1; i >= 0; i--) //筛选之后就是对选中的物体设置显隐了
{
trans[i].gameObject.SetActive(activeState);
}
}
9. 复制选中的一个object的transform(只能单选)
[MenuItem("CustomTools/CopyTransform #C")] // 复制选中的一个object的transform(只能单选)
public static void CopyTransform()
{
Transform[] trans = Selection.GetTransforms(SelectionMode.DeepAssets);
GameObject[] allGame = new GameObject[trans.Length];
for (int i = 0; i < trans.Length; i++)
{
allGame[i] = trans[i].gameObject;
}
if (trans.Length != 1)
return;
PlayerPrefs.SetFloat("PositionX", trans[0].localPosition.x); //保存在本地,防止被清零
PlayerPrefs.SetFloat("PositionY", trans[0].localPosition.y); //保存在本地,防止被清零
PlayerPrefs.SetFloat("PositionZ", trans[0].localPosition.z); //保存在本地,防止被清零
PlayerPrefs.SetFloat("RotationX", trans[0].localRotation.x); //保存在本地,防止被清零
PlayerPrefs.SetFloat("RotationY", trans[0].localRotation.y); //保存在本地,防止被清零
PlayerPrefs.SetFloat("RotationZ", trans[0].localRotation.z); //保存在本地,防止被清零
PlayerPrefs.SetFloat("RotationW", trans[0].localRotation.w); //保存在本地,防止被清零
PlayerPrefs.SetFloat("LocalScaleX", trans[0].localScale.x); //保存在本地,防止被清零
PlayerPrefs.SetFloat("LocalScaleY", trans[0].localScale.y); //保存在本地,防止被清零
PlayerPrefs.SetFloat("LocalScaleZ", trans[0].localScale.z); //保存在本地,防止被清零
}
PS:至于为什么只能单选。。。你懂的
10. 将复制的transform的属性粘贴到选中的物体上(只能单选)
public static void PasteTransform()
{
Transform[] trans = Selection.GetTransforms(SelectionMode.DeepAssets);
Undo.RecordObjects(trans, "PasteTransform");
GameObject[] allGame = new GameObject[trans.Length];
for (int i = 0; i < trans.Length; i++)
{
allGame[i] = trans[i].gameObject;
}
for (int i = 0; i < trans.Length; i++)
{
trans[i].localPosition = new Vector3(PlayerPrefs.GetFloat("PositionX"), PlayerPrefs.GetFloat("PositionY"),
PlayerPrefs.GetFloat("PositionZ"));
trans[i].localRotation = new Quaternion(PlayerPrefs.GetFloat("RotationX"), PlayerPrefs.GetFloat("RotationY"),
PlayerPrefs.GetFloat("RotationZ"), PlayerPrefs.GetFloat("RotationW"));
trans[i].localScale = new Vector3(PlayerPrefs.GetFloat("LocalScaleX"), PlayerPrefs.GetFloat("LocalScaleY"),
PlayerPrefs.GetFloat("LocalScaleZ"));
}
}
11. 在面板中找到一个物体并处于选中状态(Hieraychy面板)
[MenuItem("CustomTools/FindSelect %#X")]
public static void FindSelect()
{
Selection.activeObject= GameObject.Find("Start");
}
PS:层级很深的时候就会知道这是很有用的
12. 在面板中找到一个物体并处于选中状态(Assets面板)
Selection.activeObject = Resources.Load("New Folder/N/Q/W/E/R/Obbbbb");
PS:也就只有我才这么用Resources⁽⁽ଘ( ˊᵕˋ )ଓ⁾⁾
13. 嗯。。。。称其为三件套吧
public static void Play()
{
EditorApplication.isPlaying = true;
}
PS:之前一直想用这个功能就是找不到,现在不用了反而会用了
其他二件分别是:
EditorApplication.isPaused = true;
EditorApplication.isPlaying = false;
应该不用我翻译了吧
14. 编辑器下使用协程
参考:
> http://www.mamicode.com/info-detail-515821.html
**这个是这之前用写其他功能时用到的**
> https://user.qzone.qq.com/857686710/infocenter
private class EditorCoroutine : IEnumerator
{
private Stack<IEnumerator> executionStack;
public EditorCoroutine(IEnumerator iterator)
{
this.executionStack = new Stack<IEnumerator>();
this.executionStack.Push(iterator);
}
public bool MoveNext()
{
IEnumerator i = this.executionStack.Peek();
if (i.MoveNext())
{
object result = i.Current;
if (result != null && result is IEnumerator)
{
this.executionStack.Push((IEnumerator)result);
}
return true;
}
else
{
if (this.executionStack.Count > 1)
{
this.executionStack.Pop();
return true;
}
}
return false;
}
public void Reset()
{
throw new System.NotSupportedException("This Operation Is Not Supported.");
}
public object Current
{
get { return this.executionStack.Peek().Current; }
}
public bool Find(IEnumerator iterator)
{
return this.executionStack.Contains(iterator);
}
}
private static List<EditorCoroutine> editorCoroutineList;
private static List<IEnumerator> buffer;
public static IEnumerator StartEditorCoroutine(IEnumerator iterator)
{
if (editorCoroutineList == null)
{
// test
editorCoroutineList = new List<EditorCoroutine>();
}
if (buffer == null)
{
buffer = new List<IEnumerator>();
}
if (editorCoroutineList.Count == 0)
{
EditorApplication.update += Update;
}
// add iterator to buffer first
buffer.Add(iterator);
return iterator;
}
private static bool Find(IEnumerator iterator)
{
// If this iterator is already added
// Then ignore it this time
foreach (EditorCoroutine editorCoroutine in editorCoroutineList)
{
if (editorCoroutine.Find(iterator))
{
return true;
}
}
return false;
}
private static void Update()
{
// EditorCoroutine execution may append new iterators to buffer
// Therefore we should run EditorCoroutine first
editorCoroutineList.RemoveAll
(
coroutine => { return coroutine.MoveNext() == false; }
);
// If we have iterators in buffer
if (buffer.Count > 0)
{
foreach (IEnumerator iterator in buffer)
{
// If this iterators not exists
if (!Find(iterator))
{
// Added this as new EditorCoroutine
editorCoroutineList.Add(new EditorCoroutine(iterator));
}
}
// Clear buffer
buffer.Clear();
}
// If we have no running EditorCoroutine
// Stop calling update anymore
if (editorCoroutineList.Count == 0)
{
EditorApplication.update -= Update;
}
}
PS:这个不是我写的,偶然搜到的,另外好像只适用5之前,好久不用这个了
15. 给物体增加子物体。。。
GameObject addObj;//要增加子物体的对象
public int addObjectCount = 10; //要增加的数量
public string prefix = "Shoot";
public bool isAddObj = true;
public string addObjectDividingLine = "-----我是分割线-----";
void AddChilds()
{
addObj = Selection.activeGameObject;
Assert.AreNotEqual(addObj, null, "没有找到目标");
int objCount = addObj.transform.childCount;
string p = prefix;
for (int index = objCount; index < objCount + addObjectCount; index++)
{
GameObject clone = new GameObject();
clone.name = prefix + index;
clone.transform.parent = addObj.transform;
}
}
!!!!!!!!!!!!!!!!!!!!!!!!!!!分割!!!!!!!!!!!!!!!线!!!!!!!!!!!!!!!!!!