Get it on Google Play


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

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

Recent Comment

Archive


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

  1. 2021.01.15 c# 기본 문법
  2. 2020.12.24 MapBorder
  3. 2020.12.23 리플렉션
  4. 2020.10.20 그래디언트효과
  5. 2020.10.05 유니티 에디터 관련
  6. 2020.09.01 failed to connect to localhost port 80: Connection
  7. 2020.08.25 c# MD5
  8. 2020.08.20 UnityWebRequest
2021. 1. 15. 00:49 Unity/C#

 

 

구조체

더보기
public struct mVec3
    {
        public float x, y, z;
        public float Length
        {
            get
            {
                return (float)(Math.Sqrt((x * x) + (y * y) + (z * z)));
            }
            set
            {
                //float _t=Length*value;
                //float _t=value/(float)(Math.Sqrt((x*x)+(y*y)+(z*z)));
                if (Length <= 0)
                {
                    z = value;
                }
                else
                {
                    float _t = value / Length;
                    x *= _t;
                    y *= _t;
                    z *= _t;
                }
            }
        }
public static mVec3 forward //절대적
{
 get
 {
  return new mVec3(0f,0f,1f);
 }
}
public mVec3 up //상대적
{
 get
 {
  return new mVec3((Quaternion.Euler( this.x,this.y,this.z) * Quaternion.Euler(90f,0f,0f)).eulerAngles);
  //return mScript.len_vec(this);
 }
}
        
        public mVec3() : this(1,2,3)//생성자 (x:1,y:2,z:3)
        {

        }
        public mVec3(float X, float Y, float Z)//생성자
        {
            this.x = X;
            this.y = Y;
            this.z = Z;
        }
        public static mVec3 operator ++(mVec3 _Vec)
        {
            _Vec.x++;
            _Vec.y++;
            _Vec.z++;
            return _Vec;
        }
        public static mVec3 operator /(mVec3 _Vec1, mVec3 _Vec2)
        {
            _Vec1.x /= _Vec2.x;
            _Vec1.y /= _Vec2.y;
            _Vec1.z /= _Vec2.z;
            return _Vec1;
        }
        public static explicit operator mVec4(mVec3 _this) //명시적 형변환, 암시적은 implicit
        {
            mVec4 _return;
            _return.x=_this.x;
            _return.y=_this.y;
            _return.z=_this.z;
            _return.w=0;
            return _Vec;
        }
        

        public static bool operator ==(mVec3 _Vec1, mVec3 _Vec2)
        {
            foreach (var field in typeof(mVec3).GetFields())
            {
                if (field.GetValue(_Vec1) != field.GetValue(_Vec2))
                {
                    return false;
                }
            }
            return true;
        }
        public static bool operator !=(mVec3 _Vec1, mVec3 _Vec2)
        {
            return !(questionDictionary1== questionDictionary2);
        }
}
사용시
        //public static mVec3 zero(0f,0f,0f);

 

 

Enum

    public enum UpperPath
    {
        persistentDataPath
            , dataPath
            , streamingAssetsPath
            , temporaryCachePath
    };

 

Enum 길이 반환

int enumCount=System.Enum.GetValues(typeof(EnumName)).Length;
        Category[] openCategorysIndexes = (Category[])System.Enum.GetValues(typeof(Category));

 

 

namespace가 아닌 class using

using static SampleClass;

 

using문

using (var streamReader = new System.IO.StreamReader(response))
{
    string result = streamReader.ReadToEnd();
    streamReader.Close();
    return result;
}

 

 

 

 

자주쓰는데 은근 겁나 까먹음

try
{

}
catch(Exception ex)
{
	Debug.Log(ex.ToString());
}

 

 

 

 

변수이름

string 변수명=nameof(변수);

타입 이름

typeof(AudioClip).Name

 

 

 

c#버전 #define

public const float PointMax = 2;
public float Point = PointMax;

 

 

C#의 실제 #define

버전관리할때 유용함

#define Ver1000
#define Ver1001

#if Ver1000
    //여기서 동작함
#elif Ver1001
    //Ver1001일때 작동함
#else
    //그것도 아닐때
#endif

 

 

 

 

///함수주석

    /// <summary>
    /// 이름을 GUI에 표시함
    /// </summary>
    /// <param name="wordDictionary">이름</param>
    /// <param name="wid">가로크기</param>
    /// <param name="hei">세로크기</param>
    void DrawWordDictionary(string Name, int wid, int hei)
    {
    }

 

 

