본문 바로가기
개발/Unity

유니티 C# - 튜플로 여러 값 반환하기 (Returning Multiple Values Using Tuple)

by 피로물든딸기 2022. 10. 7.
반응형

Unity 전체 링크

 

참고

- C++ 튜플로 여러 값 반환하기

 

여러 개의 값을 리턴 받고 싶은 경우가 있다.

배열을 이용하면 아래와 같이 사용할 수 있다.

    public int[] returnArray()
    {
        int[] array = new int[3];

        array[0] = 0; array[1] = 1; array[2] = 2;

        return array;
    }

    void Start()
    {
        int[] arr = returnArray();
        foreach (int a in arr) Debug.Log(a); // 0 1 2
    }

 

하지만 전혀 다른 타입의 여러 변수를 return 받고 싶은 경우는 배열을 사용할 수 없다.

ref나  out을 쓰면 함수가 길어져 보기 싫어진다.

구조체를 선언해서 리턴하는 방법도 있지만,

다른 스크립트에서 참조하지 않는다면 잘 사용하지 않는 불필요한 구조체가 늘어날 수 있다.

 

이 경우에는 튜플을 이용하면 편리하다.


튜플의 초기화

 

튜플은 아래와 같이 초기화할 수 있다.

(float, int) tuple1 = (1.1f, 2);

 

변수의 이름을 정하지 않은 경우는 Items1, 2, 3, ...으로 변수에 접근한다.

// 이름이 없다면 Item으로 접근
Debug.Log(tuple1.Item1); // 1.1
Debug.Log(tuple1.Item2); // 2

 

자바스크립트에는 구조 분해 할당(Destructuring Assignment)라는 문법이 있는데 아래와 같이 사용할 수 있다.

let a = [1.1, 2];
let c, d;
[c, d] = a;

console.log(c); // 1.1
console.log(d); // 2

 

구조 분해 할당을 C#에서는 튜플(Tuple)로 표현할 수 있다.

위에 선언한 tuple1을 아래와 같이 사용하면 변수 f와 i에 알맞은 값이 들어간다.

(float f, int i) = tuple1;

Debug.Log(f); // 1.1
Debug.Log(i); // 2

 

두번째 초기화 방법은 변수를 선언해주는 방법이다.

(float fValue, int iValue) tuple2 = (2.2f, 3); // 변수 선언

 

이름을 정의해줬으므로 dot(.)으로 접근할 수 있다.

//이름이 정의된 경우
Debug.Log(tuple2.fValue); // 2.2
Debug.Log(tuple2.iValue); // 3

 

세번째 방법은 명시적 선언이다. 

변수명의 접근 방법은 위와 같다.

var tuple3 = (val1: 3.3f, val2: 4, val3: "string"); // 명시적 변수 지정

 

마지막으로, 아래와 같이 다른 변수를 이용해 튜플을 만드는 것도 가능하다.

string str = "tuple";
Vector3 pos = Vector3.zero;

var tuple4 = (str, position: pos);

튜플 반환

 

이제 튜플로 여러 변수를 한꺼번에 return 해보자.

 

튜플을 반환하는 함수는 아래와 같이 만들 수 있다.

public (Vector3 currentPosition, int mass, float temp) returnVariables1()
{
    Vector3 curPos = this.transform.position; // (0, 0, 0)
    int mass = 5;
    float temperature = 36.5f;

    return (curPos, mass, temperature);
}

 

사용방법은 다음과 같다. 

함수에서 선언한 이름 그대로 currentPosition, mass, temp를 사용할 수 있다.

var objInfo1 = returnVariables1(); 

Debug.Log(objInfo1); // ((0.00, 0.00, 0.00), 5, 36.5)
Debug.Log(objInfo1.currentPosition); 
Debug.Log(objInfo1.mass);
Debug.Log(objInfo1.temp);

 

튜플을 초기화할 때 이름을 생략한 것처럼 함수 반환도 마찬가지로 생략할 수 있다.

public (Vector3, int, float) returnVariables2()
{
    Vector3 curPos = this.transform.position; // (0, 0, 0)
    int mass = 5;
    float temperature = 36.5f;

    return (curPos, mass, temperature);
}

 

이 경우에는 Item1, 2, 3로만 접근이 가능하다.

var objInfo2 = returnVariables2();

Debug.Log(objInfo2); // ((0.00, 0.00, 0.00), 5, 36.5)
Debug.Log(objInfo2.Item1);
Debug.Log(objInfo2.Item2);
Debug.Log(objInfo2.Item3);

 

전체 코드는 다음과 같다.

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

public class Tuple : MonoBehaviour
{
    public (Vector3 currentPosition, int mass, float temp) returnVariables1()
    {
        Vector3 curPos = this.transform.position; // (0, 0, 0)
        int mass = 5;
        float temperature = 36.5f;

        return (curPos, mass, temperature);
    }

    public (Vector3, int, float) returnVariables2()
    {
        Vector3 curPos = this.transform.position; // (0, 0, 0)
        int mass = 5;
        float temperature = 36.5f;

        return (curPos, mass, temperature);
    }

    void Start()
    {
        // 튜플 초기화
        (float, int) tuple1 = (1.1f, 2);
        (float fValue, int iValue) tuple2 = (2.2f, 3); // 변수 선언
        var tuple3 = (val1: 3.3f, val2: 4, val3: "string"); // 명시적 변수 지정

        string str = "tuple";
        Vector3 pos = Vector3.zero;

        var tuple4 = (str, position: pos);

        // 이름이 없다면 Item으로 접근
        Debug.Log(tuple1.Item1); // 1.1
        Debug.Log(tuple1.Item2); // 2
        Debug.Log(tuple1.GetType());  


        // 구조 분해 할당 like javascript
        (float f, int i) = tuple1;

        Debug.Log(f); // 1.1
        Debug.Log(i); // 2

        //이름이 정의된 경우
        Debug.Log(tuple2.fValue); // 2.2
        Debug.Log(tuple2.iValue); // 3
        Debug.Log(tuple2.GetType());

        Debug.Log(tuple3.val1); // 3.3
        Debug.Log(tuple3.val2); // 4
        Debug.Log(tuple3.val3); // string
        Debug.Log(tuple3.GetType()); 

        Debug.Log(tuple4.str);
        Debug.Log(tuple4.position);
        Debug.Log(tuple4.GetType());

        var objInfo1 = returnVariables1(); 

        Debug.Log(objInfo1); // ((0.00, 0.00, 0.00), 5, 36.5)
        Debug.Log(objInfo1.currentPosition); 
        Debug.Log(objInfo1.mass);
        Debug.Log(objInfo1.temp);

        var objInfo2 = returnVariables2();

        Debug.Log(objInfo2); // ((0.00, 0.00, 0.00), 5, 36.5)
        Debug.Log(objInfo2.Item1);
        Debug.Log(objInfo2.Item2);
        Debug.Log(objInfo2.Item3);
    }
}

 

Unity Plus:

 

Easy 2D, 3D, VR, & AR software for cross-platform development of games and mobile apps. - Unity Store

Have a 2D, 3D, VR, or AR project that needs cross-platform functionality? We can help. Take a look at the easy-to-use Unity Plus real-time dev platform!

store.unity.com

 

Unity Pro:

 

Unity Pro

The complete solutions for professionals to create and operate.

unity.com

 

Unity 프리미엄 학습:

 

Unity Learn

Advance your Unity skills with live sessions and over 750 hours of on-demand learning content designed for creators at every skill level.

unity.com

반응형

댓글