Unity-#11. 인터페이스, 슈터

CHO WanGi·2024년 4월 12일

Unity

목록 보기
12/13

인터페이스

인터페이스를 사용하면 다양한 타입의 옵젝을 하나의 인터페이스로 추상화하여 다룰 수 있음

C# 인터페이스

외부와 통신하는 공개 통로이자 통로의 규격
-> 어떤 메서드를 구현하도록 강제하는 계약

public interface IItem {
	void Use(GameObject target);
}

Use() 메서드는 선언만 존재하고 구현이 없음
구현은 이를 상속하는 자식 클래스에게 맡김
단, 반드시 public으로 구현해야 함.

느슨한 커플링

만약 어떤 스크립트가 IItem 인터페이스를 상속한 클래스로부터 생성된 옵젝에 접근.

이 스크립트를 통해서 Use() 메서드 실행 가능
만약 어떤 스크립트에서 충돌한 아이템을 사용하는 처리를 구현

void OnTriggerEnter(Collider other){
	AmmoPack ammoPack = other.GetComponent<AmmoPack>();
    if(ammoPack != null) {
    	ammoPack.Use();
    }
    HealthPack healthPack = other.GetCompnent<HealthPack>();
    if(healthPack != null) {
    	healthPack.Use();
    }
  }

를 인터페이스를 사용한다면

void OnTriggerEnter(Collider other){
	IItem item = other.GetComponent<IItem>();
    if(item != null) {
    	item.Use();
    }
}

로 다양한 아이템 타입에 따라 일일히 코드를 짤 필요 없이 간단하게 활용 가능
즉 HealthPack, AmmoPack의 구현에 더이상 영향 x, 느슨한 커플링 구현됨.

Gun Object

Gun Pivot

Gun Object 배치할 기준점,

Line Renderer

Positions 필드에 설정된 점 사이를 이어 선을 그림.

Particle System Component

연기, 화염재 등 시각효과에 사용
여러 작은 스프라이트 이미지를 랜덤하게 휘날리는 방식으로 동작

Scriptable Object

여러 오브젝트가 사용할 데이터를 유니티 에셋 형태로 저장할 수 있는 타입

  • 여러 옵젝이 공유하여 사용할 데이터를 에셋 형태로 분리
  • 데이터를 유니티 인스펙터 창에서 편집가능한 형태로 분리
[CreateAssetMenu(fileName = "GunData", menuName = "GunData")]
public class GunData : ScriptableObject {
    
    public AudioClip shotClip; // 발사 소리
    public AudioClip reloadClip; // 재장전 소리

    public float damage = 25; // 공격력

    public int startAmmoRemain = 100; // 처음에 주어질 전체 탄약
    public int magCapacity = 25; // 탄창 용량

    public float timeBetFire = 0.12f; // 총알 발사 간격
    public float reloadTime = 1.8f; // 재장전 소요 시간
}

enum Type

enum Type 변수, 미리 정의된 여러 값 중 하나를 가짐

코루틴

대기 시간을 가질 수 있는 메서드

private IEnumerator ShotEffect(Vector3 hitPosition) {
        muzzleFlashEffect.Play();
        shellEjectEffect.Play();
        gunAudioPlayer.PlayOneShot(gunData.shotClip);

        bulletLineRenderer.SetPosition(0,fireTransform.position);
        bulletLineRenderer.SetPosition(1, hitPosition);
        // 라인 렌더러를 활성화하여 탄알 궤적을 그림
        bulletLineRenderer.enabled = true;

        // 0.03초 동안 잠시 처리를 대기
        yield return new WaitForSeconds(0.03f);

        // 라인 렌더러를 비활성화하여 탄알 궤적을 지움
        bulletLineRenderer.enabled = false;
    }

RayCast

보이지 않는 광선을 쏘았을때 광선이 다른 콜라이더와 충돌하는지 검사하는 처리
사용하는 광선 = Ray,
Ray 타입으로 이 정보만 따로 표현 가능

        if(Physics.Raycast(fireTransform.position, fireTransform.forward, out hit, fireDistance))

IK & FK

FK

Forward Kinematics(전진 운동학)
부모 조인트(관절)에서 움직임을 적용
ex. 어깨 -> 팔 -> 손 순서
즉 손의 위치는 최종 결과, 물건의 위치에 맞춘 애니메이션이 불가능, 손의 위치로 물건이 순간이동해야함

IK

Inverse Kinematics(역 운동학)
자식 조인트에서 움직임을 적용
ex. 손 -> 팔 -> 어깨 순서

-> IK Pass 설정 켜두어야 함.

private void OnAnimatorIK(int layerIndex) {
        gunPivot.position = playerAnimator.GetIKHintPosition(AvatarIKHint.RightElbow);

        playerAnimator.SetIKPositionWeight(AvatarIKGoal.LeftHand, 1.0f);
        playerAnimator.SetIKRotationWeight(AvatarIKGoal.LeftHand, 1.0f);

        playerAnimator.SetIKPosition(AvatarIKGoal.LeftHand, leftHandMount.position);
        playerAnimator.SetIKRotation(AvatarIKGoal.LeftHand, leftHandMount.rotation);
		// 가중치 적용
        playerAnimator.SetIKPositionWeight(AvatarIKGoal.RightHand, 1.0f);
        playerAnimator.SetIKRotationWeight(AvatarIKGoal.RightHand, 1.0f);

        playerAnimator.SetIKPosition(AvatarIKGoal.RightHand, rightHandMount.position);
        playerAnimator.SetIKRotation(AvatarIKGoal.RightHand, rightHandMount.rotation);
    }
profile
제 Velog에 오신 모든 분들이 작더라도 인사이트를 얻어가셨으면 좋겠습니다 :)

0개의 댓글