Unity3D

[유니티][안드로이드] 유니티 웹뷰 사용 하기 - Unity WebView Gree

DragonTory 2021. 12. 1. 17:10
반응형

 

유니티에서 웹 브라우저를 사용 할 일이 있을 때

WebView를 사용 하여 웹 브라우저를 구현 할 수 있다.

 

아래는 대표적인 플러그인.

Gree Unity Webview

https://github.com/gree/unity-webview

 

GitHub - gree/unity-webview

Contribute to gree/unity-webview development by creating an account on GitHub.

github.com

 

1. 설치

위 사이트의 우측 상단의 Code -> Download Zip으로 다운로드 합니다. ( 혹은 git으로 다운로드 )

 

압축을 해제 하면 다음과 같은 파일들을 볼 수 있습니다. 

 

dist/ 폴더에 들어가 보면

  • unity-webview.unitypackage
  • unity-webview-nofragment.unitypackage

 

이중에 unity-webview.unitypackage 를 선택 해서 Unity 프로젝트에 설치 하면 됩니다.

( 만약, File Input Field 기능을 사용 하지 않는 다면

 unity-webview-nofragment.unitypackage

을 선택 해서 설치 하면 된다고 설명 되어 있습니다. )

 

2. 사용법

 

unity-webview-master/sample/ 폴더에 보면 

SampleWebView.cs  파일이 있습니다. 

이 예제를 살펴 보고 작업 하면 됩니다. 

 

주의)

 참고로 윈도우 Unity 에디터나 윈도우 빌드로 셋팅 되어 있는 상태에서 실행 하게 되면 

위와 같이 해당 타켓에서는 Webview를 지원 하지 않는다고 에러를 띄웁니다.

프로젝트를 모바일(안드로이드/iOS)로 하고

실제 모바일 기기에서 실행해야지 정상적으로 웹뷰 화면을 볼 수 있습니다. 

 

현재 사용 중인 예제.

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
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
using System;
using UnityEngine;
using System.Collections;
using System.IO;
using UnityEngine.UI;
//using LitJson;
 
namespace My
{
    // gree webview
    // https://github.com/gree/unity-webview
    // android 9에서는 AndroidManifest.xml에 android:usesCleartextTraffic="true"를 추가 해줌. 
    // AndroidManifest.xml : 프로젝트 빌드 -> project/Temp/StagingArea/ 파일 복사 Assets/Plugins/Android/에 복사.
    // <application android:theme="@style/UnityThemeSelector" android:icon="@mipmap/app_icon" android:label="@string/app_name" android:usesCleartextTraffic="true">
 
    // 혹은 
    // Unity Define 입력창에
    //    UNITYWEBVIEW_ANDROID_USES_CLEARTEXT_TRAFFIC
    // 을 입력 하고 빌드.
 
    public class MyWebView : MonoBehaviour
    {                
        public Button CloseButton;
 
        public float LeftMargin = 300;
        public float TopMargin = 50;
        public float RightMargin = 300;
        public float BottomMargin = 50;
        public bool IsRelativeMargin = true;
 
        [HideInInspector]
        public string URL;
 
        private WebViewObject webViewObject;
 
        void Start()
        {
            AlignCloseButton();
 
            // for Test
            Show("https://www.google.com/");
        }
 
        // Update is called once per frame
        void Update()
        {
            //if (Application.platform == RuntimePlatform.Android) {
            if (Input.GetKey(KeyCode.Escape))
            {
                // 뒤 로 가 기, esc 버 튼 
                if (webViewObject )
                {
                    if (webViewObject.gameObject.activeInHierarchy)
                    {
                        // webViewObject.GoBack();
                    }
                }
                Hide();
                return;
            }
            //}
        }
 
        private void OnDestroy()
        {
            DestroyWebView();
        }
 
        void DestroyWebView()
        {
            if (webViewObject)
            {
                GameObject.Destroy(webViewObject.gameObject);
                webViewObject = null;
            }
        }
 
