[Unity] Attribute란?

Unity 2023. 3. 25. 13:46
  • Unity에서 Attribute는 특정한 기능이나 정보를 클래스, 프로퍼티, 필드, 메소드 등 코드의 요소에 부여하는 데 사용되는 특별한 타입의 메타데이터입니다. 
  • Attribute는 C#에서 제공되는 기능으로, 주로 코드를 작성할 때 추가적인 정보를 제공하거나 Unity의 인스펙터 창에 표시되는 방식을 변경하는 데 사용됩니다.
  • Unity에서는 다양한 Attribute들이 있으며, 이는 코드의 가독성을 높이고 작성자의 의도를 명확하게 전달할 수 있습니다.
  • 주요 Unity Attribute의 예시는 다음과 같습니다.

예시

SerializeField: 일반적으로 private 변수는 Unity 인스펙터에 표시되지 않지만, 이 Attribute를 사용하면 해당 변수를 인스펙터 창에서 수정할 수 있게 됩니다.

[SerializeField] private int myValue;

Tooltip: 변수에 마우스를 올렸을 때 툴팁으로 표시될 정보를 설정할 수 있습니다. 이를 통해 변수의 사용 목적을 명확하게 전달할 수 있습니다.

[Tooltip("This value represents the player's speed.")] public float speed;

Range: 인스펙터에서 변수 값의 범위를 지정할 수 있습니다. 이를 통해 변수 값의 최소값과 최대값을 제한할 수 있습니다.

[Range(0, 100)] public int health;

Header: 인스펙터에서 변수들을 그룹화하거나 구분할 때 사용할 수 있는 헤더를 추가합니다.

[Header("Player Settings")] public string playerName;

RequireComponent: 이 Attribute를 사용하면, 해당 컴포넌트와 함께 다른 특정 컴포넌트가 필요한 경우 자동으로 추가됩니다.

[RequireComponent(typeof(Rigidbody))] public class PlayerController : MonoBehaviour { ... }

블로그 이미지

RIsN

,

기본

  1. Look At Constrait을 사용

간단 확인

  1. Head Bone에 Look At Constrait을 설치
  2. 마우스 타깃으로 할 목표 오브젝트를 제작 후에 해당 Constrait에 타깃으로 적용
    • 움직임을 보면서 회전 등 미세 조정
  3. 목표 오브젝트가 마우스를 따라 다니도록 처리

블로그 이미지

RIsN

,

5줄 요약

  • Unity는 게임 개발 도구로서, 2D 및 3D 게임을 만드는 데 사용됩니다.
  • Unity는 쉽고 직관적인 사용자 인터페이스와 대부분의 플랫폼에서 실행 가능한 크로스 플랫폼 기능을 제공합니다.
  • Unity는 C# 언어를 사용하여 개발되며, 게임 오브젝트, 스크립트, 애니메이션 등의 요소를 관리합니다.
  • Unity Asset Store는 Unity 개발자가 사용할 수 있는 다양한 에셋(소스 코드, 모델, 사운드 등)을 제공합니다.
  • Unity는 대규모 게임 회사부터 개인 개발자까지 모든 레벨의 개발자들이 사용하는 인기 있는 게임 개발 도구입니다.

추가 내용

경험

블로그 이미지

RIsN

,

코드

string textData = "들어갈 내용";
GUIUtility.systemCopyBuffer = textData;

참고

  • Unity Editor에서의 사용: 성공
  • Web GL 빌드에서의 사용: 실패
  • Window 빌드에서의 사용: 실패
    • 이 부분은 조금 더 확인해야 합니다.
블로그 이미지

RIsN

,

5줄 요약

  • FixedUpdate는 고정된 주기로 실행되는 함수로, 일반적으로 물리 시뮬레이션과 관련된 코드를 작성할 때 사용됩니다.
  • FixedUpdate는 물리 시뮬레이션의 안정성과 일관성을 보장하기 위해 고정된 주기로 호출됩니다.
  • Update는 매 프레임마다 실행되는 함수로, 게임 로직과 관련된 코드를 작성할 때 사용됩니다.
  • Update는 물리 시뮬레이션과 관련이 없는 게임 로직의 갱신에 사용됩니다. 이 때 프레임당 호출 주기는 고정되어 있지 않습니다.
  • FixedUpdate와 Update는 각각의 호출 주기에 따라 실행되므로, 프레임당 실행 횟수는 다를 수 있기에, 게임 로직과 물리 시뮬레이션을 구분하여 적절한 함수를 사용하는 것이 중요합니다.

추가 내용

경험

'Programming' 카테고리의 다른 글

[5줄 요약] RAM이란?  (0) 2023.03.07
[5줄 요약] EPROM이란?  (0) 2023.03.06
[5줄 요약] 컴퓨터의 메모리(Memory) 구조는?  (0) 2023.03.01
[5줄 요약] 모던(Modern) C++이란?  (0) 2023.02.28
[5줄 요약] ROM이란?  (0) 2023.02.18
블로그 이미지

RIsN

,

참고: https://learn.microsoft.com/ko-kr/dotnet/csharp/fundamentals/coding-style/coding-conventions

  • C# Roslyn을 기본 적용
  • 클래스
    • 클래스 내부 변수: _(언더 스코어) + Camel Case
      • 클래스 내부 정적(Static) 변수: s_(언더 스코어) + Camel Case
    • 클래스 외부 변수: Pascal Case
    • 클래스 메소드: Pascal Case
      • 메소드 내 파라미터: _(언더 스코어) + Camel Case
  • 유니티 내부 animation 파일: Snake Case
  • 데이터(JSON) 파일: Snake Case
  • 리소스 파일: Snake Case