널은 안됨

class NotNullContainer<T> where T : notnull
{
}

 

new한정자

new가 붙은거만 넣을수 있음

    public static T GetClass<T>(string text) where T : new()
    {
    	if(text=="ok")
        {
            var targetClass = new T();
            return targetClass;
        }
        else
        {
            return null;
        }
    }

 

 

is 연산자

어디서 온건지 알 수 없는 obj등을 처리할 때 쓰인다

if ((objData is Dictionary<string, object>)==false)
{
	Debug.LogError("objData는 Dictionary<string, object>가 아닙니다");
	return;
}

//아래와 동일함

if ((objData.GetType() == typeof(Dictionary<string, object>))==false)
{
	Debug.LogError("objData는 Dictionary<string, object>가 아닙니다");
	return;
}

 

 

as 연산자

캐스팅 연산자인데 좀 복잡함 아래 참고

서로 동일한 코드를 나타내고 있다

string text= obj as string;

//위아래 동일함

string text;
if (obj is string)
{
    text = (string)obj;
}
else
{
    text = null;
}

 

 

if else 간소화 (남용은 금지, 복수로 쓰게될경우 가독성이 개판된다)

bool A;
if (B)
{
   A = C;
}
else
{
   A = D;
}


//위아래 동일

bool A=B?C:D;

 

null체크 간소화

if (A != null)
{
    if (B != null)
    {
        return C;
    }
}
return null;


//위아래 동일


return A?.B?.C;

 

?[]연산 에러발생시 null반환

다만 인덱스 오류는 캐치가 안 된다

string text = null;
if (array!=null)
{
    text = array[1];
}

//위아래 동일

var text = array?[1];

 

 

 

아래건 동일분기 처리를 좀 알아봐야 겠다

switch 간소화 (유니티 안됨, 비주얼스튜디오 2019 자동화 안됨)

switch(condition)
{
   case 1:
      A=B;
      break;
   case 2:
      A=C;
      break;
   default:
      A=D;
     break;
}

//위아래 동일


condition switch
{
    1 => A=B;
    2 => A=C;
    _ => A=D;
}

 

 

 

 

튜플

    void Start()
    {
        var (min, max) = FindMinMax(1, 2, 3, 4);
        Debug.Log("min: " + min);
        Debug.Log("max: " + max);
    }
    (int min, int max) FindMinMax(params int[] input)
    {
        var min = Mathf.Min(input);
        var max = Mathf.Max(input);
        return (min, max);
    }

 

여러개 리턴할때 사용

 

유니티도 된다

 

 

 

 

??연산

null처리할때 좋음

아래 네개 모두 동일한 코드이다

string a = null;
Debug.Log(a ?? "ABC"); //ABC반환
a = "a";
Debug.Log(a ?? "BCD"); //a반환

//위아래 동일

string a = null;
Debug.Log(a is string ? a:"ABC"); //ABC반환
a = "a";
Debug.Log(a is string ? a:"BCD"); //a반환

//위아래 동일

string a = null;
Debug.Log(a==null ? "ABC":a); //ABC반환
a = "a";
Debug.Log(a==null ? "BCD":a); //a반환


//위아래 동일

string a = null;
if(a!=null)
{
	Debug.Log(a);
}
else
{
	Debug.Log("ABC");
}
a = "a";
if(a!=null)
{
	Debug.Log(a);
}
else
{
	Debug.Log("BCD");
}

 

 

인덱스 체크 간소화

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


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


//위아래 동일

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

 

 

 

로컬함수

외부로 표출될 필요가 없는 함수 작성시 매우매우 유용하다.

특히 최장점은 같은 이름의 함수를 여러군데서 쓸수있다는 점

함수를 사용할때마다 생성하는 방식인지

성능을 절약하기 위해 static을 붙이라는 문구가 뜨는데 유니티 2019에서는 미지원이다

void SampleFunction()
{
    Debug.Log(LocalFunction("test")); //long text
    Debug.Log(LocalFunction("te")); //short text
    Debug.Log(LocalFunction("")); //short text


    string LocalFunction(string text)
    {
        if(text.Length>2)
        {
            return "long text";
        }
        return "short text";
    }
}

 

 

 

모든 스크립트에 using을 적용

몰론 함부로 쓰면 ㅈ된다

global using System;

 

 

 

