[Unity] 조이스틱 만들기
이 글을 참고해서 작성하였습니다. [Unity3D] Programming - 모바일 가상 조이스틱 구현하기Programming - 모바일 가상 조이스틱 구현하기 작성 기준 버전 :: 2019.2 - 2019.4 [이 포스트의 내용은 유튜브 영상
freeedeveloper.tistory.com
이전, 글에서 조이스틱을 만들었고, 이번엔 이 조이스틱에 캐릭터를 연결해 움직이기를 해보려고 한다.
일단, 테스트용 캐릭터를 생성했다.
처음으로 3d프로젝트를 만들것이기 때문에, 3d 캐릭터를 에셋 스토어에서 찾아왔다. (다른 3d 캐릭터로 해도 무방하다.)
Human Basic Motions | 3D 애니메이션 | Unity Asset Store
Elevate your workflow with the Human Basic Motions asset from Kevin Iglesias. Find this & other 애니메이션 options on the Unity Asset Store.
assetstore.unity.com
구매해뒀었던 에셋을 찾아서 씬에 임포트 시켜줬다.
일단, 이전에 만들어둔 조이스틱을 넣어줬다.
저번 글에서 마찬가지로, 클릭을 감지하기위한 System이라는 이름의 오브젝트(Image) 를 생성해준 후, 그 아래에 조이스틱을 만들어줬다. (이전글을 참고하자)
그리고, 빈 오브젝트에 Character라는 이름을 붙인 뒤, MainCharacter라는 이름의 자식 오브젝트에 카메라와 임포트한 에셋을 넣어줬다.
내가 받은 에셋은 이렇게 패키지로 임포트 된 파일이 존재했다.
이 파일을 하이어라키에 넣어주고, UnPack을 해줬다.
이렇게 언팩을 진행하면
이런 모델이 생성된다.
아직 애니메이션이 붙어있지 않은 상태라 애니메이션 컨트롤러를 생성해, 이미 임포트되어있던 애니메이션을 연결해 간단하게 움직임을 구성해뒀다.
idel과 walk 사이의 화살표를 클릭해, 애니메이션 간, 전환이 원활히 이루어지도록 설정했다.
Has Exit Time을 False로 둔 이유는, 애니메이션 간, 대기시간 없이 바로 넘어갈 수 있도록 설정해둔것이다.
그리고 여기서 MainCharacter 아래의 CharacterCam은 Chinemachine의 vertualCam을 사용했다.
시네머신은 유니티에서 제공하는 에셋으로, 화면 전환을 보다 편리하게, 화면 효과도 줄 수 있는 에셋이다.
시네머신
Unity의 시네머신으로 복잡한 카메라의 움직임을 만드는 방법을 알아보세요. 타겟 트래킹, 구성, 블렌딩 및 자르기까지 쉽고 직관적으로 작업할 수 있습니다.
unity.com
설치는 이 글을 참고하자.
시네머신을 하이어라키에 추가하면, 기존에 있던 MainCamera가 자동으로 BrainCam이 된다..
브래인 캠은 메인 카메라를 말하고, vertualCam이 여러개 있을 때, 마지막에 활성화되는 캠을 비추게 되어있다.
시네머신에 관한 설명은
[NProject] 마음대로 만드는 게임 - 3. 카메라 설정
일단 이렇게 그렸다!플레이어가 맵을 돌아다녀야되니깐 이제 카메라 설정을 해보자! 예전엔 카메라를 구현할 때 하나하나 코드로 짜 넣어야됐다... 이게 은근 복잡하고 어렵다 보니 여기가 첫
freeedeveloper.tistory.com
시네머신 개요 | Cinemachine | 2.3.5-preview.3
시네머신 개요 시네머신을 사용하려면 카메라 작동에 대한 새로운 사고 방식이 필요합니다. 예를 들어 신중하게 스크립트화된 카메라 동작에 이미 많은 투자를 했을 수 있습니다. 하지만 시네
docs.unity3d.com
이 두 글을 참고하자.
최 상단 오브젝트에 다음과 같이 설정해뒀다.
메인 캐릭터를 사용하기 위해, 전용 스크립트를 생성해줬고, 나중에 구현할 충돌을 위해 Rigidbody와 boxcollider를 추가해줬다.
캐릭터 스크립트는 다음과 같다.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Character : MonoBehaviour
{
// Data
[SerializeField] float speed = 0.01f;
[SerializeField] float angle = 0f;
// Obj
[SerializeField] GameObject mainCharacterObj;
// anim
public Animator charAnim;
public string charState_Walk => "isWalk";
// Moving Method
public void Move(Vector2 vec)
{
//atan2 -> 백터의 방향(각도) 구함, rad2dig -> 라디안을 도(degree)로 변환환
angle = Mathf.Atan2(vec.x, vec.y) * Mathf.Rad2Deg;
this.transform.position += new Vector3(vec.x, 0f, vec.y) * speed;
mainCharacterObj.transform.rotation = Quaternion.Euler(0f, angle, 0f);
}
// Collider
void OnTriggerEnter(Collider other)
{
if (other.gameObject.tag == "Trigger")
{
Debug.Log("Trigger");
}
}
}
이전에 만들어둔 조이스틱에서 반환하는 값은 vector2값이기 때문에, 이걸 각도로 바꾼 후, 캐릭터의 회전값에 전달하는 과정이 핵심이였던것 같다.
테스트를 위해 cube를 만들어, 사진과 같이 배치한 후, collider에 is Trigger를 true로 설정했다.
코드에서 OnTriggerEnter를 사용하고 있기 때문에, is Trigger를 on으로 설정해줘야한다.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;
public class JoyStick : MonoBehaviour, IPointerUpHandler, IDragHandler, IPointerDownHandler
{
[SerializeField] private RectTransform joystick;
[SerializeField] private RectTransform lever;
[SerializeField, Range(10f, 150f)] private float leverRange;
[SerializeField] private Vector2 inputVector;
[SerializeField] private bool isInput;
[SerializeField] Character player; // 추가됨.
// LifeCycle
void Update()
{
if (isInput)
{
InputControlVector();
}
}
// interface
public void OnPointerDown(PointerEventData eventData)
{
joystick.position = eventData.position;
joystick.gameObject.SetActive(true);
ContolJoystickLever(eventData);
isInput = true;
}
public void OnDrag(PointerEventData eventData)
{
ContolJoystickLever(eventData);
}
public void OnPointerUp(PointerEventData eventData)
{
inputVector = Vector2.zero;
lever.anchoredPosition = Vector2.zero;
joystick.gameObject.SetActive(false);
player.charAnim.SetBool(player.charState_Walk, false); // 추가됨
isInput = false;
}
// Method
public void ContolJoystickLever(PointerEventData eventData)
{
Vector2 localPoint;
RectTransformUtility.ScreenPointToLocalPointInRectangle(joystick, eventData.position, eventData.pressEventCamera, out localPoint);
Vector2 clamped = Vector2.ClampMagnitude(localPoint, leverRange);
lever.anchoredPosition = clamped;
inputVector = clamped / leverRange;
}
// 추가됨
private void InputControlVector()
{
//입력값 전달.
player.Move(inputVector);
if (inputVector != Vector2.zero)
{
player.charAnim.SetBool(player.charState_Walk, true);
}
}
}
이전에 만들어뒀던 조이스틱 스크립트에서 애니메이션도 변화시킬 수 있도록 코드를 몇줄 추가해줬다.
이렇게 한 후 실행하면,
이런식으로 움직일 수 있게된다.
'Develop > Unity' 카테고리의 다른 글
[Unity] 조이스틱 만들기 (0) | 2025.05.22 |
---|---|
무료 에셋 정리 (2) | 2025.03.20 |
[Unity] 외부의 사진을 앱 내부로 가져와보자 - Native Gallery (0) | 2024.11.22 |
[Unity] 이벤트의 구현을 지원하는 Signaler를 사용해보자! (echo17.Signaler) (0) | 2024.11.16 |
[Unity] Hierarchy를 정리해보자 (Hierarchy Designer) (0) | 2024.11.04 |