Unity에서 Vue.js풍의 재활성화 시스템을 만들어 보세요.

14992 단어 cecilILVue.jsUnity

입문


안녕하세요. QualiArts Advent Calendar 2019, 14일째 보도입니다.
최근에는 유니티의 개발로 그동안 인터넷 안내 데스크를 운영해왔기 때문에 본 기사는 Vue입니다.Unity에서 js의 하이라이트 기능인 재활성화 시스템에 대한 이야기를 쓰겠습니다.
※ 일본어는 현지인이 아니므로 문서를 읽을 가능성이 있으니 양해해 주십시오

Vue.js 리셋 시스템


Vue.js를 모르는 사람에게 간단한 예를 제시하다.자세한 내용은 Vue.js 공식
var app = new Vue({
  el: '#app',

  data: {
    familyName: "佐藤",
    givenName: "太郎"
  },

  computed: {
    fullName() {
      console.log('[実行されたよ]');
      return this.familyName + this.givenName;
    }
  }
});

console.log(app.fullName);
// [実行されたよ]
// 佐藤太郎

app.familyName = '鈴木';
console.log(app.fullName);
// [実行されたよ]
// 鈴木太郎

console.log(app.fullName);
// 鈴木太郎
진입data의 모든 것은 재활성화 속성이고, 진입computed의 모든 것은 계산 속성입니다.
속성 재활성화는 활성 데이터의 소스이며 값 업데이트를 모니터링합니다.
계산 속성: 기본적으로 호출하지 않으면 실행되지 않으며, 종속적인 재활성화 속성이 변하지 않으면 다시 실행되지 않습니다
뒷면이 자동으로 지연 처리와 캐시를 하기 때문에 사용자는 직관적인 코드를 쓸 수 있고 낭비된 재실행도 자동으로 관리할 수 있어 좋은 기능

셀 속성 주위


C#언어에는 이러한 기능을 대충 재현하는 속성이 있습니다.
public class App
{
    public string familyName = "佐藤";
    public string givenName = "太郎";

    string _fullName;
    public string FullName
    {
        get
        {
            var value = familyName + givenName;
            if (value != _fullName)
            {
                _fullName = value;
            }
            return _fullName;
        }
    }
}
엄격하게 함께하는 것은 아니지만 familyName + givenName의 재집행은 불가피하다.예:familyNamegivenName의 업데이트 로고를 추가하여 각각의 업데이트 검사를 처리하면 가능하지만 코드의 양은 약 2배 정도 됩니다.

기타 방법

  • 상술한 비교 캐시 처리를 방법화하고 코드 간소화

  • INotifyPropertyChanged 속성 업데이트 이벤트 발화를 통해 검출

  • UniRx의 ReactiveProperty 등록 정보 Observable화 및 구독 업데이트
  • 욕망


    여러 가지 방법이 있겠지만 드문 기회라서 Vue.js에 가까운 형식으로 재현할 수 있는 계기가 될 것 같습니다.예를 들면↓의 느낌.
    public class App
    {
        public string familyName = "佐藤";
        public string givenName = "太郎";
    
        public string FullName => familyName + giveName;
    }
    

    IL 수정과의 만남


    각종 조사를 진행하던 중 INotifyPropertyChanged인터페이스 설치 자동화 도서관Fody/PropertyChanged을 발견했다.Fody 자체는 Mono.cecil 패키지로 구성 요소의 IL을 수정할 수 있습니다.
    이걸로 하면 되잖아, issues를 찾아봤는데 유니티가 대응하지 않는 것 같아.
    응, 조금만 더 구글에서 github 안을 검색하면 유니티에 대응하는 도서관ByronMayne/Weaver이 나온다.유니티의 번역을 잘 해서 연결고리로 실행하기 때문에 이걸 채택하기로 했어요.

    원형을 만들어 보다


    IL을 구현하기 전에 참조Vue.js 다시 활성화 구현는 C#에 대한 기본 클래스를 생성합니다.

    두루뭉술한 원리

  • Watcher(A군)가 있습니다.
  • 이 A군이 있는 Watcher(B군)에 따라 B군의 값을 얻는다.
  • 이때 B군이 의존하는 다른 Watcher(C군)가 있으면 A군도 C군에게 의존하는 관계를 갖게 된다.
  • 더 이상 의존하지 않을 때까지 귀착적으로 계속한다.
  • 우리는 이 원리에 따라 원형 를 만들었다.

    IL을 통한 단순화 코드 수정


    이후 우리는 [Reactive][Computed] 두 가지 속성을 준비했습니다. 속성을 추가하면 IL에 Watcher 실례의 생성 처리와 Getter/Setter의 처리 의뢰를 자동으로 삽입합니다.
    public class App
    {
        [Reactive]
        public string FamilyName { get; set; } = "佐藤";
    
        [Reactive]
        public string GivenName { get; set; } = "太郎";
    
        [Computed]
        public string FullName => FamilyName + GivenName;
    }
    
    ↑ 코드는 IL 삽입 후 ↓ 방식으로 전개
    public class App
    {
        Wacther<string> _familyName;
        public string FamilyName
        {
            get
            {
                if (_familyName == null) 
                {
                    _familyName = new Watcher<string>();
                }
                return _familyName.Get();
            }
            set
            {
                if (_familyName == null) 
                {
                    _familyName = new Watcher<string>();
                }
                _familyName.Set();
            }
        }
    
        Wacther<string> _givenName;
        public string GivenName
        {
            get
            {
                if (_givenName == null) 
                {
                    _givenName = new Watcher<string>();
                }
                return _givenName.Get();
            }
            set
            {
                if (_givenName == null) 
                {
                    _givenName = new Watcher<string>();
                }
                _givenName.Set();
            }
        }
    
        Wacther<string> _fullName;
        public string FullName
        {
            get
            {
                if (_fullName == null) 
                {
                    _fullName = new Watcher<string>(() => 
                    {
                        return FamilyName.Get() + GivenName.Get();
                    });
                }
                return _fullName.Get();
            }
        }
    }
    
    이렇게 움직일 수 있는 최소한의 원형은 완성되었지만, 실용화되기 전에 개선과 추가 기능이 필요하다.필수 기능 예:
    · 다음 Tick에서 Setter 알림을 요약합니다(중복 방지, 순환 참조 탐지).
    · Watcher에 ID를 추가하여 ID 순서대로 실행할 것을 알립니다(실행 순서 확인).

    끝날 때


    View에 바인딩된 기능이 없기 때문에 실제로는 전혀 사용할 수 없는 원형이지만 Unity에서도 Vue입니다.제 생각에는 이미 js 스타일의 작법이 가능하다는 것을 증명한 것 같습니다.
    C#초보자이기 때문에 IL 주위의 시행착오를 통해 C#의 뒷면이 이런 느낌인지 컴파일러가 얼마나 편리한지 알게 되어 개인적으로 재미있었습니다.
    상술한 원형은github에 설치되어 공개됩니다. 관심 있으신 분들은 꼭 여기를 보세요.
    https://github.com/thammin/kaki-watcher
    지금까지 14일째 보도였습니다.앞으로의 달력을 계속 투고해 주십시오.

    좋은 웹페이지 즐겨찾기