함수내부 조건식 Predicate

 public static class Array
{
    //Array.FindIndexAll(arr,x=>x>1);
    //혹은 arr.FindIndexAll(x=>x>1);
    public static int[] FindIndexAll<T>(this 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();
    }
    
    //2개인자
    //Array.FindAll(arr,x=>x.Item1>x.Item2)
    public static int[] FindAll<T>(T[] array, System.Predicate<(T previous,T target)> match)
    {
        var indexList = new List<int>();
        for (int i = 0; i < array.Length; i++)
        {
            if (match.Invoke((array[i-1],array[i])))
            {
                indexList.Add(i);
            }
        }
        return indexList.ToArray();
    }
}

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

화면관련  (0) 2021.01.17
MapBorder  (0) 2020.12.24
리플렉션  (0) 2020.12.23
posted by 모카쨩
2020. 12. 24. 01:31 Unity/C#
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class MapBorder : MonoBehaviour {

	private void OnDrawGizmos()
	{
		Gizmos.DrawWireCube(borderCenter, borderSize);
	}
	public enum DropOption
	{
		None
		, Respawn
		, Destroy
	}
	public DropOption dropOption = DropOption.Respawn;

	public Vector3 borderCenter = Vector3.zero;
	public Vector3 borderSize = new Vector3(200,100,200);
	public Transform respawnPoint;
	Vector3 firstPosition;
	Quaternion firstRotation;
	// Use this for initialization
	void Start ()
	{
		firstPosition = transform.position;
		firstRotation = transform.rotation;
	}
	
	// Update is called once per frame
	void Update () {

		var pos = transform.position;
		pos.x = Mathf.Clamp(pos.x, borderCenter.x - borderSize.x, borderCenter.x + borderSize.x );
		pos.y = Mathf.Min(pos.y, borderCenter.y + borderSize.y );
		pos.z = Mathf.Clamp(pos.z, borderCenter.z - borderSize.z , borderCenter.z + borderSize.z);



		transform.position = pos;
		if (transform.position.y<borderCenter.y- borderSize.y )
		{
			switch (dropOption)
			{
				case DropOption.None:
					break;
				case DropOption.Respawn:
					if (respawnPoint == null)
					{
						transform.position = firstPosition;
						transform.rotation = firstRotation;
					}
					else
					{
						transform.position = respawnPoint.transform.position;
						transform.rotation = respawnPoint.transform.rotation;
					}
					break;
				case DropOption.Destroy:
					Destroy(gameObject);
					break;
				default:
					break;
			}
		}
	}
}

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

c# 기본 문법  (0) 2021.01.15
리플렉션  (0) 2020.12.23
그래디언트효과  (0) 2020.10.20
posted by 모카쨩
2020. 12. 23. 15:34 Unity/C#

 

현재 클래스 명


public class ParentClass
{
  public class TestClass
  {
      public void Log()
      {
        var className = GetType().Name
        Debug.Log(className);  //TestClass가 나옴
      }
  }
}

현재 클래스 명 (부모포함)

var className = typeof(TestClass).FullName
Debug.Log(className);   //ParentClass+TestClass가 나옴

 

해당 클래스가 존재하는지

public static bool CheckClassExists(string className)
{
    return System.Type.GetType(className) != null;
}

 

 

현재 함수 명

var methodName = System.Reflection.MethodBase.GetCurrentMethod().Name;
Debug.Log(methodName);

 

 

필드명들


string[] GetClassFieldNames<T>(T targetClass)
{
    var fields = typeof(T).GetFields();
    return System.Array.ConvertAll(fields, x => x.Name);
}

 

필드명들2

string[] GetClassFieldNames<T>(T targetClass)
{
    var fields = typeof(T).GetFields();
    return Array.ConvertAll(fields, x => $"{x.Name} - type: {x.FieldType}");
}

 

 

 

 

 

특정클래스의 필드명과 함수명에 접근

var methods = typeof(Class).GetMethods();
foreach (var method in methods)
{
    EditorGUILayout.LabelField(method.Name);
}

var fields = typeof(Class).GetFields();
foreach (var field in fields)
{
    EditorGUILayout.LabelField(field.Name);
}

 

 

 

클래스할당과 연동

구조체에는 씨알도 안 먹히니 헛고생 하지 말자


