woong's

Unity ScrollView Item 재사용 하기 본문

Develop/Unity

Unity ScrollView Item 재사용 하기

dlsdnd345 2016. 2. 13. 20:23

Unity ScrollView Item 재사용 하기 


​안녕하세요 . 저번 포스트에서 Unity ScrollView UI 구성에 대해서 공유를 했었습니다 . 

하지만 여기까지의 ScrollView 를 간단한 ScrollView 는 사용 할 수 있지만 , 

100개 200 개가 넘어 가는 ScrollView 는 퍼포먼스 상에서 이슈가 발생 합니다 .


그래서 ScrollView 를 사용할때 Item 에 대해서 재사용을 구현해야 합니다 .

필자 또한 Unity 관련해서는 초보 단계라 검색해 본 결과 Unity 잘하시는분 께서 

ScrollView  재사용 코드를 공유해 놓으셔서 이용하였습니다 .


http://idmanner.blog.me/70176641036


위 블로그에서 원본 코드와 설명을 볼 수 있습니다 .


제가 이렇게 블로그 쓰는 이유는 윗 분이 공유해주신 부분도 많은 도움이 되었지만 ,

조금 더 자세히 적어서 도움이 되 보고자 포스트를 작성해 보려 합니다 .

 

1. 우선 선행 학습으로 ScrollView  UI 를 구성해야 합니다 .

 

​2. ScrollView 구성을 완료 하면 Item 재사용을 진행합니다. 


재사용을 진행하면서 참고했던 사이트 입니다 .


http://idmanner.blog.me/70176641036

http://gods2000.tistory.com/73

 

 

 NGUIMath.cs 에 아래 코드를 넣습니다 .

 제일 하단에 넣습니다 .


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
static public Bounds CalculateRelativeWidgetBounds2 ( Transform root, Transform firstTemplate, Transform lastTemplate )
 