        void AlignCloseButton()
        {
            if (CloseButton == null)
            {
                return;
            }
 
            float defaultScreenHeight = 1080;
            float top = CloseButton.GetComponent<RectTransform>().rect.height * Screen.height / defaultScreenHeight;
 
            TopMargin = top;
        }
 
        public void Show(string url)
        {
            gameObject.SetActive(true);
 
            URL = url;
            
            StartWebView();            
        }
 
        public void Hide()
        {
            // 뒤 로 가 기, esc 버 튼 
            URL = string.Empty;
 
            if (webViewObject != null)
            {
                webViewObject.SetVisibility(false);
 
                //webViewObject.ClearCache(true);
                //webViewObject.ClearCookies();                
            }
 
            DestroyWebView();
 
            gameObject.SetActive(false);
        }
 
        public void StartWebView()
        {
            string strUrl = URL;  //"https://www.naver.com/";            
 
            try
            {
                if (webViewObject == null)
                {
                    webViewObject = (new GameObject("WebViewObject")).AddComponent<WebViewObject>();
 
                    webViewObject.Init(
                        cb: OnResultWebView,
                        err: (msg) => { Debug.Log($"WebView Error : {msg}"); },
                        httpErr: (msg) => { Debug.Log($"WebView HttpError : {msg}"); },
                        started: (msg) => { Debug.Log($"WebView Started : {msg}"); },
                        hooked: (msg) => { Debug.Log($"WebView Hooked : {msg}"); },
 
                        ld: (msg) =>
                        {
                            Debug.Log($"WebView Loaded : {msg}");
                            //webViewObject.EvaluateJS(@"Unity.call('ua=' + navigator.userAgent)");                    
                        }
                        , androidForceDarkMode: 1  // 0: follow system setting, 1: force dark off, 2: force dark on
 
        #if UNITY_EDITOR
                        , separated: true
        #endif
 
                    );
                }
 
                webViewObject.LoadURL(strUrl);
                webViewObject.SetVisibility(true);
                webViewObject.SetMargins((int)LeftMargin, (int)TopMargin, (int)RightMargin, (int)BottomMargin, IsRelativeMargin);
            }
            catch (System.Exception e)
            {
                print($"WebView Error : {e}");
            }
 
        }
 
        void OnResultWebView(string resultData)
        {
            print($"WebView CallFromJS : {resultData}");
            /*
             {
                result : string,
                data : string or json string
            }
            */
 
            //try
            //{
            //    JsonData json = JsonMapper.ToObject(resultData);
 
            //    if ((string)json["result"] == "success")
            //    {
            //        JsonData data = json["data"]["response"];
            //        long birthdayTick = (long)(data["birth"].IsLong ? (long)data["birth"] : (int)data["birth"]);
            //        string birthday = (string)data["birthday"];
            //        string unique_key = (string)data["unique_key"];
 
            //        // success
            //    }
            //    else if ((string)json["result"] == "failed")
            //    {
            //        Hide();
 
            //        // failed
            //    }
            //}
            //catch (Exception e)
            //{
            //    print("웹 리턴 값에 문제가 있습니다.");
            //}
        }
    }
}
cs

 

소스의 핵심은

StartWebView() 메소드 입니다. 

   

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
        public void StartWebView()
        {
            string strUrl = URL;  //"https://www.naver.com/";            
 
            try
            {
                if (webViewObject == null)
                {
                    webViewObject = (new GameObject("WebViewObject")).AddComponent<WebViewObject>();
 
                    webViewObject.Init(
                        cb: OnResultWebView,
                        err: (msg) => { Debug.Log($"WebView Error : {msg}"); },
                        httpErr: (msg) => { Debug.Log($"WebView HttpError : {msg}"); },
                        started: (msg) => { Debug.Log($"WebView Started : {msg}"); },
                        hooked: (msg) => { Debug.Log($"WebView Hooked : {msg}"); },
 
                        ld: (msg) =>
                        {
                            Debug.Log($"WebView Loaded : {msg}");
                            //webViewObject.EvaluateJS(@"Unity.call('ua=' + navigator.userAgent)");                    
                        }
                        , androidForceDarkMode: 1  // 0: follow system setting, 1: force dark off, 2: force dark on
 
        #if UNITY_EDITOR
                        , separated: true
        #endif
 
                    );
                }
 
                webViewObject.LoadURL(strUrl);
                webViewObject.SetVisibility(true);
                webViewObject.SetMargins((int)LeftMargin, (int)TopMargin, (int)RightMargin, (int)BottomMargin, IsRelativeMargin);
            }
            catch (System.Exception e)
            {
                print($"WebView Error : {e}");
            }
 
        }