블로그 이미지

RIsN

,

문제: Cinemachine을 사용할 때 Virtual Camera를 캐릭터에서 오브젝트(모닥불)로 변경할 때 흔들림이 발생

  • 원인
    • Follow와 LookAt에 오브젝트를 넣을 때 해당 카메라가 따라가고, 바라보며 흔들리는 현상
  • 제약 및 현 상황
    • 한 번만 발생
    • Follow와 LookAt 둘 다 써야 조금 더 보기 좋은 상황, 즉, 둘 다 써야 함
    • Delay를 넣으면 미묘하게 느낌이 안 좋음
  • 해결
    • Follow와 LookAt을 따로 메소드로 변경
    • 우선도를 바꾸기 전에 전 단계(현재 케이스는 설치 결정 팝업 화면)에서 이미 해당 메소드를 실행
      • (기존 변경) 현재 Instantiate될 오브젝트를 카메라가 따라가고 있는데, 좌표 타일 자체를 따라가도록 변경
  • 추가
    • 오브젝트가 움직일 때(위치가 바뀔 때) Follow와 LookAt도 그대로 놔둔 채로 움직이면 흔들림이 발생
      • 어차피 방향이 정해졌다면 Follow만 처리해서 위치 변경
블로그 이미지

RIsN

,

전제 조건

  • 첫번째 Scene에서 생성되어 게임이 실행되는 동안 계속 소유하고 있는 무언가가 있어야 함
    • 현재 쓰고 있는 구조에서는 App이라는 스크립트가 게임 시작부터 끝까지 존재
  • 각 Scene마다 소유하고 있는 스크립트가 존재해야 함
    • 현재 쓰고 있는 구조에서는 _Ruler(상속)라는 스크립트가 존재
      • 예) Ruler_Logo, Ruler_Lobby 등

방법

  1. (예외 처리 1) 첫번째 Scene으로 갈 지 안 갈 지를 판단
    • isGoToApp:Bool 라는 Inspector 상에서 보이는 변수를 _Ruler가 소유 중
    • 해당 isGoToApp이 True면 밑의 내용을 실행, False면 return
      • (예외 처리 2)
        • False일 때 App을 아예 생성해서 모든 작업들(데이터 로드 등)을 우선 진행한 후 이 Scene에 남아 있게 할 수도 있음
          • 이 Scene에서는 로드가 전부 될 때까지 지연 처리
        • 다만 그 경우 여러모로 각 씬 + 협업하는 사람이 합(데이터 로드는 무조건 한 곳)을 맞춰야 함
  2. _Ruler가 Awake될 때 App이라는 스크립트가 현재 화면 내에 존재하는 지 확인
  3. App이 없다면 바로 0번째 Scene을 로드
  4. 완료

생각해볼 것

  • 저런 처리(스크립트 존재) 없이 유니티 상에서 시작 시에 현재 Scene을 판단해서 어떤 항목의 ON/OFF에 따라 첫번째(0) Scene으로 갈 수 있지 않을까?
블로그 이미지

RIsN

,

목표: 게임의 레시피 UI가 카메라를 계속 바라볼 필요가 있음

  • 주의
    • 빈 게임 오브젝트를 만들고 거기에 스크립트를 부착할 필요가 있음.
    • 내부의 이미지나 글은 조금 각도 등이 수정이 가능한 형태로 만들어야 나중에 편해짐

예) 방식

using System.Collections;
using UnityEngine;

public class GearTool_LookAtCamera : _Gear
{
    public override void Init() { }

    // :: 따라갈 카메라 혹은 오브젝트
    [SerializeField] private Transform iCamera = null;

    // :: 쳐다보기
    void Update()
    {
        if (this.iCamera == null) this.iCamera = Camera.main.transform;

        this.transform.LookAt(
            this.transform.position + this.iCamera.rotation * Vector3.forward,
            this.iCamera.rotation * Vector3.up);
    }
}
  • _Gear는 현재 쓰고 있는 형식, MonoBehaviour로 사용하거나, 상황에 맞춰서 사용할 것
블로그 이미지

RIsN

,

목표: TextMeshPro에서 숫자가 바뀔 때마다 카운팅 하여 숫자를 집어 넣도록 처리

using System.Collections;

public static class ToolText
{
    public static void CountingTo(this TMPro.TMP_Text _targetText, int _goal)
    {
        // :: 코루틴을 실행할 녀석 확인
        // :: 지금 구조에서는 App이 모든 코루틴을 실행하고 관리할 예정
        App.oInstance.StartCoroutine(_targetText.IENCountingTo(_goal));
    }
    public static IEnumerator IENCountingTo(this TMPro.TMP_Text _targetText, int _goal)
    {
        // :: 현재 값
        int current = int.Parse(_targetText.text);

        // :: Up일 경우
        while (current < _goal)
        {
            if (current + 100 < _goal) current += 100;
            else if (current + 10 < _goal) current += 10;
            else current++;

            _targetText.text = string.Format("{0}", current);
            yield return null;
        }
        // :: Down일 경우
        while (current > _goal)
        {
            if (current - 100 > _goal) current -= 100;
            else if (current - 10 > _goal) current -= 10;
            else current--;

            _targetText.text = string.Format("{0}", current);
            yield return null;
        }

        // :: 마지막 재확인
        _targetText.text = string.Format("{0}", _goal);
    }
}
블로그 이미지

RIsN

,