{
if( firstTemplate == null || lastTemplate == null )
return new Bounds(Vector3.zero, Vector3.zero);
 
UIWidget[] widgets1 = firstTemplate.GetComponentsInChildren<UIWidget>(trueas UIWidget[];
UIWidget[] widgets2 = lastTemplate.GetComponentsInChildren<UIWidget>(trueas UIWidget[];
if (widgets1.Length == 0 || widgets2.Length == 0 ) return new Bounds(Vector3.zero, Vector3.zero);
 
Vector3 vMin = new Vector3(float.MaxValue, float.MaxValue, float.MaxValue);
Vector3 vMax = new Vector3(float.MinValue, float.MinValue, float.MinValue);
 
Matrix4x4 toLocal = root.worldToLocalMatrix;
 
for (int i = 0, imax = widgets1.Length; i < imax; ++i)
{
UIWidget w = widgets1[i];
Vector2 size = w.relativeSize;
Vector2 offset = w.pivotOffset;
Transform toWorld = w.cachedTransform;
 
float x = (offset.x + 0.5f) * size.x;
float y = (offset.y - 0.5f) * size.y;
size *= 0.5f;
 
// Start with the corner of the widget
Vector3 v = new Vector3(x - size.x, y - size.y, 0f);
 
// Transform the coordinate from relative-to-widget to world space
v = toWorld.TransformPoint(v);
 
// Now transform from world space to relative-to-parent space
v = toLocal.MultiplyPoint3x4(v);
 
vMax = Vector3.Max(v, vMax);
vMin = Vector3.Min(v, vMin);
 
// Repeat for the other 3 corners
v = new Vector3(x - size.x, y + size.y, 0f);
v = toWorld.TransformPoint(v);
v = toLocal.MultiplyPoint3x4(v);
 
vMax = Vector3.Max(v, vMax);
vMin = Vector3.Min(v, vMin);
 
v = new Vector3(x + size.x, y - size.y, 0f);
v = toWorld.TransformPoint(v);
v = toLocal.MultiplyPoint3x4(v);
 
vMax = Vector3.Max(v, vMax);
vMin = Vector3.Min(v, vMin);
 
v = new Vector3(x + size.x, y + size.y, 0f);
v = toWorld.TransformPoint(v);
v = toLocal.MultiplyPoint3x4(v);
 
vMax = Vector3.Max(v, vMax);
vMin = Vector3.Min(v, vMin);
}
 
for (int i = 0, imax = widgets2.Length; i < imax; ++i)
{
UIWidget w = widgets2[i];
Vector2 size = w.relativeSize;
Vector2 offset = w.pivotOffset;
Transform toWorld = w.cachedTransform;
 
float x = (offset.x + 0.5f) * size.x;
float y = (offset.y - 0.5f) * size.y;
size *= 0.5f;
 
// Start with the corner of the widget
Vector3 v = new Vector3(x - size.x, y - size.y, 0f);
 
// Transform the coordinate from relative-to-widget to world space
v = toWorld.TransformPoint(v);
 
// Now transform from world space to relative-to-parent space
v = toLocal.MultiplyPoint3x4(v);
 
vMax = Vector3.Max(v, vMax);
vMin = Vector3.Min(v, vMin);
 
// Repeat for the other 3 corners
v = new Vector3(x - size.x, y + size.y, 0f);
v = toWorld.TransformPoint(v);
v = toLocal.MultiplyPoint3x4(v);
 
vMax = Vector3.Max(v, vMax);
vMin = Vector3.Min(v, vMin);
 
v = new Vector3(x + size.x, y - size.y, 0f);
v = toWorld.TransformPoint(v);
v = toLocal.MultiplyPoint3x4(v);
 
vMax = Vector3.Max(v, vMax);
vMin = Vector3.Min(v, vMin);
 
v = new Vector3(x + size.x, y + size.y, 0f);
v = toWorld.TransformPoint(v);
v = toLocal.MultiplyPoint3x4(v);
 
vMax = Vector3.Max(v, vMax);
vMin = Vector3.Min(v, vMin);
}
 
Bounds b = new Bounds(vMin, Vector3.zero);
b.Encapsulate(vMax);
return b;
}

 

 

 

http://idmanner.blog.me/70176641036

​다음으로 위 첫번째 링크를 통해서 파일 3개를 받아서 Import 하면 오류가 몇가지 나게 됩니다 .

그래서 제가 오류 잡은 파일버젼을 첨부파일에 첨부해놓겠습니다 .

파일 3개를 받습니다 .


받고 Import 를 해도 오류가 나타 납니다 .

NGUI의 UIDraggablePanel , SpringPanel 을 수정해야 합니다 .

위 파일 수정 본도 위 링크를 통해서 하나하나 해결해 나갈 수 있습니다 .


수정 파일도 같이 첨부하겠습니다 .


위 파일 2개까지 교체를 하면 오류가 사라집니다 .

이제 Item 사용에 대한 전반 적인 준비 과정이 끝난 것 같습니다 .


선행 학습으로 ScrollView  UI 를 구성

 

위 링크를 선행 학습하고 오셨으면 아래와 같은 Hierarchy 를 보실 수 있습니다 .






 ​이제 이 Hierarchy 에 아까 준비한 스크립트를 연결하면 되겠습니다 .





1. 첫번째로 Prefab 으로 만들어 놓은 Item Prefab 에 CUIScroll List Base Script 를 적용 합니다 .




2. 두번째로 Panel 을 보시면 여러분은 UIDraggable Panel 이 적용되어 있습니다 .

UIDraggable Panel 을 위에서 준비한 UIDraggable Panel2 로 변경합니다 .

변경후 최하단의 Grid 에 Grid 를 적용하시고 Item Prefab 을 Template Prefab 에 적용 합니다 .




3. 마지막으로 ListView Script 를 작성해야 합니다 .


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
using UnityEngine;
using System.Collections;
 
public class ListView : MonoBehaviour {
    
    public UIGrid grid;
    public UIDraggablePanel2 DragPanel;
    public int count;
    
    // Use this for initialization
    void Start () {
        
        DragPanel.Init(count, delegate(UIListItem item, int index) {
            Debug.Log("item"+item);
            Debug.Log("index"+index);
            
            item.Target.name = index.ToString();
            //item.Target.transform.FindChild("Label").GetComponent<UILabel>().text = index.ToString();
            
            
        });
        
        grid.Reposition ();
        DragPanel.ResetPosition();
    }
    
    // Update is called once per frame
    void Update () {
        
    }
}
 

 

 

​제가 작성한 ListView 코드입니다 . 이파일 역시 첨부파일에 첨부 하겠습니다 . 


이렇게 코드를 넣으신후에 UIDraggable Panel2를 적용하신 Panel에 ListView Script를 적용합니다 .




적용 후에 아래와 같이 Grid 를 첨부 , DragPanel 에 Panel 을 첨부합니다 .

최하단의 Count 는 Item의 갯수가 되겠습니다 .


 

 

​실행을 해보면 하단에 두개의 Item(Clone)이 있습니다 . 

이두개는 최상단과 최하단의 위치하여

전체 사이즈를 구하고,

그 후에 N + 2의 실제 스크롤아이템을 만들어 스크롤링 될때마다 위치값을 계산

한다고 합니다 .




저는 이와 같이 하기까지 꼬박 2틀이 걸렸네요 ㅜ

Unity ListView 관련 자료가 정말 없습니다 .

서로서로 공유하는 습관을 들이면 좋을것 같습니다 .


Android ListView 를 쉽게 사용했었는데 ... 이와 같은 과정이 숨어 있었네요 !!


'Develop > Unity' 카테고리의 다른 글

Unity Assets Image 불러오기  (0) 2016.02.13
Unity Image Cache 사용하기  (0) 2016.02.13
Unity ScrollView 사용하기  (0) 2016.02.13
Unity Dynamic Font 사용하기  (0) 2016.02.13
Unity Android Plugin 사용하기  (1) 2016.02.13
Comments