TIL 25.03.17 - 팀 과제 4일차

강진규·2025년 3월 17일

Today I Learned

목록 보기
32/34
post-thumbnail

오늘은 오류 수정과 기존 기능들을 수정하는 것이 주된 과제였다.
어느정도 정리된 후 레이저 트랩을 추가하였다.


[ 반사 관련 오브젝트 효과 추가]

원래는 빛 생성기의 빛 기둥과 메테리얼이 항상 켜져있었는데, 이 부분이
성능 저하에 영향이 있을것 같아서 그 부분을 수정해주었고, 목표지점 클리어 시
서서히 빛이 줄어들게 만들어보았다.

public override bool OnInteract()
{
    HandleInteraction(CharacterManager.Instance.Player.gameObject);

    if (lightGenerator != null && !hasToggledLight)
    {
        LightGenerator lg = lightGenerator.GetComponent<LightGenerator>();

        lg.ToggleLightMaterial();
        lg.ToggleLightGeneration(true);
        hasToggledLight = true;
    }

    return true;
}

회전 상태가 true가 되게 될때 빛 생성기의 메테리얼과 빛 생성 메서드를 켜주었다.
hasToggledLight를 통해 한번 켜진 빛은 안꺼지게 해두었다.

IEnumerator ChangeToDisable()
{
    Material mat = targetRenderer.material;

    Color startColor = mat.color;             // 원래 색상
    Color targetColor = Color.gray;   // 어두운 회색
    Color startEmission = mat.GetColor("_EmissionColor");  // 원래 에미션 색상
    Color targetEmission = targetColor * 0.5f; // 어두운 회색 기반으로 에미션 감소

    float elapsedTime = 0f;

    while (elapsedTime < fadeDuration)
    {
        float t = elapsedTime / fadeDuration;
        mat.color = Color.Lerp(startColor, targetColor, t);
        mat.SetColor("_EmissionColor", Color.Lerp(startEmission, targetEmission, t)); // 에미션도 점점 어두워짐

        elapsedTime += Time.deltaTime;
        yield return null;
    }

    mat.color = targetColor;
    mat.SetColor("_EmissionColor", targetEmission); // 최종적으로 어두운 회색으로 설정
}

목표지점이 클리어되면 코루틴을 사용하였고 Lerp를 통해 서서히 빛이 어두워지게 만들어줬다.


[ 거울 반사 관련 ]

기존 거울의 반사판이 전부 켜져있었는데, 이 부분이 프레임 드랍을 유발했다.
그래서 빛 기둥과 부딪히고 있을때만 반사판을 켜주는 방식으로 변경했다.

public void SetReflectorActive(bool state)
{
    if (reflector == null)
    {
        Debug.LogWarning($"{gameObject.name}의 Reflector가 설정되지 않았습니다!");
        return;
    }

    // 현재 상태와 동일하면 중복 호출 방지
    if (reflector.activeSelf == state)
    {
        return;
    }

    Debug.Log($"{gameObject.name} Reflector 활성화: {state}");

    reflector.SetActive(state);
    Debug.Log($"Reflector 현재 상태: {reflector.activeSelf}");

    if (state)
    {
        if (disableCoroutine != null)
        {
            StopCoroutine(disableCoroutine);
            disableCoroutine = null;
        }
    }
    else
    {
        if (disableCoroutine == null)
        {
            disableCoroutine = StartCoroutine(DisableReflectorAfterDelay());
        }
    }
}

현재 상태와 동일하면 중복 호출 방지하기 위해 조건을 걸어 리턴시켜주었고,
reflector.SetActive(state)로 해서 state에 맞게 true false 해주었다.
이외 상황에서 정해둔 코루틴을 사용하여 정해둔 시간에 맞춰 꺼주었다.

또한 기존에 Reflection Probe을 통해 반사효과를 주었는데 이 부분도 성능 저하에
영향을 주는 것 같아서 일단 꺼두었다. 시간이 남으면 더 좋은 방법을 찾아봐야겠다.


[ 오브젝트 회전 방식 변경 ]

기존 방식은 e를 눌러 회전상태로 만들고 좌우로 마우스 클릭을 통해 회전시켰다.
상하로도 움직이면 좋을것 같고 방향키를 통해 회전시키면 좋을것 같아서 변경해보았다.

private void HandleRotation(float rotationInputX, float rotationInputY)
{
    Vector3 rotationAxis = Vector3.zero;

    // 좌우 회전 처리
    if (rotationInputX != 0f)
    {
        rotationAxis = transform.up;  // Y축 기준 좌우 회전
        selectedRotatableObject.Rotate(rotationInputX * selectedRotatableObject.rotationSpeed * Time.deltaTime, rotationAxis);
    }

    // 상하 회전 처리
    if (rotationInputY != 0f)
    {
        rotationAxis = selectedRotatableObject.transform.right; // X축 기준 상하 회전
        selectedRotatableObject.Rotate(rotationInputY * selectedRotatableObject.rotationSpeed * Time.deltaTime, rotationAxis);
    }

    if (rotationInputX != 0f || rotationInputY != 0f)
    {
        selectedRotatableObject.lastInputTime = Time.time;
    }

    selectedRotatableObject.RotateTimeOutCheck();

    Vector3 eulerAngles = selectedRotatableObject.transform.rotation.eulerAngles;
    eulerAngles.z = 0f;  // Z축 회전 방지
    selectedRotatableObject.transform.rotation = Quaternion.Euler(eulerAngles);
}

OnRotate로 방향키의 입력을 기록하고 HandleRotation으로 회전을 시켜줬다.

상하 회전시 이상하게 회전하는 문제가 생겼는데,
Z축 회전 방지를 추가해주니 해당 문제가 해결되었다.


[ 레이저 트랩 추가 ]

필수 기능에 장애물 관련이 있어서 레이저 트랩을 하나 추가해보았다.
아직 기능만 구현하고 맵에 배치를 다 안하긴 했지만 이걸 사용하여 맵 구성을
좀 더 다채롭게 만들 수 있을것 같다.

private void OnTriggerEnter(Collider other)
{
    if (other.TryGetComponent(out PlayerCondition player))
    {
        StartCoroutine(DamageOverTime(player));
    }
}

private void OnTriggerExit(Collider other)
{
    if (other.TryGetComponent(out PlayerCondition player))
    {
        StopAllCoroutines(); // 레이저에서 벗어나면 데미지 중단
    }
}

private IEnumerator DamageOverTime(PlayerCondition player)
{
    while (true)
    {
        player.TakePhysicalDamage(damageAmount);
        yield return new WaitForSeconds(damageInterval); // 지정한 간격마다 데미지 적용
    }
}

트리거 되었을때 playerCondition 컴포넌트에 접근해서 TakePhysicalDamage를 통해
데미지를 처리해 주었고 코루틴을 사용해서 닿고 있을때 지속적으로 데미지를
줄 수 있게 만들었다.


기능 추가는 오늘 진행하던 것 까지만 하기로 하였다.
내일은 모든 기능을 연결하고 오류를 수정하는 것이 대부분일 것 같다.
아주 든든한 팀원들을 만나서 맘 편안하게 작업하는 것 같다 ^오^ b

0개의 댓글