[Unity 강의] 뱀서라이크 강의 - 조이스틱-
카테고리: Class VamSurLike
태그: C#, Unity, VamSurLike
1. Joystick
✔ 화면 전체에 투명한 판 생성
✔ 어딜 클릭하든 조이스틱이 시작점으로 작동
✔ Prefab으로 관리
Script
✔ UI_Joystick(Canvas)에 사용하고 싶은 이미지들이 포함되어 있어서
✔ [SerializeField]로 드래그 앤 드롭, GetComponentInChildren 사용 가능
✔ IPointerClickHandler, IPointerDownHandler, IPointerUpHandler, IDragHandler
UI_Joystick 코드
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;
public class UI_Joystick : MonoBehaviour, IPointerClickHandler, IPointerDownHandler, IPointerUpHandler,IDragHandler
{
[SerializeField]
Image _bg;
[SerializeField]
Image _handler;
float _joystickRadius;
Vector2 _touchPosition;
Vector2 _moveDir;
PlayerController _player;
void Start()
{
_joystickRadius = _bg.gameObject.GetComponent<RectTransform>().sizeDelta.y / 2;
// Temp1 Joystick-Player (Find)
_player = GameObject.Find("Slime_01").GetComponent<PlayerController>();
}
public void OnPointerClick(PointerEventData eventData)
{
}
public void OnPointerDown(PointerEventData eventData)
{
_touchPosition = eventData.position;
_bg.transform.position = eventData.position;
_handler.transform.position = eventData.position;
}
public void OnPointerUp(PointerEventData eventData)
{
_handler.transform.position = _touchPosition;
_moveDir = Vector2.zero;
// Temp1 Joystick-Player (Find)
//_player.MoveDir = _moveDir;
// Temp2 Joystick-Player (Manager(Static))
Managers.MoveDir = _moveDir;
}
public void OnDrag(PointerEventData eventData)
{
Vector2 touchDir = (eventData.position - _touchPosition);
float moveDist = Mathf.Min( touchDir.magnitude, _joystickRadius);
_moveDir = touchDir.normalized; //방향
Vector2 newPosition = _touchPosition + _moveDir * moveDist;
_handler.transform.position = newPosition;
// Temp1 Joystick-Player (Find)
//_player.MoveDir = _moveDir;
// Temp2 Joystick-Player (Manager(Static))
Managers.MoveDir = _moveDir;
}
}
JoyStick - Player 연결
✔ 3가지 방법
✔ 1. Find로 PlayerContorller 찾기 -> 사용 X
✔ 2. Managers (Static) -> 매 프레임마다 통신하기 힘듦
✔ 3. 델리게이트, 콜백
1. 조이스틱스크립트에서 Find로 PlayerController
_player.MoveDir = _moveDir;
PlayerController - 프로퍼티
public class UI_Joystick : MonoBehaviour, IPointerClickHandler, IPointerDownHandler, IPointerUpHandler,IDragHandler
{
PlayerController _player;
void Start()
{
_player = GameObject.Find("Slime_01").GetComponent<PlayerController>();
}
public void OnPointerUp(PointerEventData eventData)
{
_player.MoveDir = _moveDir;
}
public void OnDrag(PointerEventData eventData)
{
_player.MoveDir = _moveDir;
}
}
public class PlayerController : MonoBehaviour
{
Vector2 _moverDir = Vector2.zero;
public Vector2 MoveDir
{
get { return _moverDir; }
set { _moverDir = value.normalized; }
}
}
2. 공용으로 사용하는 데이터를 Managers에 담아서 사용
Static을 이용해 Managers.MoveDir
public class UI_Joystick : MonoBehaviour, IPointerClickHandler, IPointerDownHandler, IPointerUpHandler,IDragHandler
{
public void OnPointerUp(PointerEventData eventData)
{
_moverDir = Managers.MoveDir;
}
public void OnDrag(PointerEventData eventData)
{
_moverDir = Managers.MoveDir;
}
}
public class Managers : MonoBehaviour
{
public static Vector2 MoveDir;
}
public class PlayerController : MonoBehaviour
{
void MovePlayer() {
_moverDir = Managers.MoveDir;
Vector3 dir = _moverDir * _speed * Time.deltaTime;
transform.position += dir;
}
}
3. 델리게이트 콜백 (4강내용)
델리게이트 - 데이터가 바뀌었을 때 구독한 곳으로 알려준다.
✔ 조이스틱으로 Managers.Game.MoveDir가 변경된다.
✔ set => OnMoveDirChanged
✔ OnMoveDirChanged 구독되어 있는 곳들에게 알려준다.
✔ PlayerController Start에서 이벤트를 미리 구독했다.
✔ HandleOnMoveDirChanged(이벤트가 발생하면 실행될 메서드)로 Player의 _moverDir를 변경
public class UI_Joystick : MonoBehaviour, IPointerClickHandler, IPointerDownHandler, IPointerUpHandler,IDragHandler
{
public void OnDrag(PointerEventData eventData)
{
Vector2 touchDir = (eventData.position - _touchPosition);
float moveDist = Mathf.Min( touchDir.magnitude, _joystickRadius);
_moveDir = touchDir.normalized; //방향
Vector2 newPosition = _touchPosition + _moveDir * moveDist;
_handler.transform.position = newPosition;
// Temp2 Joystick-Player (Manager(Static))
Managers.Game.MoveDir = _moveDir;
}
}
public class GameManager
{
Vector2 _moveDir;
public event Action<Vector2> OnMoveDirChanged;
public Vector2 MoveDir
{
get { return _moveDir; }
set
{
_moveDir = value;
OnMoveDirChanged?.Invoke(_moveDir);
}
}
}
public class PlayerController : MonoBehaviour
{
// 구독
void Start()
{
Managers.Game.OnMoveDirChanged += HandleOnMoveDirChanged;
}
void OnDestroy()
{
if (Managers.Game != null)
Managers.Game.OnMoveDirChanged -= HandleOnMoveDirChanged;
}
// 이벤트가 발생하면 실행될 메서드
void HandleOnMoveDirChanged(Vector2 dir)
{
_moverDir = dir;
}
}
이것저것 메모
Canvas Scaler
✔ Canvas Scaler - UI Scale Mode -> Scale With Screen Size
✔ 화면크기에 맞게 UI 조정
Raycast Target
✔ Raycast Target 체크 확인
vector크기(거리)
✔ magnitude = vector의 크기(거리)
Static
✔ Static - 객체랑 무관하다. (종속x)
잡담, 일기?
게임 오브젝트 - 컴포넌트의 연결 좋은 방법으로 (중요!)
댓글남기기