cs

 

webViewObject.Init(...)
: 웹뷰 초기화 및 기본 콜백 메소드 등록 함수 
                       cb: OnResultWebView  <== WebView에서 호출된 html에서 Unity.call(string)이 호출 되면 호출 된다.

HTML 쪽의 javascript 함수로 다음과 같이 Unity.call("json string")을 호출 하게 해주면

웹페이지에서 Unity쪽으로 메시지를 전달 받을 수 있다. 

 

웹페이지 소스의 호출 부분.

1
2
3
4
5
6
7
8
9
10
function sendMsgToUnity(msg) {
    //alert(msg );
    if (typeof Unity != "undefined") {
        Unity.call(msg);
    }
    else {
        //console.log(msg);
    
    }
}
cs

 

webViewObject.LoadURL(strUrl);

: 해당 웹 페이지 로드 ( URL도 되고 로컬 파일도 가능 )
webViewObject.SetVisibility(true);

: 화면을 띄움.

webViewObject.SetMargins((int)LeftMargin, (int)TopMargin, (int)RightMargin, (int)BottomMargin, IsRelativeMargin);

: 웹뷰가 앱 위에 보여 지는데 보여질 창의 상하좌우 여백 설정.

아래는 기본 심플 예제.
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
 
    public class WebView : MonoBehaviour
    {
        [HideInInspector]
        public string URL;
 
        private WebViewObject webViewObject;
 
        // Use this for initialization
        void Start()
        {
            //StartWebView();
        }
 
        // Update is called once per frame
        void Update()
        {
            //if (Application.platform == RuntimePlatform.Android) {
            if (Input.GetKey(KeyCode.Escape))
            {
                // 뒤 로 가 기, esc 버 튼 
                Hide();
                return;
            }
            //}
        }
 
        public void Show(string url)
        {
            gameObject.Show();
 
            URL = url;
            StartWebView();
        }
 
        public void Hide()
        {
            // 뒤 로 가 기, esc 버 튼 
            URL = string.Empty;
 
            if (webViewObject != null)
            {
                Destroy(webViewObject);
            }
 
            gameObject.Hide();
        }
        public void StartWebView()
        {
 
            string strUrl = URL;  //"https://www.naver.com/";
 
            try
            {
                webViewObject = (new GameObject("WebViewObject")).AddComponent<WebViewObject>();
                webViewObject.Init((msg) =>
                {
                    Debug.Log(string.Format("CallFromJS[{0}]", msg));
                });
 
                webViewObject.LoadURL(strUrl);
                webViewObject.SetVisibility(true);
                webViewObject.SetMargins(2005020050);
            }
            catchSystem.Exception e)
            {
                print($"WebView Error : {e}");
            }
        }
    }
 
cs

 

3. 에러 처리

[유니티][안드로이드] Unity WebView Android 9.0 이상에서 화면 안 나오고 에러 처리 방법

( WebView에서 하얀 화면만 나올 경우 )

https://dragontory.tistory.com/408

 

[유니티][안드로이드] Unity WebView Android 9.0 이상에서 화면 안 나오고 에러 처리

[유니티][안드로이드] Unity WebView Android 9.0 이상에서 화면 안 나오고 에러 처리 방법 유니티에서 웹페이지를 표시 하거나 웹브라우저를 사용 하기 위해서 웹뷰(WebView)를 사용 해야 하는데 유니티

dragontory.tistory.com

 

반응형