public class SampleClass
{
    string numStr = "0.5";
    int num = 1;
    float value = 1.5f;
    public SampleClass() { }
    public SampleClass (string stringData)
    {

        var fields = typeof(SampleClass).GetFields();
        var targetClass = this;

        for (int i = 0; i < fields.Length; i++)
        {
            if (fields[i].FieldType == typeof(string))
            {
                fields[i].SetValue(targetClass, stringData);
            }
            else if (fields[i].FieldType == typeof(bool))
            {
                fields[i].SetValue(targetClass, bool.Parse(stringData));
            }
            else if (fields[i].FieldType == typeof(char))
            {
                fields[i].SetValue(targetClass, char.Parse(stringData));
            }
            else if (fields[i].FieldType == typeof(int))
            {
                fields[i].SetValue(targetClass, int.Parse(stringData));
            }
            else if (fields[i].FieldType == typeof(uint))
            {
                fields[i].SetValue(targetClass, uint.Parse(stringData));
            }
            else if (fields[i].FieldType == typeof(long))
            {
                fields[i].SetValue(targetClass, long.Parse(stringData));
            }
            else if (fields[i].FieldType == typeof(ulong))
            {
                fields[i].SetValue(targetClass, ulong.Parse(stringData));
            }
            else if (fields[i].FieldType == typeof(float))
            {
                fields[i].SetValue(targetClass, float.Parse(stringData));
            }
            else if (fields[i].FieldType == typeof(double))
            {
                fields[i].SetValue(targetClass, double.Parse(stringData));
            }
            else
            {
                fields[i].SetValue(targetClass, stringData);
            }
        }
    }
    
    public override string ToString()
    {
        var fields = GetType().GetFields(System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Public);
        return string.Join("\n",System.Array.ConvertAll(fields, x => $"{x.Name}: {x.GetValue(x)}" ));
    }
    /*
    public override string ToString()
    {
        var fields = typeof(SampleClass).GetFields();
        string returnString = "";
        for (int i = 0; i < fields.Length; i++)
        {
            if (i>0)
            {
                returnString += "\n";
            }
            returnString += $"{fields[i].Name}:{fields[i].GetValue(this)}";
        }

        return returnString;
    }
    */
    public static implicit operator string(SampleClass _this) //암시적 형변환, 명시적은 explicit 
    {
        return _this.ToString();
    }

}

public class MainClass : MonoBehaviour
{
	void Start()
    {
        Debug.Log("new SampleClass()\n" + new SampleClass());
        Debug.Log("new SampleClass(\"123\")\n" + new SampleClass("123"));
    }
}

 

생성자 자동 할당

public class SampleClass
{
    public int number;
    public string name;
    public SampleClass()//생성자(자동)
    {
        var targetClass = new SampleClass(123, "Name");

        //this.number = targetClass.number;
        //this.name = targetClass.name;
        //이렇게 안쳐도 됨

        var fields = GetType().GetFields();
        foreach (var field in fields)
        {
            field.SetValue(this, field.GetValue(targetClass));
        }
    }
    public SampleClass(int number, string name)//생성자
    {
        this.number = number;
        this.name = name;
    }

}

 

클래스 깊은복사, 간단한 형식만 된다. 다중 클래스등은 불가 (문자열도 안되는듯?)

public class SampleClass
{
    public int number;
    public string name;
    public SampleClass Clone()
    {
        var targetClass = new SampleClass();
        var fields = GetType().GetFields();
        foreach (var field in fields)
        {
            field.SetValue(this, field.GetValue(targetClass));
        }
        return targetClass;
    }

}

 

BindingFlags 옵션들 (지정 안되면 논퍼블릭까지 전부 반환함)

System.Reflection.BindingFlags.NonPublic //퍼블릭이 아닌것들
System.Reflection.BindingFlags.Public //퍼블릭인것들
System.Reflection.BindingFlags.Instance  //일반적인 변수들 (지역변수)
System.Reflection.BindingFlags.Static  //전역변수들


//예시 (일반적인 필드값 불러오기)
var fields = GetType().GetFields(System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Public);
        

 

 

Type검사

field.FieldType.IsValueType //bool,int,float
field.FieldType.IsArray //bool[], int[], float[]
field.FieldType.IsClass //bool[], int[], float[], string, SubClass
field.FieldType.IsEnum //Enum타입
field.FieldType.Equals(typeof(string)) //string




//클래스인지 검사
var fieldType = field.FieldType;
if (fieldType.IsClass&&(fieldType.IsArray==false)&&(fieldType.Equals(typeof(string)) == false))
{
 //Sub클래스일경우에만
}


