본문 바로가기
NOTE/Unity

[Unity] C# 스크립팅 마스터하기 BOOK 요약정리1

by DevAthena 2016. 9. 26.

[스크립트 인스턴스화]

- 특정 오브젝트에 스크립트를 컴포넌트로서 추가해 숨을 불어넣는 과정을 인스턴스화라고 한다.


[변수 표시]

- 특정 private 변수를 표시하길 원할 때, Debug 모드를 켜서 확인하거나 [SerializeField] 특성을 함께 선언한다.


[SendMessage와 BroadcastMessage]

- 이 함수들을 사용해 오브젝트에 붙은 모든 컴포넌트의 함수를 이름으로 실행할 수 있다.

- SendMessage는 하나의 게임 오브젝트에 붙어있는 모든 컴포넌트에 걸쳐 지정된 함수를 부른다.

- BroadcastMessage는 SendMessage의 동작과 합쳐져서 게임 오브젝트의 모든 컴포넌트마다 지정된 함수를 부르고, 

씬 계층상의 모든 자식 오브젝트와 그 자식 오브젝트에게까지 재귀적으로 이 과정을 반복한다.

- Update 이벤트나 다른 프레임 기반의 호출 안에서는 현저한 성능 저하로 델리게이트와 인터페이스를 이용한 더 빠른

 기술을 사용하라.


[GetComponent]

- 데이터 형식을 알고 있는 특정한 컴포넌트 하나에 직접 접근할 때 사용.

- 게임 오브젝트에 붙여진 컴포넌트 중 일치하는 첫 번째 컴포넌트에 접근.

- 여러개의 컴포넌트에 접근시에는 GetComponents를 호출


[localPosition과 position의 차이]


[Invoke]

- 일치하는 이름을 가진 함수를 실행하기 위해 호출한다. 

- 두 번째 부동소수점 파라미터는 몇 초 후에 함수가 불릴지 시간을 초로 지정하는 것이다.

- 시간을 0으로 지정하면 즉시 불리게 된다.


[게임 오브젝트 찾기]

- GameObject.Find보단 GameObject.FindObjectWithTag를 선호한다.


[오브젝트 비교]

- CompareTag 함수를 이용하면 태그를 비교할 수 있다.

- 실제로 동일한 오브젝트인지 비교하길 원할 때에는 GetInstanceID를 사용


[가장 가까운 오브젝트 찾기]

- 임의의 두 점 간의 최단 거리를 구해 가장 가까운 오브젝트를 찾는 방법

GameObject GetNearestGameObject (GameObject Source, GameObject[] DestObjects)
{
    // 첫 번째 오브젝트를 할당한다.
    GameObject Nearest = DestObjects[0];

    // 최단 거리
    float ShortestDistance = Vector3.Distance(Source.transform.position, DestObjects[0].transform.position);

    // 모든 오브젝트를 순회한다.
    foreach(GameObject Obj in DestObjects)
    {
        // 거리를 계산한다.
        float Distance = Vector3.(Source.transform.position, Obj.transform.position);

        // 계산한 거리가 가장 짧다면 업데이트 한다.
        if(Distance < ShortestDistance)
        {
            Nearest = Obj;
            ShortestDistance = Distance;
        }
    }

    // 가장 가까운 오브젝트의 참조를 반환한다.
    return Nearest;
}


[게임 오브젝트 간 경로 만들기]

- 두 게임 오브젝트 간에 그리는 가상의 선을 통해 여기에 교차하는 충돌체가 있는지 검사하여 둘 사이의 경로를 만든다.

- AI 기능을 결정하기 위한 가시선 시스템뿐 아니라 일반적으로 오브젝트 컬링 등에도 유용한 방법이다.

public class ObjectPath : MonoBehaviour
{
    // 적 예제 오브젝트에 대한 참조
    public GameObject Enemy = null;

    // 선 검출을 제한하기 위한 레이어마스크
    public LayerMask LM;

    // Update는 매 프레임마다 한 번씩 호출된다.
    void Update()
    {
        // 오브젝트 사이에 빈 경로가 있는지 검사
        if(!Physics.Linecast(transform.position, Enemy.transform.position, LM))
        {
            // 빈 경로가 존재한다
            Debug.Log("Path clear");
        }
    }

