https://docs.microsoft.com/ko-kr/dotnet/csharp/iterators
// <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
반복자 메서드를 사용해 일정 루틴을 만들어 주는 것
어떠한 행동에 대해 조금씩 업데이트를 해 주어야 할 때 사용하면 좋다.
Start() 에서 코루틴을 등록 해 주면 => StartCoroutine(Shot()); 를 넣어주면 저 반복자 메서드를 불러와서 실행된다.
코루틴 등록을 해 줄 때 Start()에 넣어줄지 Updata()에 넣어줄지 상황에 따라 다르다.
Updata() 와 LateUpdata() 사이에 이루어진다
https://docs.unity3d.com/kr/2021.3/ScriptReference/Physics.Raycast.html
// 가상 메서드
// 오버라이딩을 강제하지 않음 => 구현 해도되고 안해도 되고
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()
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);
}
이것처럼 쓸 수 있다.