Get it on Google Play


Wm뮤 :: c# 기본 문법

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

Recent Comment

Archive


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

저사양 유저용 블로그 진입