logo
Khóa học lập trình game server - smartfox - game đa người chơi Học lập trinh game online 3dvietpro Sửa chữa và thiết kế website .net
Welcome Guest! To enable all features please Đăng nhập or Đăng ký.

Thông báo

Icon
Error

Tùy chọn
Xem
Xem bài viết cuối Go to first unread
nhminh0701  
#1 Đã gửi : 30/07/2019 lúc 02:52:34(UTC)
nhminh0701

Danh hiệu: Newbie

Nhóm: Registered
Gia nhập: 16-07-2019(UTC)
Bài viết: 1
Viet Nam
Đến từ: Hà Nội

Cảm ơn: 1 lần
Chào các bạn, như các bạn đã biết ở trong nhiều game trên Android và IOS, game thủ có thể trải nghiệm của mình qua mạng xã hội. Game ở Unity cũng có thể có được chức năng này qua hard-coding hoặc sử dụng plugin từ Asset-store. Hôm nay mình muốn chia sẻ với các bạn 1 plugin rất hay của SÜLEYMAN YASIR KULA có tên là "Native Share for Android & IOS qua 1 ứng dụng đơn giản dùng để chụp và share màn hình (tức là ảnh chụp đó ạ) qua mạng xã hội.

Điều ta mong mỏi đạt được sau bài việt này

