- RPG Project - 7 [ 상호작용 Text 구현 ]2024년 10월 14일
- SiJun-Park
- 작성자
- 2024.10.14.:21
오늘의 목표는 상호작용이 가능한 Object가 있을 시 Text를 띄워주는 System을 구현을 하려고 한다.
가장 처음 적용을 하고자 하는 곳은 NPC이다.
NPC 머리위에 “상호작용을 하려면 [Key]를 입력을 하세요”라는 문구를 띄우고 싶어서 생각을 하게 된 기능이다.
NPC 가장 먼저 NPC위의 텍스트가 소환이 될 위치를 잡아줬다.
Prefab 그리고 EventSystem에 적용을 할 Text Prefab을 만들어 줬다.
이제 스크립트 코딩을 할 차례이다.
1. Canvas
public class TotalUiControl : MonoBehaviour { static TotalUiControl _my; public static TotalUiControl _instance { get { return _my; } } void Awake() => _my = this; [Header("UI 표시 Object")] [Space(10)] [Header("원하는 key를 누르세요 Prefab")] [SerializeField] private GameObject _EventSystem; public enum Type { EventSystem = 0, ItemDescription, SkillDescription } public GameObject Create(Type type) { GameObject obj = null; switch (type) { case Type.EventSystem: obj = Instantiate(_EventSystem, transform); break; } return obj; } }
왜 Canvas에다가 이 스크립트를 만드냐면, 나중에 아이템 설명이나 스킬 설명 등 여러가지 설명이 UI 화면에 비추어지게
만들 예정이라 한번에 하기 위해 Canvas에다가 작업을 하였습니다.
가장 먼저 만들어둔 Prefab을 연동을 해주고, type을 만들어주었습니다.
그리고 GameObject를 생성해서 돌려줄 Create 함수를 작성을 하면 Canvas의 작업이 끝납니다.
=>Canvas에서 하는 이유는 간단하게 새롭게 만든 GameObject의 부모를 Canvas로 해주기 위해서 입니다.
2.Event System Control
public class EventSystemControl : MonoBehaviour { private Text _child; private Transform target; public void Init(Transform obj, string test, string key_text) { _child = GetComponentInChildren<Text>(); if (obj == null || (test == null || key_text == null) || _child == null) { Destroy(gameObject); return; } target = obj; UpdatePoint(); Chnage_Text(test, key_text); } void UpdatePoint() { Canvas canvas = GetComponentInParent<Canvas>(); RectTransform canvas_rect = canvas.GetComponent<RectTransform>(); Vector2 ScreenPos = RectTransformUtility.WorldToScreenPoint(Camera.main, target.position); RectTransformUtility.ScreenPointToLocalPointInRectangle(canvas_rect, ScreenPos, canvas.worldCamera, out Vector2 localPoint); RectTransform rect = GetComponent<RectTransform>(); rect.localPosition = localPoint; } void Update() => UpdatePoint(); private void Chnage_Text(string test, string key_text) => _child.text = test + " <color=#FFD500>"+ key_text + " </color>(을/를) 누르세요"; public void OnOff(bool b) => _child.gameObject.SetActive(b); }
이제 prefab에 달 스크립트를 작성을 해줍니다.
Init을 통해 초기 설정이 가능합니다.
UpdatePosition을 통해 target의 position을 Canvas 좌표에 맞도록 전환을 해서 표시를 해줍니다
그런데 이걸 지속적으로 표시 안해주면 텍스트가 그냥 둥둥 떠다니게 됩니다.
그러니 Update에 지속적으로 표시가 되게 연동을 해줍니다.
또한 범위를 벗어나면 Off 기능 다시 들어오면 On기능이 필요하니 연결을 해줍니다.
3. NPC
void OnTriggerEnter(Collider other) { if (other.CompareTag("UserPoint")) { _target = other.gameObject; if (_EventSystem == null) { _EventSystem = TotalUiControl._instance.Create(TotalUiControl.Type.EventSystem); _script = _EventSystem.GetComponent<EventSystemControl>(); _script.Init(_textpos, "NPC와 대화를 하려면", "[E]"); } else { _script.OnOff(true); } } } void OnTriggerExit(Collider other) { if (_target) { _target = null; } if (_EventSystem != null) _script.OnOff(false); } void OnTriggerStay(Collider other) { if (_target) return; else _target = other.gameObject; }
전에 만들었던 부분에서 추가적으로 연결을 해줍니다.
처음에 EventSystem이 없으면 첫번째로 만들었던 Canvas의 Create를 이용해서 만든 GameObject를
새롭게 할당을 해줍니다
=> 두번은 할 필요가 없으니 저장을 하기 위해 전역 변수로 선언을 하였습니다.
만약에 범위에 나가게 된다면 그 Object를 Destory를 하는 것이 아닌, OnOff기능을 이용해 Off를 시켜줍니다.
다시 들어오게 되면 EventSystem 전역변수가 null이 아니니 On만 시켜주면 됩니다.
결과 현재 Key를 하드코딩으로 넣어놨는데 추후에는 시작화면 만들면서 Key Setting을 넣을 예정입니다.
'Unity > RPG Project' 카테고리의 다른 글
RPG Project - 9 [ EXP Ball 생성 및 BezierCurve 활용 ] (0) 2024.10.19 RPG Project - 8 [ NPC Chat System ] (0) 2024.10.15 RPG Project - 6 [ NPC가 User 바라보기 구현 ] (0) 2024.10.10 RPG Project - 5 [ 플레이어 체력 감소 및 피해 효과 ] (0) 2024.10.10 RPG Project - 4 [ 카메라 제어 ] (0) 2024.10.09 다음글이전글이전 글이 없습니다.댓글