반응형

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

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

참조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버전을 사용 할 경우 프로젝트/솔루션 대상 변경을 누르고 

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

반응형
반응형

1. 정보 :

 

성수동에 위치한 할아버지공장

넓은 공간과 맛있는 음식이 마음을 사로잡는다.

1층, 2층, 3층 공간으로 기존 공장을 개조한 카페레스토랑으로 한번 가보면 또 가고싶은 그런 곳이다.

사이트

20200629일자 메뉴판 정복메뉴 밑줄

블로그 검색해보고 갔는데 메뉴가 달라진걸 보니 수시로 바뀌는듯 하다.

대림창고를 하던 사장이 대림창고를 처분하고 다시 시작한 곳이라고 하는데 홍동희작가님을 검색해봐야겠다.

 

2. 위치

 

3. 별점

반응형

'맛집' 카테고리의 다른 글

스물다섯스물하나 촬영지  (0) 2022.04.03
반응형

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(){
    //문이 닫혔을 때
}
…

 

연결 테스트영상입니다.

 

반응형
반응형

테스트 하기 위해 새로운 프로젝트를 만들고 

main.dart 코드를 다음과 같이 세팅한다.

import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      title: 'ListViews',
      theme: ThemeData(
        primarySwatch: Colors.teal,
      ),
      home: Scaffold(
        appBar: AppBar(title: Text('ListViews')),
        body: BodyLayout(),
      ),
    );
  }
}

class BodyLayout extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return _myListView(context);
  }
}

// replace this function with the code in the examples
Widget _myListView(BuildContext context) {
  return ListView();
}

 

ListView

설정메뉴나 고정적인 메뉴 항목일 경우 유용하게 사용할 수 있음.

리스트 선이 있는 경우

Widget _myListView(BuildContext context) {
  return ListView(
    children: ListTile.divideTiles(
      context: context,
      tiles: [
        ListTile(
          title: Text('Sun'),
        ),
        ListTile(
          title: Text('Moon'),
        ),
        ListTile(
          title: Text('Star'),
        ),
      ],
    ).toList(),
  );
}

 

리스트 선이 없는 경우

Widget _myListView(BuildContext context) {
  return ListView(
    children: <Widget>[
      ListTile(
        title: Text('Sun'),
      ),
      ListTile(
        title: Text('Moon'),
      ),
      ListTile(
        title: Text('Star'),
      ),
    ],
  );
}

 

Dynamic ListView

데이터를 가져와 동적으로 리스트를 생성하는 방식

Widget _myListView(BuildContext context) {

      // backing data
  final europeanCountries = ['Albania', 'Andorra', 'Armenia', 'Austria', 
    'Azerbaijan', 'Belarus', 'Belgium', 'Bosnia and Herzegovina', 'Bulgaria',
    'Croatia', 'Cyprus', 'Czech Republic', 'Denmark', 'Estonia', 'Finland',
    'France', 'Georgia', 'Germany', 'Greece', 'Hungary', 'Iceland', 'Ireland',
    'Italy', 'Kazakhstan', 'Kosovo', 'Latvia', 'Liechtenstein', 'Lithuania',
    'Luxembourg', 'Macedonia', 'Malta', 'Moldova', 'Monaco', 'Montenegro',
    'Netherlands', 'Norway', 'Poland', 'Portugal', 'Romania', 'Russia',
    'San Marino', 'Serbia', 'Slovakia', 'Slovenia', 'Spain', 'Sweden', 
    'Switzerland', 'Turkey', 'Ukraine', 'United Kingdom', 'Vatican City'];

  return ListView.separated(
    itemCount: europeanCountries.length,
    itemBuilder: (context, index) {
      return ListTile(
        title: Text(europeanCountries[index]),
      );
    },
    separatorBuilder: (context, index) {
      return Divider();
    },
  );
}

데이터를 만들어 생성하는 방식

리턴쪽에 ListView.separated로 설정해서 separatorBuilder를 넣어주면 구분선을 사용할 수 있다.

구분선이 없이 사용하려면 ListView.builder로 리턴시키면 된다.

 

Infinite List

말그대로 무한 스크롤... 그냥 되는거다 사용하는 방법은 좀더 연구해봐야겠지만...

Widget _myListView(BuildContext context) {
  return ListView.builder(
    itemBuilder: (context, index) {
      return ListTile(
        title: Text('row $index'),
      );
    },
  );
}

구분선을 추가하려면

Widget _myListView(BuildContext context) {
  return ListView.separated(
    itemCount: 1000,
    itemBuilder: (context, index) {
      return ListTile(
        title: Text('row $index'),
      );
    },
    separatorBuilder: (context, index) {
      return Divider();
    },
  );
}

 

Horizontal ListView

가로스크롤 구현이다.

