0721 배운거(레트로 좀비서바이벌)

김동현·2022년 7월 21일
0

열거형

  • 문법은 C++과 같으나 몇 가지 차이점이 있음
    • 열거형으로 만든 기호상수 사용 시 꼭 열거형을 앞에 적어줘야 함 ex) State.Ready
    • int 타입으로 암시적 형 변환 불가능. 명시적으로 변환 해야 함 ex) (int)State.Ready
    • C++보다 좀 더 풍성한 기능 지원. 메소드 ToString 같은게 사용 가능
    • 열거형 순회가 가능하다. for문에 넣어서 사용 가능하다.

반복자 메서드(Iterator Method)

https://docs.microsoft.com/ko-kr/dotnet/csharp/iterators

  • IRnumerable / IEnumerator를 반환 타입으로 가지는 메서드
  • 반복자 메서드에서는 yield문 사용 가능 yield문을 만나면 실행을 중단한다.
    • yield return : 반환값과 함께 중단
    • yield break : 반환값 없이 중단
  • MoveNext() 가 호출될 때 마다 이전에 중단됐던 지점부터 실행하며, 메서드가 끝나거나 yield문을 만날 때까지 실행한다.
// <int> 는 IEnumerator 반환값의 타임
IEnumerator<int> TestIteratorMethod()
{
    yield return 1;
    yield return 2;
    yield return 3;

}
// 반복자 메서드는 어디까지 실행했는지 기억한다 
// yield 문을 만나서 돌아가면 어디까지 실행됬는지 기억하고 다시 실행한다.
IEnumerator<int> enumerator = TestIteratorMethod();

// MoveNext 다음으로 넘어가는거
while (enumerator.MoveNext()) 
{
    // Current에 반환값 저장이 댐
    Console.WriteLine(enumerator.Current); 
}


만들었던 터렛중에 총알 발사 딜레이 시간만들었던걸 저렇게 바꿀 수 있다.

코루틴

https://namu.wiki/w/%EC%BD%94%EB%A3%A8%ED%8B%B4

  • 반복자 메서드를 활용해 함수의 명시적 실행 없이도 내부적으로 알아서 실행시켜주는 시스템
  • 시간 혹은 순차적 처리를 구현할 때 직관적으로 코드를 작성할 수 있어 유용하다.
  • C#의 반복자 메서드를 이용하여 구현되었다.
  • WaitForSeconds(??f) : ??초 동안 중단

반복자 메서드를 사용해 일정 루틴을 만들어 주는 것
어떠한 행동에 대해 조금씩 업데이트를 해 주어야 할 때 사용하면 좋다.
Start() 에서 코루틴을 등록 해 주면 => StartCoroutine(Shot()); 를 넣어주면 저 반복자 메서드를 불러와서 실행된다.

코루틴 등록을 해 줄 때 Start()에 넣어줄지 Updata()에 넣어줄지 상황에 따라 다르다.

Updata() 와 LateUpdata() 사이에 이루어진다

레이어

  • 레이어는 씬 내의 존재하는 게임 오브젝트를 구분할 수 있게 해주는 도구
  • 충돌 검출에 활용

레이캐스트

https://docs.unity3d.com/kr/2021.3/ScriptReference/Physics.Raycast.html

  • Ray를 기반으로 충돌 검출을 하는 것
  • 레이어 마스크를 이용하면 성능 향상에 이점이 있음. => Physics.Raycast()

유니티의 다형성

  • 가상 함수는 virtual 키워드를 붙인다.
  • 오버라이딩은 override 키워드를 붙인다.
  • 추상 클래스 / 메서드를 만들려면 abstract 키워드를 붙인다.
    • 추상 메서드는 반드시 자식에서 오버라이딩을 해야 한다.
// 가상 메서드
// 오버라이딩을 강제하지 않음 => 구현 해도되고 안해도 되고
class Base
{
    public virtual void Foo() { Console.WriteLine("Base의 Foo"); }
}

class Derived : Base
{
    public override void Foo()
    {
        base.Foo();
    }
}