    // 뷰포트에 디버그용 선을 보여준다.
    void OnDrawGizmos()
    {
        Gizmos.DrawLine(transform.position, Enemy.transform.position);
    }
}


[월드/시간과 업데이트]

- Update : 시간에 따라 반복적인 동작이나 업데이트,키보드 눌림이나 마우스 클릭을 확인하는 등의 모니터링 기능이 필요할 때 유용하다.

 모든 컴포넌트에 매 플임마다 불려지는 것이 보장되지 않는다. 

- FixedUpdate : 각각의 호출은 고정된 시간 간격을 기반으로 규칙적으로 표준화 되어 일어난다. 가장 널리 물리 기능을 사용할 때 

사용한다. 시간에 따라 Rigidbody 컴포넌트의 속도나 속성을 업데이트 하는 경우 Update보다는 FixedUpdate가 적합

- LateUpdate : 언제나 FixedUpdate가 호출된 이후에 호출된다. 즉, LateUpdate가 호출되었을 때는 이미 Update와 FixedUpdate가 

호출되었다는 것을 확신할 수 있다는 의미. 1인칭 카메라를 구현하는 경우, 현재 프레임에서 항상 오브젝트의 마지막 위치를 

따라가도록 움직임을 업데이트할 때 유용

- 움직임은 시간과 비례해야 한다. Time 클래스의 멤버인 deltaTime 변수를 이용하면 이런 구현이 가능해진다. (거리 = 속력x시간)

public class Mover : MonoBehaviour
{
    // 육면체의 속력
    public float Speed = 1.0f;

    // Update는 매 프레임마다 한 번씩 호출된다.
    void Update()
    {
        // 육면체를 앞쪽 방향으로 속력에 따라 움직인다.
        transform.localPosition += transform.forward * Speed * Time.deltaTime;
    }
}


[소멸되지 않는 오브젝트]

- 씬 간 유지되는 많은 오브젝트들은 자식 없는 빈 게임오브젝트처럼 동작에 필요한 기본 컴포넌트로만 구성해 가볍게 만들어진다.

+ 유니티에서 활성화된 씬을 전환하려면 Application.LoadLevel 함수를 사용한다. (+ SceneManager.LoadScene도 있다)


[싱글턴 오브젝트와 정적 멤버]

- 싱글턴은 대게 여러 씬에 걸쳐 지속적으로 유지되는 오브젝트다.

- 항상 메모리에 클래스의 인스턴스가 하나만 존재한다.

- 거의 대부분의 게임에는 GameManager나 GameController 클래스가 있고, 이런 클래스는 거의 대부분 지속적으로 유지되는

 싱글턴 오브젝트다. 

- GameManager는 기본적으로 게임의 고급 기능을 담당한다. 게임이 정지되었는지, 승리 조건이 충족되었는지 등을 판별하고,

 게임에서 무슨 일이 일어났는지 단번에 알아내는 확실한 방법을 가지고 있다.

public class GameManager : MonoBehaviour
{
    // 싱글턴 인스턴스에 접근하기 위한 C# 프로퍼티
    // get 접근자만 가지는 읽기 전용의프로퍼티
    public static GameManager Instance
    {
        // private 변수 instance의 참조를 반환한다.
        get
        {
            return Instance;
        }
    }

    private static GameManager instance = null;

    // 최고 점수
    public int HighScore = 0;

    // 게임 정지
    public bool IsPaused = false;

    // 플레이어 입력 허용
    public bool InputAllowed = true;

    // 초기화
    void Awake()
    {
        // 씬에 이미 인스턴스가 존재하는지 검사,
        // 존재하는 경우 이 인스턴스는 소멸
        if(instance)
        {
            DestroyImmediate(gameObject);
            return;
        }

        // 이 인스턴스를 유효한 유일 오브젝트로 만든다.
        instance = this;

        // 게임매니저가 지속되도록한다.
        DontDestroyOnLoad(gameObject);
    }
}

- Awake는 항상 오브젝트 생성 시에 호출된다.

- Start는 게임 오브젝트가 활성화되는 첫 번째 프레임에 호출된다.

- 다른 클래스에서 GameManager의 게임 점수 변수를 설정하려면 GameManager.Instance.HighScore = 100; 이런 식으로 사용.