W298.dev
ProjectsPostsAbout Me
youtube
Pages
ProjectsPostsAbout Me
Posts
TAGS
All
RL-Obstacle-Avoid
RL-Competitive
Robot-Escape
Assembly Definition
ML-Agent
RL-Obstacle-Avoid
RL-Competitive
Unity
RL-Obstacle-Avoid
RL-Competitive
Robot-Escape
Assembly Definition
SERIES
RL-Obstacle-Avoid
RL-Competitive
Robot-Escape

Player UI

UI를 만들기 시작했다. 3부분으로 나누어서 작업할 것이다.
  • Player UI (HUD)
  • Enemy UI (인디케이터)
  • Turret, Laptop Hack UI

Interact UI

https://velog.velcdn.com/images/lutca1320/post/838136e3-2ce1-439d-9932-64522c5a1cf8/image.webp
Interactable 한 오브젝트 (AmmoBox, MedBox 등) 에 가까이 가면 Interact UI가 나온다. description 도 추가적으로 제공할 수 있다.

Health UI

https://velog.velcdn.com/images/lutca1320/post/5378a5b2-d1cd-472c-a848-f9efa7295b24/image.webp
남은 체력을 표시한다. 아래에는 남은 Aid Kit 의 수를 보여준다.

Ammo UI

https://velog.velcdn.com/images/lutca1320/post/86f12c88-843d-412e-b4a7-8f3feff3dec5/image.webp
Ammo 관련 정보를 보여준다. 총기를 발포하면 탄약 아이콘이 하나씩 사라진다. 장전하는 동안 Reloading 텍스트가 표기된다.

PlayerUI.cs

위 3가지 UI들을 관리한다.
1public class PlayerUI : MonoBehaviour
2{
3    private GunController gunController;
4    private RobotStatusController statusController;
5    private PlayerInventory playerInventory;
6    private Animator animator;
7
8    private Canvas canvas;
9    private Text ammoText;
10    private GameObject ammoContainer;
11    private Text healthText;
12    private GameObject healthContainer;
13    private Text aidText;
14    private Text reloadText;
15    private RectTransform interactRect;
16    private Text descriptionText;
17
18    public GameObject interactObject = null;
19
20    public GameObject ammoIconPrefab;
21
22    public void ShowInteractUI(GameObject interactObject)
23    {
24        this.interactObject = interactObject;
25    }
26
27    public void HideInteractUI()
28    {
29        this.interactObject = null;
30    }
31
32    public void SetInteractDescription(string text)
33    {
34        descriptionText.text = text;
35    }
36
37    private void Start()
38    {
39        GameObject player = GameObject.Find("Player");
40        gunController = player.GetComponentInChildren<GunController>();
41        statusController = player.GetComponentInChildren<RobotStatusController>();
42        playerInventory = player.GetComponent<PlayerInventory>();
43        animator = player.GetComponent<Animator>();
44
45        canvas = transform.GetComponent<Canvas>();
46        ammoText = transform.Find("AmmoText").GetComponent<Text>();
47        ammoContainer = transform.Find("AmmoContainer").gameObject;
48        healthText = transform.Find("HealthText").GetComponent<Text>();
49        healthContainer = transform.Find("HealthContainer").gameObject;
50        aidText = transform.Find("AIDText").GetComponent<Text>();
51        reloadText = transform.Find("ReloadingText").GetComponent<Text>();
52        interactRect = transform.Find("Interact").GetComponent<RectTransform>();
53        descriptionText = transform.Find("Interact").Find("DescriptionImage").GetChild(0).GetComponent<Text>();
54    }
55
56    private void LateUpdate()
57    {
58        if (statusController.isDeath) return;
59
60        reloadText.gameObject.SetActive(animator.GetBool("isReload"));
61
62        ammoText.text = gunController.ammoSystem.magAmmo + " / " + gunController.ammoSystem.remainAmmo;
63        healthText.text = ((int)statusController.health).ToString();
64
65        interactRect.gameObject.SetActive(interactObject != null);
66        if (interactObject)
67        {
68            var screenPos = Camera.main.WorldToScreenPoint(interactObject.transform.position);
69            RectTransformUtility.ScreenPointToLocalPointInRectangle(canvas.transform as RectTransform, screenPos,
70                canvas.worldCamera, out Vector2 movePos);
71
72            interactRect.position = canvas.transform.TransformPoint(movePos + new Vector2(50, 50));
73        }
74
75        var aidKit = playerInventory.GetItem("AidKit");
76        aidText.text = "x " + (aidKit != null ? aidKit.count.ToString() : "0");
77
78        int count = gunController.ammoSystem.magAmmo - ammoContainer.transform.childCount;
79        if (count > 0)
80        {
81            for (int i = 0; i < count; i++)
82            {
83                GameObject ammoIcon = Instantiate(ammoIconPrefab, ammoContainer.transform);
84                ammoIcon.GetComponent<RectTransform>().localPosition -= new Vector3(10 * (ammoContainer.transform.childCount - 1), 0, 0);
85            }
86        }
87        else if (count < 0)
88        {
89            for (int i = 0; i < -1 * count; i++)
90            {
91                Destroy(ammoContainer.transform.GetChild(ammoContainer.transform.childCount - 1).gameObject);
92            }
93        }
94
95        int segmentCount = (int)(statusController.health /
96                           (statusController.maxHealth / healthContainer.transform.childCount));
97
98        for (int i = 0; i < segmentCount; i++)
99        {
100            healthContainer.transform.GetChild(i).gameObject.SetActive(true);
101        }
102        for (int i = segmentCount; i < healthContainer.transform.childCount; i++)
103        {
104            healthContainer.transform.GetChild(i).gameObject.SetActive(false);
105        }
106    }
107}
108

