이번에 기존에 등록된 스크립트를 제거하고 새로운 스크립트를 등록하는 툴을 유니티 스크립트로 제작하게 됐는데 이번 툴을 제작하면서 C#에서의 이름 찾기와 재귀 함수 사용법에 대해서 알게 됐습니다.
아래 스크립트는 기존 있던 Animated_Death 컴포넌트를 삭제하고 Animated_Death_Combine 이라는 새로운 컴포넌트를 추가하면서 해당 컴포넌트에 하위 오브젝트들의 이름을 뒤져 필요한 Transform을 이름으로 검색하여 자동으로 넣어주는 툴입니다.
아래 스크립트를 참고하면 여러가지 응용이 가능할거 같습니다.
using UnityEngine;
using UnityEditor;
using System;
using System.Collections;
using System.Collections.Generic;
public class AnimateDeathChange : EditorWindow
{
GameObject Target = null;
GameObject pObj = null;
string strScript = "Animated_Death_Combine";
string DelScript = "Animated_Death";
[MenuItem("RK Tools/Art/AnimateDeathChange")]
//윈도우 생성
static void InitWindow ()
{
AnimateDeathChange window = (AnimateDeathChange)EditorWindow.GetWindow(typeof(AnimateDeathChange));
window.autoRepaintOnSceneChange = true;
if (window == null)
{
Debug.Log("error: cannot find Dummy");
}
}
//오브젝트 선택창
void OnGUI()
{
SelectTargetObject ();
ScriptSetting ();
}
//원본소스 선택창
void SelectTargetObject()
{
GUILayout.Space(16f);
GUI.contentColor = Color.white;
EditorGUILayout.LabelField("해당 모델에 죽기 스크립트를 추가해 줍니다.");
EditorGUILayout.LabelField("각각의 항목을 채워주세요.");
EditorGUILayout.BeginVertical("box");
Target = (GameObject)EditorGUILayout.ObjectField("Base Model (Project)", Target, typeof(GameObject), false);
strScript = EditorGUILayout.TextField ( "Add Script Name", strScript);
DelScript = EditorGUILayout.TextField ( "Del Script Name", DelScript);
EditorGUILayout.EndVertical();
}
//복사 오브젝트는 하이어라키 창에서 실시간 교체 가능
void OnSelectionChange()
{
if (Selection.gameObjects == null || Selection.gameObjects.Length < 1) {
Focus();
Target = null;
return;
}
if (Target != Selection.gameObjects[0])
{
Target = Selection.gameObjects[0];
Focus();
}
else
Target = Selection.gameObjects[0];
}
//실행시 기존 스크 립 트 제 거
void ScriptSetting()
{
GUILayout.Space(16f);
if (GUILayout.Button ("Set Script To Object"))
{
// 새로운 컴포넌트를 넣어주는 명령어
UnityEngineInternal.APIUpdaterRuntimeServices.AddComponent(Target, "Assets/Scripts/Editor/Art/AnimateDeathChange.cs", strScript);
SerchObjectsInChild(Target.transform);
// 기존 컴포넌트를 제거해주는 명령어
GameObject.DestroyImmediate (Target.GetComponentInChildren<Animated_Death>());
GameObject.DestroyImmediate (Target.GetComponentInChildren<Animated_Death>());
GameObject.DestroyImmediate (Target.GetComponentInChildren<Animated_Death>());
if (null == Target)
return;
if (null == pObj)
return;
else
{
SerchObjectsInChild(Target.transform);
}
}
}
//
// //원본 오브젝트의 하위 더미를 찾는 재귀 함수
private void SerchObjectsInChild(Transform tr)
{
int iCount = tr.childCount;
for (int i = 0; i < iCount; ++i) {
Transform tempTr = tr.GetChild (i);
// Debug.Log (tempTr);
// Contains 명령어는 문장을 뒤져 해당 텍스트를 찾는 명령어이다.
if (tempTr.name.Contains ("_body")) {
Target.GetComponent<Animated_Death_Combine>().Model_1 = tempTr.gameObject.GetComponent<Renderer>();
}
else if (tempTr.name.Contains ("_head")|| tempTr.name.Contains ("face")) {
Target.GetComponent<Animated_Death_Combine>().Model_2 = tempTr.gameObject.GetComponent<Renderer>();
}
else if (tempTr.name.Contains ("_weap")) {
Target.GetComponent<Animated_Death_Combine>().Model_3 = tempTr.gameObject.GetComponent<Renderer>();
}
else if (tempTr.name.Contains ("_BODY")) {
Target.GetComponent<Animated_Death_Combine>().Shadow_1 = tempTr.gameObject.GetComponent<Renderer>();
} else if (tempTr.name.Contains ("_HEAD") || tempTr.name.Contains ("_FACE")) {
Target.GetComponent<Animated_Death_Combine>().Shadow_2 = tempTr.gameObject.GetComponent<Renderer>();
}else if (tempTr.name.Contains ("_WEAP")) {
Target.GetComponent<Animated_Death_Combine>().Shadow_3 = tempTr.gameObject.GetComponent<Renderer>();
}
if (tempTr.childCount > 0)
{
SerchObjectsInChild(tempTr);
}
}
}
}
'Engine > UNITY' 카테고리의 다른 글
UnityEditor.EditorGUILayout.ObjectField 에러 로그 잡기 (1) | 2016.09.28 |
---|---|
UnityEngineInternal.APIUpdaterRuntimeServices 에러 로그 잡기 (0) | 2016.09.28 |
유니티 스크립트 - 컴포넌트 삭제하기 (0) | 2016.08.04 |
유니티 스크립트 - 메터리얼 텍스쳐 정보 사용하기 (0) | 2016.07.27 |
타임 스케일 사용시 파티클 잘못 출력되는 문제를 해결하기 위해.. (0) | 2016.07.14 |