250310

lililllilillll·2025년 3월 9일

개발 일지

목록 보기
106/350

✅ What I did today


  • Project BCA


📝 Things I Learned


🏷️ C# :: Source Generator

C# Source Generators are a compile‐time feature introduced with C# 9 that let you “inject” additional source code into your project during compilation. They work by analyzing your existing code’s syntax trees and semantic models to generate new code that’s then compiled along with your original code. Here’s a breakdown, with a focus on how they relate to Unity:


What Are C# Source Generators?

  • Compile-Time Code Generation: They run during the build process and can generate boilerplate or repetitive code, reducing manual coding errors.
  • Integration with Roslyn: By implementing the ISourceGenerator interface (or deriving from helper base classes), these generators hook into the Roslyn compiler. They receive the compilation context, inspect your code, and output additional source files.
  • Transparent to Runtime: The generated code is compiled together with your code, meaning it becomes part of the final assembly without impacting runtime performance.

How Do They Work?

  • Analysis: The generator inspects your existing code by accessing syntax trees and semantic models. This lets you, for example, look for certain attributes or naming patterns.
  • Generation: Using the context’s API (typically context.AddSource()), the generator creates new source files that can, for instance, implement repetitive patterns, auto-wire dependencies, or generate serialization logic.
  • Incremental Updates: Modern source generators can be made incremental so that they only re-run when parts of the code they depend on change. This helps in maintaining faster compile times.


🎮 Project BCA


Realistic camera movement

Cinemachine

  • Timeline은 cinemachine의 설정 overrides한다.
  • Cinemachine Decollider : 카메라 벽뚫 방지
  • Cinemachine Group Framing : 여러 목표 같은 화면

cinemachine perline noise 너무 구려서
https://github.com/omid3098/camera_shakify_unity 사용

        private void Update()
        {
            // calculate the modulo so if time passes the lastTime of the animation it will loop back to the first time
            var time = (Time.time * _shakeData.FPS * speed) % lastTime;

            // add shakedata to the current position and rotation of the object
            // First more back to the last position
            transform.localPosition -= lastPosition;
            float beforeSign = lastPosition.y;
            lastPosition = new Vector3(
                _shakeData.PosX.Evaluate(time) * strenght,
                _shakeData.PosY.Evaluate(time) * strenght,
                _shakeData.PosZ.Evaluate(time) * strenght
            );
            float afterSign = lastPosition.y;
            // move to the next position
            transform.localPosition += lastPosition;

            if (beforeSign > afterSign) walkChance = true;

            if (walkChance && beforeSign < afterSign)
            {
                audioSource.Play();
                walkChance = false;
            }

y가 이전보다 커질때 발걸음 소리를 한 번 재생하도록 수정

Intro cutscene

    void Start()
    {
        walk2_target.transform.LookAt(button.transform);
        walk3_target.transform.LookAt(roboticArm.transform);
        walk4_target.transform.LookAt(chessboard.transform.position + new Vector3(0, 0.5f, 0));
    }

    void Update()
    {
        if (Input.GetKeyDown(KeyCode.Space))
        {
            StartCoroutine(MoveSequenceCoroutine());
        }
    }

    private IEnumerator MoveSequenceCoroutine()
    {
        yield return StartCoroutine(MoveToTarget(walk1_target.transform.position, walk1_duration));
        yield return StartCoroutine(MoveToTargetAndRotate(walk2_target.transform.position, walk2_target.transform.rotation, walk2_duration));
        yield return StartCoroutine(MoveToTargetAndRotate(walk3_target.transform.position, walk3_target.transform.rotation, walk3_duration));
        shakify.enabled = false;
        yield return StartCoroutine(MoveToTargetAndRotate(walk4_target.transform.position, walk4_target.transform.rotation, walk4_duration));
        vcam.Priority = 0;
        introManager.StartIntro();
        Destroy(this);
    }

    private IEnumerator MoveToTarget(Vector3 targetPosition, float duration)
    {
        Vector3 startPos = transform.position;
        float elapsedTime = 0f;

        while (elapsedTime < duration)
        {
            transform.position = Vector3.Lerp(startPos, targetPosition, elapsedTime / duration);
            elapsedTime += Time.deltaTime;
            yield return null;
        }

        transform.position = targetPosition; // 정확한 위치 보정
    }

    private IEnumerator MoveToTargetAndRotate(Vector3 targetPosition, Quaternion targetRotation, float duration)
    {
        Vector3 startPos = transform.position;
        Quaternion startRot = transform.rotation;
        float elapsedTime = 0f;

        while (elapsedTime < duration)
        {
            transform.position = Vector3.Lerp(startPos, targetPosition, elapsedTime / duration);
            transform.rotation = Quaternion.Slerp(startRot, targetRotation, elapsedTime / duration);
            elapsedTime += Time.deltaTime;
            yield return null;
        }

        transform.position = targetPosition; // 정확한 위치 보정
        transform.rotation = targetRotation; // 정확한 회전 보정
    }

인트로 컷신 초안 완성

다음엔 타임라인 쓸 수 있는 부분은 꼭 쓰자 스크립트는 수정하기 번거롭다

  • 걷는 속도가 느리다. (책상도 너무 멈) : 현실 핸드헬드 영상 참고
  • 시각적 정보가 부족해서 재미없다.
  • 어두워서 시인성이 부족하다. : 밖은 좀 더 밝아도 될지도
  • 밋밋해서 인상을 남기기 힘들다. : 포스트 프로세싱이나 셰이더 추가, 현실적이기보단 눈에 잘 띄게?
  • 음산하기보단 우중충하다. : 리얼타임 말고 베이크로 해보기
profile
너 정말 **핵심**을 찔렀어

0개의 댓글