본문 바로가기
제출용/TIL

내일배움캠프 26일차 TIL + 마우스 따라 회전하는 무기 만들기, 프리팹

by 유린테 2024. 5. 22.

어제자 TIL에 썼던 삼각함수와 ATan 으로 마우스 따라 회전하는 무기를 만들어 보겠다!

그러니깐....내가 아니고.. 튜터님이....

 


 

 

마우스 따라 회전하는 무기 만들기

플레이어의 메인스프라이트에 

자식오브젝트로 WeapinPivot ( 무기관리)

그 밑으로 Weapon Sprite / BulletSpawnPoint 를 넣어준다.

weaponpivot 을 눌러보면 캐릭터의 머리쪽에 있기 때문에

그럼 공격이 머리쪽에서 나간다.

y 를 -0.4 정도 내려주면 몸에서 나가게 할 수 있다.

 

weapon Sprite는 손에서 나가야 하기 때문에

손쪽으로 올 수 있게 위치를 옮겨준다

그리고 sprite renderer 를 달아주고 웨폰 스프라이트를 넣어주면 활을 들고 있는 것 처럼 된다

 

bulletSpawnPoint 도 활에서 나갈 수 있게 위치를 조정해준다.

 

이렇게 써주고 클래스 이름에 마우스 대고 컨트롤 점. 하면 넘겨져서 TopDownAimRotation 스크립트가 생기고, 저 클래스가 넘어간다.

 

public class TopDownAimRotation : MonoBehaviour
{
    [SerializeField] private SpriteRenderer armRenderer;
    [SerializeField] private Transform armPivot;

    [SerializeField] private SpriteRenderer characterRenderer;  
}

그리고  [SerializeField] 사용해서 저렇게 작성해줌

에임에 따라 캐릭터가 뒤집혀야 해서 키릭터 렌더러 추가

화살이 뒤집히는것도 있어서 armRenderer 도 추가한거임

 

public class TopDownAimRotation : MonoBehaviour
{
    [SerializeField] private SpriteRenderer armRenderer;
    [SerializeField] private Transform armPivot;

    [SerializeField] private SpriteRenderer characterRenderer;

    private TopDownController controller;

    private void Awake()
    {
        controller = GetComponent<TopDownController>();
    }

    private void Start()
    {
        controller.OnLookEvent += OnAim;
    }

    private void OnAim(Vector2 direction)
    {
        RotateArm(direction);
    }

    private void RotateArm(Vector2 direction)
    {
        float rotZ = MathF.Atan2(direction.y, direction.x) * Mathf.Rad2Deg;

        characterRenderer.flipX = Mathf.Abs(rotZ) > 90f;

        armPivot.rotation = Quaternion.Euler(0, 0, rotZ);
    }
}

음~ 너무어렵다~^^

일단 탑다운컨트롤러를 이용해야 하니 컨트롤러를 가져와준다.

 

  characterRenderer.flipX = Mathf.Abs(rotZ) > 90f;

-90보다 작고, 90보다 크다 >> 절대값이 90보다 크다~!!!

절대값이 90보다 크면 뒤집어라!!! 라는 뜻

 

Player 에 TopDownAimRotation 을 달아주고

ArmRenderer - WeaponSprite

ArmPivot - WeapinPivot

CharacterRenderer - MainSprite 

각자 연결해주면 마우스 따라 캐릭터가 플립되고, 화살이 마우스를 따라온다!!!!!

 

 

 

 

프리팹 (Prefab)

유니티 게임 엔진에서 사용되는 게임 오브젝트를 재사용 가능하고 관리하기 쉽게 만들기 위한 템플릿, 프리셋

프리팹을 사용하면 게임 오브젝트와 그에 관련된 컴포넌트 및 설정을 미리 정의하고, 여러 장면이나 게임에서 재사용 가능

인스턴트화를 통해 실제 게임 오브젝트로 변환될 수 있으며, 이 때 모든 프로퍼티와 컴포넌트 설정이 복사된다

프리팹의 변경사항은 모든 인스턴스에 즉시 반영되므로, 일관성을 유지하고 일괄적인 업데이트를 쉽게 할 수 있다

레벨디자인, 재사용 가능한 게임요소(캐릭터, 아이템,장애물 등)의 생성, 프로토타이핑 등에 주로 사용됨

 

프리팹만들기

생성되어있는 게임 오브젝트를 프로젝트뷰로 옮겨주면 된다.

게임오브젝트를 에셋으로 만든다! 라고 생각하면 이해가 쉬울듯

 

프리펩으로 해놓으면 100개를 만들어 놓고 고칠때 하나만 고치면 다 고쳐짐

하나하나 고칠 필요가 없다

 

Instantiate 함수

>> 복사해서 만든다!!

 

Instantiate 함수는 Unity 에서 제공하는 메소드로, 주어진 원본 개체의 복사본을 새로 생성하고 이를 반환한다

