반응형

UDP(User Datagram Protocol)는 TCP와 같이 IP에 기반한 전송 프로토콜이다.

TCP는 송수신 전에 반드시 서버-클라이언트 연결이 전제되어야 하는 반면, UDP는 별도의 연결이 필요없다.


유니티에서 UDP를 사용하기 위해서는 System.Net.Sockets 네임스페이스 안의 UdpClient 클래스Socket 클래스를 사용한다. TCP와 달리 UDP는 별도의 UDP 서버 클래스가 없으며, 서버도 UdpClient 클래스를 사용한다.

 

 

*UDP 클라이언트 구현

using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
using static System.Console;



(1) UdpClient 객체 성성

UDP 통신을 위해 System.Net.Sockets 네임스페이스의 UdpClient 객체를 생성한다. 데이터를 내보낼 때 서버와 포트가 필요한데, UdpClient 생성자에서 잡아주는 경우도 있지만, 만약 하나의 UdpClient 객체로 여러 서버에 데이터를 보낼 경우는 Send() 메서드에서 서버와 포트를 지정해준다. 

UdpClient cli = new UdpClient();



(2) 데이터 송신

UdpClient 객체의 Send() 메서드를 사용하여 데이터를  IP와 포트번호에 맞게 보낸다. 네트워크 데이터 송수신은 바이트 데이터를 사용하기 때문에, 문자열을 보낼 경우 먼저 바이트로 인코딩한 후 보내게 된다.

msg = "안녕하세요";
byte[] datagram = Encoding.UTF8.GetBytes(msg);
cli.Send(datagram, datagram.Length, "127.0.0.1", 7777);
WriteLine("[Send] 127.0.0.1:7777 로 {0} 바이트 전송", datagram.Length);



(3) 데이터 수신

UDP에서 데이타를 수신할 경우는 UdpClient 객체의 Receive() 메서드를 사용한다. Receive() 메서드는 특히 수신 데이타와 함께 상대 컴퓨터의 종단점(IP주소와 포트) 정보도 같이 전달받는데, 이를 위해 IPEndPoint 객체를 ref 파라미터로 전달한다. 이를 통해 데이타가 수신되면 누가 그 데이타를 전송했는지 알 수 있다. 

IPEndPoint epRemote = new IPEndPoint(IPAddress.Any, 0);
byte[] bytes = cli.Receive(ref epRemote);
WriteLine("[Receive] {0} 로부터 {1} 바이트 수신", epRemote.ToString(), bytes.Length);

 

 

(4) UdpClient 객체 닫기

마지막으로 UdpClient 객체를 닫는다.

cli.Close();

 

 

*UDP 서버 구현

 

UDP 서버는 포트를 열고 클라이언트로부터 들어오는 데이타그램을 수신하게 된다. 즉, UDP 서버는 통상 UDP 포트를 Listening하고 있으면서 루프 안에서 계속 데이타 송수신을 처리하는 형태로 구현된다. UDP 클라이언트로부터 데이타그램을 직접 받아 처리하면 된다. UDP 서버는 UDP 클라이언트와 같이 거의 동일한 기능을 갖기 때문에 별도의 UDP 서버 클래스가 없고 UdpClient 클래스를 사용한다.

using System;
using System.Net;
using System.Net.Sockets;

 

 

(1) UdpClient 객체 성성

UDP 클라이언트로부터 데이타를 받아들이기 위해 먼저 Listening할 포트를 지정하며 UdpClient 객체를 생성한다.

// 포트 7777 에서 Listening
UdpClient srv = new UdpClient(7777);



(2) 데이터 수신

UDP 에서 데이타를 수신하기 위해 UdpClient 객체의 Receive() 메서드를 사용한다. Receive() 메서드는 특히 수신 데이타와 함께 상대 UDP 클라이언트 종단점(IP주소와 포트) 정보도 같이 전달받는데, 이를 위해 IPEndPoint 객체를 ref 파라미터로 전달한다. 데이타 수신 후, ref 파라미터를 체크하면 데이타를 보낸 UDP 클라이언트의 IP 주소와 포트를 알 수 있다.

// 클라이언트 IP를 담을 변수
IPEndPoint remoteEP = new IPEndPoint(IPAddress.Any, 0);

while(true) {
    byte[] dgram = srv.Receive(ref remoteEP);
    Console.WriteLine("[Receive] {0} 로부터 {1} 바이트 수신", remoteEP.ToString(), dgram.Length);
}

 

 

(3) 데이타 송신

UdpClient 객체의 Send() 메서드를 사용하여 데이타를 UDP 클라이언트로 전달한다. 이 때 클라이언트 IP는 위의 Receive() 메서드에서 받아온 IP 주소를 사용한다.

srv.Send(dgram, dgram.Length, remoteEP);
Console.WriteLine("[Send] {0} 로 {1} 바이트 송신", remoteEP.ToString(), dgram.Length);

 

 

*샘플 스크립트

 

udp_connector.cs

using System;
using System.Collections;
using System.Collections.Generic;
using System.Net;
using System.Net.NetworkInformation;
using System.Net.Sockets;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.Networking;
using UnityEngine.UI;


public class UDPConnector : MonoBehaviour {
    UdpClient ReceivePort, SendPort;
    IPEndPoint remoteEndPoint;

    public class MyUDPEvent : UnityEvent<string> { }
    public MyUDPEvent OnReceiveMessage = new MyUDPEvent ();


    void Start () {
        OnReceiveMessage.AddListener (receiveMsg);
    }

    void Init () {
        ReceivePort = new UdpClient (Int32.Parse (IF_ReceivePort.text));
        ReceivePort.BeginReceive (OnReceive, null);
        Send ();
    }

    public void Send (string msg = "receive from Unity") {
        SendPort = new UdpClient ();

        string remoteIP = IF_SendIP.text;
        int remotePort = Int32.Parse (IF_SendPort.text);
        remoteEndPoint = new IPEndPoint (IPAddress.Parse (remoteIP), remotePort);

        byte[] data = System.Text.Encoding.UTF8.GetBytes (msg);
        SendPort.Send (data, data.Length, remoteEndPoint);
    }

    void OnReceive (IAsyncResult ar) {
        try {
            IPEndPoint ipEndPoint = null;
            byte[] data = ReceivePort.EndReceive (ar, ref ipEndPoint);
            message = System.Text.Encoding.UTF8.GetString (data);
        } catch (SocketException e) { }

        ReceivePort.BeginReceive (OnReceive, null);
    }