//List인지 검사
if((fieldType.IsGenericType) && fieldType.GetGenericTypeDefinition() == typeof(List<>))

 

오브젝트에서 ?배열을 반환

이런 X같은 코드도 쓸데가 있다

object objData;
var arrDatas = (System.Collections.IList)objData;

Debug.Log($"arrDatas[0]: {arrDatas[0]}");
Debug.Log($"arrDatas[1]: {arrDatas[1]}");
Debug.Log($"arrDatas.Count: {arrDatas.Count}");

 

 

오브젝트 리스트나 오브젝트 배열을 특정 형배열로 변환

using System.Linq;

//오브젝트 리스트를 float 배열로 변환
var objList=new List<object>();
float[] floatArray=objList.Cast<float>().ToArray();


//오브젝트 배열을 string 배열로 변환
object[] objArray = new object[1];
string[] stringArray = objArray.Cast<string>().ToArray();

 

 

문자열을 FieldType으로 변환

var text = "105.0";

var converter = TypeDescriptor.GetConverter(field.FieldType);
var data = converter.ConvertFrom(text);
field.SetValue(tempClass, data);

 

 

 

배열에 할당된 변수명 추출

v1

더보기
string[] ArrayToFieldNames(object containingClassWithArray, object[] array)
{
    var fields = containingClassWithArray.GetType().GetFields();
    var fieldNames = System.Array.ConvertAll(array, x => fields.First(field => field.GetValue(containingClassWithArray) == x).Name);
    return fieldNames;
}

/* 
예시 

public class Coordinator : MonoBehaviour
{
    public BodyPart head;
    public BodyPart top;
    public BodyPart bottom;
    public BodyPart gloves;
    public BodyPart shoes;

    public BodyPart hair;
    public BodyPart eye;
    public BodyPart skin;
    public BodyPart[] bodyParts
    {
        get
        {
            return new BodyPart[] { head, top, bottom, gloves, shoes, hair, eye, skin };
        }
    }
}
이렇게 있을때

var bodyPartNames = ArrayToFieldNames(coordinator, coordinator.bodyParts);
Debug.Log(string.Join(",",bodyPartNames));
하면 head,top,bottom,gloves,shoes,hair,eye,skin로 나온다
*/

 

 

 

 

v2

v1과 구조상으로는 동일한데 클래스내부로 넣어버렸다.

이게 더 편함


string[] ArrayToFieldNames(object[] array)
{
    var fields = GetType().GetFields();
    var fieldNames = System.Array.ConvertAll(array, x => fields.First(field => field.GetValue(this) == x).Name);
    return fieldNames;
}
/*
//샘플
    public BodyPart head;
    public BodyPart top;
    public BodyPart bottom;
    public BodyPart gloves;
    public BodyPart shoes;

    public BodyPart hair;
    public BodyPart eye;
    public BodyPart skin;
    public BodyPart[] bodyParts
    {
        get
        {
            return new BodyPart[] { head, top, bottom, gloves, shoes, hair, eye, skin };
        }
    }
    public string[] bodyPartNames
    {
        get
        {
            return ArrayToFieldNames(bodyParts);
        }
    }
*/

근데 이방법 쓸바엔 그냥 클래스 안에 name값 넣어서 써라

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

MapBorder  (0) 2020.12.24
그래디언트효과  (0) 2020.10.20
유니티 에디터 관련  (0) 2020.10.05
posted by 모카쨩
2020. 10. 20. 16:51

보호되어 있는 글입니다.
내용을 보시려면 비밀번호를 입력하세요.

2020. 10. 5. 11:00 Unity/C#

 

gui색을 노란색으로 바꿈

GUILayout도 적용됨

GUI.backgroundColor = Color.yellow;
{
    GUILayout.Box(nameof(gameclass.name), GUILayout.Width(50), GUILayout.Height(50));
}
GUI.backgroundColor = Color.white;

 

 

가로전환

GUILayout.BeginHorizontal();
{
}
GUILayout.EndHorizontal();

 

스크롤뷰(슬라이더)

Vector2 scrollPosition=Vector2.zero;
void OnGUI()
{
    //scrollPosition=GUILayout.BeginScrollView(scrollPosition, GUILayout.ExpandWidth(true), GUILayout.ExpandHeight(true));
    scrollPosition=GUILayout.BeginScrollView(scrollPosition);
    { 
    }
    GUILayout.EndScrollView();
}

 

