Get it on Google Play


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

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

Recent Comment

Archive


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

  1. 2021.01.18 수학 Math
  2. 2021.01.17 화면관련
  3. 2021.01.15 c# 기본 문법
  4. 2020.12.24 MapBorder
  5. 2020.12.23 리플렉션
  6. 2020.10.20 그래디언트효과
  7. 2020.10.05 유니티 에디터 관련
  8. 2020.09.01 failed to connect to localhost port 80: Connection
2021. 1. 18. 16:35 Unity/C#

 

Xⁿ=Y 일때

n을 구하려면 log(Y) / log(X)                //로그
X를 구할려면 Sqrt(Y,n)                       //루트,제곱근, 여러개이면 거듭제곱근
Y를 구할려면 Pow(X,n) 혹은 Sqr(X,n)     //제곱,여러개이면 거듭제곱    

이상한 방법들

X를 구할때 보통을 sqrt를 써야하지만 인자를 1개만 받는 함수밖에 없을경우에
Pow(Y,1/n) //혹은 Sqr
이렇게 Pow를 써서 sqrt를 구할수도 있다
즉 Sqrt(x) = pow(x,1/2) 이다

 

Sqr계열

32의 5제곱근을 구할때

Sqr(32,1/5) //1은 고정숫자임

계산기 버전

 

 

 

 

log계열

 

//1024가 2의 몇승인지 구한다

Mathf.Log(1024,2)

다른버전

Mathf.Log(1024)/Mathf.Log(2)

계산기 버전

 

쓸모는 없지만

log(32)/5 = log(2)

이다

참고로 32는 2의 5제곱이다 즉

x^y=z일때

log(z)/y = log(x)

 

 

 

 

 

 

//npot를 최적의 2pot사이즈로 변경

wid=Mathf.Pow(2, Mathf.Round(Mathf.Log(texture.width, 2))));
hei=Mathf.Pow(2, Mathf.Round(Mathf.Log(texture.height, 2))));

/*
결과:
256->256
230->256
140->128
1031->1024
*/

 

 

 

 

원점에서의 거리

var len = sqrt(x*x + y*y);

 

 

x1,y1에서 x2,y2까지의 거리

 

 

 

 

 

 

 

Len과 dir을 이용하여 좌표를 구함

		public double d_set(double _Dir)
		{
			if(_Dir<0d)
			{
				_Dir=360d-((-_Dir)%360d);
			}
			if(_Dir>=360d)
			{
				return _Dir%360d;
			}
			return _Dir;
		}
		public double len_x(double _Len,double _Dir)
		{
			_Dir = d_set(_Dir);
			return _Len*Math.Cos(_Dir*Math.PI/180.0);
		}
        
		public double len_y(double _Len,double _Dir)
		{
			_Dir = d_set (_Dir);
			return _Len*Math.Sin(_Dir*Math.PI/180.0);
		}

 

 

pdir

x1,x2,y1,y2를 이용하여 각도를 구함

float2 center = 0.5;
float2 pos = i.uv.xy-center;
float2 dir  = ((atan2(pos.x,-pos.y)*2/3.14)/4+0.75)%1;

 

 

 

 

p1,p2,r,center를 이용하여 p3를 구하는 공식
챗GPT가 짜줬다

float2 FindIntersection(float2 p1, float2 p2, float R, float2 center)
{
    float2 dir = normalize(p2 - p1);
    float2 diff = p1 - center;

    // 원의 중심에서 선까지의 거리 d 계산
    float d = abs(diff.x * dir.y - diff.y * dir.x);

    // 만약 d가 R보다 크면 교점이 없음
    if (d >= R)
        return float2(0, 0);

    // L 계산: L = sqrt(R^2 - d^2)
    float L = sqrt(R * R - d * d);

    // 원의 중심에서 교점까지의 거리 h 계산: h = sqrt(R^2 - L^2)
    float h = sqrt(R * R - L * L);

    float2 midpoint = p1 + dot(center - p1, dir) * dir; // 선 위의 원의 중심에 수직인 점

    // 두 교점은 midpoint에서 ±L만큼 dir 방향으로 떨어져 있음
    float2 intersection1 = midpoint + L * dir;
    float2 intersection2 = midpoint - L * dir;

    // 이 예제에서는 두 교점 중 하나만 반환합니다.
    // 필요에 따라 두 교점 중 원하는 교점을 선택하여 반환하면 됩니다.
    return intersection1; 
}

 

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

