2024년 1월 14일 일요일

Unity - 캐릭터 이동 (Velocity)

이번에 모바일 게임을 만들게 되었는데

캐릭터 이동을 구현할 때 조이스틱으로 이동하지 않고

터치로만 모든것을 할 수 있도록 만들게 되었다.

그래서 터치를 위주로 관리하는 스크립트와 

이동을 구현한 스크립트를 나눠서 설명하겠음





먼저 터치 관리자에서 터치 시작, 끝, 드래그를 나눠서

어느 방향으로 드래그 하였는지,

아직 터치 중인 상태인지, 터치가 막 시작된 상태인지 판별하여

다른 클래스로 전달한다.





방향을 특정하는 변수는 드래그 중이였다가 손을 땟을 때 호출하여

어느 방향으로 손꾸락을 이동하였는지 저장한다.

그리고 다시 손을 댓을 때 초기화





1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
using Unity.VisualScripting;
using UnityEngine;
 
public class JumpRopeGame : MonoBehaviour
{
    private Rigidbody m_rigidbody;
    private float m_speed = 3.0f;//이동 속도
    private float m_jumpPower = 300.0f;//점프 거리 
    private bool m_readyJump;//점프가능한 상태인지 확인하는 변수
    private bool m_rayHitted;//레이캐스트 hit한 물체가 있는지 확인하는 변수
 
    private void Start()
    {
        m_rigidbody = GetComponent<Rigidbody>();
    }
 
    private void Update()
    {
 
        float dis = 0.0f;
 
        {//땅과의 거리 측정
            Ray ray = new Ray(transform.position, Vector3.down);//캐릭터 위치에서 y -1방향으로 레이 생성
            RaycastHit hit;
 
            if (Physics.Raycast(ray, out hit))
                dis = ray.origin.y - hit.point.y;
        }
 
        if (dis < 0.51f)
        {
            Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
            Vector3 hitpos;
 
            RaycastHit hit;
            m_rayHitted = Physics.Raycast(ray, out hit);
 
            if (m_rayHitted && TouchManager.instance.IsBegan())//처음 터치한 대상이 플레이어일 때 점프가능한 상태로 만들기
            {//점프 가능한 상태일 때는 플레이어 이동이 안됨
                m_readyJump = hit.transform.tag == "Player" ? true : false;
            }
 
            if (m_readyJump && !TouchManager.instance.IsHolding())//점프 준비 상태에서 손을 땟을 때
            {
                if (TouchManager.instance.IsDragUp())//위로 드래그 했을 경우
                {
                    m_readyJump = false;//준비 상태 해제
                    m_rigidbody.AddForce(new Vector3(0, m_jumpPower, 0));//위로 AddForce
                }
            }
            
            if (m_rayHitted && TouchManager.instance.IsHolding() && !m_readyJump)//터치 누르고 있는 상태일 때 & 점프 준비 상태가 아닐 때
            {
 
                if (hit.transform.tag == "Terrain")
                {
                    hitpos = hit.point;
                }
                else
                {
                    hitpos = transform.position;
                }
 
                hitpos = hitpos - transform.position;
                hitpos.y = 0;
                m_rigidbody.velocity = hitpos.normalized * m_speed;
            }
        }
    }
}
 
cs

다음 캐릭터 이동에서 터치 관리자를 통하여 드래그 방향과

터치 상태를 가져와서 캐릭터 이동을 구현한다.

터치한 부분이 Terrain인 경우 이동할 수 있게 하였으며

캐릭터(구)를 클릭했을 때 점프를 준비하게 만들고 이동못하게 만든다.

이 상태로 플레이어가 아닌 다른 오브젝트를 누르면 준비 상태를 품



 결과


추가로 Rigidbody를 사용하여 이동시킬 때

 Rigidbody와 Character Controller를 동시에 추가하면 안됨




 

댓글 없음:

댓글 쓰기

c++ thread.h

 c++에서 쓰레드 돌릴려면 thread.h 헤더를 쓰면 되는데 이 친구는 쓰레드가 아직 실행 중인지, 아니면 강제 종료하거나 하는 함수가 없어서 조금 아쉬운 애다. std::thread 는 로컬 변수로 선언하든 new 동적 할당을 하든 start 함...