스크롤뷰(슬라이더) v2 (미완성)

Vector2 scrollPosition=Vector2.zero;
void OnGUI()
{
    scrollPosition = GUI.BeginScrollView(new Rect(0, 0, position.width, position.height), scrollPosition, new Rect(0, 0, width:500, height:800));
    {
    }
    GUI.EndScrollView();
}

 

 

 

 

 

마우스 대면 바뀌는 주석

        if (Event.current.type == EventType.Repaint && GUILayoutUtility.GetLastRect().Contains(Event.current.mousePosition))
            GUILayout.Label("Mouse over!");
        else
            GUILayout.Label("Mouse somewhere else");

 

버튼

if(GUILayout.Button("버튼"))
{

}

 

 

 

왼쪽으로 밀린 박스


    var Texture2D = new Texture2D(1, 1);//삭제가 안되어 메모리릭을 유발하므로 전역에 생성해 두어야함


{ 
    BoxBG.SetPixels(0,0,1,1, new Color[]{ Color.gray});
    BoxBG.Apply();

    var guiStyle = new GUIStyle();
    guiStyle.alignment = TextAnchor.UpperLeft;
    guiStyle.richText = true;
    guiStyle.normal.background = BoxBG;

    GUILayout.Box("내용",guiStyle);
}

 

 

 

인스펙터 변동사항이 있는지 검사한다

겸 드롭다운 샘플

EditorGUI.BeginChangeCheck();
{
    index = EditorGUILayout.Popup("Index", index, new string[] { "1", "2" });
}
if (EditorGUI.EndChangeCheck())
{
    Debug.Log("index값이 변경됨");
}

 

 

들여쓰기

EditorGUILayout계열만 적용됨

GUILayout은 안됨

EditorGUI.indentLevel++;
{


}
EditorGUI.indentLevel--;

 

 

 

스크립트오브젝트저장

//더티플래그

EditorUtility.SetDirty(scriptableObject);
var filePath = AssetDatabase.GetAssetPath(scriptableObject);
Debug.Log($"scriptableObject 저장됨, filePath: {filePath}");
//AssetDatabase.SaveAssets(); //이건 딱히 안 넣어도 되는듯

 

 

 

패스 에디터

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

#if UNITY_EDITOR
using UnityEditor;
[CustomEditor(typeof(PayloadRace))]
public class PayloadRaceEditor : Editor
{
    private Vector3 position = Vector3.zero;

    void OnSceneGUI()
    {
        var payloadRace = (PayloadRace)target;
        var tracksParent = payloadRace.tracksParent;
        if (tracksParent)
        {
            var childs = new List<Transform>();
            for (int i = 0; i < tracksParent.childCount; i++)
            {
                childs.Add(tracksParent.GetChild(i));
            }
            foreach (var child in childs)
            {
                if (Vector3.Distance(payloadRace.transform.position, child.position) < 1)
                {
                    //너무 가까우면 최상위 조작이 불가하므로
                    continue;
                }
                var newPosition = UnityEditor.Handles.PositionHandle(child.position, child.rotation);
                if (newPosition != child.position)
                {
                    UnityEditor.Undo.RecordObject(child, "Move Transform");
                    child.position = newPosition;
                }
            }
        }
    }
}
#endif
public class PayloadRace : MonoBehaviour
{
    public int team = 0;
    public GameObject payload;
    public Transform tracksParent;
#if UNITY_EDITOR_WIN
    void OnDrawGizmos()
    {
        var color = Color.red;
        if (team == 0)
        {
            color = Color.blue;
        }
        Gizmos.color = color;
        {
            Gizmos.DrawWireSphere(transform.position,5);
        }
        Gizmos.color = Color.white;

        if (tracksParent)
        {
            var childs = new List<Transform>();
            for (int i = 0; i < tracksParent.childCount; i++)
            {
                childs.Add(tracksParent.GetChild(i));
            }
            foreach (var child in childs)
            {
                Gizmos.DrawSphere(child.position,0.1f);
                if (Vector3.Distance(transform.position, child.position)<1)
                {
                    continue;
                }
            }
            for (int i = 0; i < childs.Count-1; i++)
            {
                Gizmos.DrawLine(childs[i].position, childs[i + 1].position);
            }
        }
    }
#endif
    // Start is called before the first frame update
    void Start()
    {
        
    }

