[유니티 C#] 확장 메소드

YongSeok·2022년 10월 6일
0

📌확장 메소드란?

  • 확장 메소드는 기존 클래스의 기능을 확장하는 기법
  • 우리가 아는 상식에서 메소드를 추가하려면 해당 클래스의 정의 부분에 메소드를 추가해야 한다.
  • 확장 메소드는 다른 클래스의 인스턴스 메소드를 추가할 수 있는 기능
  • 클래스 자체의 내용을 수정할 수 없고, 외부에서 그 클래스에 기능을 추가하고 싶을 때 사용한다.
  • 나만이 쓸수 있는 작은 라이브러리

✏️왜 필요한가?

  • 프로그래밍을 하다보면 카메라를 흔들어 특수효과를 주고싶을 때 우리가 직접 구현하기 위해 함수를 만들고 카메라에다 매게변수에 넣고 해야한다

  • 만약 이 기능 자체가 카메라 컴포넌트 자체에 들어 있으면 되지 않을까??

  • 함수로서 구현하기에는 일일히 구현해야하기에 버거울때 확장메소드를 사용하면 편리하다


✏️ 확장메소드 사용법

  1. ExtensionMethod 스크립트를 하나만들어준다
  2. ExtensionMethod 스크립트의 Monobehavior 는 삭제해준다
  3. 모든곳에서 참조해야하기에 static을 붙혀준다
  4. static 클래스는 모두 static 이여야하기에 모든 멤버들에게 static을 붙혀준다
  5. public static 리턴타입 확장메소드이름(this 확장하고싶은 데이터타입 value, 매게변수.....) 과 같은 형태로 코드를 작성해준다.

✏️ 코드 예제 1

using System.Collections;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using UnityEngine;

public static class ExtensionMethod
{
    // public static 리턴타입 확장메서드이름(this 확장하고싶은데이터타입 value, 매게변수...)

    public static bool IsBetween(this float value, float min, float max)
    {
        return value > min && value < max;
    }
}

☝ 확장하고싶은 기능을 만들경우에는 이곳 활용

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

public class GameManager : MonoBehaviour
{
    float min = 0;
    float max = 30;

    private void Start()
    {
        if(!transform.position.x.IsBetween(min,max))
        {
            Destroy(gameObject);
        }
    }
}

☝ 확장한 메소드를 사용하는 방식 (오브젝트의 x값이 min,max 사이에 존재하지 않으면 오브젝트를 삭제하는 코드)

  • 위의 예시와 같이 float 데이터타입을 가진 모든변수들은 IsBetween 함수를 사용할 수 있을것이다

✏️ 코드 예제 2-1

using System.Collections;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using UnityEngine;

public static class ExtensionMethod
{
    // public static 리턴타입 확장메서드이름(this 확장하고싶은데이터타입 value, 매게변수...)

    public static Color ColorChange(this Renderer temp)
    {
        return temp.material.color = Color.red;
    }
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class GameManager : MonoBehaviour
{
    private void Start()
    {
        Renderer obj = GetComponent<Renderer>();
        obj.material.color = obj.ColorChange();
    }
}

☝ 시작시 오브젝트는 빨간색큐브로 시작한다

✏️ 코드 예제 2-2

using System.Collections;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using UnityEngine;

public static class ExtensionMethod
{
    public static void PrintData(this string str)
    {
        Debug.Log(str);
    }
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class GameManager : MonoBehaviour
{
    private void Start()
    {
        string str = "안녕하세요, 날씨가 참 좋죠?";
        str.PrintData();
    }
}

☝ 시작시 원하는 텍스트를 Debug.Log에 출력시켜준다

  • 방금 본 예제들은 모두 같은 틀을 가지고있으며 안에 코드 내용만 바꾸어 기능을 바꾸어주었다
  • 이처럼 기본적인 형태안에서도 다양한 기능들을 수정하여 프로그래밍을 더 효율적으로 진행할 수 있다.

public static class ExtensionMethod
{
	// public 
}
// 편집할수 없는 녀석들을 위해서 기능을 추가하기 위해 확장 메소드를 붙혀준다
// 예를들어 float 자료형 자체한테 기능을 붙혀주고 싶을때 확장 메소드를 만들어 주면
// float 에 내가만든 함수가 생긴다..!!!

// 확장 메소드를 잘쓰면?? 가독성이 올라간다
// 함수를 한번 거친다는 것은 오버헤드가 증가한다는것을 의미
// 그러나 요즘은 가독성을 올리는 편이 더 이득인 트렌드이기 때문
// float 타입 뿐 아니라 gameObject 등 모든 클래스에 붙힐 수 있다
// 유의해야 할 점 ???? 만약에 내가 의미없는 확장메소드를 만들었다 치자

public static void ChagneValue(this float value, float input)
{
	value = input;
}
float test = 10;
void Start()
{
	test = 10;
    test.ChangeValue(50);
    Debug.Log(test);
}

바뀌지 않는다 왜????

// float 은 구조체 = 스택영역 = 깊은복사 = 값을 그대로 복사해서
// 클래스는 = 힙영역 = 얕은복사
// 참고) string 은 class 이지만 깊은복사가 일어난다

만약 이렇게 했을때 값을 바꾸고싶으면??
ref 라는 키워드를 사용해보자

0개의 댓글