BoxInteract.cs

AmmoBox, MedBox 에 접근할 시 Interact UI가 표시되도록 하는 코드이다.
1public enum BoxMode
2{
3    AMMO,
4    HEALTH
5}
6
7public class BoxInteract : MonoBehaviour
8{
9    private Animator animator;
10    private PlayerUI playerUI;
11    private bool isActive = false;
12
13    public BoxMode boxMode = BoxMode.AMMO;
14    public int amount = 3;
15
16    public void Interact(GameObject target)
17    {
18        if (!isActive) return;
19
20        bool success = false;
21        switch (boxMode)
22        {
23            case BoxMode.AMMO:
24                GunController g = target.GetComponentInChildren<GunController>();
25                if (g && amount > 0)
26                {
27                    g.ammoSystem.remainAmmo += 30;
28                    amount--;
29                    success = true;
30                }
31                break;
32            case BoxMode.HEALTH:
33                PlayerInventory i = target.GetComponent<PlayerInventory>();
34                if (i && amount > 0)
35                {
36                    i.AddItem("AidKit", 1);
37                    amount--;
38                    success = true;
39                }
40                break;
41        }
42
43        if (success) animator.SetTrigger("Interact");
44        playerUI.SetInteractDescription(amount + " remain");
45    }
46
47    private void Start()
48    {
49        animator = transform.root.GetComponent<Animator>();
50        playerUI = GameObject.Find("PlayerUICanvas").GetComponent<PlayerUI>();
51    }
52
53    private void OnTriggerEnter(Collider other)
54    {
55        if (other.name != "Player") return;
56        isActive = true;
57        playerUI.ShowInteractUI(transform.parent.gameObject);
58        playerUI.SetInteractDescription(amount + " remain");
59    }
60
61    private void OnTriggerExit(Collider other)
62    {
63        if (other.name != "Player") return;
64        isActive = false;
65        playerUI.HideInteractUI();
66        playerUI.SetInteractDescription("");
67    }
68}
69