왜.... 오셨나요?

부끄러워요

유니티개발 TIL

4주차 5일 TIL_유니티 입문(유사 2D메타버스 만들기_펜싱 미니게임 기초)

와피했는데 2025. 7. 25. 23:55

들어가기 앞서

앞선 구현중 대쉬기능을 구현했는데 오늘은 그 대쉬 기능을 앞으로 만들 펜싱게임에 맞게 재설계를 진행할예정임

렛츠고!

 


프로젝트 구현 단계


<대쉬기능 변화>

● 기존에 키입력중 값변환 하는 형식에서 => 마우스 포인트 보이는 쪽으로 클릭하면 대쉬 하도록 설계

= 회전관련 참고 : 

1. https://www.youtube.com/watch?v=VWaiU7W5HdE

2. https://jugung.tistory.com/83

    [Header("플레이어 대시 세팅")]
    [SerializeField] float dashSpeed;  //30f
    [SerializeField] float dashDuration; // 0.15ff
    [SerializeField] float dashFriction; //300
    [SerializeField] float frictionDelay;

    [Header("플레이어 레이피어세팅")]
    [SerializeField] Transform frontPoint;
    [SerializeField] float angle = 135f;
    [SerializeField] Collider2D repireTrigger;

    //====[Dash]====
    bool canDash = true;

    //====[All]====
    private Rigidbody2D rb;
    private Vector2 mouseDir;
    Vector2 aimDir;

    private void Awake()
    {
        rb = GetComponent<Rigidbody2D>();
    }

    private void Start()
    {
        canDash = true;
    }

    private void FixedUpdate()
    {
        RepierHandling();
    }

    //=======================[InputSystem]=======================
    // InputAction에 등록된 이름과 함수이름이 같은지 확인(작성법 : On+커멘드이름)

    void OnAttack()
    {
        MouseDash();
    }

    //=======================[Diraction]=======================

    void MouseDash()
    {
        if (!canDash) return;
        StartCoroutine(DashForceCoroutine());
    }

    void RepierHandling()
    {
        mouseDir = Camera.main.ScreenToWorldPoint(Input.mousePosition);
        aimDir = (mouseDir - rb.position).normalized;
        float aimAngle = Mathf.Atan2(aimDir.y, aimDir.x) * Mathf.Rad2Deg - angle;
        frontPoint.transform.rotation = Quaternion.AngleAxis(aimAngle, Vector3.forward);
    }

    IEnumerator DashForceCoroutine()
    {
        canDash = false;
        // 기존 이동 끔
        Vector2 originalVelocity = rb.velocity;
        rb.velocity = Vector2.zero;

        // 힘을 가함
        rb.AddForce(aimDir * dashSpeed, ForceMode2D.Impulse);
        repireTrigger.enabled = true;
        yield return new WaitForSeconds(dashDuration);

        // 마찰력 표현(미끄러짐)
        rb.velocity = aimDir * dashFriction * Time.fixedDeltaTime;
        yield return new WaitForSeconds(frictionDelay);

        // 기본 이동력 복원
        rb.velocity = originalVelocity;
        repireTrigger.enabled = false;
        canDash = true;
    }
  대쉬 로직 구조 설명
1.기존 Move 방식 .velocity은 zero로 초기화 
2. 마우스 클릭시 마우스 포인트 방향으로 AddForce.Impulse 힘 한번 줘서 추진력으로 나감
3. 피격을 위한 레이피어 콜라이더(isTrigger) true
4. 대쉬후 살짝 미끌리는 표현을 위한 대쉬한 반향으로 dashFriction * Time.fixedDeltaTime을 frictionDelay(딜레이시간)만큼 이동
5. 대쉬이전 움직임으로 재초기화

 

 

회전관련 연산함수들 설명
1. ScreenToWorldPoint : ScreenToWorldPoint 카메라(Camera)가 비추고 있는 화면(Screen)내의 좌표값을 사용할 수 있게 해준다
만약 2d라도 z축을 상정안하고 0으로 둘시 카메라의 위치가 찍히게 되어 제대로 작동하지 않을 수도 있다 n>0, n<0으로 설정해서 쓰도록 하자