코드 모음 사이트  (0) 2021.01.24
화면관련  (0) 2021.01.17
c# 기본 문법  (0) 2021.01.15
posted by 모카쨩
2021. 1. 17. 03:52 Unity/C#

 

 

 

 

모니터계열

public static Bitmap screenImg = new Bitmap(SystemInformation.VirtualScreen.Width
, SystemInformation.VirtualScreen.Height
, PixelFormat.Format32bppArgb);

public static Graphics graphicsScreenImg = Graphics.FromImage(screen_img);
//모니터 화면을 가져옴(전역변수에 담아둔다음 불러오는 형식)
public static System.Drawing.Bitmap GetScreen()
{
    graphicsScreenImg.CopyFromScreen(SystemInformation.VirtualScreen.X
        , SystemInformation.VirtualScreen.Y
        , 0
        , 0
        , SystemInformation.VirtualScreen.Size
        , CopyPixelOperation.SourceCopy);
    return screenImg;
}
//모니터화면을 가져옴(안정적이지만 호출시마다 메모리 사용량이 높음)
public static Bitmap GetScreenLS()
{

    Bitmap img = new Bitmap(SystemInformation.VirtualScreen.Width
            , SystemInformation.VirtualScreen.Height
            , PixelFormat.Format32bppArgb);

    Graphics graphics = Graphics.FromImage(img);
    graphics.CopyFromScreen(SystemInformation.VirtualScreen.X
        , SystemInformation.VirtualScreen.Y
        , 0
        , 0
        , SystemInformation.VirtualScreen.Size
        , CopyPixelOperation.SourceCopy);
    return img;
}
//모니터픽셀 가로
public static int GetScreenWidth()
{
    return SystemInformation.VirtualScreen.X;
}
//모니터픽셀 세로
public static int GetScreenHeight()
{
    return SystemInformation.VirtualScreen.Y;
}

 

 

 

2021년 기준 화면비

Z폴드2 (5:4)

Z플립3 (22:9)

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

수학 Math  (0) 2021.01.18
c# 기본 문법  (0) 2021.01.15
MapBorder  (0) 2020.12.24
posted by 모카쨩
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;
    }

}

 

 

위에거의 외부버전

https://gist.github.com/ahzkwid/69d7703736b5bca29b0131270ee9164a

static void CopyClass<T>(T source, T target)
{
    var fields = target.GetType().GetFields();
    foreach (var field in fields)
    {
        field.SetValue(target, field.GetValue(source));
    }
}

 

 

 

 

 

 

 

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값 넣어서 써라

 

 

 

 

 

 

 

 

 


var value = field.GetValue(component);
if (value==null)
{
    continue;
}

https://x.com/ahzkwid/status/1799549808312746276

 field.GetValue(component)을 ==null체크시 정상동작하지 않는 현상이 있는데

 

var value = field.GetValue(component);
if (value==null)
{
    continue;
}
if (value.Equals(null))
{
    continue;
}

이렇게 하면 된다

 

 

'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(); //이건 딱히 안 넣어도 되는듯

 

 

애니메이션 상태 저장

ImportAsset이 붙은 이유는 이래야 저장되더라

아마 위도 동일할듯 싶은데 나중에 해봐야지

https://github.com/ahzkwid/AhzkwidAvatarTools/blob/main/Assets/Ahzkwid/AvatarTools/CreatorTools/Editor/AnimationRepairTool.cs

여기서 사용함

UnityEditor.AssetDatabase.SaveAssetIfDirty(animationClip);
AssetDatabase.ImportAsset(AssetDatabase.GetAssetPath(animationClip));

 

 

 

 

 

패스 에디터

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 모카쨩

저사양 유저용 블로그 진입