Widget _myListView(BuildContext context) {
  return ListView.builder(
    scrollDirection: Axis.horizontal,
    itemBuilder: (context, index) {
      return Container(
        margin: const EdgeInsets.symmetric(horizontal: 1.0),
        color: Color(0xFFEEEEEE),
        child: Text('$index'),
        width: 50.0,
      );
    },
  );
}

가로 스크롤 리스트

 

리스트 타일 커스터마이즈

플루터는 기본적으로 제공되는 아이콘이 무척 많은듯 하다. 사용하는 방법도 간단함.

Widget _myListView(BuildContext context) {
  return ListView(
    children: ListTile.divideTiles(
      context: context,
      tiles: [
        ListTile(
          leading: Icon(Icons.wb_sunny),
          title: Text('Sun'),
          trailing: Icon(Icons.keyboard_arrow_right),
        ),
        ListTile(
          leading: Icon(Icons.brightness_3),
          title: Text('Moon'),
          trailing: Icon(Icons.keyboard_arrow_right),
        ),
        ListTile(
          leading: Icon(Icons.star),
          title: Text('Star'),
          trailing: Icon(Icons.keyboard_arrow_right),
        ),
      ],
    ).toList(),
  );
}

다양한 아이콘 적용

 

원하는 이미지를 리스트에 넣기

아래코드로 먼저 바꿔준 후,

Widget _myListView(BuildContext context) {
  return ListView(
    children: ListTile.divideTiles(
      context: context,
      tiles: [
        ListTile(
          leading: CircleAvatar(
            backgroundImage: AssetImage('assets/sun.jpg'),
          ),
          title: Text('Sun'),
          trailing: Icon(Icons.keyboard_arrow_right),
        ),
        ListTile(
          leading: CircleAvatar(
            backgroundImage: AssetImage('assets/moon.jpg'),
          ),
          title: Text('Moon'),
          trailing: Icon(Icons.keyboard_arrow_right),
        ),
        ListTile(
          leading: CircleAvatar(
            backgroundImage: AssetImage('assets/stars.jpg'),
          ),
          title: Text('Star'),
          trailing: Icon(Icons.keyboard_arrow_right),
        ),
      ],
    ).toList(),
  );
}

에셋폴더 생성 후 이미지 넣기

프로젝트 폴더에 에셋폴더를 위와같이 만들고 해당 이름으로 이미지를 넣어준다.

에셋 폴더 설정

pubspec.yaml파일을 열어서 

flutter:

  assets:

    - assets/ 

이부분을 추가해 준다.

 

리스트의 이미지 커스터마이징

 

서브타이틀 추가방법

ListTile(
  leading: CircleAvatar(
  	backgroundImage: AssetImage('assets/sun.jpg'),
  ),
  title: Text('Sun'),
  trailing: Icon(Icons.keyboard_arrow_right),
  subtitle: Text('93 million miles away'),
),

서브타이틀 추가

 

카드타입 리스트

 

Widget _myCardTypeList(BuildContext context) {
  final titles = [
    'bike',
    'boat',
    'bus',
    'car',
    'railway',
    'run',
    'subway',
    'transit',
    'walk'
  ];

  final icons = [
    Icons.directions_bike,
    Icons.directions_boat,
    Icons.directions_bus,
    Icons.directions_car,
    Icons.directions_railway,
    Icons.directions_run,
    Icons.directions_subway,
    Icons.directions_transit,
    Icons.directions_walk
  ];

  return ListView.builder(
    itemCount: titles.length,
    itemBuilder: (context, index) {
      return Card(
        //                           <-- Card widget
        child: ListTile(
          leading: Icon(icons[index]),
          title: Text(titles[index]),
        ),
      );
    },
  );
}

카드타입 리스트

 

커스텀 리스트 아이템

위젯 컬럼을 세팅해서 리스트에 집어넣은 경우이다.

Widget _customListItem(BuildContext context) {
  // the Expanded widget lets the columns share the space
  Widget column = Expanded(
    child: Column(
      // align the text to the left instead of centered
      crossAxisAlignment: CrossAxisAlignment.start,
      children: <Widget>[
        Card(
          child: ListTile(
            leading: Icon(Icons.computer),
            title: Text("Title"),
            subtitle: Text("SubTitle"),
          ),
        )
      ],
    ),
  );

  return ListView.builder(
    itemBuilder: (context, index) {
      return Card(
        child: Padding(
          padding: const EdgeInsets.all(8.0),
          child: Row(
            children: <Widget>[
              column,
              column,
              column,
            ],
          ),
        ),
      );
    },
  );
}

카드타입에 카드타입을 넣은 경우

 

출처 : https://pusher.com/tutorials/flutter-listviews

반응형

+ Recent posts