    void receiveMsg (string msg) {
        Txt_Message.text = Txt_Message.text + msg + "\n";
        // Debug.Log(message);
    }

    void Update () {
        OnReceiveMessage.Invoke (message);
    }

    public void ShutDown () {
        OnReceiveMessage.RemoveAllListeners ();
        if (ReceivePort != null)
            ReceivePort.Close ();
        if (SendPort != null)
            SendPort.Close ();
        ReceivePort = null;
        SendPort = null;
    }
}

 

communication_handler.cs

public class CommunicationHandler : MonoBehaviour {
    public UDPConnector UDP;

    void Start () {
        UDP.OnReceiveMessage.AddListener (ReceiveMsg);
    }

    void ReceiveMsg (string msg) {
    
    }

    public void SendMsg (string msg) {
        UDP.Send (msg);
    }

    void OnApplicationQuit () {
        UDP.ShutDown ();
    }
}

 

반응형

'unity C#' 카테고리의 다른 글

[Unity] Tetris 게임 만들기  (1) 2021.06.25
[Unity] 스도쿠게임 만들기  (0) 2021.06.15
[Unity] Partial class  (0) 2021.05.04
[Unity] Sprite Atlas  (0) 2021.04.13
[Unity] vscode .net framework C# 에러문제  (1) 2020.08.28
반응형

거대해진 클래스를 쪼갤 수 있는 방법

코드를 작성하다보면 몇백줄? 몇천줄? 이상 되는 클래스를 만들때가 있는데 이를 쪼개서 관리하기 편하도록 하는 기능이다.

참조1, 참조2 


터치핸들러를 만든다고 가정하고 예제를 작성해본다.

1. 터치 다운, 2. 드래그, 3. 터치 업 세가지 기능으로 만들어보았다.

 

TouchHandler.cs

using UnityEngine;
using UnityEngine.EventSystems;

public partial class TouchHandler : MonoBehaviour, IPointerDownHandler, IDragHandler, IPointerUpHandler
{
    Vector2 movedPos;

    void Start()
    {

    }

    void OnEnable()
    {

    }
    
    void Update()
    {

    }
}

 

TouchHandler.Down.cs

using UnityEngine.EventSystems;

public partial class TouchHandler
{
    public void OnPointerDown(PointerEventData e)
    {

    }
}

 

TouchHandler.Drag.cs

using UnityEngine.EventSystems;

public partial class TouchHandler
{
    public void OnDrag(PointerEventData e)
    {
        movedPos = e.pressPosition - e.position;
    }
}

 

TouchHandler.Up.cs

using UnityEngine.EventSystems;

public partial class TouchHandler
{
    public void OnPointerUp(PointerEventData e)
    {

    }
}

 

파일은 총 4개로 쪼개진 파일에 각 기능별로 구성을 만들면 빌드시에 알아서 하나의 파일로 합쳐주게 된다.

첫번째 파일에 movedPos라는 Variable을 만들게 되면 나머지 파일에서도 접근이 가능한데 결국 하나의 파일이라고 생각하면서 작업하면 된다.

 

끝.

반응형

'unity C#' 카테고리의 다른 글

[Unity] 스도쿠게임 만들기  (0) 2021.06.15
[Unity] UDP 통신  (0) 2021.05.04
[Unity] Sprite Atlas  (0) 2021.04.13
[Unity] vscode .net framework C# 에러문제  (1) 2020.08.28
[Unity] EventSystem설정 터치 감도 조절  (0) 2020.06.30
반응형

출처 : skuld2000.tistory.com/28

 

[Unity] 이제 Sprite Packer 는 그만. Sprite Atlas 를 사용하자.

유니티에서 아틀라스(Atlas) 는 여러 개의 스프라이트(Sprite)를 한 장의 큰 텍스쳐에 모아놓은 것이라고 볼 수 있다. 게임에는 UI와 배경, 캐릭터, 이펙트 등등에 수많은 텍스쳐 들이 사용되는데 각

skuld2000.tistory.com

사용 방법은 매우매우 간단하다고는 하지만 ...

개인적으로는 예전 방식이 더 괜찮았던 것 같다.

한꺼번에 선택하고 패킹태그만 붙이면되는데...

바뀐 방식은 일일이 하나씩 혹은 여러개 선택해서

넣어 줘야 하는 번거로움?이 좀 있다고 생각하던 중

폴더째 드래그 해서 넣어도 된다고 한다.

결론은 좋아진게 확실하니 한번 써보자.

 

📌사용방법

👉 Sprite Atlas 생성

 

👉 Sprite 옵션 설정

 

👉 Tight Packing을 할 경우에 가장자리 투명도가 있는 이미지의 여백을 무시하고 합쳐주기 때문에 문제가 생길 수가 있다. 문제가 되는 이미지는 해당 이미지 파일을 선택하여 FullRect옵션으로 바꿔주고 Apply 눌러주면 간단히 해결된다.

다른 방법으로는 Sprite Editor를 사용해 커스텀라인을 만들고 Use Sprite Mesh옵션을 켜서 해당 이미지가 그려 질 때 커스텀라인 안쪽으로만 그려주게 하는 방법도 있지만 몇장 안되는 이미지라면 큰 차이가 없어보인다. 자세한 건 링크를 확인하자.

 

👉 일단 아틀라스로 묶어놓게 되면 타겟플랫폼별 이미지 옵션을 설정할 때 한방에 처리할 수 있다.

 

👉 무엇보다 큰 장점이라고 하면 위에 보이는것 처럼 폴더째로 넣어줘도 된다는게 맘에 든다.

 

끝.

반응형

'unity C#' 카테고리의 다른 글

[Unity] UDP 통신  (0) 2021.05.04
[Unity] Partial class  (0) 2021.05.04
[Unity] vscode .net framework C# 에러문제  (1) 2020.08.28
[Unity] EventSystem설정 터치 감도 조절  (0) 2020.06.30
[Unity] Animation Curve DOTween 커스터마이징  (0) 2020.06.29
반응형

[info]: OmniSharp.Stdio.Host
        Starting OmniSharp on MacOS 10.15.6 (x64)
[info]: OmniSharp.Services.DotNetCliService
        DotNetPath set to dotnet
