공부/Unity

스크립터블 오브젝트, 총알 발사, IK

월러비 2025. 8. 26. 17:34

스크립터블 오브젝트

  • monobehaviour를 상속받은 스크립트는 게임 오브젝트와 관련된 스크립트다.
  • 스크립터블 오브젝트 : 에셋과 관련된 스크립트다.
  • 총 사용에 대한 데이터들을 같이 데이터를 모아놓는 경우에 사용될 수 있다.
    • 데이터 테이블을 만들어서 필요한 정보를 읽어오는 형식으로 사용할 수 있다.
[CreateAssetMenu(fileName = "GunData", menuName = "Scriptable Objects/GunData")] //어트리뷰트
public class GunData : ScriptableObject
{
    
}
  • CreateAssetMenu : 에셋 메뉴 생성 어트리뷰트
    • Project 창의 + 버튼을 누르면 맨 밑 항목에 Scriptable Object 에 에셋 생성 버튼이 생성된다.
      • public으로 스크립트에 선언하면 해당 에셋에 게임오브젝트를 드래그로 할당이 가능해진다.
      • 특정 오브젝트가 많이 생기면 이 에셋을 복사하여 여러 무기를 만들 수 있게되는 것이다.
    • fileName : 메뉴 이름
    • "Scriptable Objects/GunData" : /는 ‘계층 구조’를 의미한다.
  • 스크립터블 오브젝트 메뉴로 생성한 ‘데이터 에셋’은 이것도 에셋이기 때문에 해당 스크립트의 이름을 데이터형으로 선언하면 인스펙터에서 할당할 수 있게된다.
[CreateAssetMenu(fileName = "GunData", menuName = "Scriptable Objects/GunData")]
public class GunData : ScriptableObject
{
    public AudioClip shootClip;
    public AudioClip reloadClip;

    public float damage = 25f;

    public int startAmmoRemain = 100;
    public int magCapacity = 25; //탄창 용량

    public float timeBetFire = 0.12f; //발사 간격
    public float reloadTime = 1.8f;

    public float fireDistance = 50f; //사정거리
}

//GunScript
public GunData gunData;

FPS

  • 히트 스캔 : 반 직선으로 총알이 날아가고, 맞으면 맞았다고 알려주는 것이다.
    • 직선 : 시작점과 끝 점이 정해져있다.
    • 반직선 : 시작점과 방향으로 날아가는 것이다.
      • 레이캐스트를 이용한다.
  • 탄도학 적용 : 총알이 날아가는것이 물리 시뮬레이션을 통해 날아가는 것이다.

총알 발사

  • 준비, 탄환 없음, 재장전 3개의 상태가 필요하다.
  • 장전은 애니메이션이 끝난 후 장전되어야한다. → 코루틴 사용
private IEnumerator CoShotEffect(Vector3 hitPosition)//hitPosition : 끝점
{

    audioSource.PlayOneShot(gunData.shootClip);

    muzzleEffect.Play();
    shellEffect.Play();

    lineRenderer.enabled = true;
    lineRenderer.SetPosition(0, firePosition.position);
    lineRenderer.SetPosition(1, hitPosition);

    yield return new WaitForSeconds(0.2f);

    //Debug.Log("End");
    lineRenderer.enabled = false;
}

IK (Inverse Kinemetics)

  • 역 운동학 이라고 부르기도 한다.
  • ex. 벽을 밀때 벽이 움직인다면? → 손이 밀리면서 팔, 팔꿈치, 어깨의 본까지 같이 움직여야한다.
  • FK (정 운동학) : 만들어진 애니메이션에 맞춰 물건의 위치를 손으로 옮긴다.
  • IK : 물건의 위치에 손이 위치하도록 애니메이션 변형
  • 애니메이션에 각 오브젝트에 상호작용할때 오브젝트에 맞춰서 애니메이션을 생성할 수는 없으니 오브젝트 특정 위치에 본을 붙여서 각 본의 위치를 자동으로 설정해야하는것이다.
  • AvartarMask에서 IK를 활성화해야한다.
  • 포지션과 회전을 붙인 오브젝트와 같게 스크립트에서 설정한 다음 세세한 설정은 해당 오브젝트에서 진행한다.
    • 런타임에서 세세한 위치설정과 회전값을 잡고 종료시키면 안된다.
      • 런타임에서 변경한 값은 저장이 안되기 때문이다.
      • 컴포넌트의 값을 복사하고 종료하는게 좋다.
private void OnAnimatorIK(int layerIndex)
{
    gunPivot.position = animator.GetIKHintPosition(AvatarIKHint.RightElbow); //피봇이 오른쪽 팔꿈치에 있게된다.

    animator.SetIKPositionWeight(AvatarIKGoal.LeftHand, 1f);
    animator.SetIKRotationWeight(AvatarIKGoal.LeftHand, 1f);

    animator.SetIKPositionWeight(AvatarIKGoal.RightHand, 1f);
    animator.SetIKRotationWeight(AvatarIKGoal.RightHand, 1f);

    animator.SetIKPosition(AvatarIKGoal.LeftHand, leftHandMount.position);
    animator.SetIKRotation(AvatarIKGoal.LeftHand, leftHandMount.rotation);

    animator.SetIKPosition(AvatarIKGoal.RightHand, rightHandMount.position);
    animator.SetIKRotation(AvatarIKGoal.RightHand, rightHandMount.rotation);
}