Giới thiệu qua về asset này thì đây là 1 "open-source" tức là code của project này được public trên github qua url cùng với thông tin về cách sử dụng
https://github.com/yasirkula/UnityNativeShare
cũng do đó mà hiển nhiên đây là 1 asset free. Về tính năng asset này sẽ giúp người sử dụng share được dữ liệu ở 1 vài dạng cơ bản (text, image, document, ect) qua các ứng dụng có tính năng share trên thiết bị với vài dòng code, tùy chỉnh unity project cơ bản. Sự khác biệt của việc sử dụng asset này trên android so với ios nằm ở phần thiết lập project unity. Ở bài này mình sẽ đi chủ yếu vào thiết lập android (do mình đang thiếu chuột thí nghiệm bên ios nên sau mình sẽ up thêm chú ý vào :(()

Sau khi tạo được 1 project mới, việc đầu tiên ta cần làm là import vật thí nghiệm (Native Share) từ asset store (hoặc bạn nào tải xuống từ github thì thả vào cũng được). Sau đó, để có thể thực hiên được chức năng share, bám theo hướng dẫn ở github, với dòng android ta cần đảm bảo tồn tại folder Assets/Plugins/Android và tại đó, có 1 file xml tên "AndroidManifest.xml" khai báo các thông tin cần thiết của ứng dụng này (ứng dụng ta đang xây trên unity) lên thiết bị android được cài đặt. Bản chất file "AndroidManifest.xml" này vốn tồn tại khi bạn cài platform Android nên việc cần làm đầu tiên là copy file này về từ file gốc ở 1 bản cài unity nào đó. Cụ thể hơn, file này ở folder Unity\Editor\Data\PlaybackEngines\AndroidPlayer, nếu bạn không thây ở folder này, file nằm ở subfolder Apk trong AndroidPlayer. Ví dụ địa chỉ file của mình:
Trích dẫn:
C:\Program Files\Unity\Hub\Editor\2019.1.10f1\Editor\Data\PlaybackEngines\AndroidPlayer\Apk


Sau đó tại Assets/Plugins/Android/AndroidManifest.xml, ta bổ sung thông tin "content provider" cho ứng dụng bằng cách thêm vào file xml đoạn với cú pháp sau trong tag <application></application>
Trích dẫn:
<provider
android:name="com.yasirkula.unity.UnitySSContentProvider"
android:authorities="MY_UNIQUE_AUTHORITY"
android:exported="false"
android:grantUriPermissions="true" />

Trong đó lưu ý, "MY_UNIQUE_AUTHORITY" cần được thay bằng 1 chuỗi kí tự đặc biệt hạn chế trùng với các ứng dụng khác do 2 ứng dụng có provider cùng authorities không thể được cài trên cùng 1 thiết bị. Có thể nói đây là bước thiết yếu để ta share được do ta đã thêm vào ứng dụng này thành phần "content provider". Thành phần này làm cho ứng dụng của ta như 1 trung gian, quản lý và cấp quyền truy xuất dữ liệu GIỮA CÁC ỨNG DỤNG KHÁC NHAU (ví dụ như việc truy xuất vào thư viện ảnh, lấy dữ liệu vả share lên mạng xã hội của các ứng dụng mạng xã hội tương ứng)

Tiếp đó để đơn giản hóa project này, mình sẽ tạo 1 nút vừa có tác dụng chụp lại (ghi lại) ảnh màn hình và ngay sau đó thực hiện chức năng share (hoặc bạn tạo 2 nút có 2 chức năng này riêng không sao).

Sau đó ta sẽ tạo 1 empty object để lưu vào đó function sẽ thực hiện thao tác trên (ta tạm gọi object này là "Event Object") để sau đó ta sẽ dung object này để khai báo event ở onclick của nút trên. Ở object này, tạo script có chứa các function thực hiện việc chụp ảnh, lưu ảnh và SHARE ảnh (mục tiêu chính ở đây là share ảnh, phần chụp lưu ảnh để tạo ảnh-mấy con hamster thí nghiệm, để share). Mình gọi script này tên là "ButtonEvents.cs".

Ở đây đầu tiên ta khai báo hàm chính-sẽ trở thành event onclick của nút

Trích dẫn:
public void ScreenCap()
{
StartCoroutine(CaptureScreen());
}


Ở đây ta dùng Coroutine để quản lý thời điểm thực hiện việc ghi lại ảnh. Cụ thể hơn, hàm chụp màn hình có cách xử lý đơn giản như sau


Trích dẫn:
IEnumerator CaptureScreen()
{
yield return new WaitForEndOfFrame();

string fileName = System.DateTime.Now.ToString("yyyy-MM-dd-HHmmss");

Texture2D ss = new Texture2D(Screen.width, Screen.height, TextureFormat.RGB24, false);
ss.ReadPixels(new Rect(0, 0, Screen.width, Screen.height), 0, 0);
ss.Apply();

string filePath = Path.Combine(Application.temporaryCachePath, fileName + ".png");
File.WriteAllBytes(filePath, ss.EncodeToPNG());

// To avoid memory leaks
Destroy(ss);
}


Nguyên nhân có dòng đầu tiên để đảm bảo GUI, camera được "render" hoàn thiện trước khi được hiển thị trên màn hình (cũng do ta chụp ảnh màn hình). Do đó ảnh sẽ được đảm bảo hoàn thiện. Hãy cẩn thận điểm này mỗi khi bạn định ghi lại ảnh (dù với bất kì cách nào hãy đừng quên)... Tiếp sau đó là phần chụp và lưu ảnh lại. Đầu tiên 1 khung Texture2D sẽ được tạo với format dựa trên kích thước màn hình (do ta chụp màn hình), sau đó cái khung này sẽ ghi lại vị trí và khoảng trên màn hình (ở cửa sổ game) tương ứng với object Rect được đưa vào qua 2 dòng lệnh

Trích dẫn:
ss.ReadPixels(new Rect(0, 0, Screen.width, Screen.height), 0, 0);
ss.Apply();


Object Texture2D (ở đây là "ss") mang thông tin về screenshot được encode về dạng PNG qua "ss.EncodeToPNG() rồi được dùng để ghi thành file .png tại 1 filePath nào đó chỉ vị trí chứa thư mục qua

Trích dẫn:
string filePath = Path.Combine(Application.temporaryCachePath, fileName + ".png");
File.WriteAllBytes(filePath, ss.EncodeToPNG());


Việc hủy object ss sau cùng bỏ đi object ss không còn tác dụng nhằm tối ưu bộ nhớ.

Cuối là món chính, "Native Share". Thực sự là để sử dụng cái plugin này.... bạn không cần import thêm 1 thư viện nào cả (tin mình đi, mình đã tìm hộc bơ "Native Share" ở phần khai báo). Ta có thể sử dụng, khai báo trực tiếp phương thức từ plugin này để thực hiện thao tác "Share" qua 1 dòng lệnh

Trích dẫn:
new NativeShare().AddFile(filePath).SetSubject("Screen Shot").SetText("Check This Out!").Share();


Trong đó filePath cũng như phần trước, là file ảnh cùng với vị trí của file, SetSubject/SetText giúp tạo thông điệp tự động cho chủ đề khi ta gửi dữ liệu qua mail/ messenger, ect (và ta vẫn chỉnh được chủ đề thư hay tin nhắn text chủ đề đi kèm)




Phần cuối của project này mình cũng muốn chia sẻ thêm 1 sản phẩm nữa của anh SÜLEYMAN YASIR KULA là "NATIVE GALLERY" sẽ giúp chúng ta lưu dữ liệu vào các mục kiểu "bộ sưu tập" trong thiết bị. Đây cũng là 1 asset free, open source https://github.com/yasirkula/UnityNativeGallery
thao tác cũng đơn giản như Native Share, cũng có yêu cầu về thiết lập.

Để sử dụng được asset này, sau khi bạn import từ asset store, vào edit->project setting->player->Configuration, ở đây write permission ta chọn "External(SD card)" và như vậy khi ảnh được lưu dưới sự điều chỉnh từ asset này, một hộp thoại sẽ hiện lên hỏi người sử dụng về cấp quyền truy cập thư viện ảnh, bộ nhớ, ect cho ứng dụng (quen k ta). Và tương tự như Native Share, ta không cần khai báo thư viện và tác vụ chỉ đơn giản 1 dòng code


Trích dẫn:
NativeGallery.SaveImageToGallery(ss.EncodeToPNG(), "Test Album", fileName + ".png");


Ở đây cần chú ý là ứng dụng sẽ tạo 1 album tên là "Test Album" ở bộ sưu tập rồi ghi dữ liệu từ bytes[] ss.EncodeToPNG() dưới 1 file tên fileName + ".png".

Dưới tác dụng của NativeGallery, file được lưu vào 1 album khởi tạo tên "Test Album" (được đánh dấu xanh)

Vậy code đầy đủ của ButtonEvents.cs là

Trích dẫn:
using System.Collections;
using UnityEngine;
using System.IO;

public class ButtonEvents : MonoBehaviour
{
public void ScreenCap()
{
StartCoroutine(CaptureScreen());
}

IEnumerator CaptureScreen()
{
yield return new WaitForEndOfFrame();

string fileName = System.DateTime.Now.ToString("yyyy-MM-dd-HHmmss");

Texture2D ss = new Texture2D(Screen.width, Screen.height, TextureFormat.RGB24, false);
ss.ReadPixels(new Rect(0, 0, Screen.width, Screen.height), 0, 0);
ss.Apply();

string filePath = Path.Combine(Application.temporaryCachePath, fileName + ".png");
// Save to system
File.WriteAllBytes(filePath, ss.EncodeToPNG());
// Save to Gallery
NativeGallery.SaveImageToGallery(ss.EncodeToPNG(), "Test Album", fileName + ".png");
// To avoid memory leaks
Destroy(ss);

new NativeShare().AddFile(filePath).SetSubject("Screen Shot").SetText("Check This Out!").Share();
}
}


Trong đó thư viên System.IO quản lý các hàm liên quan tới truy xuất file như Path.

Vậy đó là những gì chúng ta có thể dùng để tạo 1 tính năng screenshot, share dữ liệu qua mạng xã hội. Mong các bạn tìm được điều gì đó mới cho mình từ bài này và cũng mong nhận được phản hồi góp ý từ các bạn về các tính năng mình kể trên. Mình sẽ nghiên cứu tiếp về thực hiện trên IOS và bàn với các bạn sau.

Link down các asset
Link down Native Share
https://assetstore.unity.com/packages/tools/integration/native-share-for-android-ios-112731

Link down Native Gallery
https://assetstore.unity.com/packages/tools/integration/native-gallery-for-android-ios-112630


Tài liệu tham khảo

Native Gallery
https://github.com/yasirkula/UnityNativeGallery

Native Share
https://github.com/yasirkula/UnityNativeShare

Tổng quan về Content Provider trong Android
https://viblo.asia/p/android-content-provider-p1-tong-quan-cach-chia-se-du-lieu-giua-2-hoac-nhieu-ung-dung-khac-nhau-63vKj0nNl2R

Documentation của Unity: ScreenCapture.CaptureScreenshotAsTexture (để giải thích sao ta cần WaitForEndOfFrame())
https://docs.unity3d.com/ScriptReference/ScreenCapture.CaptureScreenshotAsTexture.html

Bởi Nguyễn Hoàng Minh

Sửa bởi người viết 30/07/2019 lúc 11:27:49(UTC)  | Lý do: Bổ sung ảnh, link tài liệu và ứng dụng

Bạn bình luận ngay tại đây
Ai đang xem chủ đề này?
Guest
Di chuyển  
Bạn không thể tạo chủ đề mới trong diễn đàn này.
Bạn không thể trả lời chủ đề trong diễn đàn này.
Bạn không thể xóa bài của bạn trong diễn đàn này.
Bạn không thể sửa bài của bạn trong diễn đàn này.
Bạn không thể tạo bình chọn trong diễn đàn này.
Bạn không thể bỏ phiếu bình chọn trong diễn đàn này.

Powered by YAF 2.1.0 | YAF © 2003-2019, Yet Another Forum.NET
Thời gian xử lý trang này hết 0.163 giây.


close(x)