주로 게임오브젝트, 즉 캐릭터, 아이템, 프로젝타일 등을 동적으로 게임세계에 추가할 때 사용함

Instantiate 함수는 원본 개체의 모든 컴포넌트와 그 프로퍼티를 복사하여 새 게임오브젝트를 생성

이 함수를 통해 생성된 게임 오브젝트는 독립적이며, 원본 개체에 대한 변화는 이에 영향을 주지 않음

원본 게임 오브젝트, 위치 및 회전정보를 인자로 받을 수 있다

 

인스턴트화 한다!!! 할 때 그 인스턴스

 

public void OnFire (InputValue value)
{
    
    IsAttacking = value.isPressed;
}

public class PlayerInputController : TopDownController 

 

여기에 저걸 넣어주는데 이때 IsAttacking이 정의되어 있지 않으므로 해줘야함!

근데 이게 TopDownController 의 상속을 받으니까

InAttacking 은 TopDownController에 적어준다

 

protected bool IsAttacking { get; set; }

protected bool 로 적어줌

이 상속을 받는 클래스들에서는 IsAttacking 을 사용할 수 있다~

 

오 드래그해서 알트하고 내리면 내려짐

 

private float timeSinceLastAttack = float.MaxValue;

private void Update()
{
    HandleAttackDelay();
}

private void HandleAttackDelay()
{
    // magic number 수정 해야함
    if(timeSinceLastAttack < 0.2f)
    {
        timeSinceLastAttack += Time.deltaTime;
    }
    else
        timeSinceLastAttack = 0f;
        CallAttackEvent();
}

Update 만들어주고  핸들어택딜레이 만들어줌

그리고 CallAttackEvent 도 없어서 컨트롤 . 으로 만들어줌

 

 private void CallAttackEvent()
 {
     OnAttackEvent?.Invoke();
 }

요거 해준 다음

 

public event Action OnAttackEvent;

 

이거 붙여서 해주고

 

public class TopDownShooting : MonoBehaviour
{

}

 

요거 컨트롤 . 해서 스크립트 만들어줌

 

public class TopDownShooting : MonoBehaviour
{
    private TopDownController controller;

    [SerializeField] private Transform projectileSpawnPosition;
    private Vector2 aimDirection = Vector2.right;

    public GameObject TestPrefab;
    

    private void Awake()
    {
        controller = GetComponent<TopDownController>(); 
    }

    private void Start()
    {
        controller.OnAttackEvent += OnShoot;

        controller.OnLookEvent += OnAim;
    }

    private void OnAim(Vector2 direction)
    {
        aimDirection = direction;
    }

    private void OnShoot()
    {
        CreatProjectile();
    }

    private void CreatProjectile()
    {
        // 날아가질 않기 때문에 날아가게 만들어야함
        Instantiate(TestPrefab, projectileSpawnPosition.position, Quaternion.identity);
    }
}

진짜 모르겠다

그냥 코드 열심히 따라적는 사람 됨.... 힝구

 

 

>> 하이어라키에 새로운 오브젝트 만들 때는 빈오브젝트 하나 만들고 그 아래 만드는걸 추천

 

빈 오브젝트로 Arrow 하나 만들고

그 밑에 빈 오브젝트로 weapon_arrow 만들어서 스프라이트렌더러 붙여주고, 화살모양 넣어주기

 

Prefabs 폴더 만들고 거기에 Arrow 넣으면 프리펩 됨.

그러면 하이어라키에서는 지우기!

그리고 아까 TopDownShooting에 testprefab 에 Arrow 를 드래그 앤 드롭 해주면 된다

프리팹은 검색으로 안나와서 직접 드래그 앤 드롭 해줘야함~!!!

 

근데 이대로만 해줬더니 마우스를 안눌러도 화살이 나간다!!!

else 로 해줬던걸 else if  로 바꿔서 해줘야함

 private void HandleAttackDelay()
 {
     // magic number 수정 해야함
     if (timeSinceLastAttack < 0.2f)
     {
         timeSinceLastAttack += Time.deltaTime;
     }
     else if (IsAttacking && timeSinceLastAttack >= 0.2f)
     {
         timeSinceLastAttack = 0f;
         CallAttackEvent();
     }
 }

else if 로 바꿔서 IsAttacking (마우스클릭)과 함께 마지막 어택에서 0.2초가 지났을 때 화살이 발사된다

 

 

이렇게 해주면 활이 마우스 따라 회전하고, 클릭하면 화살도 발사된다!

정말멋져!

 


 

 

하지만 저 회전부분이나 화살부분 너무 어려워서 

넋 놓고 따라 치게 되었다... 힝구

나중에 꼭 다시 보면서 다시 해봐야지!!!!  

오늘은 내 생일! 

부트캠프 하느라 밖에도 못나가보고 맛있는것도 못먹지만! 내일 마감이라 바쁘지만!

헤헷...

Happy Birthday For ME ~~~~~~~