Get it on Google Play


Wm뮤 :: 'Unity/C#' 카테고리의 글 목록 (6 Page)

블로그 이미지
가끔 그림그리거나 3D모델링하거나
취미로 로봇만드는
퇴직한 전자과 게임프로그래머
2020.3.48f1 , 2022.3.6f1 주로 사용
모카쨩
@Ahzkwid

Recent Comment

Archive


'Unity/C#'에 해당되는 글 65건

  1. 2020.08.11 형변환 모음
  2. 2020.07.30 유니티 씬 계열 함수 모음
  3. 2020.07.30 C# 파일관련 함수들
  4. 2020.07.29 c# Array(배열)관련
  5. 2020.07.28 유니티 키보드
  6. 2020.07.28 c# @변수
  7. 2020.07.28 c# 문자열 처리
  8. 2020.07.27 OnGUI
2020. 8. 11. 16:58 Unity/C#

 

 

일반적으로 사용하는 타입

var 변수= (타입)오브젝트;

 

가독성을 위해 간간히 쓰이는 타입, 괄호가 너무 많을때 사용함

var 변수= 오브젝트 as 타입

 

옛날방식

int 변수=int.Parse("1");

 

 

 

'Unity > C#' 카테고리의 다른 글

UnityWebRequest  (0) 2020.08.20
유니티 씬 계열 함수 모음  (0) 2020.07.30
C# 파일관련 함수들  (0) 2020.07.30
posted by 모카쨩
2020. 7. 30. 19:19 Unity/C#

씬 이동시에도 파괴 안됨

DontDestroyOnLoad(gameObject);

 

 

 

씬로드 v1~v5

더보기

씬 로드 Object형(에디터상에서만 먹힘)

    public void LoadScene(Object SceneFile)
    {
        UnityEngine.SceneManagement.SceneManager.LoadScene(SceneFile.name);
    }

 

 

유니티가 씬 로드에 있어 워낙 불친절한놈이라 아래처럼 수동으로 짜줘야함

using UnityEngine;
using UnityEditor;

[CustomEditor(typeof(ScenePicker), true)]
public class ScenePickerEditor : Editor
{
    public override void OnInspectorGUI()
    {
        var picker = target as ScenePicker;
        var oldScene = AssetDatabase.LoadAssetAtPath<SceneAsset>(picker.scenePath);

        serializedObject.Update();

        EditorGUI.BeginChangeCheck();
        var newScene = EditorGUILayout.ObjectField("scene", oldScene, typeof(SceneAsset), false) as SceneAsset;

        if (EditorGUI.EndChangeCheck())
        {
            var newPath = AssetDatabase.GetAssetPath(newScene);
            var scenePathProperty = serializedObject.FindProperty("scenePath");
            scenePathProperty.stringValue = newPath;
        }
        serializedObject.ApplyModifiedProperties();
    }
}
public class ScenePicker : MonoBehaviour
{
    [SerializeField]
    public string scenePath;
}

 

 

축약버전

using UnityEngine;
using UnityEditor;

[CustomEditor(typeof(ScenePicker), true)]
public class ScenePickerEditor : Editor
{
    public override void OnInspectorGUI()
    {
        serializedObject.Update();
		{
          var target_ScenePicker = target as ScenePicker;
          var oldScene = AssetDatabase.LoadAssetAtPath<Object>(target_ScenePicker.scenePath);
          var newScene = EditorGUILayout.ObjectField(nameof(target_ScenePicker.scenePath), oldScene, typeof(Object), false);
          target_ExcelReader.scenePath = AssetDatabase.GetAssetPath(newScene);
        }
        serializedObject.ApplyModifiedProperties();
    }
}
public class ScenePicker : MonoBehaviour
{
    [SerializeField]
    public string scenePath;
}

 

 

그냥 오브젝트를 추가한 버전

이딴 버전을 왜 만들었냐 하면 인스펙터상에서 파일을 추적할때는 오브젝트를 써야하고

인 게임에서 파일을 추적할때는 string을 써야하기 때문이다

[HideInInspector]는 쓰면 안 된다. 값이 날아가 버리기 때문에(아닌가?)

using UnityEngine;
using UnityEditor;

[CustomEditor(typeof(ScenePicker), true)]
public class ScenePickerEditor : Editor
{
    public override void OnInspectorGUI()
    {
        base.OnInspectorGUI();
        serializedObject.Update();
		{
            var target_ScenePicker = target as ScenePicker;
            if(target_ScenePicker.scene!=null)
            {
                target_ScenePicker.scenePath = AssetDatabase.GetAssetPath(target_ScenePicker.scene);
            }
        }
        serializedObject.ApplyModifiedProperties();
    }
}
public class ScenePicker : MonoBehaviour
{
    public Object scene;
    public string scenePath;
}

위랑 똑같은데 Path가 아닌 이름을 쓰는 버전

어차피 이래해도 작동은 잘 된다. 결국 원점회귀

using UnityEngine;


#if UNITY_EDITOR
using UnityEditor;
[CustomEditor(typeof(ScenePicker), true)]
public class ScenePickerEditor : Editor
{
    public override void OnInspectorGUI()
    {
        base.OnInspectorGUI();
        serializedObject.Update();
		{
            var target_ScenePicker = target as ScenePicker;
            if(target_ScenePicker.scene!=null)
            {
                target_ScenePicker.sceneName = target_ScenePicker.scene.name;
            }
        }
        serializedObject.ApplyModifiedProperties();
    }
}
#endif
public class ScenePicker : MonoBehaviour
{
#if UNITY_EDITOR
    public SceneAsset scene;
#endif
    [HideInInspector]
    public string sceneName;
}

 

 v5

using UnityEngine;


#if UNITY_EDITOR
using UnityEditor;
[CustomEditor(typeof(ScenePicker), true)]
public class ScenePickerEditor : Editor
{
    public override void OnInspectorGUI()
    {
        serializedObject.Update();
        {
            DrawPropertiesExcluding(serializedObject, nameof(ScenePicker.sceneName));

            var scene = serializedObject.FindProperty(nameof(ScenePicker.scene));
            var sceneName = serializedObject.FindProperty(nameof(ScenePicker.sceneName));
            sceneName.stringValue = scene.objectReferenceValue.name;
        }
        serializedObject.ApplyModifiedProperties();
    }
}
#endif
public class ScenePicker : MonoBehaviour
{
#if UNITY_EDITOR
    public SceneAsset scene;
#endif
    [HideInInspector]
    public string sceneName;
}

 

 

 

씬로드 v6

v5랑 동일하지만 바로바로 사용하기 편하게 함수내장시켰다

using UnityEngine;


#if UNITY_EDITOR
using UnityEditor;
[CustomEditor(typeof(SceneLoader), true)]
public class SceneLoaderEditor : Editor
{
    public override void OnInspectorGUI()
    {
        serializedObject.Update();
        {
            DrawPropertiesExcluding(serializedObject, nameof(SceneLoader.sceneName));

            var scene = serializedObject.FindProperty(nameof(SceneLoader.scene));
            var sceneName = serializedObject.FindProperty(nameof(SceneLoader.sceneName));
            sceneName.stringValue = scene.objectReferenceValue.name;
        }
        serializedObject.ApplyModifiedProperties();
    }
}
#endif
public class SceneLoader : MonoBehaviour
{
#if UNITY_EDITOR
    public SceneAsset scene;
#endif
    [HideInInspector]
    public string sceneName;

    public void LoadScene()
    {
        UnityEngine.SceneManagement.SceneManager.LoadScene(sceneName);
    }
}

 

 

씬들로드

#if UNITY_EDITOR
using UnityEditor;


[CustomEditor(typeof(GotoRandomScene), true)]
public class GotoRandomSceneInspecter : Editor
{
    public override void OnInspectorGUI()
    {
        EditorGUI.BeginChangeCheck();
        serializedObject.Update();
        {
            DrawPropertiesExcluding(serializedObject, nameof(GotoRandomScene.sceneNames));
        }
        serializedObject.ApplyModifiedProperties();
        if (EditorGUI.EndChangeCheck())
        {
            var picker = target as GotoRandomScene;
            picker.sceneNames = System.Array.ConvertAll(picker.scenes, x => x.name);
        }
    }
}
#endif



public class GotoRandomScene : MonoBehaviour
{
    [Header("랜덤룸으로 이동함")]
#if UNITY_EDITOR
    public UnityEditor.SceneAsset[] scenes;
#endif
    public string[] sceneNames;
}

 

 

 

 

 

현재 씬 이름

UnityEngine.SceneManagement.SceneManager.GetActiveScene().name

 

 

 

 

환경은 그대로 두고 맵만 불러올떄 사용한거

var sceneName = gotoRandomScene.sceneNames[sceneNumber];

for (int i = 0; i < SceneManager.sceneCount; i++)
{
    var scene = SceneManager.GetSceneAt(i);

    //없는 이름 스킵
    if (System.Array.Find(gotoRandomScene.sceneNames, x => x == scene.name) == null)
    {
        continue;
    }

    //원하는 씬이 맞음
    if (sceneName == scene.name)
    {
        return;
    }

    //원하는 씬이 아님
    {
        SceneManager.UnloadSceneAsync(scene);
    }
}
//원하는 씬이 없음
{
    DestroyAll();
    UnityEngine.SceneManagement.SceneManager.LoadScene(sceneName, LoadSceneMode.Additive);
}
/*
if (sceneName != UnityEngine.SceneManagement.SceneManager.GetActiveScene().name)
{
    DestroyAll();
    UnityEngine.SceneManagement.SceneManager.LoadScene(sceneName, LoadSceneMode.Additive);
}
*/