[info]: OmniSharp.MSBuild.Discovery.MSBuildLocator
        Located 1 MSBuild instance(s)
            1: StandAlone 16.8.0 - "/Users/jangbeom-seok/.vscode/extensions/ms-dotnettools.csharp-1.23.1/.omnisharp/1.37.0/omnisharp/.msbuild/Current/Bin"
[info]: OmniSharp.MSBuild.Discovery.MSBuildLocator
        MSBUILD_EXE_PATH environment variable set to '/Users/jangbeom-seok/.vscode/extensions/ms-dotnettools.csharp-1.23.1/.omnisharp/1.37.0/omnisharp/.msbuild/Current/Bin/MSBuild.exe'
[info]: OmniSharp.MSBuild.Discovery.MSBuildLocator
        Registered MSBuild instance: StandAlone 16.8.0 - "/Users/jangbeom-seok/.vscode/extensions/ms-dotnettools.csharp-1.23.1/.omnisharp/1.37.0/omnisharp/.msbuild/Current/Bin"
            CscToolExe = csc.exe
            MSBuildToolsPath = /Users/jangbeom-seok/.vscode/extensions/ms-dotnettools.csharp-1.23.1/.omnisharp/1.37.0/omnisharp/.msbuild/Current/Bin
            CscToolPath = /Users/jangbeom-seok/.vscode/extensions/ms-dotnettools.csharp-1.23.1/.omnisharp/1.37.0/omnisharp/.msbuild/Current/Bin/Roslyn
            BypassFrameworkInstallChecks = true
            MSBuildExtensionsPath = /Users/jangbeom-seok/.vscode/extensions/ms-dotnettools.csharp-1.23.1/.omnisharp/1.37.0/omnisharp/.msbuild
[info]: OmniSharp.Cake.CakeProjectSystem
        Detecting Cake files in '/Users/jangbeom-seok/Desktop/Project/Project_Owao/Owao_IOS'.
[info]: OmniSharp.Cake.CakeProjectSystem
        Could not find any Cake files
[info]: OmniSharp.MSBuild.ProjectSystem
        Detecting projects in '/Users/jangbeom-seok/Desktop/Project/Project_Owao/Owao_IOS/Owao_IOS.sln'.
[info]: OmniSharp.MSBuild.ProjectManager
        Queue project update for '/Users/jangbeom-seok/Desktop/Project/Project_Owao/Owao_IOS/Assembly-CSharp.csproj'
[info]: OmniSharp.MSBuild.ProjectManager
        Queue project update for '/Users/jangbeom-seok/Desktop/Project/Project_Owao/Owao_IOS/Assembly-CSharp-firstpass.csproj'
[info]: OmniSharp.MSBuild.ProjectManager
        Queue project update for '/Users/jangbeom-seok/Desktop/Project/Project_Owao/Owao_IOS/Assembly-CSharp-Editor.csproj'
[info]: OmniSharp.MSBuild.ProjectManager
        Queue project update for '/Users/jangbeom-seok/Desktop/Project/Project_Owao/Owao_IOS/Assembly-CSharp-Editor-firstpass.csproj'
[info]: OmniSharp.Script.ScriptProjectSystem
        Detecting CSX files in '/Users/jangbeom-seok/Desktop/Project/Project_Owao/Owao_IOS'.
[info]: OmniSharp.Script.ScriptProjectSystem
        Could not find any CSX files
[info]: OmniSharp.WorkspaceInitializer
        Invoking Workspace Options Provider: OmniSharp.Roslyn.CSharp.Services.CSharpFormattingWorkspaceOptionsProvider, Order: 0
[info]: OmniSharp.MSBuild.ProjectManager
        Loading project: /Users/jangbeom-seok/Desktop/Project/Project_Owao/Owao_IOS/Assembly-CSharp.csproj
[info]: OmniSharp.WorkspaceInitializer
        Invoking Workspace Options Provider: OmniSharp.Roslyn.CSharp.Services.RenameWorkspaceOptionsProvider, Order: 100
[info]: OmniSharp.WorkspaceInitializer
        Invoking Workspace Options Provider: OmniSharp.Roslyn.CSharp.Services.ImplementTypeWorkspaceOptionsProvider, Order: 110
[info]: OmniSharp.WorkspaceInitializer
        Invoking Workspace Options Provider: OmniSharp.Roslyn.CSharp.Services.BlockStructureWorkspaceOptionsProvider, Order: 140
[info]: OmniSharp.WorkspaceInitializer
        Configuration finished.
[info]: OmniSharp.Stdio.Host
        Omnisharp server running using Stdio at location '/Users/jangbeom-seok/Desktop/Project/Project_Owao/Owao_IOS' on host 20273.
[fail]: OmniSharp.MSBuild.ProjectLoader
        The reference assemblies for .NETFramework,Version=v4.7.1 were not found. To resolve this, install the Developer Pack (SDK/Targeting Pack) for this framework version or retarget your application. You can download .NET Framework Developer Packs at https://aka.ms/msbuild/developerpacks
[warn]: OmniSharp.MSBuild.ProjectManager
        Failed to load project file '/Users/jangbeom-seok/Desktop/Project/Project_Owao/Owao_IOS/Assembly-CSharp.csproj'.
/Users/jangbeom-seok/Desktop/Project/Project_Owao/Owao_IOS/Assembly-CSharp.csproj
/Users/jangbeom-seok/.vscode/extensions/ms-dotnettools.csharp-1.23.1/.omnisharp/1.37.0/omnisharp/.msbuild/Current/Bin/Microsoft.Common.CurrentVersion.targets(1178,5): Error: The reference assemblies for .NETFramework,Version=v4.7.1 were not found. To resolve this, install the Developer Pack (SDK/Targeting Pack) for this framework version or retarget your application. You can download .NET Framework Developer Packs at https://aka.ms/msbuild/developerpacks

[info]: OmniSharp.MSBuild.ProjectManager
        Loading project: /Users/jangbeom-seok/Desktop/Project/Project_Owao/Owao_IOS/Assembly-CSharp-firstpass.csproj
[fail]: OmniSharp.MSBuild.ProjectLoader
        The reference assemblies for .NETFramework,Version=v4.7.1 were not found. To resolve this, install the Developer Pack (SDK/Targeting Pack) for this framework version or retarget your application. You can download .NET Framework Developer Packs at https://aka.ms/msbuild/developerpacks
[warn]: OmniSharp.MSBuild.ProjectManager
        Failed to load project file '/Users/jangbeom-seok/Desktop/Project/Project_Owao/Owao_IOS/Assembly-CSharp-firstpass.csproj'.
