Just 4 fun!

Of course I can change the world, If you give me a source code

Post Ads (Documentation)

Author Info (Documentation)

style="display:block"
data-ad-client="ca-pub-2623284640924516"
data-ad-slot="8347113188"
data-ad-format="auto">

Friday, July 5, 2019

Cô đơn chưởng pháp từ cơ bản đến nâng cao


Để mở đầu thì đây không phải là bài viết về cách (thoát) độc thân :)) Đây là về Singleton trong Unity, mình giật tít tí thôi :P

I. Singleton để làm gì?
    Mình sẽ giả vờ rằng bạn chưa hề biết tí gì về singleton trong bất cứ ngôn ngữ nào. CÒn nếu bạn đã biết rồi thì có thể bỏ qua phần này và kéo xuống những phần sau đọc giải trí :3.
Ở trong bài viết "Mấy ông game dev ơi, đừng dùng GameObject.Find nữa đi!" mình có đề cập đến việc truy cập đến component của gameobject khác thông qua biến public hoặc SerializeField. Nhưng giả sử bạn đảm bảo rằng một đối tượng A trong scene chỉ có nó là duy nhất, không tồn tại một thằng gameobject thứ 2 cũng có component A, và rất nhiều đối tượng khác cần truy cập đến thằng A, bao gồm cả những đối tượng mới sinh ra trong quá trình game chạy. Vậy thì việc dùng public hoặc SerializeField rồi kéo thả A vào từng thằng là ko thể. Đó là lúc mình cần dùng đến Singleton.

II. Cô đơn chưởng pháp chiêu thứ nhất:
    Vậy cách triển khai singleton cơ bản nhất là gì? Nó như sau:

    public class A{
        private static A instan = null;
        public static A _Instan{
            get{
                return instan;
            }
        }

        void Awake(){
            instan = this; //Gán đối tượng vào biến instan khi scene chạy
        }
    }

Đầu tiên, mình cần khai báo một biến static là instan để chứ chính đối tượng cần singleton. Vậy tại sao phải để là private? Để đảm bảo chỉ có chính nó mới đc phép gán hoặc bỏ những class khác chỉ đc phép lấy nó ra và dùng, và lấy ra bằng cách gọi A._Instan như mình đã khai báo biến static _Instan public và chỉ được phép get. Hiểu được đến đây là xong chiêu thứ nhất.

III. Cô đơn chưởng pháp chiêu thứ hai:
    Chiêu thứ nhất căn bản vkl, nên nó sẽ tồn tại nhiều sơ hở cho đối phương khai thác. Ví dụ nhỡ tay thả 2 thằng gameobject cùng gắn component A vào scene, vậy khi scene start sẽ có ngay 2 thằng instance của A đc tạo ra, còn gì là singleton nữa T_T. VÍ dụ khác, có một class B cũng là singleton, cơ mà chưa có đối tượng nào cần truy cập, nhưng mặc định lúc Awake vẫn tạo ra một instance của B, lãng phí vl lãng phí. Nên ta phải sửa lại như sau:

    public class A{
        private static A instan = null;
        public static A _Instan{
            get{
                if (instan == null) {
                    instan = FindObjectOfType ();
                }

                if (instan == null) {
                    GameObject obj = new GameObject ();
                    instan = obj.AddComponent (A);
                }
                return instan;
            }
        }

    }

Đấy, chiêu thức biến ảo vl rồi, chuyển thành tâm pháp cho dễ học thuộc nè. Đầu tiên để tránh instance 2 object cùng lúc thì ta sẽ kiểm tra xem no đã tồn tại chưa bằng FindObjectOfType(). Ok, nếu chứ tồn tại thì tạo một thằng gameobject mới rồi add nó vào và trả về cho người cần thôi, EZ vkl. Đến đây là đủ để hạ khối đứa rồi đếi, nhưng mình là một thằng lười vkl, cho nên, phải sáng tạo ra đường tắt.

IV. Cô đơn chưởng pháp chiêu thứ ba:
    Bây giờ một game mình có ít thì vài cái nhiều thì vài chục cái cần dùng singleton. Chả nhẽ cứ phải code đi code lại cái đoạn như kia à. Đéo, lười vl, dỗi vl :((
Nên, mình mới tạo một class như sau:

    public class SingletonClass<T>: MonoBehaviour where T: MonoBehaviour
    {
        private static T instan;

        public static T _Instan
        {
            get
            {
                if (instan == null) {
                    instan = (T)FindObjectOfType(typeof(T));
                }

                if (instan == null) {
                    GameObject obj = new GameObject ();
                    instan = obj.AddComponent<T>();
                }
                return instan;
            }
        }
    }

Xong, giờ mỗi class muốn singleton mình chỉ việc kế thừa từ thằng SingletonClass mình vừa tạo thôi:

    A:SingletonClass<A>

ngon lành chưa. Chém ko trượt phát nào nhé :)))

Nói chung đến đây là hết rồi, để mình nghĩ xem còn lười thêm đc phần nào nữa ko bổ sung tiếp trong các bài viết sau nhé :3 Chúc các bạn độc thân vui vẻ :P