    // Update is called once per frame
    void Update()
    {
        
    }
}

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

그래디언트효과  (0) 2020.10.20
failed to connect to localhost port 80: Connection  (0) 2020.09.01
c# MD5  (0) 2020.08.25
posted by 모카쨩
2020. 9. 1. 12:36 Unity/C#

 

 

파일 주소앞에 file:///를 넣는다

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

유니티 에디터 관련  (0) 2020.10.05
c# MD5  (0) 2020.08.25
UnityWebRequest  (0) 2020.08.20
posted by 모카쨩
2020. 8. 25. 17:17 Unity/C#

v1

    public string GetMD5(byte[] data)
    {
        System.Text.StringBuilder sb = new System.Text.StringBuilder();
        byte[] hash = System.Security.Cryptography.MD5.Create().ComputeHash(data);
        foreach (byte b in hash)
        {
            sb.Append(b.ToString("X2"));
        }
        return sb.ToString();
    }

 

 

v2

public string GetMD5(byte[] data)
{
    byte[] bytes = System.Security.Cryptography.MD5.Create().ComputeHash(data);
    return System.BitConverter.ToString(bytes).Replace("-", "");
}

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

failed to connect to localhost port 80: Connection  (0) 2020.09.01
UnityWebRequest  (0) 2020.08.20
형변환 모음  (0) 2020.08.11
posted by 모카쨩
2020. 8. 20. 15:54 Unity/C#

파일을 다운로드

    public string url;
    public string fileName;
    public string fileType;
    IEnumerator DownloadFile()
    {
        string filePath= $"{Application.persistentDataPath}/{fileName}";
        if( (fileType != null)&& (fileType.Trim() != "") )
        {
            filePath += $".{fileType}";
        }
        UnityWebRequest unityWebRequest = UnityWebRequest.Get(url);
        yield return unityWebRequest.SendWebRequest();
        if (unityWebRequest.isNetworkError)
        {
            Debug.LogError(unityWebRequest.error);
        }
        else
        {
            File.WriteAllBytes(filePath, unityWebRequest.downloadHandler.data);
        }
    }

 

 

V2




    /// <summary>
    /// 다운 다되면 파일경로를 반환
    /// </summary>
    /// <param name="downloadlink"></param>
    /// <param name="filePath"></param>
    /// <returns></returns>
    IEnumerator DownloadFile(string downloadlink, string filePath)
    {
        Debug.Log($"Download:{downloadlink}");
        {
            DOWNLOAD_RETRY:;
            {
                var unityWebRequest = UnityWebRequest.Get(downloadlink);
                var operation = unityWebRequest.SendWebRequest();
                yield return new WaitUntil(() => operation.isDone);

                if (unityWebRequest.isNetworkError)
                {
                    Debug.LogError(unityWebRequest.error);
                    yield return new WaitForSeconds(3f);
                    goto DOWNLOAD_RETRY;
                }
                else
                {
                    Debug.Log(filePath);

                    var folderPath = System.IO.Path.GetDirectoryName(filePath);
                    Debug.Log(folderPath);
                    if (System.IO.Directory.Exists(folderPath) == false)//폴더가 없으면 생성
                    {
                        System.IO.Directory.CreateDirectory(folderPath);
                    }
                    System.IO.File.WriteAllBytes(filePath, unityWebRequest.downloadHandler.data);
                }
            }
        }
        yield return filePath;
    }

 

 

 

 

 

DownloadHandlerFile 방식 

메모리를 딱 필요한만큼만 쓴다. 위에는 2배사용

V3



    List<string> downloadList = new List<string>();
    IEnumerator DownloadFile(string downloadlink, string filePath)
    {
        downloadList.Add(downloadlink);

        DOWNLOADRETRY:;
        {
            UnityWebRequest unityWebRequest = UnityWebRequest.Get(downloadlink);
            unityWebRequest.downloadHandler = new DownloadHandlerFile(filePath);

            var operation = unityWebRequest.SendWebRequest();
            yield return new WaitUntil(() => operation.isDone);

            if (unityWebRequest.isNetworkError)
            {
                Debug.LogError(unityWebRequest.error);
                yield return new WaitForSeconds(1f);
                goto DOWNLOADRETRY;
            }
            else
            {
                Debug.Log(filePath);
            }
        }
        downloadList.Remove(downloadlink);
    }

 

V1~V2

