[25.05.20] TIL( 개인 프로젝트 도전과제 진 )

설민우·2025년 5월 20일

내일배움캠프 - Unity

목록 보기
45/85

개인 프로젝트를 본격적으로 시작하면서 필수 과제 전부와 도전과제 1개를 완료하였습니다.

완료 내역

(도전 과제)

  • 움직이는 플랫폼 구현 (난이도 : ★★★☆☆) << 완료
  • 추가 UI (난이도 : ★★☆☆☆) 및 스테미나 달리기 << 완료
  • 다양한 아이템 구현 (난이도 : ★★★★☆) << 완료
  • 장비 장착 (난이도 : ★★★★☆) << 완료
  • 상호작용 가능한 오브젝트 표시 (난이도 : ★★★★★) << 완성
  • 플랫폼 발사기 (난이도 : ★★★★★) << 완성
  • 벽 타기 및 매달리기 (난이도 : ★★★★☆) (사다리, 마리오 벽타기) << 완성
  • 레이저 트랩 (난이도 : ★★★★☆) << 완성

< 움직이는 플랫폼 구현 >

using System.Collections;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using UnityEngine;

public class MovePlatform : MonoBehaviour
{

    [SerializeField] private Transform _startPoint;
    [SerializeField] private Transform _endPoint;
    private GameObject _platform;

    [SerializeField] private float _waitTime = 1.0f;
    [SerializeField] private float _moveSpeed = 2.0f;

    private float _yPivot;
    private float _extra = 0.1f;

    private void Start()
    {
        _platform = transform.gameObject;
        _platform.transform.position = _startPoint.position;
        _yPivot = transform.position.y + _platform.transform.localScale.y / 2;


        StartCoroutine(MoveRoutine());
    }
    private IEnumerator MoveRoutine()
    {
        while (true)
        {
            // 시작에서 끝 지점으로
            yield return StartCoroutine(MoveTo(_endPoint.position));
            yield return new WaitForSeconds(_waitTime);

            // 끝에서 시작 지점으로
            yield return StartCoroutine(MoveTo(_startPoint.position));
            yield return new WaitForSeconds(_waitTime);
        }
    }

    private IEnumerator MoveTo(Vector3 target)
    {
        while (Vector3.Distance(_platform.transform.position, target) > 0.01f)
        {
            _platform.transform.position =
                Vector3.MoveTowards(_platform.transform.position,target,_moveSpeed * Time.deltaTime);
            yield return null;
        }

        _platform.transform.position = target;
    }

    private void OnCollisionEnter(Collision collision)
    {
        if (collision.transform.CompareTag("Player"))
        {
            float playerPivot = collision.transform.position.y + collision.transform.localScale.y / 2;
            if (playerPivot + _extra > _yPivot)
            {
                collision.transform.SetParent(_platform.transform, true);
            }
        }
    }

    private void OnCollisionExit(Collision collision)
    {
        if (collision.transform.CompareTag("Player"))
        {
            collision.transform.SetParent(null);
        }
    }

}
  • 움직이는 플랫폼을 만들되, 위에 그냥 플레이어가 올라가면 떨어져버리는 문제가 있었습니다
  • 플랫폼 위에 올라서면 플레이어가 플랫폼의 자식 오브젝트로 들어가도록 했습니다
  • 문제!! << 플랫폼 자체에 올리니, 플랫폼의 스케일에 따라 플레이어의 스케일이 영향을 받는 문제가 있었습니다.
  • 콜라이더와 메쉬를 분리하여 해당 문제를 해결했습니다(부모가 될 녀석은 무조건 1,1,1 스케일로)

< 추가 UI >

  • 달리기를 사용하면 스태미너가 감소하고, 스태미너가 0이되면 달리기가 자동으로 멈추도록 설정했습니다.
  • 이 반영은 옵저버 패턴을 이용하여 구현했습니다.

< 다양한 아이템 구현 >

  • 섭취 가능 아이템을 생성하고, 채력 증가, 이동속도 증가등의 아이템을 추가했습니다.
  • 아이템 데이터는 스크립터블 오브젝트로 구현했습니다.

< 장비 장착 >

  • 섭취 아이템과 마찬가지로 장착 할 수 있는 아이템도 생성했습니다.
  • 장착시 E 표시가 나옵니다.
  • 지금은 이동속도 증가만 가능합니다.

< 상호작용 가능한 오브젝트 표시 >

using TMPro;
using UnityEngine;
using UnityEngine.UI;

public class UI_Hover : UI_Scene
{
    private Camera mainCamera;
    [SerializeField] private GameObject hoverUI;
    private TextMeshProUGUI hoverTxt;
    [SerializeField] private LayerMask interactableLayer;
    enum Texts
    {
        Txt,
    }

    public override void Init()
    {
        hoverUI.SetActive(true);

        Bind<TextMeshProUGUI>(typeof(Texts));
        hoverTxt = Get<TextMeshProUGUI>((int)Texts.Txt);
        mainCamera = Camera.main;

        hoverUI.SetActive(false);
    }

    private void Update()
    {
        Ray ray = mainCamera.ScreenPointToRay(Input.mousePosition);

        if (Physics.Raycast(ray, out RaycastHit hit, 100f, interactableLayer))
        {
            // 마우스 근처에 UI 표시
            hoverUI.SetActive(true);
            hit.transform.TryGetComponent<ItemObject>(out ItemObject item);
            hoverTxt.text = item.Data.DisplayName;

            Vector2 screenPos = Input.mousePosition;
            hoverUI.transform.position = screenPos + new Vector2(20f, -20f); // 마우스 옆에 띄움
        }
        else
        {
            hoverUI.SetActive(false);
        }
    }
}

  • 상호작용 가능한 물체에 마우스가 가까이 가면 UI가 출력됩니다.

< 플랫폼 발사기 >

  • 360 도 돌아가며 그 방향으로 플레이어를 발사시켜주는 마리오 대포식 장치입니다.

< 벽 타기 및 매달리기 >

  • 사다리 타기 기능 및 마리오식 벽점프 기능을 추가했습니다.

< 레이저 트랩 >

  • 평소에는 가만히 있다가 Ray에 닿으면 이동하는 레이저 트랩을 생성했습니다.
profile
클라이언트 개발자를 지망하고 있습니다.

0개의 댓글