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, June 17, 2016

Mấy ông Dev Unity ơi, đừng dùng GameObject.Find nữa đê!


(Quan điểm cá nhân)
Tại sao?
 Unity cung cấp một số phương pháp để tiếp cận và tham chiếu đến một đối tượng (GameObject) trong một Scene, một trong số các phương pháp đó là duyệt qua tất cả các GameObject và các đối tượng con có trong scene và tìm ra đối tượng cần tham chiếu nhờ tên của nó. Lúc đầu mình thường xuyên sử dụng cách này và thấy nó thật là fucking awesome. Nhưng giờ, mình biết được tốt nhất là không nên sử dụng nó. Tại sao? hãy nhìn vào ví dụ sau. Đây là mộn script đếm và hiển thị ra có bao nhiêu đối tượng trong Canvas của scene:

using UnityEngine;
using UnityEngine.UI;

public class ShowNumberOfCanvasChildren : MonoBehaviour

{
    private GameObject _canvas;
    private Text _childText;

    private void Start()

    {
        // grab an object in the scene called Canvas
        _canvas = GameObject.Find("Canvas");

        // and grab some text in a child of the object

        // that this script is attached to
        _childText = this.transform.FindChild("ChildText").GetComponent<Text>();
    }

    private void Update()

    {
        // on every frame, modify that text
        _childText.text = "Canvas child count: " + _canvas.transform.childCount;
    }
}

Mình có thể liệt kê ra những vấn đề như sau:
   1.Mình thực sự không biết cái tên đó có tồn tại hay không? Dĩ nhiên là cả 2 đều do mình đặt, nhưng nếu mình gõ nhầm "Canvas" thành "Camvas" hoặc quên mất và đặt tên "ChildText" thành "ChildTextObject". Tất nhiên là chương trình vẫn chạy, tất nhiên là biên dịch không thể  phát hiện ra lỗi đặt tên sai của mình được, và mình cũng thế, cho đến khi game chạy không như những gì mình muốn và mình phải xem lại code, đối chiếu với tên đối tượng trong scene. Đấy là trong trường hợp một Project nhỏ, thử tưởng tượng một Project với hàng trăm đối tượng trong scene và hàng trăm dòng code. Thôi mình không muốn tưởng tượng nữa đâu :v
   2.Với cách code như trên, mình không thể thay đổi thứ tự của các GameObject trong scene. Mình không thể cho một đối tượng con ra ngoài hoặc đặt đối tượng cha cho một GameObject. Đơn giản là khi mình làm thế, đoạn code kia sẽ bỏ qua, không tìm đến GameObject đó nữa và tất nhiên, game sẽ chạy không như ý mình.
   3.Mình không thể đổi tên đối tượng một cách tự do. Như vấn đề 1, nếu mình muốn đổi tên một GameObject, mình phải tìm nó trong scene, đổi tên, mở Script, tìm đoạn code, sửa lại đoạn text trong đó cho giống với tên mới. Và tất nhiên, với một Project to thì mình sẽ bỏ cuộc trước khi bắt đầu (y).
Đó là tất cả những vấn đề mà đoạn code trên gặp phải. Nếu bạn áp dụng phương pháp tương tự như này vào trong code của mình thì. Đơn giản là mỗi script chỉ có thể áp dụng trong một trường hợp đặc biệt và không thể tái sử dụng. Điều này làm lãng phí tài nguyên không đáng có và tất nhiên là cũng gây khó khăn trong việc quản lí hơn rất nhiều.
Vậy, cách tốt hơn là gì?
Thay vì khai báo biến private trong script, cách tốt hơn là khai báo chúng public. Bằng cách đó, ta có thể biết chính xác script đó dùng để làm gì và cần những gì, như sau:

using UnityEngine;
using UnityEngine.UI;

public class ShowNumberOfCanvasChildren : MonoBehaviour

{
    public GameObject Canvas;
    public Text NumChildrenText;

    private void Update()

    {
        NumChildrenText.text = "Canvas child count: " + Canvas.transform.childCount;
    }
}

Ngoài ra, nếu bạn không thích dùng public thì có thể dùng SerializeField. Tất nhiên, mình thuộc phần thích dùng public nên mình sẽ chẳng thèm quan tâm đến cái SerializeField kia :v
Tóm lại là dù dùng cách nào thì sau đó, bạn cũng trông thấy nó như thế này

Tốt hơn rồi đấy, bây giờ bạn có thể thấy code của mình phụ thuộc vào đối tượng Canvas và Text. Giờ chỉ việc kéo thả đối tượng vào đúng vị trí của nó.

Đỡ hơn chưa, giờ mình có thể đổi tên và thay đổi cha con thoải mái mà chẳng cần phải dò code để sửa từng tí một, hãy nhớ và áp dụng vào những dự án của các bạn nhé. Chúc thành công!

1 comment:

  1. chào anh. anh cho em hỏi nếu đối với những script được đặt trong prefabs thì ta không thể kéo thả đối tượng từ khung hierarchy vào prefabs của đối tượng đó thì ta phải xử lí như thế nào. em cảm ơn.

    ReplyDelete