Sự khác biệt giữa việc sử dụng GetComponent <Transform> () và this.transform là gì?


7

Tôi đã đọc một số mã ví dụ và làm việc trên công cụ của riêng tôi trong Unity. Tôi đã nhìn thấy rất nhiềuGetComponent<>() , và thường thì điều này sẽ được thực hiện cho việc chuyển đổi như Transform _transform = GetComponent<Transform>().

Tuy nhiên, tôi đã có quyền truy cập vào các biến thể đối tượng trò chơi đính kèm, như transform, this.transformhoặc gameObject.transform. Tôi có thể hiểu việc sử dụng GetComponent()trong hầu hết các trường hợp, nhưng tại sao bạn lại sử dụng cụ thể chức năng cho GameObjectTransformkhi hai mục có thể truy cập được từ tập lệnh để bắt đầu?


1
Không có sự khác biệt trong kết quả cuối cùng.
Savlon

Câu trả lời:


11

Tốc độ (nhanh đến chậm):

cached _transform >> Component.transform >> Component.GetComponent<Transform>

Và nếu bạn tháo rời nhị phân UnityEngine.dll C #, bạn có thể thấy biến đổi không gọi GetComponent (thành viên lớp Thành phần), chỉ cần gọi phương thức thời gian chạy đơn nội bộ. Đây là mã biến đổi.

// UnityEngine.Component
public Transform transform
{
    get
    {
        return this.InternalGetTransform();
    }
}

[WrapperlessIcall]
[MethodImpl(MethodImplOptions.InternalCall)]
internal extern Transform InternalGetTransform();

Và đây là Phương thức GetComponent của lớp Thành phần được phân tách.

public extern Component GetComponent(Type type);
public T GetComponent<T>() where T : Component
{
    return this.GetComponent(typeof(T)) as T;
}
[WrapperlessIcall]
[MethodImpl(MethodImplOptions.InternalCall)]
public extern Component[] GetComponents(Type type);

GetComponent là một loại chức năng Tìm kiếm bằng cách sử dụng thuốc generic. Vì vậy, nó chậm hơn một chút so với bộ nhớ đệm.


Nguồn chính thức :

public class Test : MonoBehaviour
{
    Transform _transform;
    void Start()
    {
        _transform = this.transform;
        _transform = gameObject.GetComponent<Transform>();
    }
}

Nhị phân nhị phân:

public class Test : MonoBehaviour
{
    private Transform _transform;
    private void Start()
    {
        // == UnityEngine.Component::get_transform()
        this._transform = base.get_transform(); 

        // == UnityEngine.Component::GetComponent<UnityEngine.Transform>()
        this._transform = base.get_gameObject().GetComponent<Transform>();
    }
}

8

Như Jinbom đã nói sự khác biệt chính ở đây là tốc độ.

Tuy nhiên, điều quan trọng cần lưu ý là đây chỉ là trường hợp cho thuộc tính biến đổi của GameObject. Các thuộc tính khác như máy ảnh và máy cứng chỉ là các thuộc tính tiện lợi và gọi GetComponent <> dưới mui xe để hiệu suất giống hệt nhau. Vì lý do này, Unity đã hủy bỏ các thuộc tính 'người trợ giúp' này trong Unity vì không rõ ràng rằng Unity sẽ tìm kiếm thành phần thay vì trả về một phiên bản được lưu trong bộ nhớ cache.

Ngoại trừ thuộc tính biến đổi được đề cập trong câu hỏi, tất cả các thành phần khác phải được lưu vào bộ đệm tại cơ hội có sẵn đầu tiên bằng cách sử dụng GetComponent <> và giá trị được lưu trong bộ nhớ cache đó sẽ được sử dụng sau đó.


0

Ngay bây giờ bạn có thể giả định rằng mọi đối tượng trò chơi sẽ có thành phần Transform do this.transformcú pháp. Tôi đoán là Unity đã cập nhật API của mình với GetComponent<>()cú pháp để trong tương lai bạn có thể có GameObject mà không có các thành phần "đặc biệt" như Transform.

Sau đó, bạn có thể có kiến ​​trúc "tinh khiết hơn" trong đó GameObject của bạn không phải đi kèm với Biến đổi (mặc dù trình chỉnh sửa vẫn có thể thêm chúng theo mặc định như một quy ước).


Transform thành phần duy nhất hoạt động theo cách này. Bất kể, tôi không nghĩ rằng sự phụ thuộc vào đầu cơ trong tương lai sẽ cho một câu trả lời tốt. Unity đã không đưa ra bất kỳ đề nghị nào về việc di chuyển theo cách này và cá nhân tôi nghi ngờ họ sẽ (cho rằng việc có một đối tượng vật lý trong trò chơi của bạn yêu cầu đối tượng đó phải chứa thông tin phù hợp với trạng thái vật lý của nó, chẳng hạn như vị tríkích thước ).
Gnemlock

Ngoài ra, điều này dường như để bình luận về câu hỏi của tôi, nhưng không trả lời nó.
Gnemlock

-1

Lý do duy nhất this.transformhoạt động hoàn toàn là vì MonoBehavior thực hiện một thuộc tính tiện lợi cho thành phần Transform trên GameObject mà hành vi được đính kèm. ... Nó khá sai lệch. Tôi nghĩ gameObject.transformlà đúng hơn về mặt ngữ nghĩa, nhưng đó là chia tóc. Họ làm điều tương tự.


Điều này cung cấp không có gì để trả lời câu hỏi thực tế của tôi. Lý do duy nhất bất cứ điều gì hoạt động là vì nó đã được thiết lập, quan điểm của bạn là gì? Tôi đang hỏi về sự khác biệt giữa this.transformGetComponent<Transform>(), không this.transformgameObject.transform.
Gnemlock

Một lần nữa, họ làm điều tương tự.
xanh
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.