/Users/jangbeom-seok/Desktop/Project/Project_Owao/Owao_IOS/Assembly-CSharp-firstpass.csproj
/Users/jangbeom-seok/.vscode/extensions/ms-dotnettools.csharp-1.23.1/.omnisharp/1.37.0/omnisharp/.msbuild/Current/Bin/Microsoft.Common.CurrentVersion.targets(1178,5): Error: The reference assemblies for .NETFramework,Version=v4.7.1 were not found. To resolve this, install the Developer Pack (SDK/Targeting Pack) for this framework version or retarget your application. You can download .NET Framework Developer Packs at https://aka.ms/msbuild/developerpacks

[info]: OmniSharp.MSBuild.ProjectManager
        Loading project: /Users/jangbeom-seok/Desktop/Project/Project_Owao/Owao_IOS/Assembly-CSharp-Editor.csproj
[fail]: OmniSharp.MSBuild.ProjectLoader
        The reference assemblies for .NETFramework,Version=v4.7.1 were not found. To resolve this, install the Developer Pack (SDK/Targeting Pack) for this framework version or retarget your application. You can download .NET Framework Developer Packs at https://aka.ms/msbuild/developerpacks
[warn]: OmniSharp.MSBuild.ProjectManager
        Failed to load project file '/Users/jangbeom-seok/Desktop/Project/Project_Owao/Owao_IOS/Assembly-CSharp-Editor.csproj'.
/Users/jangbeom-seok/Desktop/Project/Project_Owao/Owao_IOS/Assembly-CSharp-Editor.csproj
/Users/jangbeom-seok/.vscode/extensions/ms-dotnettools.csharp-1.23.1/.omnisharp/1.37.0/omnisharp/.msbuild/Current/Bin/Microsoft.Common.CurrentVersion.targets(1178,5): Error: The reference assemblies for .NETFramework,Version=v4.7.1 were not found. To resolve this, install the Developer Pack (SDK/Targeting Pack) for this framework version or retarget your application. You can download .NET Framework Developer Packs at https://aka.ms/msbuild/developerpacks

[info]: OmniSharp.MSBuild.ProjectManager
        Loading project: /Users/jangbeom-seok/Desktop/Project/Project_Owao/Owao_IOS/Assembly-CSharp-Editor-firstpass.csproj
[fail]: OmniSharp.MSBuild.ProjectLoader
        The reference assemblies for .NETFramework,Version=v4.7.1 were not found. To resolve this, install the Developer Pack (SDK/Targeting Pack) for this framework version or retarget your application. You can download .NET Framework Developer Packs at https://aka.ms/msbuild/developerpacks
[warn]: OmniSharp.MSBuild.ProjectManager
        Failed to load project file '/Users/jangbeom-seok/Desktop/Project/Project_Owao/Owao_IOS/Assembly-CSharp-Editor-firstpass.csproj'.
/Users/jangbeom-seok/Desktop/Project/Project_Owao/Owao_IOS/Assembly-CSharp-Editor-firstpass.csproj
/Users/jangbeom-seok/.vscode/extensions/ms-dotnettools.csharp-1.23.1/.omnisharp/1.37.0/omnisharp/.msbuild/Current/Bin/Microsoft.Common.CurrentVersion.targets(1178,5): Error: The reference assemblies for .NETFramework,Version=v4.7.1 were not found. To resolve this, install the Developer Pack (SDK/Targeting Pack) for this framework version or retarget your application. You can download .NET Framework Developer Packs at https://aka.ms/msbuild/developerpacks

[fail]: OmniSharp.MSBuild.ProjectManager
        Attempted to update project that is not loaded: /Users/jangbeom-seok/Desktop/Project/Project_Owao/Owao_IOS/Assembly-CSharp.csproj
[fail]: OmniSharp.MSBuild.ProjectManager
        Attempted to update project that is not loaded: /Users/jangbeom-seok/Desktop/Project/Project_Owao/Owao_IOS/Assembly-CSharp-firstpass.csproj
[fail]: OmniSharp.MSBuild.ProjectManager
        Attempted to update project that is not loaded: /Users/jangbeom-seok/Desktop/Project/Project_Owao/Owao_IOS/Assembly-CSharp-Editor.csproj
[fail]: OmniSharp.MSBuild.ProjectManager
        Attempted to update project that is not loaded: /Users/jangbeom-seok/Desktop/Project/Project_Owao/Owao_IOS/Assembly-CSharp-Editor-firstpass.csproj

유니티를 새로 설치하고 이런에러가 뜨면서 코드힌트라든지 레퍼런스가 뜨지 않는 경우가 생긴다.

구글링하다보니 Mono설정문제인듯 하다.

참고 : github.com/OmniSharp/omnisharp-vscode/issues/3063

 

세팅 검색창에 mono라고 검색해 보면 Omnisharp: Use Global Mono 라는 부분이 나오는데 auto에서 always로 바꿔주면 에러가 사라진다.

재시작 해주면 정상 작동 한다.

반응형
반응형

private const float inchToCm = 2.54f; 
[SerializeField] private EventSystem eventSystem = null; 
[SerializeField] private float dragThresholdCM = 0.5f; //For drag Threshold 
private void SetDragThreshold() { 
    if (eventSystem != null) { 
        eventSystem.pixelDragThreshold = (int)(dragThresholdCM * Screen.dpi / inchToCm); 
    } 
} 

void Awake() { 
    SetDragThreshold(); 
}

Unity로 안드로이드 앱을 개발하다보면 스크롤 안에 버튼이 들어갈 경우가 종종 있다.

PC에서 테스트 할 때는 마우스로 잘 눌리던 버튼이 스마트 폰에 넣어서 테스트 해보면 간혹 잘 눌리지 않는 경우가 있다. 이럴때 EventSystem 설정을 바꿔줘야하는데 다음과 같이 세팅 하면 적당하다.

 

반응형
반응형

커스텀 애니메이션커브를 담은 스크립(HnineCurves.cs)을 만들고 AnimationCurve를 적당한 이름으로 선언해 줍니다.

인스펙터에 가보면 이처럼 에디트할 수있는 창을 띄울 수 있겠죠.

클릭해서 원하는 모양의 이지값을 아래처럼 만들어 줍니다.

이렇게 만든 커브를 다음과 같이 DOTween에 사용할 수 있습니다.