더보기
    IEnumerator DownloadFile(string downloadlink, string filePath)
    {
        UnityWebRequest unityWebRequest = UnityWebRequest.Get(downloadlink);
        unityWebRequest.downloadHandler = new DownloadHandlerFile(filePath);
        var operation = unityWebRequest.SendWebRequest();
        while (!operation.isDone)
        {
            yield return new WaitForSeconds(0.01f);
        }
        if (unityWebRequest.isNetworkError)
        {
            Debug.LogError(unityWebRequest.error);
        }
        else
        {
            Debug.Log(filePath);
        }
    }

 

 

 

V2

List<String> DownloadList = new List<String>();
    IEnumerator DownloadFile(string downloadlink, string filePath)
    {
        UnityWebRequest unityWebRequest = UnityWebRequest.Get(downloadlink);
        unityWebRequest.downloadHandler = new DownloadHandlerFile(filePath);

        DownloadList.Add(downloadlink);
        DOWNLOADRETRY:;
        var operation = unityWebRequest.SendWebRequest();
        while (!operation.isDone)
        {
            yield return new WaitForSeconds(0.01f);
        }
        if (unityWebRequest.isNetworkError)
        {
            Debug.LogError(unityWebRequest.error);
            yield return new WaitForSeconds(1f);
            goto DOWNLOADRETRY;
        }
        else
        {
            Debug.Log(filePath);
        }
        DownloadList.RemoveAt(DownloadList.FindIndex(0, DownloadList.Count, x => x == downloadlink));
    }

 

 

 

 

 

 

HTML 다운로드

    public string urlSample= "https://wmmu.tistory.com/";
    IEnumerator DownloadHTML(string url)
    {
        UnityWebRequest unityWebRequest;
        unityWebRequest = UnityWebRequest.Get(url);
        yield return unityWebRequest.SendWebRequest();
        if (unityWebRequest.isNetworkError)
        {
            Debug.LogError(unityWebRequest.error);
        }
        else
        {
            Debug.Log(unityWebRequest.downloadHandler.text);
        }
    }

 

 

 

오디오 파일 로드

//전용 세이브 폴더 참조시에는
//$"file://{UnityEngine.Application.persistentDataPath}/Audio.mp3";
static AudioClip LoadAudioClip(string downloadLink)
{
    var fileName= downloadLink;
    if (System.IO.File.Exists(downloadLink))
    {
        downloadLink = $"file://{downloadLink}";
        fileName = System.IO.Path.GetFileNameWithoutExtension(downloadLink);
    }
    UnityWebRequest unityWebRequest = UnityWebRequestMultimedia.GetAudioClip(downloadLink, AudioType.UNKNOWN);

    var operation = unityWebRequest.SendWebRequest();
    while (!operation.isDone)
    {
        Thread.Sleep(1);
    }
    if (unityWebRequest.isNetworkError)
    {
        Debug.LogError(unityWebRequest.error);
    }
    else
    {
        //Debug.Log("LoadAudioClipSuccess");
    }
    var clip = DownloadHandlerAudioClip.GetContent(unityWebRequest);
    clip.name = fileName;
    return clip;
}

 

 

 

 

캐시 테스트

    public string url;
    public string cookie;
    public string fileName;
    public string fileType;
    IEnumerator DownloadFile()
    {
        string filePath = $"{Application.persistentDataPath}/{fileName}";
        if ((fileType != null) && (fileType.Trim() != ""))
        {
            filePath += $".{fileType}";
        }
        UnityWebRequest unityWebRequest = UnityWebRequest.Get(url);
        if (string.IsNullOrWhiteSpace(cookie)==false)
        {
            unityWebRequest.SetRequestHeader("Cookie", cookie);
        }
        yield return unityWebRequest.SendWebRequest();
        if (unityWebRequest.isNetworkError)
        {
            Debug.LogError(unityWebRequest.error);
        }
        else
        {
            Debug.Log(unityWebRequest.downloadHandler.text);
            //File.WriteAllBytes(filePath, unityWebRequest.downloadHandler.data);
        }
    }
    // Start is called before the first frame update
    void Start()
    {
        StartCoroutine(DownloadFile());
    }

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

c# MD5  (0) 2020.08.25
형변환 모음  (0) 2020.08.11
유니티 씬 계열 함수 모음  (0) 2020.07.30
posted by 모카쨩

  • total
  • today
  • yesterday

Recent Post

저사양 유저용 블로그 진입