Mã nào trong hai mã này là 'tốt hơn'? Làm biến cục bộ hay biến lớp?


11

Tôi đang làm nhiều trò chơi hơn và hỏi những câu hỏi ngu ngốc hơn.

Hy vọng rằng điều này là rất ngắn gọn. Tôi đang tạo một lớp rất cơ bản, chỉ di chuyển một đối tượng Người chơi bằng cách tác dụng lực lên một người cứng nhắc, nhưng điều đó làm tôi băn khoăn, liệu tôi có nên tạo một tham chiếu lớp cho rb hay chỉ là một biến cục bộ trong Cập nhật mọi khung hình? (ghi nhớ rằng nó đã tồn tại trong lớp cha mẹ đơn nhất Monobehaviour.GameObject).

Tôi tự hỏi nếu thực hiện nhiều biến cục bộ sẽ làm chậm toàn bộ vòng lặp (theo ý tôi cục bộ bên trong hàm chứ không phải ở đầu lớp - hy vọng tôi sử dụng thuật ngữ chính xác).

Ý tôi là đây, hai cách tôi nghĩ khi làm nó:

public class Player : MonoBehaviour {

private void FixedUpdate()
{
    Rigidbody rb = GetComponent<Rigidbody>();

    float v = Input.GetAxis("Vertical");

    rb.AddForce(v * rb.transform.forward * Const.walkForce);
}
}

hoặc là...

public class Player : MonoBehaviour {
Rigidbody rb;

private void Awake()
{
    rb = GetComponent<Rigidbody>();
}

private void FixedUpdate()
{
    float v = Input.GetAxis("Vertical");

    rb.AddForce(v * rb.transform.forward * Const.walkForce);
}
}

4
Điều này có vẻ giống như một câu hỏi để xem xét mã SE.
Orphevs

1
Bạn cũng có thể làm nổi và tài sản lớp.
Chad

Cuối cùng tôi có lẽ sẽ thực sự là Chad, vì tôi sẽ sử dụng nó theo hai phương thức trong lớp. Nó thực sự chỉ là mã đơn giản để có được câu hỏi về các biến cục bộ và biến lớp mà không làm mờ nó với rất nhiều mã. Tôi thực sự thích giữ các biến cục bộ (và 'tránh đường' như nó ở đâu!) Nhưng tất nhiên tôi phải đảm bảo rằng tôi không bắt đầu sao chép mọi thứ thay vì có một biến lớp cho mỗi biến.
Big T Larrity

Một đoạn mã không phải là "mã". Hỏi về "mã nào tốt hơn" khiến bạn trông giống như một người nghiệp dư.
Miles Rout

1
Tôi là một người nghiệp dư nên điều đó rất tốt với tôi, cảm ơn Miles
Big T Larrity

Câu trả lời:


25

Nói chung, tôi thấy rằng bạn nên bắt đầu phạm vi dữ liệu càng hẹp càng tốt để bắt đầu và mở rộng phạm vi khi bạn phát hiện ra mình cần. Điều đó có nghĩa là nếu bạn có thể biến nó thành một biến cục bộ thay vì thành viên, có lẽ bạn nên bắt đầu từ đó.

Điều này là do phạm vi hẹp hơn làm giảm số lượng vị trí trong mã nơi bạn phải suy luận về dữ liệu đó và do đó làm giảm số lượng vị trí bạn có thể suy luận về dữ liệu đó không chính xác (dẫn đến lỗi).

Trên thực tế, chỉ riêng việc khai báo các biến cục bộ sẽ không bao giờ trở thành mối quan tâm về hiệu năng: chúng rẻ và các trình biên dịch hiện đại thậm chí có thể tối ưu hóa các "tính năng bổ sung".

Khởi tạo chúng có thể là một mối quan tâm; trong trường hợp của bạn, cơ thể cứng nhắc của bạn được tìm kiếm mỗi lần thông qua GetComponent, có một số chi phí khác không. Nếu bạn biết rằng thành phần cơ thể cứng nhắc sẽ không thay đổi cho đối tượng trò chơi cụ thể này, bạn có thể tra cứu nó một lần và lưu kết quả vào một biến thành viên và tránh một chút chi phí cho mỗi cuộc gọi.

Không chắc rằng chi phí cho mỗi cuộc gọi sẽ có ý nghĩa trong trường hợp này, nhưng theo thời gian, việc này đối với nhiều thành phần có thể tăng lên. Bạn muốn áp dụng một hồ sơ để chắc chắn.

Vì vậy, để tóm tắt: nói chung, mặc định làm cho mọi thứ trở nên cục bộ nhất có thể, nhưng trong trường hợp này có thể hợp lý để tạo rbthành viên để bạn có thể thực hiện tra cứu một lần Awakevà tránh phải thực hiện mỗi FixedUpdatecuộc gọi.


1
cảm ơn Josh, tôi đã cảm thấy sẽ tốt hơn nếu rb khởi tạo chỉ một lần, và cảm ơn rất nhiều vì đã giải thích rõ ràng lý do tại sao. Thật tuyệt khi biết chắc chắn, bạn thấy tôi không chắc chắn 100% rằng GetComponent được tính là khởi tạo nó mỗi lần, hoặc chỉ đơn giản là 'tìm kiếm nó' từ Monobehaviour. Nhưng bây giờ tôi nhận được rất nhiều lời cảm ơn vì câu trả lời hữu ích siêu nhanh
Big T Larrity