'Unity > C#' 카테고리의 다른 글

형변환 모음  (0) 2020.08.11
C# 파일관련 함수들  (0) 2020.07.30
c# Array(배열)관련  (0) 2020.07.29
posted by 모카쨩
2020. 7. 30. 17:31 Unity/C#

 

 

프로젝트 내 에셋들의 파일주소는 다음과 같이 얻어야 한다 안드로이드에서는 못 쓴다.

앞부분에 Assets/가 있으면 중첩될수도 있으니 그럴땐 겹치는 부분을 지우고 합쳐야한다

return $"{Application.dataPath}/{파일명}.txt";

세이브 데이터 경로

string filePath= $"{Application.persistentDataPath}/{fileName}.csv";

 

 

 

 

 

 

 

바이트배열 모두 읽기

byte[] datas=System.IO.File.ReadAllBytes(파일주소);

바이트배열 모두 쓰기

System.IO.File.WriteAllBytes(파일주소, 바이트배열);

문자열(텍스트) 모두 쓰기

string fileName = "save";
string filePath = $"{fileName}.txt";
string data = sb.ToString();
System.IO.File.WriteAllText(filePath, data);

문자열(텍스트) 모두 읽기

string filePath = $"{fileName}.txt";
string data = null;
if (System.IO.File.Exists(filePath))
{
    data = System.IO.File.ReadAllText(filePath);
}

아래와 동일함

 

public static bool SaveAllTextType2(string fileName, string data)
{
    try
    {
        System.IO.File.WriteAllBytes(filePath, System.Text.Encoding.Default.GetBytes(data));
        return true;
    }
    catch (Exception ex)
    {
        MessageBox.Show(ex.ToString());
        return false;
        throw;
    }
}
public static bool SaveAllText(string fileName, string value)
{
    try
    {
        FileStream fs = new FileStream(fileName, FileMode.Create);
        StreamWriter st = new StreamWriter(fs, Encoding.UTF8);
        st.Write(value);
        st.Close();
        fs.Close();
        return true;
    }
    catch (Exception ex)
    {
        MessageBox.Show(ex.ToString());
        return false;
        throw;
    }
}

public static string ReadAllText(string fileName)
{
    try
    {
        FileStream fs = new FileStream(fileName, FileMode.Open);
        StreamReader st = new StreamReader(fs, Encoding.UTF8);
        string data = st.ReadToEnd();
        st.Close();
        fs.Close();
        return data;
    }
    catch (Exception ex)
    {
        MessageBox.Show(ex.ToString());
        return null;
        throw;
    }
}

 

 

 

 

 

JSON 저장 읽기

이중클래스 저장시에는 내부에 들어가는 클래스에
[System.Serializable]가 붙어야 한다

HashTable, Dictionary는 저장불가

v1~v2

더보기
  public static string filePath
  {
      get
      {
          return $"{Application.persistentDataPath}/{nameof(SaveClass)}.json";
      }
  }
//쓰기
System.IO.File.WriteAllText(filePath, JsonUtility.ToJson(saveClass));

//읽기
if(System.IO.File.Exists(filePath))
{
	saveClass= JsonUtility.FromJson<SaveClass>(System.IO.File.ReadAllText(filePath));
}
else
{
	saveClass = new SaveClass();
}

V2

public class SaveClass
{
	public static string filePath
	{
		get
		{
			return $"{Application.persistentDataPath}/{GetType().Name}.json";
		}
	}
    public void Save()
    {
        System.IO.File.WriteAllText(filePath, JsonUtility.ToJson(this));
    }
    public static SaveClass Load()
    {
        if (System.IO.File.Exists(filePath))
        {
            return JsonUtility.FromJson<SaveClass>(System.IO.File.ReadAllText(filePath));
        }
        else
        {
            return new SaveClass();
        }
    }
}

public class TargetClass : MonoBehaviour
{
    public static SaveClass saveClass;
    // Start is called before the first frame update
    void Start()
    {
        saveClass = SaveClass.Load();
    }
    public void SetData()
    {
        saveClass.Save();
    }
    // Update is called once per frame
    void Update()
    {

    }
}

 

 

 

 

V3


public class SaveClass
{
    public double[] Datas { get; set; }
    string FilePath
    {
        get
        {
            return $"{Application.StartupPath}/{GetType().Name}.json";
        }
    }
    public void Save()
    {
        System.IO.File.WriteAllText(FilePath, JsonSerializer.Serialize(this));
    }
    public static SaveClass Load()
    {
        return new SaveClass().LoadThis();
    }
    SaveClass LoadThis()
    {
        if (System.IO.File.Exists(FilePath))
        {
            return JsonSerializer.Deserialize<SaveClass>(System.IO.File.ReadAllText(FilePath));
        }
        else
        {
            Datas = new double[15];
            return this;
        }
    }
}
public class TargetClass : MonoBehaviour
{
    public static SaveClass saveClass;
    // Start is called before the first frame update
    void Start()
    {
        saveClass = SaveClass.Load();
    }
    public void SetData()
    {
        saveClass.Save();
    }
    // Update is called once per frame
    void Update()
    {

    }
}

 

 

 

 

 

 

폴더가 없으면 만들기

if (System.IO.Directory.Exists(folderPath) == false)
{
  System.IO.Directory.CreateDirectory(folderPath);
}

 

 

해당 파일의 폴더경로(폴더명)를 반환