반응형
반응형

1. 빌드세팅에서 그림과같이 체크한부분을 확인하여 맞춰준다.

2. 플레이어세팅에 XR Settings를 열고 위와같이 세팅한다.

 

3. Publishing Settings / Capablilities의 SpatialPerception을 체크한다.

 

4. MRTK에서 제공하는 샘플신을 열고 빌드를 하면 해당폴더에 Visual Studio Project가 생성이되는데 실행하면 비쥬얼 스튜디오가 열린다. (별도 설치 필요)

 

5. 아까 유니티 빌드세팅에서 맞춰놓은대로 비쥬얼 스튜디오도 그림처럼 맞춘다.

 

6. 속성을 눌러 들어간다.

 

7. 디버깅 탭을 누르고 컴퓨터 이름을 맞춰주는데 이때 이름은 홀로렌즈의 이름을 넣어주어야 한다. 홀로렌즈이름은 홀로렌즈 홈에서 /세팅/시스템 순서로 들어가면 확인할 수 있다.

 

8. 상단의 빌드/ 솔루션배포를 누르면 홀로렌즈에 앱을 빌드 할 수 있다. 여기서 만양 홀로렌즈에 배포가 되지 않고 핀번호를 입력하라고 나오면, 홀로렌즈 홈에서 세팅/업데이트/개발자모드 로 들어가서 페어링 버튼을 누르면 기기의 페어링번호가 뜨고 그 번호를 넣어주면 된다.

 

 

**2019.1.14f1일 경우 솔루션대상을 변경해주어야 합니다. 마찬가지로 비쥬얼 스튜디오 2019버전을 사용 할 경우 프로젝트/솔루션 대상 변경을 누르고 

확인을 눌러주변 홀로렌즈로 빌드를 할 수 있습니다.

반응형
반응형