1
@SuperMegaBroBro GetComponent khá nhanh - bạn sẽ khó thực hiện bất kỳ loại tra cứu có tốc độ tương đương. Trừ khi bạn có dữ liệu hiệu suất cho thấy đó là một vấn đề, hãy kiên trì với phương pháp "giữ mọi thứ cục bộ". Bạn luôn có thể tối ưu hóa nó sau này. Xem answer.unity.com/questions/185164/ từ Đừng quên rằng bộ nhớ đệm cũng không miễn phí - nếu bạn lưu trữ mọi bộ nhớ GetComponenttrong trò chơi của mình, điều đó có thể sẽ bị mất mạng. Đo lường. Xác định nơi tối ưu hóa có giá trị nó. Tập trung vào việc tạo ra một trò chơi tuyệt vời :)
Luaan

1
Ý chính bạn nên bỏ qua câu trả lời này (khá tốt) là: Nếu bạn muốn tìm mã dễ hiểu nhất, để kiểm tra và để đảm bảo rằng nó không có lỗi, hãy lấy biến cục bộ. Nhưng, như mọi khi, đôi khi chúng ta cần phải hy sinh để hoàn thiện mã vì lý do hiệu năng, vì vậy một thành viên trong lớp có thể phù hợp (nhưng trước tiên, không nên tối ưu hóa sớm).
Polygnome

cảm ơn rất nhiều người, đặc biệt là Luaan vì tôi đã tự hỏi về vấn đề 'bộ nhớ đệm' đó trong khi tôi viết câu hỏi ban đầu (nhưng tôi không thực sự biết cách nói từ đó). Tôi chắc chắn sẽ thực hiện phương pháp 'địa phương' càng nhiều càng tốt. cảm ơn vì tất cả sự giúp đỡ tuyệt vời như các fellas thông thường.
Chuyện lớn

2

Câu trả lời của Josh Petrie là rất tốt - đây là một quan điểm bổ sung.

Khi bạn làm việc với mã mà bạn hiểu miền khá tốt, bạn có thể phạm vi biến đến nơi chúng có ý nghĩa.

Ví dụ, nếu tôi có một Personlớp với một waveGoodbyephương thức, có thể lớp của tôi không có handđối tượng trước đó và vì vậy tôi có thể khai báo nó cục bộ waveGoodbye. Bây giờ ở đây rõ ràng là một người có một bàn tay để bạn có thể tự nhiên tuyên bố nó là một thành viên Personmà không nghĩ về nó, nhưng vấn đề tương tự được áp dụng.

Nếu bạn tuyên bố hand cục bộ thì sau này bạn có thể thêm một karateChopphương thức cũng cần một bàn tay. Đây là khi khai báo các biến cục bộ có thể trở nên có vấn đề - bởi vì các nhà phát triển cơ sở thường quay lại sao chép / dán khai báo từ đó waveGoodbyevà bây giờ bạn có cùng một khái niệm nằm ở hai điểm. Bất kỳ thay đổi nào handsau đó cần phải được sửa đổi ở cả hai nơi và do đó bắt đầu một đồi kiến .

Vì vậy tất cả trong tất cả,

  1. Nếu bạn tự tin vào vị trí khai báo của mình, hãy đưa nó vào vị trí hợp lý.

  2. Nếu bạn không tự tin, thì hãy bắt đầu cục bộ và đảm bảo cấu trúc lại khi bạn nhận được một lần sử dụng lại mã.

Chỉnh sửa: Ồ và đừng phạm sai lầm tương tự tôi đã dành quá nhiều thời gian để tìm ra nơi để khai báo các tuyên bố của bạn. Thật khó để hiểu cấu trúc dữ liệu của bạn ở phía trước và khi bạn viết mã của mình, cấu trúc có một cách để lộ chính nó.


2
Cũng có những thứ được sắp xếp một cách tự nhiên, như mọi người Personnên có thành viênhand nên có trong ứng dụng, thường giúp các nhà phát triển khác (hầu hết các bạn 6 tháng sau) hiểu rõ hơn về mã. Trong trường hợp này, có vẻ logic khi có một Rigidbodythành viên của bạn Playervà, tôi nói nhiều hơn, ngay cả khi điều đó ngụ ý hiệu suất kém hơn. Trong các trò chơi video là một điểm có liên quan để xem xét, nhưng tôi nghĩ trong mã , để rõ ràng thường quan trọng hơn
kể cả

1
câu trả lời tuyệt vời cảm ơn các bạn. Tôi không cố tỏ ra là một người hiểu biết, nhưng tất cả những câu trả lời này vừa khẳng định lại những gì tôi đã nghĩ, vì vậy lần đầu tiên tôi rất vui và đạt được những tiến bộ tốt đẹp trong các trò chơi của mình. Ngay bây giờ tôi đang làm một trò chơi bóng đá 3d với hình ảnh động và mọi thứ phù hợp, thực hiện những bước tiến thực sự: D tôi sẽ sớm có mặt ở đây để giúp tôi làm thế nào để làm cho nó 2 người chơi và tôi dám nói người chơi trực tuyến: D có những người vui vẻ và cảm ơn một lần nữa!
Big T Larrity
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.