2. Mathf.Atan2(y, x) : 탄젠트의 역함수로 계산하는 연산함수로 각도가 -180~180도의 절대각도를 반환한다 아래 그림처럼 표현해주어 물체의 360도 회전 각도를 표현해준다

3. Mathf.Rad2Deg : 각도를 라디안 값으로 바꿔주는 함수로  



아크탄젠트

 

연산식으로 나타내면 아래와 같은 수식으로 나타낼수있다 여기서 마지막 '-90'만 조절하면 원하는 각도을 얻을수있다 (보통은 안바꿈)

 

본인의 경우 캐릭터가 돌아가면 안되서 'Front'라는 투명의 공을 두고 그주위를 'Rapier'가 돌기 때문에 각도를 수정할 필요가 있다

레이피어 리소스가 45도 정도 누워있는 관계로 더더욱 수정이 필요했다(그래서 본인 각도는 -145)이다


<상호작용 인식 기능 변경>

기존 Raycast로 캐릭터 보는 방향으로 쏘던 형식에서 캐릭터 주변 범위에 걸린 오브젝트를 인식하는 형식으로 변경

(기존)
RaycastHit2D rayHit = Physics2D.Raycast(rayPoint.position, dirVec, rayLangth, LayerMask.GetMask("Object"));
=>(변경)
 Collider2D hit = Physics2D.OverlapCircle(rayPoint.position, rayLangth, LayerMask.GetMask("Object"));
Overlap 함수
Overlap 함수는 특정 범위 안에 들어온 콜라이더를 인식하는 함수이다 (오브젝트위치, 범위크기, 인식오브젝트 레이어)
추가적으로 Mathf.lerp 같은 각도 연산을 사용하면 부채꼴 모양으로 인식범위를 조절할수있다

인식된 오브젝트가 있다면 E버튼 활성화

● 빨간 원안에 들어오는 콜라이더를 인식함


=>변경

 //=======================[Interaction Trigger]=======================

 private void OnTriggerEnter2D(Collider2D collision)
 {
     if (collision.gameObject.CompareTag("Object"))
     {
         currentTarget = collision.GetComponent<IInteractable>();
         buttenUI.SetActive(true);
     }
 }

 private void OnTriggerExit2D(Collider2D collision)
 {
     if (collision.gameObject.CompareTag("Object"))
     {
         currentTarget = null;
         buttenUI.SetActive(false);
     }
 }

테스트 해보니 무한정으로 인식하는 방식이 한번! 상호작용과 의도와 기능이 맞지않아서 변경함


<카메라에 추가 기능>

미니게임용 캐릭터를 새로운 prefab으로 생성했기 때문에 카메라가 새로운 캐릭터에 위치를 맞추기 위해 로직 추가

transform.position = new Vector3(player.position.x, player.position.y, -10);  // 케릭터 오브젝트 변경될시 위치 변환


<점수시스템 기반>

앞으로 미니게임들에서 쓸 점수, 타이머등 데이터들을 담당할 DataManager 생성

    private int currentScore = 0;

    public void AddScore(int score)
    {
        currentScore += score;

        Debug.Log("Score: " + currentScore);
    }
    private static DataManager dataManager;
    public static DataManager Data { get { return dataManager; } }

    private void InitManagers()
    {
        GameObject dataObj = new GameObject();
        dataObj.name = "DataManager";
        dataObj.transform.parent = transform;
        dataManager = dataObj.AddComponent<DataManager>();
    }

아직 초반이라 점수 득점 코드밖에 없음

GameManager에 등록


버그수정


무기가 회전만 하고 부모오브젝트와 같이 움직이지 않음
무기가 회전만 하고 부모오브젝트와 같이 움직이지 않음

 


마치며.


 

막상 연구하고 기능 테스트 하고 별이상한 일들이 많았는데 왜 진행된게 없는것 같지라는 생각이 지배되던 하루였다 이건 주말도 열심히 해야되는 진행속도가 되었다 

내일에 나야 화이팅 하자....