이 두 코드 중 어느 것이 더 낫습니까? 지역 변수 또는 클래스 변수를 만드시겠습니까?


11

더 많은 게임을 만들고 더 어리석은 질문을합니다.

잘만되면 이것은 매우 간단하다. 강체에 힘을 가하여 Player 객체를 이동시키는 매우 기본적인 클래스를 만들고 있습니다.하지만 매 프레임마다 Update 내에서 rb 또는 로컬 변수에 대한 클래스 참조를 만들어야합니까? (이것은 Monobehaviour.GameObject unity parent 클래스에 이미 존재한다는 것을 명심하십시오).

많은 지역 변수를 수행하면 루프가 전체적으로 느려질 지 궁금합니다 (지역에 따라 함수 자체 내부를 의미하며 클래스의 상단이 아니라 올바른 용어를 사용하기를 바랍니다).

여기 내가 생각하는 두 가지 방법이 있습니다.

public class Player : MonoBehaviour {

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

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

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

또는...

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
이것은 코드 검토 SE에 대한 질문처럼 보입니다.
— Orphevs

1
float va class 속성을 만들 수도 있습니다.
— 차드

나는 아마도 실제로 Chad를 끝낼 것입니다. 왜냐하면 클래스 내에서 두 가지 방법으로 사용할 것입니다. 많은 코드로 그것을 부 풀리지 않고 로컬 대 클래스 변수에 대한 질문을 얻는 것은 실제로 간단한 코드였습니다. 나는 변수를 로컬로 유지하는 것을 좋아하고 (그리고 어디에서나 '정지'!) 물론, 물론 각각에 대해 하나의 클래스 변수를 갖는 대신 물건을 복제하지 않도록해야합니다.
— Big T Larrity

코드 스 니펫은 '코드'가 아닙니다. '어떤 코드가 더 좋은지'물어 보면 아마추어처럼 보입니다.
— Miles Rout 2018 년

1
나는 아마추어입니다 나와 함께 먹으 렴 미세 감사 마일 그래서
— 빅 T Larrity

답변:


25

일반적으로 데이터 범위를 최대한 좁혀서 범위를 넓히고 범위를 넓혀야한다는 것을 알게되었습니다. 즉 , 멤버 대신 로컬 변수로 만들 수 있다면 시작해야 할 것입니다.

범위가 좁을수록 코드에서 해당 데이터에 대해 추론해야하는 장소 수가 줄어들 기 때문에 잘못 추론 할 수있는 장소 수가 줄어들 기 때문입니다 (버그로 이어짐).

실제로 로컬 변수 만 선언 해도 실제로 성능 문제가되지는 않습니다. 싸고 최신 컴파일러는 "extras"를 최적화 할 수도 있습니다.

그것들을 초기화하는 것이 문제가 될 수 있습니다. 귀하의 경우 강체는을 통해 매번 조회되며 GetComponent, 이는 0이 아닌 비용입니다. 이 특정 게임 오브젝트에 대해 강체 구성 요소가 변경되지 않는다는 것을 알고 있다면 한 번 찾아서 멤버 변수에 결과를 저장하고 호출 당 약간의 오버 헤드를 피할 수 있습니다.

이 경우에는 통화 당 오버 헤드가 크지 않을 것 같지만 시간이 지남에 따라 많은 구성 요소에 대해이 작업을 수행하면 결과가 더해질 수 있습니다. 확실하게 프로파일 러를 적용하고 싶을 것입니다.

요약하자면, 일반적으로 기본적으로 가능한 한 로컬로 설정하는 것이 좋지만,이 경우 rb멤버 를 만들어 한 번에 조회 Awake를 수행하고 매번 FixedUpdate호출 하지 않아도 되도록 멤버 를 만드는 것이 합리적 입니다.


1
Josh에게 감사합니다. rb를 한 번만 초기화하는 것이 더 좋을 것이라고 생각했으며 그 이유를 분명히 설명해 주셔서 대단히 감사합니다. GetComponent가 매번 초기화하는 것으로 100 % 확신하지 않았거나 Monobehaviour에서 단순히 '찾아 보는'것이 100 % 확실하지 않다는 것을 알면 기쁩니다. 하지만 지금은 그것에게 슈퍼 빠른 도움이 답변에 대한 많은 감사를 얻을
— 빅 T Larrity에게

1
@SuperMegaBroBro GetComponent 는 매우 빠릅니다. 속도가 비슷한 모든 종류의 조회를 수행하기가 어렵습니다. 문제를 시사하는 성능 데이터가 없으면 "로컬을 유지"접근 방식을 사용하십시오. 나중에 언제든지 최적화 할 수 있습니다. answers.unity.com/questions/185164/…를 참조하십시오. 캐싱도 무료가 아님을 잊지 마십시오. GetComponent게임에서 모든 것을 캐싱 하면 순 손실 이 될 수 있습니다. 법안. 최적화가 가치가있는 곳을 식별하십시오. 훌륭한 게임을 만드는 데 집중하십시오 :)
— Luaan

