[UniRx] Update() 타이밍의 이벤트를FixedUpdate() 타이밍으로 변환

9280 단어 UniRxUnity

Update 및 FixedUpdate


UnityUpdateFixedUpdate는 다음과 같이 구분해서 사용해야 한다.
  • Input의 입력 이벤트는 Update()내에서만 올바르게 획득할 수 있습니다
  • RigidBody 에 대한 작업이 FixedUpdate() 내에 수행되지 않으면 잘못된 작업
  • 따라서 입력 이벤트 기반 작업RigidBody을 수행하려면 처리 시간을 Update()에서 FixedUpdate()로 이동해야 합니다.
    이번에는 유닉스로 이런 처리를 써 보았다.

    Update에서 FixedUpdate로 타이밍만 변환


    '점프 버튼을 눌렀습니다' 를 입력하는 시기가 매우 중요합니다. 메시지의 값 자체가 가치가 없으면 조작원이 사용할 수 있습니다.

    BatchFrame 운영자

    BatchFrame는'On Next 메시지를 버퍼에 저장해 지정된 Unity의 이벤트와 정시에 출력'하는 사업자를 말한다.
    열네릭스와 BatchFrame형을 사용했을 때의 행동이 다르기 때문에 이번에 Unit형을 사용하기로 결정했다.

    유닛

    public static IObservable<Unit> BatchFrame(this IObservable<Unit> source, int frameCount, FrameCountType frameCountType)
    
  • BatchFrame: 입력의 흐름으로
  • this IObservable<Unit> source: 프레임 수 지연.0을 지정하면 다음 이벤트 타이밍입니다.
  • int frameCount: Unity의 이벤트와 정시 동기화됩니다.
  • FrameCountType frameCountType 취형Unit은 간단한'사건을 전환할 시기'의 행위이다.
    JNERKS를 얻으려면 여러 입력의 이벤트를 버퍼링할 수 있지만 BatchFrame 형식의 버전에서는 버퍼 길이가 1에 고정되어 있습니다.

    실제 코드


    실제 사용Unit은 시간을 BatchFrame에서 Update 코드로 변환한다.
    using UniRx;
    using UniRx.Triggers;
    using UnityEngine;
    
    public class RigidBodyMover : MonoBehaviour
    {
        void Start()
        {
            var rigidBody = GetComponent<Rigidbody>();
    
            this.UpdateAsObservable()
                .Where(_ => Input.GetKeyDown(KeyCode.Space))
                .AsUnitObservable() // Unit型に変換
                .BatchFrame(0, FrameCountType.FixedUpdate) //入力メッセージを次のFixedUpdate時に出力する
                .Subscribe(_ =>
                {
                    rigidBody.AddForce(Vector3.up * 10, ForceMode.VelocityChange);
                });
        }
    }
    
    
    지정FixedUpdate을 통해 입력 이벤트를 다음BatchFrame(0, FrameCountType.FixedUpdate)으로 이동할 수 있습니다.

    Update에서 FixedUpdate에 설정된 값을 사용하는 경우

    FixedUpdate 등 최신 입력 값이 Input.GetAxis에서 사용되고 싶을 때FixedUpdate 조작원이 사용할 수 있습니다.

    WithLatestFrom 운영자


    WithLatestFrom는 한 흐름을 주축으로 하고 다른 흐름을 합성하는 최신 값의 조작원이다.
    public static IObservable<TResult> WithLatestFrom<TLeft, TRight, TResult>(this IObservable<TLeft> left, IObservable<TRight> right, Func<TLeft, TRight, TResult> selector)
    
  • WithLatestFrom: 주축이 되는 흐름.이 흐름의 입력이 정해진 시간에 출력됩니다.
  • this IObservable<TLeft> left: 성대류.이 흐름의 최신 값은 주 축 메시지와 합성됩니다.
  • IObservable<TRight> right: 입력값을 처리하고 최종 결과로 변환하는 함수입니다.
  • 실제 코드


    실제 사용Func<TLeft, TRight, TResult> selectorWithLatestFrom에서 입력한 값을 꺼낸 코드입니다.
    using UniRx;
    using UniRx.Triggers;
    using UnityEngine;
    
    public class RigidBodyMover2 : MonoBehaviour
    {
        void Start()
        {
            var rigidBody = GetComponent<Rigidbody>();
    
            //入力ストリーム
            var inputStream = this.UpdateAsObservable()
                .Select(_ => new Vector3(Input.GetAxis("Horizontal"), 0, Input.GetAxis("Vertical")));
    
            //FixedUpdateを主軸にし、そこにinputStreamを合成する
            this.FixedUpdateAsObservable()
                .WithLatestFrom(inputStream, (_, input) => input)
                .Subscribe(input =>
                {
                    rigidBody.AddForce(input, ForceMode.Acceleration);
                });
        }
    }
    
    

    총결산


    UniRx에는 여러 가지 조작원이 있는데, 조합하면 의외로 무엇이든 할 수 있다.
    기회가 된다면 조작원들을 모두 소개하고 싶습니다.

    좋은 웹페이지 즐겨찾기