2016/01/19 - [unity C#] - [Unity] GUI Infinity Scroll List 무한 리스트 구현 Json 

 

[Unity] GUI Infinity Scroll List 무한 리스트 구현 Json

어떻게 보면 간단한 구현 일 수도 있겠지만 난 어려웠다. ㅠㅠ 그래서 다시 정리하는 차원에서 포스팅 해본다. 먼저 간략하게 요약해보자면… Unity의 기본제공되는 GUI를 사용, 데이터 형태는 Json형태로 만들어..

knightk.tistory.com

이미지가 깨져서 다시 올려봅니다.

 

Hierarchy 구성

Hierarchy
리스트 요소가 될 Item은 Image와 Text 정도만으로 구성

스크립트 구성

스크립트 구성

 

ManagerHandler.cs

using UnityEngine;

public class ManagerHandler : MonoBehaviour {
    public InfiniteScroll infiniteScroll;
    void Start () {
        Application.targetFrameRate = 60;
        initList ();
    }

    void initList () {
        infiniteScroll.ListStart ();
    }
}

 

ModelHandler.cs

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

public class ModelHandler : MonoBehaviour {
    private JsonData jsonData;
    public List<DataVO> List;
    string jsonString () {
        TextAsset t = (TextAsset) Resources.Load ("data", typeof (TextAsset));
        return t.text;
    }

    void Awake () {
        jsonData = JsonMapper.ToObject (jsonString ());
        parsing ();
    }

    void parsing () {
        for (int i = 0; i < jsonData["music"].Count; i++) {

            ListModel.Instance.dataVO.SongTitle = (string) jsonData["music"][i]["songtitle"];
            ListModel.Instance.dataVO.Singer = (string) jsonData["music"][i]["singer"];
            ListModel.Instance.dataVO.Color = hexToColor ((string) jsonData["music"][i]["color"]);
            ListModel.Instance.dataVO.Genre = (string) jsonData["music"][i]["genre"];
            ListModel.Instance.dataVO.PlayTime = float.Parse ((string) jsonData["music"][i]["playtime"]);

            ListModel.Instance.MusicList.Add (ListModel.Instance.dataVO);
        }
    }

    static Color hexToColor (string hex) {
        hex = hex.Replace ("0x", "");
        hex = hex.Replace ("#", "");
        byte a = 255;
        byte r = byte.Parse (hex.Substring (0, 2), System.Globalization.NumberStyles.HexNumber);
        byte g = byte.Parse (hex.Substring (2, 2), System.Globalization.NumberStyles.HexNumber);
        byte b = byte.Parse (hex.Substring (4, 2), System.Globalization.NumberStyles.HexNumber);
        if (hex.Length == 8) {
            a = byte.Parse (hex.Substring (6, 2), System.Globalization.NumberStyles.HexNumber);
        }
        return new Color32 (r, g, b, a);
    }
}

 

ListModel.cs

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

[Serializable]
public struct DataVO {
    public string SongTitle;
    public string Singer;
    public Color32 Color;
    public string Genre;
    public float PlayTime;
}

public class ListModel : MonoBehaviour {
    private static ListModel _instance = null;
    public DataVO dataVO;
    public List<DataVO> MusicList = new List<DataVO> ();
    public static ListModel Instance {
        get {
            if (_instance == null) {
                _instance = (GameObject.Find ("Manager")).AddComponent<ListModel> ();
            }
            return _instance;
        }
    }

}

 

InfiniteScroll.cs

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

public class InfiniteScroll : MonoBehaviour {
    [SerializeField]
    private RectTransform m_ItemBase;
    [SerializeField]
    int m_instantiateItemCount = 9;
    [SerializeField]
    float m_itemWidth = 1080;
    [SerializeField]
    float m_itemHeight = 200;
    [SerializeField]
    float gap = 10;
    public Direction direction;
    [System.NonSerialized]
    public List<RectTransform> m_itemList = new List<RectTransform> ();
    protected float m_diffPreFramePosition = 0;
    [SerializeField]
    private int m_currentItemNo = 0;
    public ScrollRect scrollRect;
    public List<DataVO> listData;
    public enum Direction {
        Vertical,
        Horizontal,
    }

    // cache component
    public RectTransform m_Content;

    private float AnchoredPosition {
        get {
            return (direction == Direction.Vertical) ?
                -m_Content.anchoredPosition.y :
                m_Content.anchoredPosition.x;
        }
    }
    private float ItemScale {
        get {
            return (direction == Direction.Vertical) ?
                m_itemHeight :
                m_itemWidth;
        }
    }

    void Start () {
        m_itemWidth = Screen.width;
        m_itemHeight = Screen.height / 12;
    }

    public void ListStart () {
        listData = ListModel.Instance.MusicList;

        if (listData.Count < m_instantiateItemCount) {
            m_instantiateItemCount = listData.Count;
        } else {
            m_instantiateItemCount = (direction == Direction.Vertical) ?
                Mathf.RoundToInt (Screen.height / ItemScale) + 3 :
                Mathf.RoundToInt (Screen.width / ItemScale) + 3;
        }

        // create items
        scrollRect.horizontal = direction == Direction.Horizontal;
        scrollRect.vertical = direction == Direction.Vertical;

        if (direction == Direction.Vertical) {
            m_Content.SetSizeWithCurrentAnchors (RectTransform.Axis.Vertical, (ItemScale + gap) * (listData.Count - 1) + gap);
            m_Content.SetSizeWithCurrentAnchors (RectTransform.Axis.Horizontal, m_itemWidth + gap * 2);
        } else {
            m_Content.SetSizeWithCurrentAnchors (RectTransform.Axis.Horizontal, (ItemScale + gap) * (listData.Count - 1) + gap);
            m_Content.SetSizeWithCurrentAnchors (RectTransform.Axis.Vertical, m_itemHeight + gap * 2);
        }

        scrollRect.onValueChanged.AddListener (valueChange);
        Debug.Log (listData.Count);
        m_ItemBase.gameObject.SetActive (false);
        for (int i = 0; i < m_instantiateItemCount; i++) {
            var item = GameObject.Instantiate (m_ItemBase) as RectTransform;
            item.SetParent (transform, false);
            item.name = i.ToString ();

            if (direction == Direction.Vertical) {
                item.SetSizeWithCurrentAnchors (RectTransform.Axis.Horizontal, m_itemWidth - gap * 2);
                item.SetSizeWithCurrentAnchors (RectTransform.Axis.Vertical, m_itemHeight);
            } else {
                item.SetSizeWithCurrentAnchors (RectTransform.Axis.Horizontal, m_itemWidth);
                item.SetSizeWithCurrentAnchors (RectTransform.Axis.Vertical, m_itemHeight);
            }

            item.anchoredPosition =
                (direction == Direction.Vertical) ?
                new Vector2 (gap, -gap - (ItemScale + gap) * i) :
                new Vector2 ((ItemScale + gap) * i + gap, -gap);
            m_itemList.Add (item);

            item.gameObject.SetActive (true);
            item.GetComponent<Item> ().UpdateItem (i);
        }
    }

    private void valueChange (Vector2 _pos) {
        // scroll up, item attach bottom  or  right
        while (AnchoredPosition - m_diffPreFramePosition < -(ItemScale + gap) * 2) {
            m_diffPreFramePosition -= (ItemScale + gap);

            var item = m_itemList[0];
            m_itemList.RemoveAt (0);
            m_itemList.Add (item);

            var pos = (ItemScale + gap) * m_instantiateItemCount + (ItemScale + gap) * m_currentItemNo;
            item.anchoredPosition = (direction == Direction.Vertical) ? new Vector2 (gap, -pos - gap) : new Vector2 (pos + gap, -gap);

            m_currentItemNo++;

            if (m_currentItemNo + m_instantiateItemCount < listData.Count) {
                item.GetComponent<Item> ().UpdateItem (m_currentItemNo + m_instantiateItemCount);
            } else {
                item.GetComponent<Item> ().UpdateItem (-100);
            }
        }

        // scroll down, item attach top  or  left
        while (AnchoredPosition - m_diffPreFramePosition > 0) {
            m_diffPreFramePosition += (ItemScale + gap);

            var itemListLastCount = m_instantiateItemCount - 1;
            var item = m_itemList[itemListLastCount];
            m_itemList.RemoveAt (itemListLastCount);
            m_itemList.Insert (0, item);

            m_currentItemNo--;

            var pos = (ItemScale + gap) * m_currentItemNo + gap;
            item.anchoredPosition = (direction == Direction.Vertical) ? new Vector2 (gap, -pos) : new Vector2 (pos, -gap);

            if (m_currentItemNo > -1) {
                item.GetComponent<Item> ().UpdateItem (m_currentItemNo);
            } else {
                item.GetComponent<Item> ().UpdateItem (-100);
            }
        }
    }
}

 

Item.cs

using UnityEngine;
using UnityEngine.UI;

public class Item : MonoBehaviour {
    public Text m_Text;
    public Image m_Image;
    public void UpdateItem (int count) {
        if (count == -100) {
            m_Text.gameObject.SetActive (false);
            m_Image.gameObject.SetActive (false);
        } else {
            m_Text.gameObject.SetActive (true);
            m_Image.gameObject.SetActive (true);
            m_Text.text = count + 1 + " - " + Screen.width + " x " + Screen.height;
            m_Image.color = ListModel.Instance.MusicList[count].Color;
        }
    }
}

 

Manager 오브젝트에 ManagerHandler.cs / ModelHandler.cs / ListModel.cs 붙여줍니다.

Manager Object

ScrollView를 만들어 다음과같이 세팅해줍니다.

ScrollRect

InfinityContent 오브젝트에 InfinityScroll.cs 를 붙여주고

ScrollRect항목에 위에서 설정한 ScrollRect를 드래그앤 드랍으로 넣어줍니다.

Content항목에 InfinityContent오브젝트를 끌어넣어 연결해줍니다.

InfinityScroll.cs 붙이기

 

Item 오브젝트에 Item.cs를 붙여주고 위에 InfinityScroll 인스펙터에 ItemBase에 드래그앤 드랍으로 넣어줍니다.

Item인스펙터의 Text와 Image를 해당 오브젝트로 연결시켜줍니다.

Item.cs 붙이기

 

data.txt 파일 생성

Resources폴더에 data.txt파일만들어 아래와 같이 데이터를 넣어줍니다. 아래 데이터는 테스트 하기 위해 임의로 생성한 것이고 자신의 리스트에 맞게 수정해서 사용하면 됩니다.

{
  "music":[
    {
      "songtitle" : "Love Will Show You Everything",
      "singer" : "Various Artists",
      "color" : "f98181",
      "genre" : "rock",
      "playtime" : "0"
    },
    {
      "songtitle" : "Love Will Show You Everything",
      "singer" : "Various Artists",
      "color" : "f981bc",
      "genre" : "rock",
      "playtime" : "0"
    }, 
    {
      "songtitle" : "Love Will Show You Everything",
      "singer" : "Various Artists",
      "color" : "f881f9",
      "genre" : "rock",
      "playtime" : "0"
    },
    {
      "songtitle" : "Love Will Show You Everything",
      "singer" : "Various Artists",
      "color" : "d081f9",
      "genre" : "rock",
      "playtime" : "0"
    }, 
    {
      "songtitle" : "Love Will Show You Everything",
      "singer" : "Various Artists",
      "color" : "ab81f9",
      "genre" : "rock",
      "playtime" : "0"
    },
    {
      "songtitle" : "Love Will Show You Everything",
      "singer" : "Various Artists",
      "color" : "8c81f9",
      "genre" : "rock",
      "playtime" : "0"
    }, 
    {
      "songtitle" : "Love Will Show You Everything",
      "singer" : "Various Artists",
      "color" : "8192f9",
      "genre" : "rock",
      "playtime" : "0"
    },
    {
      "songtitle" : "Love Will Show You Everything",
      "singer" : "Various Artists",
      "color" : "81a8f9",
      "genre" : "rock",
      "playtime" : "0"
    }, 
    {
      "songtitle" : "Love Will Show You Everything",
      "singer" : "Various Artists",
      "color" : "81c8f9",
      "genre" : "rock",
      "playtime" : "0"
    },
    {
      "songtitle" : "Love Will Show You Everything",
      "singer" : "Various Artists",
      "color" : "81e4f9",
      "genre" : "rock",
      "playtime" : "0"
    }, 
    {
      "songtitle" : "Love Will Show You Everything",
      "singer" : "Various Artists",
      "color" : "81f9e4",
      "genre" : "rock",
      "playtime" : "0"
    },
    {
      "songtitle" : "Love Will Show You Everything",
      "singer" : "Various Artists",
      "color" : "81f9c5",
      "genre" : "rock",
      "playtime" : "0"
    }, 
    {
      "songtitle" : "Love Will Show You Everything",
      "singer" : "Various Artists",
      "color" : "81f9a3",
      "genre" : "rock",
      "playtime" : "0"
    },
    {
      "songtitle" : "Love Will Show You Everything",
      "singer" : "Various Artists",
      "color" : "81f989",
      "genre" : "rock",
      "playtime" : "0"
    }, 
    {
      "songtitle" : "Love Will Show You Everything",
      "singer" : "Various Artists",
      "color" : "a0f981",
      "genre" : "rock",
      "playtime" : "0"
    },
    {
      "songtitle" : "Love Will Show You Everything",
      "singer" : "Various Artists",
      "color" : "c2f981",
      "genre" : "rock",
      "playtime" : "0"
    }, 
    {
      "songtitle" : "Love Will Show You Everything",
      "singer" : "Various Artists",
      "color" : "e9f981",
      "genre" : "rock",
      "playtime" : "0"
    },
    {
      "songtitle" : "Love Will Show You Everything",
      "singer" : "Various Artists",
      "color" : "f9e981",
      "genre" : "rock",
      "playtime" : "0"
    }, 
    {
      "songtitle" : "Love Will Show You Everything",
      "singer" : "Various Artists",
      "color" : "f9cd81",
      "genre" : "rock",
      "playtime" : "0"
    },
    {
      "songtitle" : "Love Will Show You Everything",
      "singer" : "Various Artists",
      "color" : "f9b181",
      "genre" : "rock",
      "playtime" : "0"
    }, 
    {
      "songtitle" : "Love Will Show You Everything",
      "singer" : "Various Artists",
      "color" : "f99781",
      "genre" : "rock",
      "playtime" : "0"
    }
  ]
}

 

실행화면

실행화면

 

반응형
반응형

[진행과정]

1. 아두이노에 HC-06블루투스 모듈 설치

2. 아두이노 세팅 및 코딩

3. 유니티프로젝트 생성 및 세팅 (

4. 안드로이드 빌드 및 블루투스 연결

 

요렇게 진행합니다.

 

1. 아두이노에 HC-06모듈 및 마그네틱 센서 설치

HC-06 : 디지털인풋 2/3번/GND/5V 에 연결.

마그네틱 센서 : 디지털인풋 8번/GND에 연결.

hc-06 모듈 및 마그네틱센서 설치

참조1

 

[아두이노 - 블루투스 연동]

안녕하세요!! 이번 포스팅은 아두이노에서 블루투스 연동을 통해 앱과 통신하는 방법을 알아보겠습니다. * ...

blog.naver.com

참조2

 

[Unity]04.아두이노 사용하기 - Blutooth로 채팅하기

안녕하세요 유랑입니다. 오늘은 아두이노와 유니티 통신하는 방법에 대해서 알아보겠습니다. 통신방법은 블루투스를 사용하겠습니다^^ 1. 아두이노와 유니티로 채팅하기 유니티에서 Android 프로젝트에서 디바이스..

you-rang.tistory.com

2. 아두이노 세팅 및 코딩

먼저 아두이노사이트에 가서 아두이노를 설치해 줍니다.

아두이노 프로그램 다운로드

아두이노와 PC를 USB로 연결 한 후 아래 그림처럼 순서대로 보드와 포트를 자신에 맞는 것으로 선택해 줍니다.

아두이노 보드/포트 설정

블루투스 모듈을 슬레이브로변경하기 위해,시리얼 모니터창을 열어 아래 명령어를  입력해줍니다.

AT+ROLE=S

참고

 

HC-06 블루투스모듈 설정 변경하기! (마스터에서 슬레이브, 슬레이브에서 마스터로, HC-06자가진단하기!)

안녕하세요 메카솔루션입니다. 이번에는 HC-06의 마스터와 슬레이브를 수정하는방법과, 그리고 간단하게 ...

blog.naver.com

시리얼 모니터창에서 “AT”라고입력하여 OK가 반환되면,블루투스 모듈 연결이 잘 된 것입니다.

이후,AT+NAME이름을 입력하면 블루투스 모듈 이름을 설정할 수 있습니다.(AT+NAME000입력 시,000으로이름 설정)

그리고 AT+PIN핀번호 4자리를 입력하면 블루투스 연결 시 비밀번호를 설정할 수 있습니다.

마지막으로 AT+BAUD4 을 입력하여 OK9600이 반환되는 것을 확인합니다.(통신 속도 설정)

참고

 

[아두이노 - 블루투스 연동]

안녕하세요!! 이번 포스팅은 아두이노에서 블루투스 연동을 통해 앱과 통신하는 방법을 알아보겠습니다. * ...

blog.naver.com

모두 설정되었다면 아두이노에 코딩작업을 해줍니다.

#include<SoftwareSerial.h>

SoftwareSerial BTSerial (3, 2); //Connect HC-06. Use your (TX, RX) settings

int val;
int tempVal;

void setup () {
  Serial.begin (9600);
  BTSerial.begin (9600); // set the data rate for the BT port
  pinMode (8, INPUT_PULLUP);
}

void loop () {
  //switch value update
  val = digitalRead (8);

  // BT –> Data –> Serial
  if (BTSerial.available ()) {
    Serial.println ("BT available");
    Serial.write (BTSerial.read ());
  }

  if (val == HIGH) {
    if (val != tempVal) {
      tempVal = val;
      BTSerial.println ("off");
      // Do Something

    }
  } else {
    if (val != tempVal) {
      tempVal = val;
      BTSerial.println ("on");
      // Do Something

    }
  }
  delay (100);
}

코드를 대략 요약하자면 마그네틱센서가 붙으면 "on", 떨어지면 "off"라는 스티링을 블루투스 시리얼로 보내는 동작을 합니다.

찾아본 바로는 BTSerial.write("on"); 요렇게 하라고 되어있었는데 전혀 아무런 신호가 보내지지 않아서 저렇게 바꿔보니 잘되더군요.

코딩작업을 마쳤으면 두번째 아이콘을 눌러 아두이노에 업로드를 합니다.

 

3. 유니티프로젝트 생성 및 세팅

적당한 이름으로 새로운 프로젝트를 만들고 아래 파일을 다운받아 임포트 시켜줍니다.

ArduinoBluetooth.unitypackage
1.23MB

Build Settings / Player Settings… 를 열어 Other Settings를 다음과 같이 설정합니다. 

Bundle Identifier 는 똑같지 않아도 상관없으며ApiCompatibility Level* 이부분이 .Net4.x 로 선택해주어야 합니다.

안드로이드로 타겟플랫폼을 변경해주고

새로운 Scene을 만들고 Project탭의Assets/ArduinoBluetooth/Demo/Prefab폴더로 이동하여

__Manager파일을 Hierarchy에 끌어 넣습니다.

 

숫자 "0"번 키로 아래 GUI를 끄고 켤수 있습니다.

 

__Manager를 클릭해보면 Manager.cs라는 스크립트파일이 붙어있습니다.

Manager.cs를 열어서 deviceName 을 위에 아두이노 설정시 변경했던 블루투스 이름과 동일하게 수정해줍니다.

예)AT+NAMEHC-06

OnDoorOpenOnDoorClose위 두가지 이벤트가 있고외부 클래스에서 다음과 같이 사용할 수 있습니다.

public Manager _manager;

void Start(){
    _manager.onDoorOpen.AddListener(OnDoorOpen);
    _manager.onDoorClose.AddListener(OnDoorClose);
}

void OnDoorOpen(){
    //문이 열렸을 때
}
void OnDoorOpen(){
    //문이 닫혔을 때
}
…

 

연결 테스트영상입니다.

 

반응형
반응형

간혹 빌드가 끝나고나서 특정 이미지를 교체해야 하거나 영상을 바꿔야 되면 해당 비디오 파일 또는 이미지 파일을 교체 후 새롭게 빌드를 시켜야 하는 번거러운 작업을 해야할 경우가 생긴다. 

교체해야할 상황이 빈번하다고 판단되는 프로젝트일 경우 특정 폴더에 교체 할 소스 파일을 넣어두고 해당 소스파일만 바꾸면 새로 빌드할 필요가 없게 미리 처리해 두면 될 것이다. 

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

public class FileItemHandler : MonoBehaviour {
    public string ParentFolderName;
    public string TargetFolderName;
    public List<string> FilePathList;
    public List<string> CoverPathList;
    public List<Texture2D> CoverSpriteList;
    string filepath;
    void Awake () { GetPathList (); }

    void GetPathList () {
        string _path = "";

        //타켓 폴더 패스 설정
        if (Application.platform == RuntimePlatform.Android) {
            //android일 경우 //
            _path = AndroidRootPath () + "Download/FH/" + ParentFolderName + "/" + TargetFolderName;
        } else {
            //unity일 경우 //
            _path = System.Environment.GetFolderPath (System.Environment.SpecialFolder.Personal) + "/Desktop/FH/" + ParentFolderName + "/" + TargetFolderName;
        }

        DirectoryInfo Folder = new DirectoryInfo (_path);

        //각 비디오의 패스(URL) 리스트 만들기
        foreach (var file in Folder.GetFiles ()) {
            if (file.Extension != ".meta" && file.Extension != ".DS_Store") { //비디오 이외의 확장자를 가진 파일 제외시키기
                filepath = _path + "/" + file.Name;
                if (!filepath.Contains ("._")) { //파일명 에러 수정해주기
                    // filepath = filepath.Replace ("._", "");
                    if (filepath.Contains (".mp4")) //비디오 파일 add 리스트
                        FilePathList.Add (filepath);
                    else if (filepath.Contains (".jpg")) { //커버이미지 파일 add 리스트
                        CoverPathList.Add (filepath);
                        Texture2D tex = null;
                        byte[] filedata;
                        if (File.Exists (filepath)) {
                            filedata = File.ReadAllBytes (filepath);
                            tex = new Texture2D (2, 2);
                            tex.LoadImage (filedata);
                            // Sprite sp = SpriteFromTexture2D (tex);
                            CoverSpriteList.Add (tex);
                        }
                    }
                }
            }
        }
        Debug.Log(ParentFolderName + "/" + TargetFolderName + ", FileCount : " + FilePathList.Count+ ",, SpriteCount : " + CoverSpriteList.Count);
    }

    string AndroidRootPath () {
        string[] temp = (Application.persistentDataPath.Replace ("Android", "")).Split (new string[] { "//" }, System.StringSplitOptions.None);
        return (temp[0] + "/");
    }

    Sprite SpriteFromTexture2D (Texture2D texture) {
        return Sprite.Create (texture, new Rect (0.0f, 0.0f, texture.width, texture.height), new Vector2 (0.5f, 0.5f), 100.0f);
    }
}

 

 

반응형

+ Recent posts