1
이 답변에서 제외해야 할 주요 요점은 다음과 같습니다. 가장 추론하기 쉬운 코드를 찾고 테스트하고 버그가 없는지 확인하려면 로컬 변수를 사용하십시오. 그러나 항상 그렇듯이 때때로 성능상의 이유로 완벽한 코드를 희생해야하기 때문에 클래스 멤버가 적절할 수 있습니다 (그러나 프로파일 우선, 단순히 조기 최적화를하지는 마십시오).
— Polygnome

원래 질문을 쓰는 동안 '캐싱'문제에 대해 궁금해하는 매우 많은 사람들, 특히 Luaan에게 감사드립니다 (그러나 나는 그 말을하는 법을 정말로 몰랐습니다). 가능한 한 '로컬'접근 방식을 취할 것입니다. 평소 친구들과 같이 큰 도움을 주셔서 감사합니다.
— Big T Larrity

2

Josh Petrie의 답변은 매우 훌륭합니다. 여기에 보완적인 관점이 있습니다.

도메인을 상당히 잘 이해하는 코드로 작업 할 때 변수의 범위를 변수의 범위에 맞출 수 있습니다.

예를 들어 메소드 가있는 Person클래스 가있는 경우 클래스 waveGoodbye에 hand객체가 없었기 때문에 로컬에서로 선언 할 수 있습니다 waveGoodbye. 이제 사람이 손을 가지고 있음을 분명히 알 수 있으므로 Person생각하지 않고 자연스럽게 회원으로 선언 할 수도 있지만 동일한 문제가 적용됩니다.

hand로컬로 선언하면 나중에 karateChop손이 필요한 메소드를 추가 할 수 있습니다 . 주니어 개발자는 종종 선언을 복사 / 붙여 넣기로 넘어 가기 때문에 waveGoodbye동일한 개념을 두 지점에 위치 시키기 때문에 변수를 로컬로 선언하는 것이 문제가 될 수 있습니다 . hand그런 다음 변경 사항을 두 곳에서 수정해야하므로 개미 버그 언덕 이 시작됩니다 .

결국,

  1. 신고서의 배치에 확신이있는 경우, 신고 내용의 범위를 적절하게 지정하십시오.

  2. 확신이 없다면 로컬을 시작하고 코드 재사용이 필요할 때 리팩터링해야합니다.

편집 : 아, 그리고 당신의 선언의 범위를 알아내는 데 너무 많은 시간을 소비하는 것과 같은 실수를하지 마십시오. 데이터의 구조를 미리 이해하기 어렵고 코드를 작성할 때 구조 자체를 드러내는 방법이 있습니다.


2
또한 모든이 같은 것들을 자연스럽게, 주문 가진 Person멤버가 있어야 hand 그 관련있는 경우 응용 프로그램에서 종종 다른 개발자 (대부분의 시간 데 도움이 당신이 더 나은 코드를 이해 6 개월 후를). 이 경우 성능을 저하시키는 경우에도 Rigidbody귀하의 회원으로 가입 Player하는 것이 좋습니다. 비디오 게임에서 고려해야 할 관련 포인트입니다,하지만 내가 생각하는 코드를 명확하게하는 것이 종종 더 중요하다,
— alseether

1
훌륭한 답변 감사합니다. 나는 아는 것처럼 들리려고 노력하지는 않지만이 모든 대답은 이미 내가 생각했던 것을 다시 확인 했으므로 한 번은 매우 행복하고 내 게임에서 멋진 발전을 이루었습니다. 지금은 적절한 애니메이션과 모든 것을 갖춘 3D 축구 게임을 만들고 있으며 실제 걸음을 내딛고 있습니다. 곧 D 플레이어를 만드는 방법에 대한 도움이 필요합니다.
— Big T Larrity
당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.