Develop_Log

[내배캠 최종 프로젝트] 맵 장애물 구현

리네엔 2024. 12. 3. 23:09

쿠키런 : 모험의 탑을 레퍼런스로 개발중.

  • 정작 쿠키런 : 모험의 탑을 즐겨하는 팀원은 없다는게 웃음 벨
  • 구현 사항 본다고 내가 제일 많이 해본듯. 아니 기획한 사람은 왜 안하면서 왜 이걸 레퍼로 잡자고 한건데?

문과 버튼 구현

버튼

  • 쿠키런 플레이시 보면 밟으면 문이 열리는 기믹이 존재
  • TriggerSource 클래스를 구현하여 트리거 되면 실행될 오브젝트를 받아서 실행시키는 기믹을 구현함
  • 버튼은 TriggerSource를 상속받아 OnTriggerEnter가 될때 실행되도록 함.
  • 니케 로스트 섹터를 보면 밟고 있어야 열리고 발을 떼면 닫히는 버튼이 존재함.
    • Trigger될 오브젝트와 TriggerSource에 Cancle을 구현
    • OnTriggerEnter일 때 Excute, OnTriggerExit일때 Cancle을 실행하도록 함.
      상세 코드
  • Trigger Source
public class TriggerSource : MonoBehaviour
{
    [SerializeField] protected GameObject triggerableObj;
    private ITriggerable triggerable;
    private void Awake()
    {
        if(triggerableObj.TryGetComponent<ITriggerable>(out ITriggerable componet) )
        {
            triggerable = componet;
        }
        else
        {
            Debug.Log("잘못된 오브젝트 연결");
        }
    }

    protected void Excute()
    {
        triggerable.Excute();
    }
    protected void Cancle()
    {
        triggerable.Cancle();
    }

}
  • ToggleButton

public class ToggleButton : TriggerSource
{
    private bool isActivate = false;
    BattleZone zone;
    private void Start()
    {
        zone = triggerableObj.GetComponent<BattleZone>();
    }
    private void OnTriggerEnter(Collider collision)
    {
        if (!isActivate)
        {
            Excute();
            isActivate = true;
            zone.BattelStart = true;

        }

    }
}

  • ITriggerable 인터페이스를 상속받아 트리거가 실행될때 실행될 함수와 트리거가 취소 될때 실행될 함수를 선언해놨다
public interface ITriggerable
{
    public void Excute();
    public void Cancle();
}
  • 문은 기본적으로 시작 위치와 종료 위치를 저장해두고, Trigger될때 시작위치에서 종료 위치로, 해제 될때 종료에서 시작 위치로 움직이도록 해두었다.
  • 근데 이제 스윙으로 열리는문과 슬라이딩으로 열리는 문 두 종류가 있을 수 있으므로...! Gate를 구현하고 SlidingGate와 SwingGate가 Gate를 상속받도록 하였다.

  • 또한 커스텀 에디터로 시작위치와 종료 위치를 오브젝트를 움직여서 저장 할 수 있도록 하였다.

  • GateBase
public abstract class GateBase : MonoBehaviour, ITriggerable
{
    [SerializeField] protected float delayTime;
    [SerializeField] protected float duration;
    [SerializeField] protected Vector3 start;
    [SerializeField] protected Vector3 end;

    private Coroutine coroutine;

    public void Excute()
    {
        if (coroutine != null)
        {
            StopCoroutine(coroutine);
        }
        coroutine = StartCoroutine(Action(this.transform.localPosition, end));
    }
    public void Cancle()
    {
        if (coroutine != null)
        {
            StopCoroutine(coroutine);
        }
        coroutine = StartCoroutine(Action(this.transform.localPosition, start));
    }

    protected abstract IEnumerator Action(Vector3 start, Vector3 end);

    public abstract void SaveStartPosition();
    public abstract void SaveEndPosition();
}
  • SlidingGate
public class SlidingGate : GateBase
{
    private void Awake()
    {
        this.transform.localPosition = start;
    }
    protected override IEnumerator Action(Vector3 start, Vector3 end)
    {
        float currentTime = 0;
        float actduration = duration * ((start - end).magnitude / (this.start - this.end).magnitude);
        while (currentTime<= actduration)
        {
            currentTime += Time.deltaTime;
            this.transform.localPosition = Vector3.Lerp(start, end, currentTime / actduration);
            yield return null;
        }

    }

    public override void SaveStartPosition()
    {
        start = this.transform.localPosition;
    }
    public override void SaveEndPosition()
    {
        end = this.transform.localPosition;
    }

}