folderPath = filePath.Substring(0, Mathf.Max(filePath.LastIndexOf("/"), filePath.LastIndexOf(@"\")));

V2

var folderPath = System.IO.Path.GetDirectoryName(filePath);

 

 

파일 삭제하기

public static bool Delete(string filePath)
{
    if (!System.IO.File.Exists(filePath))
    {
        return false;
    }
    System.IO.File.Delete(filePath);
    return true;
}

 

 

윈도우에서 폴더 열기(실행)

System.Diagnostics.Process.Start(folderPath);

 

파일 복사

경로는 확장자도 포함 되어야 하고 C:/과 같이 드라이브 명으로 시작하는 경로여야함

System.IO.File.Copy(불러올파일경로, 저장될파일경로);

 

 

파일이름 반환 구버전

더보기
public static string GetFileName(string filePath)
{
    int filePath_LastIndexOf = filePath.LastIndexOf("/");
    if (filePath_LastIndexOf > 0)
    {
        filePath = filePath.Substring(filePath_LastIndexOf + "/".Length, filePath.Length - (filePath_LastIndexOf + "/".Length));
    }
    return filePath;
}

 

확장자 붙은 파일이름 반환 (유니티, 윈도우 겸용)

string fileName = System.IO.Path.GetFileName("경로");

 

확장자 없는 파일이름 반환 (유니티, 윈도우 겸용)

string fileName = System.IO.Path.GetFileNameWithoutExtension("경로");

 

 

파일이름들 반환

해당 파일 주소 바로 아래의 파일들을 가져온다. 아래아래같은경우엔 안됨

c:/부터 시작하는 파일경로를 쭉 불러와서 확장자까지 반환한다.

이상하게 파일명 앞에는 /이 아니고 \가 붙음. 쓰는덴 지장없다

//리스트 반환
List<string> filePaths = new List<string>(System.IO.Directory.GetFiles(폴더주소));

//배열 반환
string[] filePaths = System.IO.Directory.GetFiles(폴더주소);

//교정후 반환
List<string> filePaths = new List<string>(System.IO.Directory.GetFiles(folderPath)).ConvertAll(x=> x.Replace(@"\","/"));

 

 

 

파일 정보 (파일시간, 파일용량 등)

var info = new System.IO.FileInfo(filePath);
string md5 = $"{GetMD5(System.IO.File.ReadAllBytes(filePath))}";
string version =  $"{info.LastWriteTimeUtc.Ticks / 10000000 }";
string fileSize = $"{info.Length}";

 

 

 

 

zip압축/해제

쓰려면 Plugins/Windows/System.IO.Compression.FileSystem.dll이 필요하다

//압축
System.IO.Compression.ZipFile.CreateFromDirectory(압축할 폴더주소, 저장될 zip 파일 주소+".zip");

//압축해제
System.IO.Compression.ZipFile.ExtractToDirectory(zip 파일 주소+".zip", 압축해제할 폴더주소);

 

unityzip

ZipUtil.Zip(저장될파일주소, System.IO.Directory.GetFiles(압축할폴더주소));
//위아래 동일함
System.IO.Compression.ZipFile.CreateFromDirectory(압축할폴더주소, 저장될파일주소);

 

 

파일탐색기 열어서 파일 위치 반환

(파일 다이얼로그,윈폼기반)

유니티에서 쓰려면 System.Windows.Forms.dll이 있어야 하는데 생각보다 복잡하므로

스탠드얼론 파일 브라우저를 쓰자(하단 참조)

public static string FileSearch()
{
    System.Windows.Forms.OpenFileDialog openFile = new System.Windows.Forms.OpenFileDialog();
    //openFile.DefaultExt = "png";
    //openFile.Filter = "(*.txt)|*.txt";
    openFile.Filter = "All files(*.*)|*.*";
    openFile.ShowDialog();


    if (openFile.FileName.Length > 0)//파일이선택될경우 
    {
        return openFile.FileName;
    }
    return "";
}

 

유니티기반 다이얼로그

에디터 전용

c:/로 시작하는 경로를 반환함

string path = EditorUtility.OpenFilePanel("Overwrite with png", "", "png");
string path = EditorUtility.OpenFilePanel("Overwrite with img", "", "png;*.jpg");

 

 

유니티 스탠드얼론 파일 브라우저 (기본적으로 위와 같음) (2019.4.1.f1지원, 2019.4.31f1 미지원)

https://github.com/gkngkc/UnityStandaloneFileBrowser

string[] paths=SFB.StandaloneFileBrowser.OpenFilePanel("Open File", "", "txt", false);

 

스탠드얼론으로 폴더경로 받을때

{
    var paths = SFB.StandaloneFileBrowser.OpenFilePanel("Open File", "", "txt", false);
    {
        if (paths.Length > 0)
        {
            var filePath = paths[0];
            var folderPath = System.IO.Path.GetDirectoryName(filePath);
            return folderPath;
        }
    }
    return null;
}

 

 

 

 

 

object to path

오브젝트의 path를 반환함

Asset/로 시작하는 경로를 반환함

string path = AssetDatabase.GetAssetPath(오브젝트);

폴더 삭제

        if (System.IO.Directory.Exists(folderPath))
        {
            System.IO.Directory.Delete(folderPath, true);
        }

 

에셋폴더오브젝트의 하위폴더 이름들을 반환

#if UNITY_EDITOR
public static string[] GetFolderNames(Object folder)
{
    string folderPath = UnityEditor.AssetDatabase.GetAssetPath(folder);
    string[] folderPaths = UnityEditor.AssetDatabase.GetSubFolders(folderPath);
    string[] folderNames = System.Array.ConvertAll(folderPaths, x => System.IO.Path.GetFileName(x));

    return folderNames;
}
public static string[] GetFolderNames(string folderPath)
{
    string[] folderPaths = UnityEditor.AssetDatabase.GetSubFolders(folderPath);
    string[] folderNames = System.Array.ConvertAll(folderPaths, x => System.IO.Path.GetFileName(x));

    return folderNames;
}
#endif

 

특정 에셋폴더가 있는지 검사

바로 위 스크립트랑 같이씀

var assetsFolderNames = GetFolderNames("Assets");
if (assetsFolderNames.Contains("DynamicBone"))
{
	Debug.Log("다이나믹본 폴더가 존재함");
}
if (assetsFolderNames.Contains("VRCSDK"))
{
	Debug.Log("VRCSDK 폴더가 존재함");
}

 

 

 

 

 

에셋들을 전부 리로드

AssetDatabase.CreateAsset에는 필요없음

AssetDatabase.Refresh();

특정파일만 리프레시함

AssetDatabase.ImportAsset (파일경로);


폴더오브젝트에서  마테리얼, 텍스처들을 반환

static Material[] GetFolderToMaterials(Object folder)
{
    var folderPath = AssetDatabase.GetAssetPath(folder);
    var filePaths = AssetDatabase.FindAssets($"t:{typeof(Material).Name}", new string[] { folderPath });
    var assets = new Material[filePaths.Length];
    for (int i = 0; i < assets.Length; i++)
    {
        assets[i] = AssetDatabase.LoadAssetAtPath<Material>(AssetDatabase.GUIDToAssetPath(filePaths[i]));
    }
    return assets;
}

static Texture[] GetFolderToTextures(Object folder)
{
    var folderPath = AssetDatabase.GetAssetPath(folder);
    var filePaths = AssetDatabase.FindAssets($"t:{typeof(Texture).Name}", new string[] { folderPath });
    var assets = new Texture[filePaths.Length];
    for (int i = 0; i < assets.Length; i++)
    {
        assets[i] = AssetDatabase.LoadAssetAtPath<Texture>(AssetDatabase.GUIDToAssetPath(filePaths[i]));
    }
    return assets;
}

 

 

폴더오브젝트에서 오디오 클립들을 반환

    static AudioClip[] GetFolderToAudioAssets(Object folder)
    {
        var folderPath = AssetDatabase.GetAssetPath(folder);
        var filePathAudioClips = AssetDatabase.FindAssets($"t:{typeof(AudioClip).Name}", new string[] { folderPath });
        var audios = new AudioClip[filePathAudioClips.Length];
        for (int i = 0; i < audios.Length; i++)
        {
            audios[i] = AssetDatabase.LoadAssetAtPath<AudioClip>(AssetDatabase.GUIDToAssetPath(filePathAudioClips[i]));
        }
        return audios;
    }

 

 

파일 경로에서 오디오클립들을 반환

static AudioClip[] GetFolderToAudioFiles(string folderPath)
{
    string[] filePaths = System.IO.Directory.GetFiles(folderPath);
    var audios = new AudioClip[filePaths.Length];
    for (int i = 0; i < audios.Length; i++)
    {
        audios[i] = LoadAudioClip(filePaths[i]);
        audios[i].name = System.IO.Path.GetFileNameWithoutExtension(filePaths[i]);
    }
    return audios;
}

 

코루틴 버전

    IEnumerator GetFolderToAudioFilesListCo(params string[] folderPaths)
    {
        var audiosList = new List<AudioClip[]>();

        var ienumerators = new IEnumerator[folderPaths.Length];
        for (int i = 0; i < ienumerators.Length; i++)
        {
            ienumerators[i] = GetFolderToAudioFilesCo(folderPaths[i]);
            StartCoroutine(ienumerators[i]);
        }
        for (int i = 0; i < ienumerators.Length; i++)
        {
            yield return new WaitUntil(() => ienumerators[i].Current.GetType() == typeof(AudioClip[]));
            audiosList.Add((AudioClip[])ienumerators[i].Current);
        }
        yield return audiosList;
    }

 

 

 

빠른버전

    static AudioClip[] GetFolderToAudioFiles(string folderPath)
    {
        string[] filePaths = System.IO.Directory.GetFiles(folderPath);
        var audios = new AudioClip[filePaths.Length];
        string[] downloadLinks = Array.ConvertAll(filePaths, x => $"file://{x}");
        var operations = new UnityWebRequestAsyncOperation[filePaths.Length];
        var unityWebRequests = new UnityWebRequest[filePaths.Length];
        for (int i = 0; i < audios.Length; i++)
        {
            unityWebRequests[i] = UnityWebRequestMultimedia.GetAudioClip(downloadLinks[i], AudioType.UNKNOWN);
            operations[i] = unityWebRequests[i].SendWebRequest();
        }
        for (int i = 0; i < audios.Length; i++)
        {
            while (!operations[i].isDone)
            {
                Thread.Sleep(1);
            }
            if (unityWebRequests[i].isNetworkError)
            {
                Debug.LogError(unityWebRequests[i].error);
            }
            else
            {
                Debug.Log("LoadAudioClipSuccess");
            }
            audios[i] = DownloadHandlerAudioClip.GetContent(unityWebRequests[i]);
            audios[i].name = System.IO.Path.GetFileNameWithoutExtension(filePaths[i]);
        }
        return audios;
    }
    
    static AudioClip[] GetFolderToAudioFiles(string folderPath, string[] fileNames)
    {
        string[] filePaths = System.IO.Directory.GetFiles(folderPath);
        filePaths = System.Array.FindAll(filePaths, x => fileNames.Contains(System.IO.Path.GetFileNameWithoutExtension(x)));
        
        var audios = new AudioClip[filePaths.Length];
        string[] downloadLinks = Array.ConvertAll(filePaths, x => $"file://{x}");
        var operations = new UnityWebRequestAsyncOperation[filePaths.Length];
        var unityWebRequests = new UnityWebRequest[filePaths.Length];
        for (int i = 0; i < audios.Length; i++)
        {
            unityWebRequests[i] = UnityWebRequestMultimedia.GetAudioClip(downloadLinks[i], AudioType.UNKNOWN);
            operations[i] = unityWebRequests[i].SendWebRequest();
        }
        for (int i = 0; i < audios.Length; i++)
        {
            while (!operations[i].isDone)
            {
                Thread.Sleep(1);
            }
            if (unityWebRequests[i].isNetworkError)
            {
                Debug.LogError(unityWebRequests[i].error);
            }
            else
            {
                Debug.Log("LoadAudioClipSuccess");
            }
            audios[i] = DownloadHandlerAudioClip.GetContent(unityWebRequests[i]);
            audios[i].name = System.IO.Path.GetFileNameWithoutExtension(filePaths[i]);
        }
        return audios;
    }

 

비동기타입

    static IEnumerator GetFolderToAudioFilesCo(string folderPath)
    {
        string[] filePaths = System.IO.Directory.GetFiles(folderPath);
        var audios = new AudioClip[filePaths.Length];
        string[] downloadLinks = System.Array.ConvertAll(filePaths, x => $"file://{x}");
        var operations = new UnityWebRequestAsyncOperation[filePaths.Length];
        var unityWebRequests = new UnityWebRequest[filePaths.Length];
        for (int i = 0; i < audios.Length; i++)
        {
            unityWebRequests[i] = UnityWebRequestMultimedia.GetAudioClip(downloadLinks[i], AudioType.UNKNOWN);
            operations[i] = unityWebRequests[i].SendWebRequest();
        }
        for (int i = 0; i < audios.Length; i++)
        {
            yield return new WaitUntil(() => operations[i].isDone);
            if (unityWebRequests[i].isNetworkError)
            {
                Debug.LogError(unityWebRequests[i].error);
            }
            else
            {
                //Debug.Log("LoadAudioClipSuccess");
                audios[i] = DownloadHandlerAudioClip.GetContent(unityWebRequests[i]);
                audios[i].name = System.IO.Path.GetFileNameWithoutExtension(filePaths[i]);
            }
        }
        yield return audios;
    }

불러올때

        {
            var co = GetFolderToAudioFilesCo(GetInfomationsFolderPath());
            StartCoroutine(co);


            yield return new WaitUntil(() => co.Current.GetType() == typeof(AudioClip[]));
            infomationAudios = (AudioClip[])co.Current;
        }

 

 

 

 

 

폴더오브젝트에서 텍스처에셋들을 반환

static Texture2D[] GetFolderToTextureAssets(Object folder)
{
    var folderPath = UnityEditor.AssetDatabase.GetAssetPath(folder);
    var filePathTextures = UnityEditor.AssetDatabase.FindAssets($"t:{typeof(Texture2D).Name}", new string[] { folderPath });
    var GUIDToAssetPaths = System.Array.ConvertAll(filePathTextures,x=> UnityEditor.AssetDatabase.GUIDToAssetPath(x));
    var textures = System.Array.ConvertAll(GUIDToAssetPaths,x=> UnityEditor.AssetDatabase.LoadAssetAtPath<Texture2D>(x));
    return textures;
}

 

폴더오브젝트에서 텍스처파일들을 반환

    static Texture2D[] GetFolderToTexture2DFiles(string folderPath)
    {
        string[] filePaths = System.IO.Directory.GetFiles(folderPath);
        var texture2Ds = new Texture2D[filePaths.Length];
        for (int i = 0; i < texture2Ds.Length; i++)
        {
            texture2Ds[i] = LoadTexture2D(filePaths[i]);
            texture2Ds[i].name = System.IO.Path.GetFileNameWithoutExtension(filePaths[i]);
        }
        return texture2Ds;
    }

 

 

 

빠른버전

    static Texture2D[] GetFolderToTexture2DFilesHS(string folderPath)
    {
        string[] filePaths = System.IO.Directory.GetFiles(folderPath);
        var texture2Ds = new Texture2D[filePaths.Length];
        string[] downloadLinks = Array.ConvertAll(filePaths, x => $"file://{x}");
        var operations = new UnityWebRequestAsyncOperation[filePaths.Length];
        var unityWebRequests = new UnityWebRequest[filePaths.Length];
        for (int i = 0; i < texture2Ds.Length; i++)
        {
            unityWebRequests[i] = UnityWebRequestTexture.GetTexture(downloadLinks[i]);
            operations[i] = unityWebRequests[i].SendWebRequest();
        }
        for (int i = 0; i < texture2Ds.Length; i++)
        {
            while (!operations[i].isDone)
            {
                Thread.Sleep(1);
            }
            if (unityWebRequests[i].isNetworkError)
            {
                Debug.LogError(unityWebRequests[i].error);
            }
            else
            {
                Debug.Log("LoadAudioClipSuccess");
                texture2Ds[i] = DownloadHandlerTexture.GetContent(unityWebRequests[i]);
                texture2Ds[i].name = System.IO.Path.GetFileNameWithoutExtension(filePaths[i]);
            }
        }
        return texture2Ds;
    }

비동기타입

    IEnumerator GetFolderToSpriteFilesCo(string folderPath)
    {

        var co = GetFolderToTexture2DFilesCo(folderPath);
        StartCoroutine(co);
        yield return new WaitUntil(() => co.Current.GetType() == typeof(Texture2D[]));
        

        var texture2Ds = (Texture2D[])co.Current;
        var sprites = new Sprite[texture2Ds.Length];
        for (int i = 0; i < texture2Ds.Length; i++)
        {

            sprites[i] = Sprite.Create(texture2Ds[i], new Rect(0, 0, texture2Ds[i].width, texture2Ds[i].height), Vector2.zero);
            sprites[i].name = texture2Ds[i].name;
        }
        yield return sprites;
    }
    static IEnumerator GetFolderToTexture2DFilesCo(string folderPath)
    {
        string[] filePaths = System.IO.Directory.GetFiles(folderPath);
        var texture2Ds = new Texture2D[filePaths.Length];
        string[] downloadLinks = Array.ConvertAll(filePaths, x => $"file://{x}");
        var operations = new UnityWebRequestAsyncOperation[filePaths.Length];
        var unityWebRequests = new UnityWebRequest[filePaths.Length];
        for (int i = 0; i < texture2Ds.Length; i++)
        {
            unityWebRequests[i] = UnityWebRequestTexture.GetTexture(downloadLinks[i]);
            operations[i] = unityWebRequests[i].SendWebRequest();
        }
        for (int i = 0; i < texture2Ds.Length; i++)
        {
            yield return new WaitUntil(() => operations[i].isDone);
            if (unityWebRequests[i].isNetworkError)
            {
                Debug.LogError(unityWebRequests[i].error);
            }
            else
            {
                Debug.Log("LoadAudioClipSuccess");
                texture2Ds[i] = DownloadHandlerTexture.GetContent(unityWebRequests[i]);
                texture2Ds[i].name = System.IO.Path.GetFileNameWithoutExtension(filePaths[i]);
            }
        }
        yield return texture2Ds;
    }

 

 

 

 

오디오클립, 스프라이트 로드

    static Sprite LoadAsset(string fileName, string folderPath, List<Sprite> listBuffer)
    {
        Sprite sprite = null;


        sprite = listBuffer.Find(x => x.name.Trim().ToUpper() == fileName.Trim().ToUpper());

        if (sprite == null)
        {
            string[] filePaths = System.IO.Directory.GetFiles(folderPath);
            string filePath = System.Array.Find(filePaths, x => System.IO.Path.GetFileNameWithoutExtension(x).Trim().ToUpper() == fileName.Trim().ToUpper());

            sprite = LoadSprite(filePath);


            listBuffer.Add(sprite);
        }


        return sprite;
    }
    static AudioClip LoadAsset(string fileName, string folderPath, List<AudioClip> listBuffer)
    {
        AudioClip audioClip = null;


        audioClip = listBuffer.Find(x => x.name.Trim().ToUpper() == fileName.Trim().ToUpper());

        if (audioClip == null)
        {
            string[] filePaths = System.IO.Directory.GetFiles(folderPath);
            string filePath = System.Array.Find(filePaths, x => System.IO.Path.GetFileNameWithoutExtension(x).Trim().ToUpper() == fileName.Trim().ToUpper());

            audioClip = LoadAudioClip(filePath);


            listBuffer.Add(audioClip);
        }


        return audioClip;
    }

 

 

 

 

오디오클립, 스프라이트 언로드

    void UnLoadAssets(List<Sprite> spriteList)
    {
        UnLoadAssets(spriteList.ToArray());
        spriteList.Clear();
    }
    void UnLoadAssets(params Sprite[] sprites)
    {
        foreach (var sprite in sprites)
        {
            Destroy(sprite.texture);
            Destroy(sprite);
        }
    }

    void UnLoadAssets(List<AudioClip> audioList)
    {
        UnLoadAssets(audioList.ToArray());
        audioList.Clear();
    }
    void UnLoadAssets(params AudioClip[] audios)
    {
        foreach (var audio in audios)
        {
            Destroy(audio);
        }
    }


    
    void OnDestroy()
    {
        UnLoadAssets(spriteList);
        UnLoadAssets(audioClipList);
    }

 

 

 

 

폴더 경로에서 스프라이트들을 반환

    static Sprite[] GetFolderToSpriteFiles(string folderPath)
    {
        string[] filePaths = System.IO.Directory.GetFiles(folderPath);
        var sprites = new Sprite[filePaths.Length];
        for (int i = 0; i < sprites.Length; i++)
        {
            sprites[i] = LoadSprite(filePaths[i]);
            sprites[i].name = System.IO.Path.GetFileNameWithoutExtension(filePaths[i]);
        }
        return sprites;
    }
    static Sprite LoadSprite(string downloadLink)
    {
        var texture2D = LoadTexture2D(downloadLink);
        var sprite = Sprite.Create(texture2D, new Rect(0, 0, texture2D.width, texture2D.height), Vector2.zero);
        sprite.name = System.IO.Path.GetFileNameWithoutExtension(downloadLink);
        return sprite;
        
    }

폴더오브젝트에서 스프라이트에셋들을 반환

    static Sprite[] GetFolderToSpriteAssets(Object folder)
    {
        var folderPath = UnityEditor.AssetDatabase.GetAssetPath(folder);
        var filePathSprites = UnityEditor.AssetDatabase.FindAssets($"t:{typeof(Sprite).Name}", new string[] { folderPath });
        var GUIDToAssetPaths = System.Array.ConvertAll(filePathSprites, x => UnityEditor.AssetDatabase.GUIDToAssetPath(x));
        var sprites = System.Array.ConvertAll(GUIDToAssetPaths, x => UnityEditor.AssetDatabase.LoadAssetAtPath<Sprite>(x));
        return sprites;
    }

 

경로에서 Texture2D 가지고 오기

    static Texture2D LoadTexture2D(string filePath)
    {
        Texture2D texture2D = Texture2D.blackTexture;
        var fileData = System.IO.File.ReadAllBytes(filePath);
        if (texture2D.LoadImage(fileData))
        {
            //성공
        }
        return texture2D;
    }
    
    //v2
static Texture2D LoadTexture2D(string filePath)
{
    Texture2D texture2D = new Texture2D(1, 1);
    if (System.IO.File.Exists(filePath)==false)
    {
        Debug.LogError($"{filePath}에 해당 파일 없음");
    }
    var fileData = System.IO.File.ReadAllBytes(filePath);
    if (texture2D.LoadImage(fileData))
    {
        //성공
    }
    return texture2D;
}

 

 

 

 

경로에서 이미지 가져오기

//닷넷버전

public static Bitmap GetImage(string filePath)
{
    return new Bitmap(filePath);
}
public static Bitmap[] GetImage(string[] filePath)
{
    if (filePath != null)
    {
        Bitmap[] images = new Bitmap[filePath.Length];
        for (int i = 0; i < filePath.Length; i++)
        {
            images[i] = new Bitmap(filePath[i]);
        }
        return images;
    }
    return null;
}

 

 

UnityWebRequest용 스트리밍 에셋 경로 (dataPath타입)

//안드로이드
string filePath=$"jar:file://{Application.dataPath}!/assets/{fileName}.zip";

UnityWebRequest용 스트리밍 에셋 경로 (내장타입)

var streamingAssetsPath = $"{Application.streamingAssetsPath}/{fileName}";

 

 

스트리밍에셋

    public string fileName = "";
    void Awake()
    {
        StartCoroutine(StreamingAssetCreate());
    }

    IEnumerator StreamingAssetCreate()
    {
        var extractFolderPath = $"{Application.persistentDataPath}/StreamingAssets";
        var filePath = $"{extractFolderPath }/{fileName}";
        var streamingAssetsPath = $"{Application.streamingAssetsPath}/{fileName}";
        //if (!File.Exists(filePath))
        {

            if (Application.platform == RuntimePlatform.IPhonePlayer)
            {
                streamingAssetsPath = "file:///" + streamingAssetsPath;
            }

            UnityWebRequest unityWebRequest = UnityWebRequest.Get(streamingAssetsPath);
            unityWebRequest.downloadedBytes.ToString();
            
            var operation = unityWebRequest.SendWebRequest();
            yield return new WaitUntil(()=>operation.isDone);


            if (System.IO.Directory.Exists(extractFolderPath) == false)//폴더가 없으면 생성
            {
                System.IO.Directory.CreateDirectory(extractFolderPath);
            }
            File.WriteAllBytes(filePath, unityWebRequest.downloadHandler.data);

        }
    }

 

 

 

파일저장창

 //System.IO.Stream s = null;
 SaveFileDialog f = new SaveFileDialog();
 f.Filter = "3D File(*.stl)|*.stl|Point Cloud(*.asc)|*.asc";
 if (f.ShowDialog() == DialogResult.OK)
 {
     MessageBox.Show("" + f.FileName);
     //s = f.OpenFile()

 

유니티 경로를 윈도우 경로로 반환

    public static string ConvertWindowFilePath(string unityFilePath)
    {
        string windowFilePath = null;
        string assetsFolderPath = "Assets/";

        if ((unityFilePath.Length >= assetsFolderPath.Length) && (unityFilePath.Substring(0, assetsFolderPath.Length) == assetsFolderPath))
        {
            windowFilePath = Application.dataPath+"/"+unityFilePath.Substring(assetsFolderPath.Length, unityFilePath.Length - assetsFolderPath.Length);
        }
        return windowFilePath;
    }

 

 

파일이름 바꾸기 윈도우버전


void RenameFiles(string folderPath)
{
    var filePaths = System.IO.Directory.GetFiles(folderPath);
    foreach (var filePath in filePaths)
    {
        var fileName = System.IO.Path.GetFileNameWithoutExtension(filePath);
        var filterName = fileName.Replace("_", "").Trim().ToLower();
        var extension = System.IO.Path.GetExtension(filePath);
        if (fileName != filterName)
        {
            var newFilePath = $"{folderPath}\\{filterName}{extension}";
            Console.WriteLine($"파일이름 변경됨 {filePath}->{newFilePath}");
            System.IO.File.Move(filePath, $"{folderPath}\\{filterName}{extension}");
        }
    }
}

 

 

 

파일이름 바꾸기 

    public void SetSpritesNames(UnityEngine.Object folder)
    {
        var folderPath = UnityEditor.AssetDatabase.GetAssetPath(folder);
        var filePathSpriteDatas = UnityEditor.AssetDatabase.FindAssets($"t:{typeof(Sprite).Name}", new string[] { folderPath });
        var filterNames = new List<string>();
        for (int i = 0; i < filePathSpriteDatas.Length; i++)
        {
            var assetPath = UnityEditor.AssetDatabase.GUIDToAssetPath(filePathSpriteDatas[i]);
            var fileName = System.IO.Path.GetFileNameWithoutExtension(assetPath);
            var filterName = fileName.Replace("_", "").Trim().ToLower();

            if (filterNames.Contains(filterName))
            {
                UnityEditor.AssetDatabase.MoveAssetToTrash(assetPath);
                Debug.LogWarning("이름이 중복되어 삭제"+assetPath);
            }
            else
            {
                UnityEditor.AssetDatabase.RenameAsset(assetPath, filterName);
                filterNames.Add(filterName);
            }
        }
    }

 

 

 

 

csv파일이나 txt파일(텍스트 파일) 읽을때

주의점은 에셋번들로 호출시 항상 txt파일이 Resources폴더아래에 있어야 함

왜냐면 유니티는 txt파일 이런건 번들에 안 올리기 때문이다.

대신 Resource.Load 이딴건 안 써도 됨

TextAsset textAsset;

string text= textAsset.text;

 

'Unity > C#' 카테고리의 다른 글

유니티 씬 계열 함수 모음  (0) 2020.07.30
c# Array(배열)관련  (0) 2020.07.29
유니티 키보드  (0) 2020.07.28
posted by 모카쨩
2020. 7. 29. 19:25 Unity/C#

배열 생성 이상한방식

//1차원
Array array1 = Array.CreateInstance(typeof(int), 사이즈);

//2차원
Array array2 = Array.CreateInstance(typeof(int), X사이즈, y사이즈);

//가변
Array arrayMain = Array.CreateInstance(typeof(Array), 2);
BossArray.SetValue(array1, 0);
BossArray.SetValue(array2, 1);

 

배열관련 함수

//해당조건을 만족하는 번호를 반환. 없으면 -1
var nameAIndex = System.Array.FindIndex(array,x => x.name == "A");

//해당조건을 만족하는 값을 반환.
var nameA = System.Array.Find(array,x => x.name == "A");

//해당조건을 만족하는 값들을 반환. RemoveAll대용으로도 사용가능
var nameAs = System.Array.FindAll(array,x => x.name == "A");

//중복되는것만 추출
var redundantArray = System.Array.FindAll(array, x => List.Contains(x));

//중복되는것만 추출2
redundantArray = System.Array.FindAll(array, x => System.Array.FindIndex(array2,y=>y==x)>=0);

//RemoveAll(삭제)용도일경우
System.Array.FindAll(배열,x => x.name != "A");

//해당조건을 만족하는게 한개라도 존재하는지
System.Array.Exists(배열,x => x.name == "A");

//내용물에 전부 1을 더하여 반환
int[] 배열=System.Array.ConvertAll(배열,x => x+1);

//변수값 0으로 초기화
int[] 배열=System.Array.ConvertAll(배열,x => 0);


//bool[] 중 하나라도 true인지 검사
return System.Array.Find(bools, x => x == true);

//bool[] 중 하나라도 true인지 검사 2
System.Array.TrueForAll(toggles, x => x.isOn == false)

//array가 List안에 전부 포함되어 있는지 검사
if (System.Array.TrueForAll(array, x => List.Contains(x)))

 

 

배열관련 함수 Linq계열

using System.Linq;


//맥스값 추출
arrayCount = array.Max(x => x.level);


//맥스값'들' 추출
var timeMax = saves.Max(save => save.time);
var timeMaxSaves = System.Array.FindAll(saves,save => save.time == timeMax);



//평균추출
var average = array.Average();


//중복제거(중복제거의 반대는 FindAll을 쓴다)
array = array.GroupBy(x => x.Substring(0,3)).Select(x=>x.First()).ToArray(); //앞글자 3개가 똑같다면 제거
array = array.GroupBy(x => x).Select(x=>x.First()).ToArray(); //완벽히 동일한것만 제거


//셔플(미세한 편향)
System.Random seed = new System.Random((System.Int32)System.DateTime.Now.Ticks);
array = array.OrderBy(a => seed.Next()).ToArray();


//셔플 유니티타입(미세한 편향)
array = array.OrderBy(a => Random.value).ToArray();

//정렬
array = array.OrderBy(x => x).ToArray();

//합치기
if(array2 != null)
{
    array1 = array1.Concat(array2).ToArray();
}

//인자1개 추가
array1 = array1.Append(data).ToArray();

//슬라이스(자르기)
var array = new int[] { 1, 2, 3, 4, 5 };
var length = 3;
var sliceArray =  array.Take(length).ToArray();
Debug.Log(string.Join(", ", sliceArray));
//결과: 1,2,3

//슬라이스2 (중간부터)
var array = new int[] { 1, 2, 3, 4, 5 };
var startIndex = 1;
var length = 3;
var sliceArray =  array.Skip(startIndex).Take(length).ToArray();
Debug.Log(string.Join(", ", sliceArray));
//결과: 2,3,4


//슬라이스3 (뒤에서부터)
var array = new int[] { 1, 2, 3, 4, 5 };
var length = 3;
var sliceArray =  array.Skip(array.Length-length).ToArray();
Debug.Log(string.Join(", ", sliceArray));
//결과: 3,4,5


//해당조건을 만족하는 값을 반환
//FirstOrDefault (System.Array.Find와 동일)
var nameA = array.FirstOrDefault(x => x.name == "A");

//모두 true인지 검사
//Array.TrueForAll과 동일하다
var allNameA = array.All(x => x.name == "A");

//하나라도 true인지 검사
//Find검사로 비슷하게 구현할수 있다
var anyNameA = array.Any(x => x.name == "A");

 

 

Array.Copy

var array1 = new int[] { 1, 2, 3, 4, 5 };
var array2 = new int[] {6,7,8,9,10 };
System.Array.Copy(array1, array2, 3);
Debug.Log(string.Join(", ", array2));
//결과 1,2,3,9,10

 

배열깊은복사 (배열복제)

var stringArrayClone = (string[])stringArray.Clone();

 

 

오브젝트 리스트를 스트링배열로 변경


using System.Linq;
var list = new List<object> ();
list.Cast<string>().ToArray()

 

FindIndexAll

    public static class Array
    {
        public static int[] FindIndexAll<T>(T[] array, System.Predicate<T> match)
        {
            var indexList = new List<int>();
            for (int i = 0; i < array.Length; i++)
            {
                if (match.Invoke(array[i]))
                {
                    indexList.Add(i);
                }
            }
            return indexList.ToArray();
        }
    }

 

 

 

중간에 끼워넣기

var randomIndex=(int)Random.Range(0,list.Count);
list.Insert(randomIndex, memorizeList[index]);
list.RemoveAt(index);

 

 

 

이동평균함수

고속으로 처리할일이 생겨서 만듦

써보니까 앞부분은 처리해도 도움이 안 되길래 과감히 지우는쪽으로 했다

double[] MovingAverageHS(double[] datas,int period)
{
    if (datas.Length< period)
    {
        return null;
    }
    var movingAverages = new double[datas.Length- period + 1];

    var sum = 0.0;
    for (int i = 0; i < period; i++)
    {
        sum += datas[i];
        movingAverages[0]=sum/ period;
    }
    for (int i = period; i < datas.Length; i++)
    {
        sum = sum - datas[i - period] + datas[i];
        movingAverages[i - period + 1] = sum / period;
    }
    return movingAverages;
}

 

 

인덱스 체크 간소화

근데 어차피 쓰려면 null체크 추가로 들어가서 그렇게 효율적이진 않음
오히려 협업할때는 누구나 알기쉬운 위쪽이 나을수도 있겠다

if((index >= 0) && (index < array.Length))
{
    var item = array[index];
    //작동할 코드
}


//위아래 동일

var item = array.ElementAtOrDefault(index);
if(item != null)
{
    //작동할 코드
}

 

 

'Unity > C#' 카테고리의 다른 글

C# 파일관련 함수들  (0) 2020.07.30
유니티 키보드  (0) 2020.07.28
c# @변수  (0) 2020.07.28
posted by 모카쨩
2020. 7. 28. 13:17 Unity/C#

 

 

 

정석적인 방법

if (Input.GetKeyDown(KeyCode.A))
{
	//명령
}

 

 

OnGUI 계열

    void OnGUI()
    {
        Event e = Event.current;
        if (e.isKey)
        {
            if (e.keyCode== KeyCode.A)
            {
            //명령
            }
        }
    }

 

press체크의 경우

    void OnGUI()
    {
        Event e = Event.current;
        if (e.isKey)
        {
            KeyCode k= e.keyCode;
            if (e.Equals(Event.KeyboardEvent(k.ToString())))
            {
                if (k== KeyCode.A)
                {
                    //명령
                }
            }

        }
    }

 

다른방식

    void OnGUI()
    {
        Event e = Event.current;
        if (e.type == EventType.KeyDown)
        {
            if (e.keyCode== KeyCode.A)
            {
            	//명령
            }
        }
    }

 

inputString 방식, 한프레임에 여러키가 와도 순서가 안 섞임

string _str = Input.inputString;
for (int i = 0; i < _str.Length; i++)
{
	if(_str[i]=="k")
    {
    	//명령
    }
}

'Unity > C#' 카테고리의 다른 글

c# Array(배열)관련  (0) 2020.07.29
c# @변수  (0) 2020.07.28
c# 문자열 처리  (0) 2020.07.28
posted by 모카쨩
2020. 7. 28. 12:51 Unity/C#

별 의미 없고 그냥 키워드를 변수로 사용가능하게 해주는거

 

 

예를들어


Event @event= Event.current;

 이런식으로 씀

 

근데 애초에 저런식으로 겹치게 짜지 마라

'Unity > C#' 카테고리의 다른 글

유니티 키보드  (0) 2020.07.28
c# 문자열 처리  (0) 2020.07.28
OnGUI  (0) 2020.07.27
posted by 모카쨩
2020. 7. 28. 10:48 Unity/C#

일반

//텍스트에서 A를 찾는다
int index = text.IndexOf("A");



//문자열 자르기
string text=nameof(speed);
string textSpe = text.Substring(startIndex:0, length:3); //spe
string textPee = text.Substring(startIndex:1, length:3); //pee
string textEed = text.Substring(startIndex:2); //eed


//숫자만 추출
text = new string(System.Array.FindAll(text.ToCharArray(), c => char.IsDigit(c)));


//숫자앞에 0붙이기
int num=7;
num.ToString("D3"); //7 -> 007 , 76 -> 076같이 3글자 숫자로 바꿔줌


//숫자앞에 0붙이기2
string text="7";
text.ToString().PadLeft(3,'0'); //7 -> 007 , 76 -> 076같이 3글자 숫자로 바꿔줌


//소숫점 자르기
7.014837f.ToString("N4"); //7.0148
7.014837f.ToString("N2"); //7.01


//text가 숫자인지 확인(bool반환)
string text="";
if(int.TryParse(text, out int num))
/*
    -결과 모음, int형에 부합하는것만 true를 반환
    A : False
    A1 : False
    1 : True
    1.0 : False
    001 : True
    1+1 : False
    2147483647 : True
    2147483648 : False

    -복합사용예제
    if (int.TryParse(text, out int num))
    {
        if (num > 5)
        {
        }
    }


*/


문자열을 int형으로 변환
int number = System.Int32.Parse(text);







//A~Z 랜덤 문자열
string randomChar = ((char)Random.Range('A', 'Z')).ToString();



//따옴표를 표기할때
Debug.Log(@"""A""");//"A"가 표시됨


//문자열을 ?형으로 변환
//일반적으로 리플렉션과 연동할때 사용

public static T StringArrayToClass<T>(string[] texts) where T : new()
{
    var fields = typeof(T).GetFields();
    var tempClass = new T();
    for (int i = 0; i < fields.Length; i++)
    {
        var field = fields[i];

        try
        {
            var converter = System.ComponentModel.TypeDescriptor.GetConverter(field.FieldType);
            var objData = converter.ConvertFrom(texts[i]);
            field.SetValue(tempClass, objData);
        }
        catch (System.Exception ex)
        {
            Debug.LogError(ex);
            Debug.LogError($"text:{texts[i]}");
            Debug.LogError($"field.Name:{field.Name}");
            Debug.LogError($"field.FieldType:{field.FieldType}");
            throw;
        }
    }
    return tempClass;
}

 

형변환

//char를 string으로 변환
string text= char.ToString();



//char[]를 string으로 변환
//절대로 toString()을 쓰면 안된다
string text= new string(chars);

//string을 char[]로 변환
char[] charArray= text.ToCharArray();



//키코드를 문자열로 바꿈
text=((KeyCode)key).ToString().Replace("Alpha", "");



//10진수 정수를 16진수 문자열로 바꿈
int num=61;
string hex = System.Convert.ToString(num, 16);
Debug.Log(hex); //결과 3d

//16진수 문자열을 10진수 정수로 바꿈
System.Int32.Parse(hex, System.Globalization.NumberStyles.HexNumber);





//문자열 배열을 문자열로 통합
string text=string.Concat(texts);


//문자열 배열을 사이에 엔터를 넣어가며 문자열로 통합
string text=string.Join("\n", texts);


//String to StringArray
//문자열을 잘라서 문자열 배열로 반환
//분할후 공백을 모두 제거
string text="line1 \n Line2"
string[] lines = text.Split(new char[] { '\r', '\n' },StringSplitOptions.RemoveEmptyEntries);

//String to StringArray2
//이번엔 string으로 구분값을 사용
var texts = text.Split(new string[] { ":--:" });

 

 

 

 

 

 

세줄 모두 같은 처리결과를 가진다

int count=0;
string t;
t="count: " + count;
t=$"count: {count}";
t=string.Format("count: {0}", count);

 

마지막 줄 코드는 틀니스러운 방법이다. 이젠 쓰이지 않는다

 

 

 

 

StringBuilder 예제

var sb = new System.Text.StringBuilder();
sb.AppendLine("AB");
sb.AppendLine("C");
Debug.Log(sb.ToString());

//결과: 
AB
C
var sb = new System.Text.StringBuilder();
sb.Append("AB");
sb.Append("C");
Debug.Log(sb.ToString());

//결과: 
ABC

 

 

앞에 @가 붙으면 입력받은 그대로 쓸수있게 해준다 가령 \n이 엔터가 아니라 그대로 보이게 해준다

파일주소를 그대로 넣을때도 사용한다

Debug.Log(@"\n보\n이\n냐\n?");
//결과: \n보\n이\n냐\n?

$와 @를 동시에 써야할때

int num=100;
Debug.Log($@"\n보\n인\n다{num}\n?");
//결과: \n보\n인\n다100\n?

 

 

 

 

 

Replace는 해당 문자가 들어있으면 지워버린다.

경로에 StreamingAssets/가 포함되어있으면 Streaming만 남으니 주의하자

Debug.Log("Assets/user.csv".Replace("Assets/",""));
//결과: user.csv

응용해서 띄어쓰기 지우기

Debug.Log("문자 테스트 입니다.".Replace(" ",""));
//결과: 문자테스트입니다.

 

 

Regex패턴들 (정규표현식)

@"^[a-zA-Z ',.?""!]+$" //일반적인 영어문장에 사용되는 패턴
@"^[0-9]+$" //숫자만
@"^[a-zA-Z]+$" //알파벳만

영어로만 이루어져있는지 검사

System.Text.RegularExpressions.Regex.IsMatch("ABC",@"^[a-zA-Z]+$"); //true
System.Text.RegularExpressions.Regex.IsMatch("한글",@"^[a-zA-Z]+$"); //false

지정한 문자열만 제거

System.Text.RegularExpressions.Regex.Replace("테스트@$%^", @"[^\w\.@-]", "") //결과:테스트

 

지정한 화이트리스트에 등록된 문자열만 통과

    public static string ReplaceWhiteList(string text,string regexPattern)//화이트리스트
    {
        if (string.IsNullOrWhiteSpace(text))
        {
            return text;
        }
        var convertText = new List<char>();
        for (int i = 0; i < text.Length; i++)
        {
            if(System.Text.RegularExpressions.Regex.IsMatch(text[i].ToString(), regexPattern))
            {
                convertText.Add(text[i]);
            }
        }
        if(convertText.Count==0)
        {
            return "";
        }
        else
        {
            return new string(convertText.ToArray());
        }
    }

 

앞글자를 대문자로 바꿈

int jumpSpeed=0;

{
    string text=nameof(speed);
    var textInfo = new System.Globalization.CultureInfo("en-US", false).TextInfo;
    string toUpperTitleLetter = textInfo.ToTitleCase(text);
    //toUpperTitleLetter는 Jumpspeed가 됨
}

{
    string text=nameof(speed);
    string toUpperFirstLetter = text.ToUpper()[0] + text.Substring(1, text.Length - 1);
    //toUpperFirstLetter는 JumpSpeed가 됨
}

 

 

 

 

 

 

 

 

 

 

 

 

소문자인지 체크

if (inputString==inputString.ToLower())

 

 

 

중복제거

using System.Linq;

var text = "ABCABD";
var filterText = new string(text.ToCharArray().Distinct().ToArray());
Debug.Log(filterText);
//결과 : ABCD

 

 

 

컬러텍스트 (유니티)

    public string ColorText(string text, Color color)
    {
        return $"<color=#{ColorUtility.ToHtmlStringRGB(color)}>{text}</color>";
    }

 

 

특정 문자의 사이즈와 컬러를 바꿈

 

심플타입

    public static string HighlightWord(string originalText, string highlightChar, Color highlightColor, int fontSize)
    {
        var convertText = originalText;
        convertText = convertText.Replace(highlightChar.ToLower(), highlightChar.ToUpper());
        convertText = convertText.Replace(highlightChar.ToUpper(), $"<size={fontSize}><color=#{ColorUtility.ToHtmlStringRGB(highlightColor)}>{highlightChar.ToUpper()}</color></size>");

        return convertText;

    }

 

해쉬키타입, 간단하지만 변경될 문자에 해쉬키의 일부가 있으면 안된다

    public static string HighlightWord(string originalText, string highlightChar, Color highlightColor, int fontSize)
    {
        var convertText = originalText;
        string hash = "&*&*&*&*&*&";
        for (int i = 0; i < 100; i++)
        {
            if (originalText.Contains(hash))
            {
                hash += $"Dummy{(int)Random.Range(0,100)}";
            }
            else
            {
                break;
            }
        }
        convertText = convertText.Replace(highlightChar.ToLower(), hash);
        convertText = convertText.Replace(highlightChar.ToUpper(), $"<size={fontSize}><color=#{ColorUtility.ToHtmlStringRGB(highlightColor)}>{highlightChar.ToUpper()}</color></size>");
        convertText = convertText.Replace(hash, highlightChar.ToLower());

        return convertText;

    }

 

레겍스 타입 (미완성임)

    public static string HighlightWord(string originalText, string highlightChar, Color highlightColor, int fontSize)
    {
        var convertText = originalText;
        var pattern = new System.Text.RegularExpressions.Regex($"^[{highlightChar.ToLower()}]|[{highlightChar.ToUpper()}]+$");
        return pattern.Replace(convertText, $"<size={fontSize}><color=#{ColorUtility.ToHtmlStringRGB(highlightColor)}>{highlightChar.ToUpper()}</color></size>");
    }

 

찾아낸 첫번째 문자만 하이라이트

    public static string HighlightWordFirstIndex(string originalText, string highlightChar, Color highlightColor, int fontSize)
    {
        var convertText = originalText;
        var firstIndexLower = originalText.IndexOf(highlightChar.ToLower());
        var firstIndexUpper = originalText.IndexOf(highlightChar.ToUpper());

        int firstIndex = -1;
        if (firstIndexLower==-1)
        {
            firstIndex = firstIndexUpper;
        }
        if (firstIndexUpper == -1)
        {
            firstIndex = firstIndexLower;
        }
        if (firstIndex == -1)
        {
            firstIndex = Mathf.Max(firstIndexLower, firstIndexUpper);
        }
        if (firstIndex == -1)
        {
            Debug.LogWarning("찾는 문자열이 없음");
            return originalText;
        }
        convertText =convertText.Remove(firstIndex,1);
        convertText = convertText.Insert(firstIndex, $"<size={fontSize}><color=#{ColorUtility.ToHtmlStringRGB(highlightColor)}>{highlightChar.ToUpper()}</color></size>");

        return convertText;
    }

 

 

 

찾아낸 첫번째 글자를 기준으로 분할함

        public static string[] SplitFirstIndex(string text, string separator)
        {

            var splitTextList = new List<string>();
            var firstIndexLower = text.IndexOf(separator.ToLower());
            var firstIndexUpper = text.IndexOf(separator.ToUpper());

            int firstIndex = -1;
            if (firstIndexLower == -1)
            {
                firstIndex = firstIndexUpper;
            }
            if (firstIndexUpper == -1)
            {
                firstIndex = firstIndexLower;
            }
            if (firstIndex == -1)
            {
                firstIndex = Mathf.Max(firstIndexLower, firstIndexUpper);
            }
            if (firstIndex == -1)
            {
                Debug.LogWarning("찾는 문자열이 없음");
                return null;
            }

            if (firstIndex == 0)
            {
                splitTextList.Add("");
            }
            else
            {
                splitTextList.Add(text.Substring(0, firstIndex));
            }
            
            if (firstIndex == text.Length)
            {
                splitTextList.Add("");
            }
            else
            {
                splitTextList.Add(text.Substring(firstIndex , text.Length-(firstIndex)));
            }

            return splitTextList.ToArray();
        }

 

 

대소문자구분없이 리플레이스

 

    public static string RelaceUL(string text,string oldValue, string newValue)
    {
        if (string.IsNullOrEmpty(oldValue))
        {
            return text;
        }
        var charList = text.ToCharArray().ToList();
        {
            int i = 0;
            while (i+ oldValue.Length-1 < charList.Count)
            {
                bool replaceCheck = true;
                for (int j = 0; j < oldValue.Length; j++)
                {
                    var word = charList[i + j].ToString();
                    if (System.Text.RegularExpressions.Regex.IsMatch(word, @"^[a-zA-Z]+$"))
                    {
                        var oldWord = oldValue[j].ToString();
                        if (word.ToUpper() != oldWord.ToUpper())
                        {
                            replaceCheck = false;
                            break;
                        }
                    }
                    else if (charList[i + j] != oldValue[j])
                    {
                        replaceCheck = false;
                        break;
                    }
                }

                if (replaceCheck)
                {
                    charList.RemoveRange(i, oldValue.Length);
                    charList.InsertRange(i, newValue.ToCharArray());
                    i += newValue.Length;
                }
                else
                {
                    i++;
                }
            }
        }
        return new string(charList.ToArray());

    }
    
    //Debug.Log(RelaceUL("1text 2Text 3TEXT 4텍스트 5text","text","convert"));
    //1convert 2convert 3convert 4텍스트 5convert

 

한국어 처리관련

Debug.Log((char)('가' + 1)); //각
Debug.Log((char)('가' + 2)); //갂
Debug.Log((char)('가' + 3)); //갃
Debug.Log((char)('나' + ('나' - '가'))); //따

 

 

Char To Hex

Debug.Log(((int)'가').ToString("X")); //AC00
Debug.Log(((int)'나').ToString("X")); //B098
Debug.Log(((int)'다').ToString("X")); //B2E4
Debug.Log(System.String.Format("{0:X}", (int)'가')); //AC00
Debug.Log(System.String.Format("{0:X}", (int)'나')); //B098
Debug.Log(System.String.Format("{0:X}", (int)'다')); //B2E4

 

String To HexString 간략버전

//String To HexString
string text = "테스트";
var bytes = System.Text.Encoding.UTF8.GetBytes(text);
var hexString = System.BitConverter.ToString(bytes);
Debug.Log(text);
Debug.Log(string.Join(",", bytes));
Debug.Log(hexString);


//HexString To String
var bytes2 = System.Array.ConvertAll(hexString.Split('-'), x => System.Convert.ToByte(x, 16));
var text2 = System.Text.Encoding.UTF8.GetString(bytes2);
Debug.Log(string.Join(",", bytes2));
Debug.Log(text2);

 

 

 

 

String To HexString 경량버전

//String To HexString2
string text = "테스트";
var bytes = System.Text.Encoding.UTF8.GetBytes(text);
var hexString = System.BitConverter.ToString(bytes).Replace("-","");
Debug.Log(text);
Debug.Log(string.Join(",", bytes));
Debug.Log(hexString);


//HexString To String2
var bytes2 = new byte[hexString.Length / 2];
for (int i = 0; i < bytes2.Length; i++)
{
	bytes2[i] = System.Convert.ToByte(hexString.Substring(i * 2, 2), 16);
}
var text2 = System.Text.Encoding.UTF8.GetString(bytes2);
Debug.Log(string.Join(",", bytes2));
Debug.Log(text2);

 

 

 

Bytes To HexString V1

//bytes To HexString
{
    System.Text.StringBuilder sb = new System.Text.StringBuilder();
    foreach (byte b in bytes)
    {
        sb.Append(b.ToString("X2"));
    }
    string hexString = sb.ToString();
}

 

Bytes To HexString V2

string hexString = System.BitConverter.ToString(bytes).Replace("-", "");

 

 

 

 

UTF8 to ASCII

옛날시스템과 호환시킬때 사용한다

ASCII는 7비트니까 UTF7으로 변환시킨후 아스키로 바꿔서 전송

//UTF8 to ASCII
string text = "테스트";
var bytes = System.Text.Encoding.UTF7.GetBytes(text);
var ascii = System.Text.Encoding.ASCII.GetString(bytes);
Debug.Log(text);
Debug.Log(string.Join(",", bytes));
Debug.Log(ascii);


//ASCII to UTF8
var bytes2 = System.Text.Encoding.ASCII.GetBytes(ascii);
var text2 = System.Text.Encoding.UTF7.GetString(bytes2);
Debug.Log(string.Join(",", bytes2));
Debug.Log(text2);

 

 

 

String To Bytes

//문자열 -> 바이트배열
System.Text.Encoding.Default.GetBytes(text);

//바이트배열 -> 문자열 
System.Text.Encoding.Default.GetString(bytes2)

 

 

 

Root를 제외한 경로반환

가령 Root/armature/Hips는 /armature/Hips가 된다

string ArmaturePath(Transform bone)
{
    var rootName = bone.transform.root.name;
    var hierarchyPath = bone.transform.GetHierarchyPath();
    return hierarchyPath.Substring(rootName.Length, hierarchyPath.Length - rootName.Length);
}

 

 

 

Second To String

//0:02:13.878
System.TimeSpan.FromSeconds(clip.length).ToString("g")

 

 

비슷한 문장 검색

클래스형이 아니라 string으로 바꿔놔야 쓰기 편할텐데 나중에하자

MemorizationData GetSimilarWord(MemorizationData fromWord, List<MemorizationData> words)
{
    var similarWords = GetSimilarWords(fromWord, words);
    if (similarWords.Count == 0)
    {
        return null;
    }

    //셔플
    similarWords = similarWords.OrderBy(a => Random.value).ToList();


    return similarWords[0];
}
List<MemorizationData> GetSimilarWords(MemorizationData fromWord, List<MemorizationData> words)
{


    //중복이 아닌 단어들만 가져옴
    var filteredWords = words.FindAll(x => x.question != fromWord.question);
    if (filteredWords.Count == 0)
    {
        return null;
    }


    var similarWords = new List<MemorizationData>();
    for (int n = 2; n > 0; n--) //2글자까지만 검색
    {
        //n글자 이상 중복
        similarWords.AddRange(filteredWords.FindAll(word =>
        {
            if (word.question.Length < n)
            {
                return false;
            }
            for (int i = 0; i <= fromWord.question.Length-n; i++)
            {

                var fromWordSub= fromWord.question.Substring(i, n);
                if (fromWordSub.Length==1)
                {
                    if (fromWordSub[0] >= 0x20000 && fromWordSub[0] <= 0xFA2D)
                    {
                        //이것은 한자임
                    }
                    else
                    {
                        return false; //단일문자인데 한자가 아니라서 스킵
                    }
                }
                if (word.question.Contains(fromWord.question.Substring(i, n)))
                {
                    return true;
                }
            }
            return false;
        }));

        if (similarWords.Count > 0)
        {
            return similarWords;
        }
    }
    /*
    if (similarWords.Count == 0)
    {
        return null;
    }
    */
    return similarWords;
}

'Unity > C#' 카테고리의 다른 글

c# @변수  (0) 2020.07.28
OnGUI  (0) 2020.07.27
싱글톤 패턴  (0) 2020.07.20
posted by 모카쨩
2020. 7. 27. 14:48 Unity/C#

 

 

 

Debug.Log로 추적하기 힘든 실시간 상황값들을 추적할때 사용한다.

 

그냥 UGUI에 띄우면 되는거 아니냐? 하겠지만

ugui 할당하려면 캔버스 할당해서 Text 박스 맞추고 디버그모드에서만 활성화 하도록 따로 맞춰주고

누구한테 보여주려는거도 아니고 변수 하나 보는것뿐인데 여간 번거로운게 아니라 이쪽이 이득이다.

    #if UNITY_EDITOR //||true
    void OnGUI()
    {
        if (Debug.isDebugBuild)
        {
            GUI.Box(new Rect(0, 0, 200, 24), "Count: " + count);
        }
    }
    #endif
    public static int count = 0;

V3

    void OnGUI()
    {
#if UNITY_EDITOR
        if (UnityEditor.EditorUserBuildSettings.development)
#else
        if (Debug.isDebugBuild)
#endif
        {
            GUI.Box(new Rect(0, 0, 200, 24), "Count: " + count);
        }
    }
    public static int count = 0;

 

 

 

 

왼쪽정렬이 필요할때

    #if UNITY_EDITOR //||true
    void OnGUI()
    {
        GUI.Box(new Rect(0, 0, 200, 24), "");
        GUI.Label(new Rect(10, 0, 200, 24), "Count: " + count);
    }
    #endif
    public static int count = 0;

GUIStyle을 안 쓰는 이유는 글자색이나 크기 배경색 등등을 전부 지정해줘야해서

 

 

 

 

아래처럼 짜면 실시간으로 변수를 확인하면서 수정할수 있다.

근데 가능하면 인스펙터를 쓰고 이런건 전역값들을 추적할때 쓰자

int count=0;
string input = "";
#if UNITY_EDITOR //||true
void OnGUI()
{
  int lineHei = 18;
  input = GUI.TextField(new Rect(10, lineHei * 4, 300, lineHei * 1)
  , (input == "") ? input : count.ToString());
  if(input!="")
  {
  	count = int.Parse(input);
  }
}
#endif

 

버튼

    #if UNITY_EDITOR //||true
    void OnGUI()
    {
        if (Debug.isDebugBuild)
        {
            if(GUI.Button(new Rect(100, 100, 100, 24), "button"))
            {
                //명령
            }
        }
        
    }
    #endif

 

'Unity > C#' 카테고리의 다른 글

c# 문자열 처리  (0) 2020.07.28
싱글톤 패턴  (0) 2020.07.20
유니티 버그, 에러, 오류모음  (0) 2020.07.20
posted by 모카쨩

  • total
  • today
  • yesterday

Recent Post

저사양 유저용 블로그 진입