123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079 |
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using JetBrains.Annotations;
- using UnityEngine;
- using VRC.Udon.Common;
- using VRC.Udon.Common.Interfaces;
- using VRC.Udon.Serialization.OdinSerializer;
- using VRC.Udon.VM;
- #if VRC_CLIENT
- using VRC.Udon.Security;
- #endif
- #if UNITY_EDITOR && !VRC_CLIENT
- using UnityEditor.SceneManagement;
-
- #endif
-
- namespace VRC.Udon
- {
- public class UdonBehaviour : VRC.SDKBase.VRC_Interactable, ISerializationCallbackReceiver, IUdonEventReceiver, IUdonSyncTarget, VRC.SDKBase.INetworkID
- {
- #region Odin Serialized Fields
-
- public IUdonVariableTable publicVariables = new UdonVariableTable();
-
- #endregion
-
- #region Serialized Public Fields
-
- public bool SynchronizePosition = false;
- public readonly bool SynchronizeAnimation = false; //We don't support animation sync yet, coming soon.
- public bool AllowCollisionOwnershipTransfer = true;
-
- #endregion
-
- #region Serialized Private Fields
-
- [SerializeField]
- private AbstractSerializedUdonProgramAsset serializedProgramAsset;
-
- #if UNITY_EDITOR && !VRC_CLIENT
- [SerializeField]
- public AbstractUdonProgramSource programSource;
-
- #endif
-
- #endregion
-
- #region Public Fields and Properties
-
- [PublicAPI]
- public static System.Action<UdonBehaviour, IUdonProgram> OnInit = null;
-
- [PublicAPI]
- public bool HasInteractiveEvents { get; private set; } = false;
-
- public override bool IsInteractive => HasInteractiveEvents;
-
- [HideInInspector]
- public int NetworkID { get; set; }
-
- #endregion
-
- #region Private Fields
-
- private IUdonProgram program;
- private IUdonVM _udonVM;
- private bool _isNetworkReady;
- private int _debugLevel;
- private bool _hasError;
-
- #endregion
-
- #region Editor Only
-
- #if UNITY_EDITOR && !VRC_CLIENT
-
- public void RunEditorUpdate(ref bool dirty)
- {
- if(programSource == null)
- {
- return;
- }
-
- programSource.RunEditorUpdate(this, ref dirty);
-
- if(!dirty)
- {
- return;
- }
-
- EditorSceneManager.MarkSceneDirty(gameObject.scene);
- }
-
- #endif
-
- #endregion
-
- #region Private Methods
-
- private bool LoadProgram()
- {
- if(serializedProgramAsset == null)
- {
- return false;
- }
-
- program = serializedProgramAsset.RetrieveProgram();
-
- IUdonSymbolTable symbolTable = program?.SymbolTable;
- IUdonHeap heap = program?.Heap;
- if(symbolTable == null || heap == null)
- {
- return false;
- }
-
- foreach(string variableSymbol in publicVariables.VariableSymbols)
- {
- if(!symbolTable.HasAddressForSymbol(variableSymbol))
- {
- continue;
- }
-
- uint symbolAddress = symbolTable.GetAddressFromSymbol(variableSymbol);
-
- if(!publicVariables.TryGetVariableType(variableSymbol, out Type declaredType))
- {
- continue;
- }
-
- publicVariables.TryGetVariableValue(variableSymbol, out object value);
- if(declaredType == typeof(GameObject) || declaredType == typeof(UdonBehaviour) ||
- declaredType == typeof(Transform))
- {
- if(value == null)
- {
- value = new UdonGameObjectComponentHeapReference(declaredType);
- declaredType = typeof(UdonGameObjectComponentHeapReference);
- }
- }
-
- heap.SetHeapVariable(symbolAddress, value, declaredType);
- }
-
- return true;
- }
-
- #endregion
-
- #region Unity Events
-
- private readonly List<uint> _startPoints = new List<uint>();
-
- public override void Start()
- {
- InitializeUdonContent();
- }
-
- [PublicAPI]
- public void InitializeUdonContent()
- {
- SetupLogging();
-
- UdonManager udonManager = UdonManager.Instance;
- if(udonManager == null)
- {
- enabled = false;
- VRC.Core.Logger.LogError($"Could not find the UdonManager; the UdonBehaviour on '{gameObject.name}' will not run.", _debugLevel, this);
- return;
- }
-
- if(!LoadProgram())
- {
- enabled = false;
- VRC.Core.Logger.Log($"Could not load the program; the UdonBehaviour on '{gameObject.name}' will not run.", _debugLevel, this);
-
- if(OnInit != null)
- {
- try
- {
- OnInit(this, null);
- }
- catch(Exception exception)
- {
- VRC.Core.Logger.LogError(
- $"An exception '{exception.Message}' occurred during initialization; the UdonBehaviour on '{gameObject.name}' will not run. Exception:\n{exception}",
- _debugLevel,
- this
- );
- }
- }
-
- return;
- }
-
- IUdonSymbolTable symbolTable = program?.SymbolTable;
- IUdonHeap heap = program?.Heap;
- if(symbolTable == null || heap == null)
- {
- enabled = false;
- VRC.Core.Logger.Log($"Invalid program; the UdonBehaviour on '{gameObject.name}' will not run.", _debugLevel, this);
- return;
- }
-
- if(!ResolveUdonHeapReferences(symbolTable, heap))
- {
- enabled = false;
- VRC.Core.Logger.Log($"Failed to resolve a GameObject/Component Reference; the UdonBehaviour on '{gameObject.name}' will not run.", _debugLevel, this);
- return;
- }
-
- _udonVM = udonManager.ConstructUdonVM();
-
- if(_udonVM == null)
- {
- enabled = false;
- VRC.Core.Logger.LogError($"No UdonVM; the UdonBehaviour on '{gameObject.name}' will not run.", _debugLevel, this);
- return;
- }
-
- #if VRC_CLIENT
- program = new UdonProgram(
- program.InstructionSetIdentifier,
- program.InstructionSetVersion,
- program.ByteCode,
- new UdonSecureHeap(program.Heap, udonManager),
- program.EntryPoints,
- program.SymbolTable,
- program.SyncMetadataTable
- );
- #endif
-
- _udonVM.LoadProgram(program);
-
- ProcessEntryPoints();
-
- #if !VRC_CLIENT
- _isNetworkReady = true;
- #endif
-
- if(OnInit != null)
- {
- try
- {
- OnInit(this, program);
- }
- catch(Exception exception)
- {
- enabled = false;
- VRC.Core.Logger.LogError(
- $"An exception '{exception.Message}' occurred during initialization; the UdonBehaviour on '{gameObject.name}' will not run. Exception:\n{exception}",
- _debugLevel,
- this
- );
- }
- }
- }
-
- private void ProcessEntryPoints()
- {
- foreach(string entryPoint in program.EntryPoints.GetExportedSymbols())
- {
- uint address = program.EntryPoints.GetAddressFromSymbol(entryPoint);
- switch(entryPoint)
- {
- case "_start":
- {
- _startPoints.Add(address);
- break;
- }
-
- case "_update":
- {
- _updatePoints.Add(address);
- break;
- }
-
- case "_lateUpdate":
- {
- _lateUpdatePoints.Add(address);
- break;
- }
-
- case "_interact":
- {
- HasInteractiveEvents = true;
- _interactPoints.Add(address);
- break;
- }
-
- case "_fixedUpdate":
- {
- _fixedUpdatePoints.Add(address);
- break;
- }
-
- case "_onAnimatorIk":
- {
- _onAnimatorIkPoints.Add(address);
- break;
- }
-
- case "_onAnimatorMove":
- {
- _onAnimatorMovePoints.Add(address);
- break;
- }
-
- case "_onAudioFilterRead":
- {
- _onAudioFilterReadPoints.Add(address);
- break;
- }
-
- case "_onBecameInvisible":
- {
- _onBecameInvisiblePoints.Add(address);
- break;
- }
-
- case "_onBecameVisible":
- {
- _onBecameVisiblePoints.Add(address);
- break;
- }
-
- case "_onCollisionEnter":
- {
- _onCollisionEnterPoints.Add(address);
- break;
- }
-
- case "_onCollisionEnter2D":
- {
- _onCollisionEnter2DPoints.Add(address);
- break;
- }
-
- case "_onCollisionExit":
- {
- _onCollisionExitPoints.Add(address);
- break;
- }
-
- case "_onCollisionExit2D":
- {
- _onCollisionExit2DPoints.Add(address);
- break;
- }
-
- case "_onCollisionStay":
- {
- _onCollisionStayPoints.Add(address);
- break;
- }
-
- case "_onCollisionStay2D":
- {
- _onCollisionStay2DPoints.Add(address);
- break;
- }
-
- case "_onControllerColliderHit":
- {
- _onControllerColliderHitPoints.Add(address);
- break;
- }
-
- case "_onDestroy":
- {
- _onDestroyPoints.Add(address);
- break;
- }
-
- case "_onDisable":
- {
- _onDisablePoints.Add(address);
- break;
- }
-
- case "_onDrawGizmos":
- {
- _onDrawGizmosPoints.Add(address);
- break;
- }
-
- case "_onDrawGizmosSelected":
- {
- _onDrawGizmosSelectedPoints.Add(address);
- break;
- }
-
- case "_onEnable":
- {
- _onEnablePoints.Add(address);
- break;
- }
-
- case "_onGUI":
- {
- _onGUIPoints.Add(address);
- break;
- }
-
- case "_onJointBreak":
- {
- _onJointBreakPoints.Add(address);
- break;
- }
-
- case "_onJointBreak2D":
- {
- _onJointBreak2DPoints.Add(address);
- break;
- }
-
- case "_onMouseDown":
- {
- _onMouseDownPoints.Add(address);
- break;
- }
-
- case "_onMouseDrag":
- {
- _onMouseDragPoints.Add(address);
- break;
- }
-
- case "_onMouseEnter":
- {
- _onMouseEnterPoints.Add(address);
- break;
- }
-
- case "_onMouseExit":
- {
- _onMouseExitPoints.Add(address);
- break;
- }
-
- case "_onMouseOver":
- {
- _onMouseOverPoints.Add(address);
- break;
- }
-
- case "_onMouseUp":
- {
- _onMouseUpPoints.Add(address);
- break;
- }
-
- case "_onMouseUpAsButton":
- {
- _onMouseUpAsButtonPoints.Add(address);
- break;
- }
-
- case "_onParticleCollision":
- {
- _onParticleCollisionPoints.Add(address);
- break;
- }
-
- case "_onParticleTrigger":
- {
- _onParticleTriggerPoints.Add(address);
- break;
- }
-
- case "_onPostRender":
- {
- _onPostRenderPoints.Add(address);
- break;
- }
-
- case "_onPreCull":
- {
- _onPreCullPoints.Add(address);
- break;
- }
-
- case "_onPreRender":
- {
- _onPreRenderPoints.Add(address);
- break;
- }
-
- case "_onRenderImage":
- {
- _onRenderImagePoints.Add(address);
- break;
- }
-
- case "_onRenderObject":
- {
- _onRenderObjectPoints.Add(address);
- break;
- }
-
- case "_onTransformChildrenChanged":
- {
- _onTransformChildrenChangedPoints.Add(address);
- break;
- }
-
- case "_onTransformParentChanged":
- {
- _onTransformParentChangedPoints.Add(address);
- break;
- }
-
- case "_onTriggerEnter":
- {
- _onTriggerEnterPoints.Add(address);
- break;
- }
-
- case "_onTriggerEnter2D":
- {
- _onTriggerEnter2DPoints.Add(address);
- break;
- }
-
- case "_onTriggerExit":
- {
- _onTriggerExitPoints.Add(address);
- break;
- }
-
- case "_onTriggerExit2D":
- {
- _onTriggerExit2DPoints.Add(address);
- break;
- }
-
- case "_onTriggerStay":
- {
- _onTriggerStayPoints.Add(address);
- break;
- }
-
- case "_onTriggerStay2D":
- {
- _onTriggerStay2DPoints.Add(address);
- break;
- }
-
- case "_onValidate":
- {
- _onValidatePoints.Add(address);
- break;
- }
-
- case "_onWillRenderObject":
- {
- _onWillRenderObjectPoints.Add(address);
- break;
- }
-
- //case "_onDataStorageAdded":
- //{
- // _onDataStorageAddedPoints.Add(address);
- // break;
- //}
-
- //case "_onDataStorageChanged":
- //{
- // _onDataStorageChangedPoints.Add(address);
- // break;
- //}
-
- //case "_onDataStorageRemoved":
- //{
- // _onDataStorageRemovedPoints.Add(address);
- // break;
- //}
-
- case "_onDrop":
- {
- _onDropPoints.Add(address);
- break;
- }
-
- case "_onOwnershipTransferred":
- {
- _onOwnershipTransferredPoints.Add(address);
- break;
- }
-
- case "_onPickup":
- {
- _onPickupPoints.Add(address);
- break;
- }
-
- case "_onPickupUseDown":
- {
- _onPickupUseDownPoints.Add(address);
- break;
- }
-
- case "_onPickupUseUp":
- {
- _onPickupUseUpPoints.Add(address);
- break;
- }
-
- case "_onPlayerJoined":
- {
- _onPlayerJoinedPoints.Add(address);
- break;
- }
-
- case "_onPlayerLeft":
- {
- _onPlayerLeftPoints.Add(address);
- break;
- }
-
- case "_onSpawn":
- {
- _onSpawnPoints.Add(address);
- break;
- }
-
- case "_onStationEntered":
- {
- _onStationEnteredPoints.Add(address);
- break;
- }
-
- case "_onStationExited":
- {
- _onStationExitedPoints.Add(address);
- break;
- }
-
- case "_onVideoEnd":
- {
- _onVideoEndPoints.Add(address);
- break;
- }
-
- case "_onVideoPause":
- {
- _onVideoPausePoints.Add(address);
- break;
- }
-
- case "_onVideoPlay":
- {
- _onVideoPlayPoints.Add(address);
- break;
- }
-
- case "_onVideoStart":
- {
- _onVideoStartPoints.Add(address);
- break;
- }
- case "_onPreSerialization":
- {
- _onPreSerializationStartPoints.Add(address);
- break;
- }
- case "_onDeserialization":
- {
- _onDeserializationStartPoints.Add(address);
- break;
- }
- }
- }
- }
-
- private bool ResolveUdonHeapReferences(IUdonSymbolTable symbolTable, IUdonHeap heap)
- {
- bool success = true;
- foreach(string symbolName in symbolTable.GetSymbols())
- {
- uint symbolAddress = symbolTable.GetAddressFromSymbol(symbolName);
- object heapValue = heap.GetHeapVariable(symbolAddress);
- if(!(heapValue is UdonBaseHeapReference udonBaseHeapReference))
- {
- continue;
- }
-
- if(!ResolveUdonHeapReference(heap, symbolAddress, udonBaseHeapReference))
- {
- success = false;
- }
- }
-
- return success;
- }
-
- private bool ResolveUdonHeapReference(IUdonHeap heap, uint symbolAddress, UdonBaseHeapReference udonBaseHeapReference)
- {
- switch(udonBaseHeapReference)
- {
- case UdonGameObjectComponentHeapReference udonGameObjectComponentHeapReference:
- {
- Type referenceType = udonGameObjectComponentHeapReference.type;
- if(referenceType == typeof(GameObject))
- {
- heap.SetHeapVariable(symbolAddress, gameObject);
- return true;
- }
- else if(referenceType == typeof(Transform))
- {
- heap.SetHeapVariable(symbolAddress, gameObject.transform);
- return true;
- }
- else if(referenceType == typeof(UdonBehaviour))
- {
- heap.SetHeapVariable(symbolAddress, this);
- return true;
- }
- else if(referenceType == typeof(UnityEngine.Object))
- {
- heap.SetHeapVariable(symbolAddress, this);
- return true;
- }
- else
- {
- VRC.Core.Logger.Log(
- $"Unsupported GameObject/Component reference type: {udonBaseHeapReference.GetType().Name}. Only GameObject, Transform, and UdonBehaviour are supported.",
- _debugLevel,
- this);
-
- return false;
- }
- }
- default:
- {
- VRC.Core.Logger.Log($"Unknown heap reference type: {udonBaseHeapReference.GetType().Name}", _debugLevel, this);
- return false;
- }
- }
- }
-
- private readonly List<uint> _updatePoints = new List<uint>();
- private bool _hasDoneStart;
-
- private void Update()
- {
- if(!_isNetworkReady)
- {
- return;
- }
-
- if(!_hasDoneStart)
- {
- foreach(uint startPoint in _startPoints)
- {
- RunProgram(startPoint);
- }
-
- _hasDoneStart = true;
- }
-
- foreach(uint updatePoint in _updatePoints)
- {
- RunProgram(updatePoint);
- }
- }
-
- private readonly List<uint> _lateUpdatePoints = new List<uint>();
-
- private void LateUpdate()
- {
- if(!_hasDoneStart)
- {
- return;
- }
-
- foreach(uint lateUpdatePoint in _lateUpdatePoints)
- {
- RunProgram(lateUpdatePoint);
- }
- }
-
- private readonly List<uint> _fixedUpdatePoints = new List<uint>();
-
- public void FixedUpdate()
- {
- if(!_hasDoneStart)
- {
- return;
- }
-
- foreach(uint fixedUpdatePoint in _fixedUpdatePoints)
- {
- RunProgram(fixedUpdatePoint);
- }
- }
-
- private readonly List<uint> _onAnimatorIkPoints = new List<uint>();
-
- public void OnAnimatorIK(int layerIndex)
- {
- if(!_hasDoneStart)
- {
- return;
- }
-
- SetProgramVariable("onAnimatorIkLayerIndex", layerIndex);
- foreach(uint onAnimatorIkPoint in _onAnimatorIkPoints)
- {
- RunProgram(onAnimatorIkPoint);
- }
- }
-
- private readonly List<uint> _onAnimatorMovePoints = new List<uint>();
-
- public void OnAnimatorMove()
- {
- if(!_hasDoneStart)
- {
- return;
- }
-
- foreach(uint onAnimatorMovePoint in _onAnimatorMovePoints)
- {
- RunProgram(onAnimatorMovePoint);
- }
- }
-
- private readonly List<uint> _onAudioFilterReadPoints = new List<uint>();
-
- public void OnAudioFilterRead(float[] data, int channels)
- {
- if(!_hasDoneStart)
- {
- return;
- }
-
- SetProgramVariable("onAudioFilterReadData", data);
- SetProgramVariable("onAudioFilterReadChannels", channels);
- foreach(uint onAudioFilterReadPoint in _onAudioFilterReadPoints)
- {
- RunProgram(onAudioFilterReadPoint);
- }
- }
-
- private readonly List<uint> _onBecameInvisiblePoints = new List<uint>();
-
- public void OnBecameInvisible()
- {
- if(!_hasDoneStart)
- {
- return;
- }
-
- foreach(uint onBecameInvisiblePoint in _onBecameInvisiblePoints)
- {
- RunProgram(onBecameInvisiblePoint);
- }
- }
-
- private readonly List<uint> _onBecameVisiblePoints = new List<uint>();
-
- public void OnBecameVisible()
- {
- if(!_hasDoneStart)
- {
- return;
- }
-
- foreach(uint onBecameVisiblePoint in _onBecameVisiblePoints)
- {
- RunProgram(onBecameVisiblePoint);
- }
- }
-
- private readonly List<uint> _onCollisionEnterPoints = new List<uint>();
-
- public void OnCollisionEnter(Collision other)
- {
- if(!_hasDoneStart)
- {
- return;
- }
-
- SetProgramVariable("onCollisionEnterOther", other);
- foreach(uint onCollisionEnterPoint in _onCollisionEnterPoints)
- {
- RunProgram(onCollisionEnterPoint);
- }
-
- SetProgramVariable("onCollisionEnterOther", null);
- }
-
- private readonly List<uint> _onCollisionEnter2DPoints = new List<uint>();
-
- public void OnCollisionEnter2D(Collision2D other)
- {
- if(!_hasDoneStart)
- {
- return;
- }
-
- SetProgramVariable("onCollisionEnter2DOther", other);
- foreach(uint onCollisionEnter2DPoint in _onCollisionEnter2DPoints)
- {
- RunProgram(onCollisionEnter2DPoint);
- }
-
- SetProgramVariable("onCollisionEnter2DOther", null);
- }
-
- private readonly List<uint> _onCollisionExitPoints = new List<uint>();
-
- public void OnCollisionExit(Collision other)
- {
- if(!_hasDoneStart)
- {
- return;
- }
-
- SetProgramVariable("onCollisionExitOther", other);
- foreach(uint onCollisionExitPoint in _onCollisionExitPoints)
- {
- RunProgram(onCollisionExitPoint);
- }
-
- SetProgramVariable("onCollisionExitOther", null);
- }
-
- private readonly List<uint> _onCollisionExit2DPoints = new List<uint>();
-
- public void OnCollisionExit2D(Collision2D other)
- {
- if(!_hasDoneStart)
- {
- return;
- }
-
- SetProgramVariable("onCollisionExit2DOther", other);
- foreach(uint onCollisionExit2DPoint in _onCollisionExit2DPoints)
- {
- RunProgram(onCollisionExit2DPoint);
- }
-
- SetProgramVariable("onCollisionExit2DOther", null);
- }
-
- private readonly List<uint> _onCollisionStayPoints = new List<uint>();
-
- public void OnCollisionStay(Collision other)
- {
- if(!_hasDoneStart)
- {
- return;
- }
-
- SetProgramVariable("onCollisionStayOther", other);
- foreach(uint onCollisionStayPoint in _onCollisionStayPoints)
- {
- RunProgram(onCollisionStayPoint);
- }
-
- SetProgramVariable("onCollisionStayOther", null);
- }
-
- private readonly List<uint> _onCollisionStay2DPoints = new List<uint>();
-
- public void OnCollisionStay2D(Collision2D other)
- {
- if(!_hasDoneStart)
- {
- return;
- }
-
- SetProgramVariable("onCollisionStay2DOther", other);
- foreach(uint onCollisionStay2DPoint in _onCollisionStay2DPoints)
- {
- RunProgram(onCollisionStay2DPoint);
- }
-
- SetProgramVariable("onCollisionStay2DOther", null);
- }
-
- private readonly List<uint> _onControllerColliderHitPoints = new List<uint>();
-
- public void OnControllerColliderHit(ControllerColliderHit hit)
- {
- if(!_hasDoneStart)
- {
- return;
- }
-
- SetProgramVariable("onControllerColliderHitHit", hit);
- foreach(uint onControllerColliderHitPoint in _onControllerColliderHitPoints)
- {
- RunProgram(onControllerColliderHitPoint);
- }
-
- SetProgramVariable("onControllerColliderHitHit", null);
- }
-
- private readonly List<uint> _onDestroyPoints = new List<uint>();
-
- public void OnDestroy()
- {
- if(!_hasDoneStart)
- {
- return;
- }
-
- foreach(uint onDestroyPoint in _onDestroyPoints)
- {
- RunProgram(onDestroyPoint);
- }
- }
-
- private readonly List<uint> _onDisablePoints = new List<uint>();
-
- public void OnDisable()
- {
- if(!_hasDoneStart)
- {
- return;
- }
-
- foreach(uint onDisablePoint in _onDisablePoints)
- {
- RunProgram(onDisablePoint);
- }
- }
-
- private readonly List<uint> _onDrawGizmosPoints = new List<uint>();
-
- public void OnDrawGizmos()
- {
- if(!_hasDoneStart)
- {
- return;
- }
-
- foreach(uint onDrawGizmosPoint in _onDrawGizmosPoints)
- {
- RunProgram(onDrawGizmosPoint);
- }
- }
-
- private readonly List<uint> _onDrawGizmosSelectedPoints = new List<uint>();
-
- public void OnDrawGizmosSelected()
- {
- if(!_hasDoneStart)
- {
- return;
- }
-
- foreach(uint onDrawGizmosSelectedPoint in _onDrawGizmosSelectedPoints)
- {
- RunProgram(onDrawGizmosSelectedPoint);
- }
- }
-
- private readonly List<uint> _onEnablePoints = new List<uint>();
-
- public void OnEnable()
- {
- if(!_hasDoneStart)
- {
- return;
- }
-
- foreach(uint onEnablePoint in _onEnablePoints)
- {
- RunProgram(onEnablePoint);
- }
- }
-
- private readonly List<uint> _onGUIPoints = new List<uint>();
-
- public void OnGUI()
- {
- if(!_hasDoneStart)
- {
- return;
- }
-
- foreach(uint onGUIPoint in _onGUIPoints)
- {
- RunProgram(onGUIPoint);
- }
- }
-
- private readonly List<uint> _onJointBreakPoints = new List<uint>();
-
- public void OnJointBreak(float breakForce)
- {
- if(!_hasDoneStart)
- {
- return;
- }
-
- SetProgramVariable("onJointBreakBreakForce", breakForce);
- foreach(uint onJointBreakPoint in _onJointBreakPoints)
- {
- RunProgram(onJointBreakPoint);
- }
- }
-
- private readonly List<uint> _onJointBreak2DPoints = new List<uint>();
-
- public void OnJointBreak2D(Joint2D brokenJoint)
- {
- if(!_hasDoneStart)
- {
- return;
- }
-
- SetProgramVariable("onJointBreak2DBrokenJoint", brokenJoint);
- foreach(uint onJointBreak2DPoint in _onJointBreak2DPoints)
- {
- RunProgram(onJointBreak2DPoint);
- }
- }
-
- private readonly List<uint> _onMouseDownPoints = new List<uint>();
-
- public void OnMouseDown()
- {
- if(!_hasDoneStart)
- {
- return;
- }
-
- foreach(uint onMouseDownPoint in _onMouseDownPoints)
- {
- RunProgram(onMouseDownPoint);
- }
- }
-
- private readonly List<uint> _onMouseDragPoints = new List<uint>();
-
- public void OnMouseDrag()
- {
- if(!_hasDoneStart)
- {
- return;
- }
-
- foreach(uint onMouseDragPoint in _onMouseDragPoints)
- {
- RunProgram(onMouseDragPoint);
- }
- }
-
- private readonly List<uint> _onMouseEnterPoints = new List<uint>();
-
- public void OnMouseEnter()
- {
- if(!_hasDoneStart)
- {
- return;
- }
-
- foreach(uint onMouseEnterPoint in _onMouseEnterPoints)
- {
- RunProgram(onMouseEnterPoint);
- }
- }
-
- private readonly List<uint> _onMouseExitPoints = new List<uint>();
-
- public void OnMouseExit()
- {
- if(!_hasDoneStart)
- {
- return;
- }
-
- foreach(uint onMouseExitPoint in _onMouseExitPoints)
- {
- RunProgram(onMouseExitPoint);
- }
- }
-
- private readonly List<uint> _onMouseOverPoints = new List<uint>();
-
- public void OnMouseOver()
- {
- if(!_hasDoneStart)
- {
- return;
- }
-
- foreach(uint onMouseOverPoint in _onMouseOverPoints)
- {
- RunProgram(onMouseOverPoint);
- }
- }
-
- private readonly List<uint> _onMouseUpPoints = new List<uint>();
-
- public void OnMouseUp()
- {
- if(!_hasDoneStart)
- {
- return;
- }
-
- foreach(uint onMouseUpPoint in _onMouseUpPoints)
- {
- RunProgram(onMouseUpPoint);
- }
- }
-
- private readonly List<uint> _onMouseUpAsButtonPoints = new List<uint>();
-
- public void OnMouseUpAsButton()
- {
- if(!_hasDoneStart)
- {
- return;
- }
-
- foreach(uint onMouseUpAsButtonPoint in _onMouseUpAsButtonPoints)
- {
- RunProgram(onMouseUpAsButtonPoint);
- }
- }
-
- private readonly List<uint> _onParticleCollisionPoints = new List<uint>();
-
- public void OnParticleCollision(GameObject other)
- {
- if(!_hasDoneStart)
- {
- return;
- }
-
- SetProgramVariable("onParticleCollisionOther", other);
- foreach(uint onParticleCollisionPoint in _onParticleCollisionPoints)
- {
- RunProgram(onParticleCollisionPoint);
- }
- }
-
- private readonly List<uint> _onParticleTriggerPoints = new List<uint>();
-
- public void OnParticleTrigger()
- {
- if(!_hasDoneStart)
- {
- return;
- }
-
- foreach(uint onParticleTriggerPoint in _onParticleTriggerPoints)
- {
- RunProgram(onParticleTriggerPoint);
- }
- }
-
- private readonly List<uint> _onPostRenderPoints = new List<uint>();
-
- public void OnPostRender()
- {
- if(!_hasDoneStart)
- {
- return;
- }
-
- foreach(uint onPostRenderPoint in _onPostRenderPoints)
- {
- RunProgram(onPostRenderPoint);
- }
- }
-
- private readonly List<uint> _onPreCullPoints = new List<uint>();
-
- public void OnPreCull()
- {
- if(!_hasDoneStart)
- {
- return;
- }
-
- foreach(uint onPreCullPoint in _onPreCullPoints)
- {
- RunProgram(onPreCullPoint);
- }
- }
-
- private readonly List<uint> _onPreRenderPoints = new List<uint>();
-
- public void OnPreRender()
- {
- if(!_hasDoneStart)
- {
- return;
- }
-
- foreach(uint onPreRenderPoint in _onPreRenderPoints)
- {
- RunProgram(onPreRenderPoint);
- }
- }
-
- private readonly List<uint> _onRenderImagePoints = new List<uint>();
-
- public void OnRenderImage(RenderTexture src, RenderTexture dest)
- {
- if(!_hasDoneStart)
- {
- return;
- }
-
- if(_onRenderImagePoints.Count == 0)
- {
- Graphics.Blit(src, dest);
- return;
- }
-
- SetProgramVariable("onRenderImageSrc", src);
- SetProgramVariable("onRenderImageDest", dest);
- foreach(uint onRenderImagePoint in _onRenderImagePoints)
- {
- RunProgram(onRenderImagePoint);
- }
- }
-
- private readonly List<uint> _onRenderObjectPoints = new List<uint>();
-
- public void OnRenderObject()
- {
- if(!_hasDoneStart)
- {
- return;
- }
-
- foreach(uint onRenderObjectPoint in _onRenderObjectPoints)
- {
- RunProgram(onRenderObjectPoint);
- }
- }
-
- private readonly List<uint> _onTransformChildrenChangedPoints = new List<uint>();
-
- public void OnTransformChildrenChanged()
- {
- if(!_hasDoneStart)
- {
- return;
- }
-
- foreach(uint onTransformChildrenChangedPoint in _onTransformChildrenChangedPoints)
- {
- RunProgram(onTransformChildrenChangedPoint);
- }
- }
-
- private readonly List<uint> _onTransformParentChangedPoints = new List<uint>();
-
- public void OnTransformParentChanged()
- {
- if(!_hasDoneStart)
- {
- return;
- }
-
- foreach(uint onTransformParentChangedPoint in _onTransformParentChangedPoints)
- {
- RunProgram(onTransformParentChangedPoint);
- }
- }
-
- private readonly List<uint> _onTriggerEnterPoints = new List<uint>();
-
- public void OnTriggerEnter(Collider other)
- {
- if(!_hasDoneStart)
- {
- return;
- }
-
- SetProgramVariable("onTriggerEnterOther", other);
- foreach(uint onTriggerEnterPoint in _onTriggerEnterPoints)
- {
- RunProgram(onTriggerEnterPoint);
- }
-
- SetProgramVariable("onTriggerEnterOther", null);
- }
-
- private readonly List<uint> _onTriggerEnter2DPoints = new List<uint>();
-
- public void OnTriggerEnter2D(Collider2D other)
- {
- if(!_hasDoneStart)
- {
- return;
- }
-
- SetProgramVariable("onTriggerEnter2DOther", other);
- foreach(uint onTriggerEnter2DPoint in _onTriggerEnter2DPoints)
- {
- RunProgram(onTriggerEnter2DPoint);
- }
-
- SetProgramVariable("onTriggerEnter2DOther", null);
- }
-
- private readonly List<uint> _onTriggerExitPoints = new List<uint>();
-
- public void OnTriggerExit(Collider other)
- {
- if(!_hasDoneStart)
- {
- return;
- }
-
- SetProgramVariable("onTriggerExitOther", other);
- foreach(uint onTriggerExitPoint in _onTriggerExitPoints)
- {
- RunProgram(onTriggerExitPoint);
- }
-
- SetProgramVariable("onTriggerExitOther", null);
- }
-
- private readonly List<uint> _onTriggerExit2DPoints = new List<uint>();
-
- public void OnTriggerExit2D(Collider2D other)
- {
- if(!_hasDoneStart)
- {
- return;
- }
-
- SetProgramVariable("onTriggerExit2DOther", other);
- foreach(uint onTriggerExit2DPoint in _onTriggerExit2DPoints)
- {
- RunProgram(onTriggerExit2DPoint);
- }
-
- SetProgramVariable("onTriggerExit2DOther", null);
- }
-
- private readonly List<uint> _onTriggerStayPoints = new List<uint>();
-
- public void OnTriggerStay(Collider other)
- {
- if(!_hasDoneStart)
- {
- return;
- }
-
- SetProgramVariable("onTriggerStayOther", other);
- foreach(uint onTriggerStayPoint in _onTriggerStayPoints)
- {
- RunProgram(onTriggerStayPoint);
- }
-
- SetProgramVariable("onTriggerStayOther", null);
- }
-
- private readonly List<uint> _onTriggerStay2DPoints = new List<uint>();
-
- public void OnTriggerStay2D(Collider2D other)
- {
- if(!_hasDoneStart)
- {
- return;
- }
-
- SetProgramVariable("onTriggerStay2DOther", other);
- foreach(uint onTriggerStay2DPoint in _onTriggerStay2DPoints)
- {
- RunProgram(onTriggerStay2DPoint);
- }
-
- SetProgramVariable("onTriggerStay2DOther", null);
- }
-
- private readonly List<uint> _onValidatePoints = new List<uint>();
-
- public void OnValidate()
- {
- if(!_hasDoneStart)
- {
- return;
- }
-
- foreach(uint onValidatePoint in _onValidatePoints)
- {
- RunProgram(onValidatePoint);
- }
- }
-
- private readonly List<uint> _onWillRenderObjectPoints = new List<uint>();
-
- public void OnWillRenderObject()
- {
- if(!_hasDoneStart)
- {
- return;
- }
-
- foreach(uint onWillRenderObjectPoint in _onWillRenderObjectPoints)
- {
- RunProgram(onWillRenderObjectPoint);
- }
- }
-
- #endregion
-
- #region VRCSDK Events
-
- #if VRC_CLIENT
- private void OnNetworkReady()
- {
- _isNetworkReady = true;
- }
- #endif
-
- private readonly List<uint> _interactPoints = new List<uint>();
-
- public override void Interact()
- {
- foreach(uint interactPoint in _interactPoints)
- {
- RunProgram(interactPoint);
- }
- }
-
- //private readonly List<uint> _onDataStorageAddedPoints = new List<uint>();
-
- //public void OnDataStorageAdded(VRC_DataStorage ds, int idx)
- //{
- // if(!_hasDoneStart)
- // {
- // return;
- // }
-
- // SetHeapVariable("onDataStorageAddedDs", ds);
- // SetHeapVariable("onDataStorageAddedIdx", idx);
- // foreach(uint onDataStorageAddedPoint in _onDataStorageAddedPoints)
- // {
- // RunProgram(onDataStorageAddedPoint);
- // }
- //}
-
- //private readonly List<uint> _onDataStorageChangedPoints = new List<uint>();
-
- //public void OnDataStorageChanged(VRC_DataStorage ds, int idx)
- //{
- // if(!_hasDoneStart)
- // {
- // return;
- // }
-
- // SetHeapVariable("onDataStorageChangedDs", ds);
- // SetHeapVariable("onDataStorageChangedIdx", idx);
- // foreach(uint onDataStorageChangedPoint in _onDataStorageChangedPoints)
- // {
- // RunProgram(onDataStorageChangedPoint);
- // }
- //}
-
- //private readonly List<uint> _onDataStorageRemovedPoints = new List<uint>();
-
- //public void OnDataStorageRemoved(VRC_DataStorage ds, int idx)
- //{
- // if(!_hasDoneStart)
- // {
- // return;
- // }
-
- // SetHeapVariable("onDataStorageRemovedDs", ds);
- // SetHeapVariable("onDataStorageRemovedIdx", idx);
- // foreach(uint onDataStorageRemovedPoint in _onDataStorageRemovedPoints)
- // {
- // RunProgram(onDataStorageRemovedPoint);
- // }
- //}
-
- private readonly List<uint> _onDropPoints = new List<uint>();
-
- public override void OnDrop()
- {
- if(!_hasDoneStart)
- {
- return;
- }
-
- foreach(uint onDropPoint in _onDropPoints)
- {
- RunProgram(onDropPoint);
- }
- }
-
- private readonly List<uint> _onOwnershipTransferredPoints = new List<uint>();
-
- public void OnOwnershipTransferred()
- {
- if(!_hasDoneStart)
- {
- return;
- }
-
- foreach(uint onOwnershipTransferredPoint in _onOwnershipTransferredPoints)
- {
- RunProgram(onOwnershipTransferredPoint);
- }
- }
-
- private readonly List<uint> _onPickupPoints = new List<uint>();
-
- public override void OnPickup()
- {
- if(!_hasDoneStart)
- {
- return;
- }
-
- foreach(uint onPickupPoint in _onPickupPoints)
- {
- RunProgram(onPickupPoint);
- }
- }
-
- private readonly List<uint> _onPickupUseDownPoints = new List<uint>();
-
- public override void OnPickupUseDown()
- {
- if(!_hasDoneStart)
- {
- return;
- }
-
- foreach(uint onPickupUseDownPoint in _onPickupUseDownPoints)
- {
- RunProgram(onPickupUseDownPoint);
- }
- }
-
- private readonly List<uint> _onPickupUseUpPoints = new List<uint>();
-
- public override void OnPickupUseUp()
- {
- if(!_hasDoneStart)
- {
- return;
- }
-
- foreach(uint onPickupUseUpPoint in _onPickupUseUpPoints)
- {
- RunProgram(onPickupUseUpPoint);
- }
- }
-
- private readonly List<uint> _onPlayerJoinedPoints = new List<uint>();
-
- public void OnPlayerJoined(VRC.SDKBase.VRCPlayerApi player)
- {
- SetProgramVariable("onPlayerJoinedPlayer", player);
- foreach(uint onPlayerJoinedPoint in _onPlayerJoinedPoints)
- {
- RunProgram(onPlayerJoinedPoint);
- }
- }
-
- private readonly List<uint> _onPlayerLeftPoints = new List<uint>();
-
- public void OnPlayerLeft(VRC.SDKBase.VRCPlayerApi player)
- {
- SetProgramVariable("onPlayerLeftPlayer", player);
- foreach(uint onPlayerLeftPoint in _onPlayerLeftPoints)
- {
- RunProgram(onPlayerLeftPoint);
- }
- }
-
- private readonly List<uint> _onSpawnPoints = new List<uint>();
-
- public void OnSpawn()
- {
- if(!_hasDoneStart)
- {
- return;
- }
-
- foreach(uint onSpawnPoint in _onSpawnPoints)
- {
- RunProgram(onSpawnPoint);
- }
- }
-
- private readonly List<uint> _onStationEnteredPoints = new List<uint>();
-
- public void OnStationEntered()
- {
- if(!_hasDoneStart)
- {
- return;
- }
-
- foreach(uint onStationEnteredPoint in _onStationEnteredPoints)
- {
- RunProgram(onStationEnteredPoint);
- }
- }
-
- private readonly List<uint> _onStationExitedPoints = new List<uint>();
-
- public void OnStationExited()
- {
- if(!_hasDoneStart)
- {
- return;
- }
-
- foreach(uint onStationExitedPoint in _onStationExitedPoints)
- {
- RunProgram(onStationExitedPoint);
- }
- }
-
- private readonly List<uint> _onVideoEndPoints = new List<uint>();
-
- public void OnVideoEnd()
- {
- if(!_hasDoneStart)
- {
- return;
- }
-
- foreach(uint onVideoEndPoint in _onVideoEndPoints)
- {
- RunProgram(onVideoEndPoint);
- }
- }
-
- private readonly List<uint> _onVideoPausePoints = new List<uint>();
-
- public void OnVideoPause()
- {
- if(!_hasDoneStart)
- {
- return;
- }
-
- foreach(uint onVideoPausePoint in _onVideoPausePoints)
- {
- RunProgram(onVideoPausePoint);
- }
- }
-
- private readonly List<uint> _onVideoPlayPoints = new List<uint>();
-
- public void OnVideoPlay()
- {
- if(!_hasDoneStart)
- {
- return;
- }
-
- foreach(uint onVideoPlayPoint in _onVideoPlayPoints)
- {
- RunProgram(onVideoPlayPoint);
- }
- }
-
- private readonly List<uint> _onVideoStartPoints = new List<uint>();
-
- public void OnVideoStart()
- {
- if(!_hasDoneStart)
- {
- return;
- }
-
- foreach(uint onVideoStartPoint in _onVideoStartPoints)
- {
- RunProgram(onVideoStartPoint);
- }
- }
-
- private readonly List<uint> _onPreSerializationStartPoints = new List<uint>();
-
- public void OnPreSerialization()
- {
- if(!_isNetworkReady)
- {
- return;
- }
-
- foreach(uint OnPreSerializationStartPoint in _onPreSerializationStartPoints)
- {
- RunProgram(OnPreSerializationStartPoint);
- }
- }
-
- private readonly List<uint> _onDeserializationStartPoints = new List<uint>();
-
- public void OnDeserialization()
- {
- if(!_isNetworkReady)
- {
- return;
- }
-
- foreach(uint OnDeserializationStartPoint in _onDeserializationStartPoints)
- {
- RunProgram(OnDeserializationStartPoint);
- }
- }
-
- #endregion
-
- #region RunProgram Methods
-
- [PublicAPI]
- public static System.Action<UdonBehaviour, NetworkEventTarget, string> RunProgramAsRPCHook = null;
-
- [PublicAPI]
- public void RunProgramAsRPC(NetworkEventTarget target, string eventName)
- {
- RunProgramAsRPCHook?.Invoke(this, target, eventName);
- }
-
- public void RunProgram(string eventName)
- {
- if(program == null)
- {
- return;
- }
-
- foreach(string entryPoint in program.EntryPoints.GetExportedSymbols())
- {
- if(entryPoint != eventName)
- {
- continue;
- }
-
- uint address = program.EntryPoints.GetAddressFromSymbol(entryPoint);
- RunProgram(address);
- }
- }
-
- private void RunProgram(uint entryPoint)
- {
- if(_hasError)
- {
- return;
- }
-
- if(_udonVM == null)
- {
- return;
- }
-
- uint originalAddress = _udonVM.GetProgramCounter();
- UdonBehaviour originalExecuting = UdonManager.Instance.currentlyExecuting;
-
- _udonVM.SetProgramCounter(entryPoint);
- UdonManager.Instance.currentlyExecuting = this;
-
- _udonVM.DebugLogging = UdonManager.Instance.DebugLogging;
-
- try
- {
- uint result = _udonVM.Interpret();
- if(result != 0)
- {
- VRC.Core.Logger.LogError($"Udon VM execution errored, this UdonBehaviour will be halted.", _debugLevel, this);
- _hasError = true;
- enabled = false;
- }
- }
- catch(UdonVMException error)
- {
- VRC.Core.Logger.LogError($"An exception occurred during Udon execution, this UdonBehaviour will be halted.\n{error}", _debugLevel, this);
- _hasError = true;
- enabled = false;
- }
-
- UdonManager.Instance.currentlyExecuting = originalExecuting;
- if(originalAddress < 0xFFFFFFFC)
- {
- _udonVM.SetProgramCounter(originalAddress);
- }
- }
-
- [PublicAPI]
- public string[] GetPrograms()
- {
- if(program == null)
- {
- return new string[0];
- }
-
- return program.EntryPoints.GetExportedSymbols();
- }
-
- #endregion
-
- #region Serialization
-
- [SerializeField]
- private string serializedPublicVariablesBytesString;
-
- [SerializeField]
- private List<UnityEngine.Object> publicVariablesUnityEngineObjects;
-
- [SerializeField]
- private DataFormat publicVariablesSerializationDataFormat = DataFormat.Binary;
-
- void ISerializationCallbackReceiver.OnAfterDeserialize()
- {
- DeserializePublicVariables();
- }
-
- private void DeserializePublicVariables()
- {
- byte[] serializedPublicVariablesBytes = Convert.FromBase64String(serializedPublicVariablesBytesString ?? "");
- publicVariables = SerializationUtility.DeserializeValue<IUdonVariableTable>(
- serializedPublicVariablesBytes,
- publicVariablesSerializationDataFormat,
- publicVariablesUnityEngineObjects
- ) ?? new UdonVariableTable();
-
- // Validate that the type of the value can actually be cast to the declaredType to avoid InvalidCastExceptions later.
- foreach(string publicVariableSymbol in publicVariables.VariableSymbols.ToArray())
- {
- if(!publicVariables.TryGetVariableValue(publicVariableSymbol, out object value))
- {
- continue;
- }
-
- if(value == null)
- {
- continue;
- }
-
- if(!publicVariables.TryGetVariableType(publicVariableSymbol, out Type declaredType))
- {
- continue;
- }
-
- if(declaredType.IsInstanceOfType(value))
- {
- continue;
- }
-
- if(declaredType.IsValueType)
- {
- publicVariables.TrySetVariableValue(publicVariableSymbol, Activator.CreateInstance(declaredType));
- }
- else
- {
- publicVariables.TrySetVariableValue(publicVariableSymbol, null);
- }
- }
- }
-
- void ISerializationCallbackReceiver.OnBeforeSerialize()
- {
- SerializePublicVariables();
- }
-
- private void SerializePublicVariables()
- {
- byte[] serializedPublicVariablesBytes = SerializationUtility.SerializeValue(publicVariables, publicVariablesSerializationDataFormat, out publicVariablesUnityEngineObjects);
- serializedPublicVariablesBytesString = Convert.ToBase64String(serializedPublicVariablesBytes);
- }
-
- #endregion
-
- #region IUdonEventReceiver and IUdonSyncTarget Interface
-
- #region IUdonEventReceiver Only
-
- public void SendCustomEvent(string eventName)
- {
- RunProgram(eventName);
- }
-
- public void SendCustomNetworkEvent(NetworkEventTarget target, string eventName)
- {
- RunProgramAsRPC(target, eventName);
- }
-
- #endregion
-
- #region IUdonSyncTarget Only
-
- public IUdonSyncMetadataTable SyncMetadataTable => program?.SyncMetadataTable;
-
- public Type GetHeapVariableType(string symbolName)
- {
- if(!program.SymbolTable.HasAddressForSymbol(symbolName))
- {
- return null;
- }
-
- uint symbolAddress = program.SymbolTable.GetAddressFromSymbol(symbolName);
- return program.Heap.GetHeapVariableType(symbolAddress);
- }
-
- public void SetHeapVariable(string symbolName, object value)
- {
- SetProgramVariable(symbolName, value);
- }
-
- public object GetHeapVariable(string symbolName)
- {
- return GetProgramVariable(symbolName);
- }
-
- #endregion
-
- #region Shared
-
- public void SetProgramVariable(string symbolName, object value)
- {
- if(program == null)
- {
- return;
- }
-
- if(!program.SymbolTable.TryGetAddressFromSymbol(symbolName, out uint symbolAddress))
- {
- return;
- }
-
- program.Heap.SetHeapVariable(symbolAddress, value);
- }
-
- public object GetProgramVariable(string symbolName)
- {
- if(program == null)
- {
- return null;
- }
-
- if(!program.SymbolTable.TryGetAddressFromSymbol(symbolName, out uint symbolAddress))
- {
- return null;
- }
-
- return program.Heap.GetHeapVariable(symbolAddress);
- }
-
- #endregion
-
- #endregion
-
- #region Logging Methods
-
- private void SetupLogging()
- {
- _debugLevel = GetType().GetHashCode();
- if(VRC.Core.Logger.DebugLevelIsDescribed(_debugLevel))
- {
- return;
- }
-
- VRC.Core.Logger.DescribeDebugLevel(_debugLevel, "UdonBehaviour");
- VRC.Core.Logger.AddDebugLevel(_debugLevel);
- }
-
- #endregion
-
- #region Manual Initialization Methods
- public void AssignProgramAndVariables(VRC.Udon.AbstractSerializedUdonProgramAsset compiledAsset, IUdonVariableTable variables)
- {
- serializedProgramAsset = compiledAsset;
- publicVariables = variables;
- }
- #endregion
- }
- }
|