// 추상 메서드
// 추상클래스를 상속받으면 오류가 뜸 추상 메서드를 구현해야 오류가 안뜸 즉,
// 오버라이딩을 강제함 => 꼭 구현해야 함
abstract class AbstractBase
{
    public abstract void Foo();
}

class Derived2 : AbstractBase
{
    public override void Foo()
    {

    }
}

// 인터페이스는 여러개를 상속받을 수 있지만 추상클래스는 단 하나만 상속받을 수 있다.
// 추상클래스는 메서드 외 다양한 멤버를 받을 수 있지만
// 인터페이스는 오직 메서드만 가능

// 객체지향적으로 보면 인터페이스는 메시지를 정의
// 추상클래스는 역할을 정의

운동학

  • 전진운동학(FK; Forward Kinematics) : 큰 관절에 의해 작은 관절이 움직이는것

  • 역운동학(LK; Inverse Kinematics) : 작은 관절에 의해 큰 관절이 움직이는것

  • OnAnimatorIK() : IK가 적용될 때마다 호출

    	> SetIKPositionWeight() / SetIKPosition() / SetIKRotationWeight() / SetIKRotation()

확장 메서드

  • 확장 메서드(Extension Method)는 기존 타입에 메서드를 추가할 수 있게 한다.
  • 정적 메서드로 구현하며, 첫 번재 매개변수에 this 키워드와 함께 확장시킬 타입을 적는다.
  • 확장 메서드는 확장하는 타입의 private에 접근할 수 없다. 즉, 캡슐화의 원칙을 위배할 수 없다.
using UnityEngine;

// 메서드만들기
// 정적 클래스여야 함
public static class Extension
{
    public static void SetIKPositionAndWeight(this Animator animator, AvatarIKGoal goal, Vector3 goalPosition, float weight = 1f)
    {
        animator.SetIKPositionWeight(goal, weight);
        animator.SetIKPosition(goal, goalPosition);
    }

    public static void SetIKRotationAndWeight(this Animator animator, AvatarIKGoal goal, Quaternion goalQuaternion, float weight = 1f)
    {
        animator.SetIKRotationWeight(goal, weight);
        animator.SetIKRotation(goal, goalQuaternion);
    }
}

위 처럼 작성하고

    // 애니메이터의 IK 갱신
    private void OnAnimatorIK(int layerIndex) 
    {
        GunPivot.position = _animator.GetIKHintPosition(AvatarIKHint.RightElbow);

        //// 왼손
        //_animator.SetIKPositionWeight(AvatarIKGoal.LeftHand, 1f);
        //_animator.SetIKPosition(AvatarIKGoal.LeftHand, LeftHandMount.position);
        //_animator.SetIKPositionWeight(AvatarIKGoal.RightHand, 1f);
        //_animator.SetIKPosition(AvatarIKGoal.RightHand, RightHandMount.position);

        // 위의 코드를 줄이기 위해 확장함수를 사용함 스크립드 Uitle의 Extension을 참조
        _animator.SetIKPositionAndWeight(AvatarIKGoal.LeftHand, LeftHandMount.position);
        _animator.SetIKPositionAndWeight(AvatarIKGoal.RightHand, RightHandMount.position);



        //// 오른손
        //_animator.SetIKRotationWeight(AvatarIKGoal.LeftHand, 1f);
        //_animator.SetIKRotation(AvatarIKGoal.LeftHand, LeftHandMount.rotation);
        //_animator.SetIKRotationWeight(AvatarIKGoal.RightHand, 1f);
        //_animator.SetIKRotation(AvatarIKGoal.RightHand, RightHandMount.rotation);

        // 위의 코드를 줄이기 위해 확장함수를 사용함 스크립드 Uitle의 Extension을 참조
        _animator.SetIKRotationAndWeight(AvatarIKGoal.LeftHand, LeftHandMount.rotation);
        _animator.SetIKRotationAndWeight(AvatarIKGoal.RightHand, RightHandMount.rotation);

    }

이것처럼 쓸 수 있다.

profile
해보자요

0개의 댓글