The Swartz-Manning’s first exhibit will provide a detailed history of Aaron Swartz Day. https://www.aaronswartzday.org/vr
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

UdonBehaviour.cs 58KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using JetBrains.Annotations;
  5. using UnityEngine;
  6. using VRC.Udon.Common;
  7. using VRC.Udon.Common.Interfaces;
  8. using VRC.Udon.Serialization.OdinSerializer;
  9. using VRC.Udon.VM;
  10. #if VRC_CLIENT
  11. using VRC.Udon.Security;
  12. #endif
  13. #if UNITY_EDITOR && !VRC_CLIENT
  14. using UnityEditor.SceneManagement;
  15. #endif
  16. namespace VRC.Udon
  17. {
  18. public class UdonBehaviour : VRC.SDKBase.VRC_Interactable, ISerializationCallbackReceiver, IUdonEventReceiver, IUdonSyncTarget, VRC.SDKBase.INetworkID
  19. {
  20. #region Odin Serialized Fields
  21. public IUdonVariableTable publicVariables = new UdonVariableTable();
  22. #endregion
  23. #region Serialized Public Fields
  24. public bool SynchronizePosition = false;
  25. public readonly bool SynchronizeAnimation = false; //We don't support animation sync yet, coming soon.
  26. public bool AllowCollisionOwnershipTransfer = true;
  27. #endregion
  28. #region Serialized Private Fields
  29. [SerializeField]
  30. private AbstractSerializedUdonProgramAsset serializedProgramAsset;
  31. #if UNITY_EDITOR && !VRC_CLIENT
  32. [SerializeField]
  33. public AbstractUdonProgramSource programSource;
  34. #endif
  35. #endregion
  36. #region Public Fields and Properties
  37. [PublicAPI]
  38. public static System.Action<UdonBehaviour, IUdonProgram> OnInit = null;
  39. [PublicAPI]
  40. public bool HasInteractiveEvents { get; private set; } = false;
  41. public override bool IsInteractive => HasInteractiveEvents;
  42. [HideInInspector]
  43. public int NetworkID { get; set; }
  44. #endregion
  45. #region Private Fields
  46. private IUdonProgram program;
  47. private IUdonVM _udonVM;
  48. private bool _isNetworkReady;
  49. private int _debugLevel;
  50. private bool _hasError;
  51. #endregion
  52. #region Editor Only
  53. #if UNITY_EDITOR && !VRC_CLIENT
  54. public void RunEditorUpdate(ref bool dirty)
  55. {
  56. if(programSource == null)
  57. {
  58. return;
  59. }
  60. programSource.RunEditorUpdate(this, ref dirty);
  61. if(!dirty)
  62. {
  63. return;
  64. }
  65. EditorSceneManager.MarkSceneDirty(gameObject.scene);
  66. }
  67. #endif
  68. #endregion
  69. #region Private Methods
  70. private bool LoadProgram()
  71. {
  72. if(serializedProgramAsset == null)
  73. {
  74. return false;
  75. }
  76. program = serializedProgramAsset.RetrieveProgram();
  77. IUdonSymbolTable symbolTable = program?.SymbolTable;
  78. IUdonHeap heap = program?.Heap;
  79. if(symbolTable == null || heap == null)
  80. {
  81. return false;
  82. }
  83. foreach(string variableSymbol in publicVariables.VariableSymbols)
  84. {
  85. if(!symbolTable.HasAddressForSymbol(variableSymbol))
  86. {
  87. continue;
  88. }
  89. uint symbolAddress = symbolTable.GetAddressFromSymbol(variableSymbol);
  90. if(!publicVariables.TryGetVariableType(variableSymbol, out Type declaredType))
  91. {
  92. continue;
  93. }
  94. publicVariables.TryGetVariableValue(variableSymbol, out object value);
  95. if(declaredType == typeof(GameObject) || declaredType == typeof(UdonBehaviour) ||
  96. declaredType == typeof(Transform))
  97. {
  98. if(value == null)
  99. {
  100. value = new UdonGameObjectComponentHeapReference(declaredType);
  101. declaredType = typeof(UdonGameObjectComponentHeapReference);
  102. }
  103. }
  104. heap.SetHeapVariable(symbolAddress, value, declaredType);
  105. }
  106. return true;
  107. }
  108. #endregion
  109. #region Unity Events
  110. private readonly List<uint> _startPoints = new List<uint>();
  111. public override void Start()
  112. {
  113. InitializeUdonContent();
  114. }
  115. [PublicAPI]
  116. public void InitializeUdonContent()
  117. {
  118. SetupLogging();
  119. UdonManager udonManager = UdonManager.Instance;
  120. if(udonManager == null)
  121. {
  122. enabled = false;
  123. VRC.Core.Logger.LogError($"Could not find the UdonManager; the UdonBehaviour on '{gameObject.name}' will not run.", _debugLevel, this);
  124. return;
  125. }
  126. if(!LoadProgram())
  127. {
  128. enabled = false;
  129. VRC.Core.Logger.Log($"Could not load the program; the UdonBehaviour on '{gameObject.name}' will not run.", _debugLevel, this);
  130. if(OnInit != null)
  131. {
  132. try
  133. {
  134. OnInit(this, null);
  135. }
  136. catch(Exception exception)
  137. {
  138. VRC.Core.Logger.LogError(
  139. $"An exception '{exception.Message}' occurred during initialization; the UdonBehaviour on '{gameObject.name}' will not run. Exception:\n{exception}",
  140. _debugLevel,
  141. this
  142. );
  143. }
  144. }
  145. return;
  146. }
  147. IUdonSymbolTable symbolTable = program?.SymbolTable;
  148. IUdonHeap heap = program?.Heap;
  149. if(symbolTable == null || heap == null)
  150. {
  151. enabled = false;
  152. VRC.Core.Logger.Log($"Invalid program; the UdonBehaviour on '{gameObject.name}' will not run.", _debugLevel, this);
  153. return;
  154. }
  155. if(!ResolveUdonHeapReferences(symbolTable, heap))
  156. {
  157. enabled = false;
  158. VRC.Core.Logger.Log($"Failed to resolve a GameObject/Component Reference; the UdonBehaviour on '{gameObject.name}' will not run.", _debugLevel, this);
  159. return;
  160. }
  161. _udonVM = udonManager.ConstructUdonVM();
  162. if(_udonVM == null)
  163. {
  164. enabled = false;
  165. VRC.Core.Logger.LogError($"No UdonVM; the UdonBehaviour on '{gameObject.name}' will not run.", _debugLevel, this);
  166. return;
  167. }
  168. #if VRC_CLIENT
  169. program = new UdonProgram(
  170. program.InstructionSetIdentifier,
  171. program.InstructionSetVersion,
  172. program.ByteCode,
  173. new UdonSecureHeap(program.Heap, udonManager),
  174. program.EntryPoints,
  175. program.SymbolTable,
  176. program.SyncMetadataTable
  177. );
  178. #endif
  179. _udonVM.LoadProgram(program);
  180. ProcessEntryPoints();
  181. #if !VRC_CLIENT
  182. _isNetworkReady = true;
  183. #endif
  184. if(OnInit != null)
  185. {
  186. try
  187. {
  188. OnInit(this, program);
  189. }
  190. catch(Exception exception)
  191. {
  192. enabled = false;
  193. VRC.Core.Logger.LogError(
  194. $"An exception '{exception.Message}' occurred during initialization; the UdonBehaviour on '{gameObject.name}' will not run. Exception:\n{exception}",
  195. _debugLevel,
  196. this
  197. );
  198. }
  199. }
  200. }
  201. private void ProcessEntryPoints()
  202. {
  203. foreach(string entryPoint in program.EntryPoints.GetExportedSymbols())
  204. {
  205. uint address = program.EntryPoints.GetAddressFromSymbol(entryPoint);
  206. switch(entryPoint)
  207. {
  208. case "_start":
  209. {
  210. _startPoints.Add(address);
  211. break;
  212. }
  213. case "_update":
  214. {
  215. _updatePoints.Add(address);
  216. break;
  217. }
  218. case "_lateUpdate":
  219. {
  220. _lateUpdatePoints.Add(address);
  221. break;
  222. }
  223. case "_interact":
  224. {
  225. HasInteractiveEvents = true;
  226. _interactPoints.Add(address);
  227. break;
  228. }
  229. case "_fixedUpdate":
  230. {
  231. _fixedUpdatePoints.Add(address);
  232. break;
  233. }
  234. case "_onAnimatorIk":
  235. {
  236. _onAnimatorIkPoints.Add(address);
  237. break;
  238. }
  239. case "_onAnimatorMove":
  240. {
  241. _onAnimatorMovePoints.Add(address);
  242. break;
  243. }
  244. case "_onAudioFilterRead":
  245. {
  246. _onAudioFilterReadPoints.Add(address);
  247. break;
  248. }
  249. case "_onBecameInvisible":
  250. {
  251. _onBecameInvisiblePoints.Add(address);
  252. break;
  253. }
  254. case "_onBecameVisible":
  255. {
  256. _onBecameVisiblePoints.Add(address);
  257. break;
  258. }
  259. case "_onCollisionEnter":
  260. {
  261. _onCollisionEnterPoints.Add(address);
  262. break;
  263. }
  264. case "_onCollisionEnter2D":
  265. {
  266. _onCollisionEnter2DPoints.Add(address);
  267. break;
  268. }
  269. case "_onCollisionExit":
  270. {
  271. _onCollisionExitPoints.Add(address);
  272. break;
  273. }
  274. case "_onCollisionExit2D":
  275. {
  276. _onCollisionExit2DPoints.Add(address);
  277. break;
  278. }
  279. case "_onCollisionStay":
  280. {
  281. _onCollisionStayPoints.Add(address);
  282. break;
  283. }
  284. case "_onCollisionStay2D":
  285. {
  286. _onCollisionStay2DPoints.Add(address);
  287. break;
  288. }
  289. case "_onControllerColliderHit":
  290. {
  291. _onControllerColliderHitPoints.Add(address);
  292. break;
  293. }
  294. case "_onDestroy":
  295. {
  296. _onDestroyPoints.Add(address);
  297. break;
  298. }
  299. case "_onDisable":
  300. {
  301. _onDisablePoints.Add(address);
  302. break;
  303. }
  304. case "_onDrawGizmos":
  305. {
  306. _onDrawGizmosPoints.Add(address);
  307. break;
  308. }
  309. case "_onDrawGizmosSelected":
  310. {
  311. _onDrawGizmosSelectedPoints.Add(address);
  312. break;
  313. }
  314. case "_onEnable":
  315. {
  316. _onEnablePoints.Add(address);
  317. break;
  318. }
  319. case "_onGUI":
  320. {
  321. _onGUIPoints.Add(address);
  322. break;
  323. }
  324. case "_onJointBreak":
  325. {
  326. _onJointBreakPoints.Add(address);
  327. break;
  328. }
  329. case "_onJointBreak2D":
  330. {
  331. _onJointBreak2DPoints.Add(address);
  332. break;
  333. }
  334. case "_onMouseDown":
  335. {
  336. _onMouseDownPoints.Add(address);
  337. break;
  338. }
  339. case "_onMouseDrag":
  340. {
  341. _onMouseDragPoints.Add(address);
  342. break;
  343. }
  344. case "_onMouseEnter":
  345. {
  346. _onMouseEnterPoints.Add(address);
  347. break;
  348. }
  349. case "_onMouseExit":
  350. {
  351. _onMouseExitPoints.Add(address);
  352. break;
  353. }
  354. case "_onMouseOver":
  355. {
  356. _onMouseOverPoints.Add(address);
  357. break;
  358. }
  359. case "_onMouseUp":
  360. {
  361. _onMouseUpPoints.Add(address);
  362. break;
  363. }
  364. case "_onMouseUpAsButton":
  365. {
  366. _onMouseUpAsButtonPoints.Add(address);
  367. break;
  368. }
  369. case "_onParticleCollision":
  370. {
  371. _onParticleCollisionPoints.Add(address);
  372. break;
  373. }
  374. case "_onParticleTrigger":
  375. {
  376. _onParticleTriggerPoints.Add(address);
  377. break;
  378. }
  379. case "_onPostRender":
  380. {
  381. _onPostRenderPoints.Add(address);
  382. break;
  383. }
  384. case "_onPreCull":
  385. {
  386. _onPreCullPoints.Add(address);
  387. break;
  388. }
  389. case "_onPreRender":
  390. {
  391. _onPreRenderPoints.Add(address);
  392. break;
  393. }
  394. case "_onRenderImage":
  395. {
  396. _onRenderImagePoints.Add(address);
  397. break;
  398. }
  399. case "_onRenderObject":
  400. {
  401. _onRenderObjectPoints.Add(address);
  402. break;
  403. }
  404. case "_onTransformChildrenChanged":
  405. {
  406. _onTransformChildrenChangedPoints.Add(address);
  407. break;
  408. }
  409. case "_onTransformParentChanged":
  410. {
  411. _onTransformParentChangedPoints.Add(address);
  412. break;
  413. }
  414. case "_onTriggerEnter":
  415. {
  416. _onTriggerEnterPoints.Add(address);
  417. break;
  418. }
  419. case "_onTriggerEnter2D":
  420. {
  421. _onTriggerEnter2DPoints.Add(address);
  422. break;
  423. }
  424. case "_onTriggerExit":
  425. {
  426. _onTriggerExitPoints.Add(address);
  427. break;
  428. }
  429. case "_onTriggerExit2D":
  430. {
  431. _onTriggerExit2DPoints.Add(address);
  432. break;
  433. }
  434. case "_onTriggerStay":
  435. {
  436. _onTriggerStayPoints.Add(address);
  437. break;
  438. }
  439. case "_onTriggerStay2D":
  440. {
  441. _onTriggerStay2DPoints.Add(address);
  442. break;
  443. }
  444. case "_onValidate":
  445. {
  446. _onValidatePoints.Add(address);
  447. break;
  448. }
  449. case "_onWillRenderObject":
  450. {
  451. _onWillRenderObjectPoints.Add(address);
  452. break;
  453. }
  454. //case "_onDataStorageAdded":
  455. //{
  456. // _onDataStorageAddedPoints.Add(address);
  457. // break;
  458. //}
  459. //case "_onDataStorageChanged":
  460. //{
  461. // _onDataStorageChangedPoints.Add(address);
  462. // break;
  463. //}
  464. //case "_onDataStorageRemoved":
  465. //{
  466. // _onDataStorageRemovedPoints.Add(address);
  467. // break;
  468. //}
  469. case "_onDrop":
  470. {
  471. _onDropPoints.Add(address);
  472. break;
  473. }
  474. case "_onOwnershipTransferred":
  475. {
  476. _onOwnershipTransferredPoints.Add(address);
  477. break;
  478. }
  479. case "_onPickup":
  480. {
  481. _onPickupPoints.Add(address);
  482. break;
  483. }
  484. case "_onPickupUseDown":
  485. {
  486. _onPickupUseDownPoints.Add(address);
  487. break;
  488. }
  489. case "_onPickupUseUp":
  490. {
  491. _onPickupUseUpPoints.Add(address);
  492. break;
  493. }
  494. case "_onPlayerJoined":
  495. {
  496. _onPlayerJoinedPoints.Add(address);
  497. break;
  498. }
  499. case "_onPlayerLeft":
  500. {
  501. _onPlayerLeftPoints.Add(address);
  502. break;
  503. }
  504. case "_onSpawn":
  505. {
  506. _onSpawnPoints.Add(address);
  507. break;
  508. }
  509. case "_onStationEntered":
  510. {
  511. _onStationEnteredPoints.Add(address);
  512. break;
  513. }
  514. case "_onStationExited":
  515. {
  516. _onStationExitedPoints.Add(address);
  517. break;
  518. }
  519. case "_onVideoEnd":
  520. {
  521. _onVideoEndPoints.Add(address);
  522. break;
  523. }
  524. case "_onVideoPause":
  525. {
  526. _onVideoPausePoints.Add(address);
  527. break;
  528. }
  529. case "_onVideoPlay":
  530. {
  531. _onVideoPlayPoints.Add(address);
  532. break;
  533. }
  534. case "_onVideoStart":
  535. {
  536. _onVideoStartPoints.Add(address);
  537. break;
  538. }
  539. case "_onPreSerialization":
  540. {
  541. _onPreSerializationStartPoints.Add(address);
  542. break;
  543. }
  544. case "_onDeserialization":
  545. {
  546. _onDeserializationStartPoints.Add(address);
  547. break;
  548. }
  549. }
  550. }
  551. }
  552. private bool ResolveUdonHeapReferences(IUdonSymbolTable symbolTable, IUdonHeap heap)
  553. {
  554. bool success = true;
  555. foreach(string symbolName in symbolTable.GetSymbols())
  556. {
  557. uint symbolAddress = symbolTable.GetAddressFromSymbol(symbolName);
  558. object heapValue = heap.GetHeapVariable(symbolAddress);
  559. if(!(heapValue is UdonBaseHeapReference udonBaseHeapReference))
  560. {
  561. continue;
  562. }
  563. if(!ResolveUdonHeapReference(heap, symbolAddress, udonBaseHeapReference))
  564. {
  565. success = false;
  566. }
  567. }
  568. return success;
  569. }
  570. private bool ResolveUdonHeapReference(IUdonHeap heap, uint symbolAddress, UdonBaseHeapReference udonBaseHeapReference)
  571. {
  572. switch(udonBaseHeapReference)
  573. {
  574. case UdonGameObjectComponentHeapReference udonGameObjectComponentHeapReference:
  575. {
  576. Type referenceType = udonGameObjectComponentHeapReference.type;
  577. if(referenceType == typeof(GameObject))
  578. {
  579. heap.SetHeapVariable(symbolAddress, gameObject);
  580. return true;
  581. }
  582. else if(referenceType == typeof(Transform))
  583. {
  584. heap.SetHeapVariable(symbolAddress, gameObject.transform);
  585. return true;
  586. }
  587. else if(referenceType == typeof(UdonBehaviour))
  588. {
  589. heap.SetHeapVariable(symbolAddress, this);
  590. return true;
  591. }
  592. else if(referenceType == typeof(UnityEngine.Object))
  593. {
  594. heap.SetHeapVariable(symbolAddress, this);
  595. return true;
  596. }
  597. else
  598. {
  599. VRC.Core.Logger.Log(
  600. $"Unsupported GameObject/Component reference type: {udonBaseHeapReference.GetType().Name}. Only GameObject, Transform, and UdonBehaviour are supported.",
  601. _debugLevel,
  602. this);
  603. return false;
  604. }
  605. }
  606. default:
  607. {
  608. VRC.Core.Logger.Log($"Unknown heap reference type: {udonBaseHeapReference.GetType().Name}", _debugLevel, this);
  609. return false;
  610. }
  611. }
  612. }
  613. private readonly List<uint> _updatePoints = new List<uint>();
  614. private bool _hasDoneStart;
  615. private void Update()
  616. {
  617. if(!_isNetworkReady)
  618. {
  619. return;
  620. }
  621. if(!_hasDoneStart)
  622. {
  623. foreach(uint startPoint in _startPoints)
  624. {
  625. RunProgram(startPoint);
  626. }
  627. _hasDoneStart = true;
  628. }
  629. foreach(uint updatePoint in _updatePoints)
  630. {
  631. RunProgram(updatePoint);
  632. }
  633. }
  634. private readonly List<uint> _lateUpdatePoints = new List<uint>();
  635. private void LateUpdate()
  636. {
  637. if(!_hasDoneStart)
  638. {
  639. return;
  640. }
  641. foreach(uint lateUpdatePoint in _lateUpdatePoints)
  642. {
  643. RunProgram(lateUpdatePoint);
  644. }
  645. }
  646. private readonly List<uint> _fixedUpdatePoints = new List<uint>();
  647. public void FixedUpdate()
  648. {
  649. if(!_hasDoneStart)
  650. {
  651. return;
  652. }
  653. foreach(uint fixedUpdatePoint in _fixedUpdatePoints)
  654. {
  655. RunProgram(fixedUpdatePoint);
  656. }
  657. }
  658. private readonly List<uint> _onAnimatorIkPoints = new List<uint>();
  659. public void OnAnimatorIK(int layerIndex)
  660. {
  661. if(!_hasDoneStart)
  662. {
  663. return;
  664. }
  665. SetProgramVariable("onAnimatorIkLayerIndex", layerIndex);
  666. foreach(uint onAnimatorIkPoint in _onAnimatorIkPoints)
  667. {
  668. RunProgram(onAnimatorIkPoint);
  669. }
  670. }
  671. private readonly List<uint> _onAnimatorMovePoints = new List<uint>();
  672. public void OnAnimatorMove()
  673. {
  674. if(!_hasDoneStart)
  675. {
  676. return;
  677. }
  678. foreach(uint onAnimatorMovePoint in _onAnimatorMovePoints)
  679. {
  680. RunProgram(onAnimatorMovePoint);
  681. }
  682. }
  683. private readonly List<uint> _onAudioFilterReadPoints = new List<uint>();
  684. public void OnAudioFilterRead(float[] data, int channels)
  685. {
  686. if(!_hasDoneStart)
  687. {
  688. return;
  689. }
  690. SetProgramVariable("onAudioFilterReadData", data);
  691. SetProgramVariable("onAudioFilterReadChannels", channels);
  692. foreach(uint onAudioFilterReadPoint in _onAudioFilterReadPoints)
  693. {
  694. RunProgram(onAudioFilterReadPoint);
  695. }
  696. }
  697. private readonly List<uint> _onBecameInvisiblePoints = new List<uint>();
  698. public void OnBecameInvisible()
  699. {
  700. if(!_hasDoneStart)
  701. {
  702. return;
  703. }
  704. foreach(uint onBecameInvisiblePoint in _onBecameInvisiblePoints)
  705. {
  706. RunProgram(onBecameInvisiblePoint);
  707. }
  708. }
  709. private readonly List<uint> _onBecameVisiblePoints = new List<uint>();
  710. public void OnBecameVisible()
  711. {
  712. if(!_hasDoneStart)
  713. {
  714. return;
  715. }
  716. foreach(uint onBecameVisiblePoint in _onBecameVisiblePoints)
  717. {
  718. RunProgram(onBecameVisiblePoint);
  719. }
  720. }
  721. private readonly List<uint> _onCollisionEnterPoints = new List<uint>();
  722. public void OnCollisionEnter(Collision other)
  723. {
  724. if(!_hasDoneStart)
  725. {
  726. return;
  727. }
  728. SetProgramVariable("onCollisionEnterOther", other);
  729. foreach(uint onCollisionEnterPoint in _onCollisionEnterPoints)
  730. {
  731. RunProgram(onCollisionEnterPoint);
  732. }
  733. SetProgramVariable("onCollisionEnterOther", null);
  734. }
  735. private readonly List<uint> _onCollisionEnter2DPoints = new List<uint>();
  736. public void OnCollisionEnter2D(Collision2D other)
  737. {
  738. if(!_hasDoneStart)
  739. {
  740. return;
  741. }
  742. SetProgramVariable("onCollisionEnter2DOther", other);
  743. foreach(uint onCollisionEnter2DPoint in _onCollisionEnter2DPoints)
  744. {
  745. RunProgram(onCollisionEnter2DPoint);
  746. }
  747. SetProgramVariable("onCollisionEnter2DOther", null);
  748. }
  749. private readonly List<uint> _onCollisionExitPoints = new List<uint>();
  750. public void OnCollisionExit(Collision other)
  751. {
  752. if(!_hasDoneStart)
  753. {
  754. return;
  755. }
  756. SetProgramVariable("onCollisionExitOther", other);
  757. foreach(uint onCollisionExitPoint in _onCollisionExitPoints)
  758. {
  759. RunProgram(onCollisionExitPoint);
  760. }
  761. SetProgramVariable("onCollisionExitOther", null);
  762. }
  763. private readonly List<uint> _onCollisionExit2DPoints = new List<uint>();
  764. public void OnCollisionExit2D(Collision2D other)
  765. {
  766. if(!_hasDoneStart)
  767. {
  768. return;
  769. }
  770. SetProgramVariable("onCollisionExit2DOther", other);
  771. foreach(uint onCollisionExit2DPoint in _onCollisionExit2DPoints)
  772. {
  773. RunProgram(onCollisionExit2DPoint);
  774. }
  775. SetProgramVariable("onCollisionExit2DOther", null);
  776. }
  777. private readonly List<uint> _onCollisionStayPoints = new List<uint>();
  778. public void OnCollisionStay(Collision other)
  779. {
  780. if(!_hasDoneStart)
  781. {
  782. return;
  783. }
  784. SetProgramVariable("onCollisionStayOther", other);
  785. foreach(uint onCollisionStayPoint in _onCollisionStayPoints)
  786. {
  787. RunProgram(onCollisionStayPoint);
  788. }
  789. SetProgramVariable("onCollisionStayOther", null);
  790. }
  791. private readonly List<uint> _onCollisionStay2DPoints = new List<uint>();
  792. public void OnCollisionStay2D(Collision2D other)
  793. {
  794. if(!_hasDoneStart)
  795. {
  796. return;
  797. }
  798. SetProgramVariable("onCollisionStay2DOther", other);
  799. foreach(uint onCollisionStay2DPoint in _onCollisionStay2DPoints)
  800. {
  801. RunProgram(onCollisionStay2DPoint);
  802. }
  803. SetProgramVariable("onCollisionStay2DOther", null);
  804. }
  805. private readonly List<uint> _onControllerColliderHitPoints = new List<uint>();
  806. public void OnControllerColliderHit(ControllerColliderHit hit)
  807. {
  808. if(!_hasDoneStart)
  809. {
  810. return;
  811. }
  812. SetProgramVariable("onControllerColliderHitHit", hit);
  813. foreach(uint onControllerColliderHitPoint in _onControllerColliderHitPoints)
  814. {
  815. RunProgram(onControllerColliderHitPoint);
  816. }
  817. SetProgramVariable("onControllerColliderHitHit", null);
  818. }
  819. private readonly List<uint> _onDestroyPoints = new List<uint>();
  820. public void OnDestroy()
  821. {
  822. if(!_hasDoneStart)
  823. {
  824. return;
  825. }
  826. foreach(uint onDestroyPoint in _onDestroyPoints)
  827. {
  828. RunProgram(onDestroyPoint);
  829. }
  830. }
  831. private readonly List<uint> _onDisablePoints = new List<uint>();
  832. public void OnDisable()
  833. {
  834. if(!_hasDoneStart)
  835. {
  836. return;
  837. }
  838. foreach(uint onDisablePoint in _onDisablePoints)
  839. {
  840. RunProgram(onDisablePoint);
  841. }
  842. }
  843. private readonly List<uint> _onDrawGizmosPoints = new List<uint>();
  844. public void OnDrawGizmos()
  845. {
  846. if(!_hasDoneStart)
  847. {
  848. return;
  849. }
  850. foreach(uint onDrawGizmosPoint in _onDrawGizmosPoints)
  851. {
  852. RunProgram(onDrawGizmosPoint);
  853. }
  854. }
  855. private readonly List<uint> _onDrawGizmosSelectedPoints = new List<uint>();
  856. public void OnDrawGizmosSelected()
  857. {
  858. if(!_hasDoneStart)
  859. {
  860. return;
  861. }
  862. foreach(uint onDrawGizmosSelectedPoint in _onDrawGizmosSelectedPoints)
  863. {
  864. RunProgram(onDrawGizmosSelectedPoint);
  865. }
  866. }
  867. private readonly List<uint> _onEnablePoints = new List<uint>();
  868. public void OnEnable()
  869. {
  870. if(!_hasDoneStart)
  871. {
  872. return;
  873. }
  874. foreach(uint onEnablePoint in _onEnablePoints)
  875. {
  876. RunProgram(onEnablePoint);
  877. }
  878. }
  879. private readonly List<uint> _onGUIPoints = new List<uint>();
  880. public void OnGUI()
  881. {
  882. if(!_hasDoneStart)
  883. {
  884. return;
  885. }
  886. foreach(uint onGUIPoint in _onGUIPoints)
  887. {
  888. RunProgram(onGUIPoint);
  889. }
  890. }
  891. private readonly List<uint> _onJointBreakPoints = new List<uint>();
  892. public void OnJointBreak(float breakForce)
  893. {
  894. if(!_hasDoneStart)
  895. {
  896. return;
  897. }
  898. SetProgramVariable("onJointBreakBreakForce", breakForce);
  899. foreach(uint onJointBreakPoint in _onJointBreakPoints)
  900. {
  901. RunProgram(onJointBreakPoint);
  902. }
  903. }
  904. private readonly List<uint> _onJointBreak2DPoints = new List<uint>();
  905. public void OnJointBreak2D(Joint2D brokenJoint)
  906. {
  907. if(!_hasDoneStart)
  908. {
  909. return;
  910. }
  911. SetProgramVariable("onJointBreak2DBrokenJoint", brokenJoint);
  912. foreach(uint onJointBreak2DPoint in _onJointBreak2DPoints)
  913. {
  914. RunProgram(onJointBreak2DPoint);
  915. }
  916. }
  917. private readonly List<uint> _onMouseDownPoints = new List<uint>();
  918. public void OnMouseDown()
  919. {
  920. if(!_hasDoneStart)
  921. {
  922. return;
  923. }
  924. foreach(uint onMouseDownPoint in _onMouseDownPoints)
  925. {
  926. RunProgram(onMouseDownPoint);
  927. }
  928. }
  929. private readonly List<uint> _onMouseDragPoints = new List<uint>();
  930. public void OnMouseDrag()
  931. {
  932. if(!_hasDoneStart)
  933. {
  934. return;
  935. }
  936. foreach(uint onMouseDragPoint in _onMouseDragPoints)
  937. {
  938. RunProgram(onMouseDragPoint);
  939. }
  940. }
  941. private readonly List<uint> _onMouseEnterPoints = new List<uint>();
  942. public void OnMouseEnter()
  943. {
  944. if(!_hasDoneStart)
  945. {
  946. return;
  947. }
  948. foreach(uint onMouseEnterPoint in _onMouseEnterPoints)
  949. {
  950. RunProgram(onMouseEnterPoint);
  951. }
  952. }
  953. private readonly List<uint> _onMouseExitPoints = new List<uint>();
  954. public void OnMouseExit()
  955. {
  956. if(!_hasDoneStart)
  957. {
  958. return;
  959. }
  960. foreach(uint onMouseExitPoint in _onMouseExitPoints)
  961. {
  962. RunProgram(onMouseExitPoint);
  963. }
  964. }
  965. private readonly List<uint> _onMouseOverPoints = new List<uint>();
  966. public void OnMouseOver()
  967. {
  968. if(!_hasDoneStart)
  969. {
  970. return;
  971. }
  972. foreach(uint onMouseOverPoint in _onMouseOverPoints)
  973. {
  974. RunProgram(onMouseOverPoint);
  975. }
  976. }
  977. private readonly List<uint> _onMouseUpPoints = new List<uint>();
  978. public void OnMouseUp()
  979. {
  980. if(!_hasDoneStart)
  981. {
  982. return;
  983. }
  984. foreach(uint onMouseUpPoint in _onMouseUpPoints)
  985. {
  986. RunProgram(onMouseUpPoint);
  987. }
  988. }
  989. private readonly List<uint> _onMouseUpAsButtonPoints = new List<uint>();
  990. public void OnMouseUpAsButton()
  991. {
  992. if(!_hasDoneStart)
  993. {
  994. return;
  995. }
  996. foreach(uint onMouseUpAsButtonPoint in _onMouseUpAsButtonPoints)
  997. {
  998. RunProgram(onMouseUpAsButtonPoint);
  999. }
  1000. }
  1001. private readonly List<uint> _onParticleCollisionPoints = new List<uint>();
  1002. public void OnParticleCollision(GameObject other)
  1003. {
  1004. if(!_hasDoneStart)
  1005. {
  1006. return;
  1007. }
  1008. SetProgramVariable("onParticleCollisionOther", other);
  1009. foreach(uint onParticleCollisionPoint in _onParticleCollisionPoints)
  1010. {
  1011. RunProgram(onParticleCollisionPoint);
  1012. }
  1013. }
  1014. private readonly List<uint> _onParticleTriggerPoints = new List<uint>();
  1015. public void OnParticleTrigger()
  1016. {
  1017. if(!_hasDoneStart)
  1018. {
  1019. return;
  1020. }
  1021. foreach(uint onParticleTriggerPoint in _onParticleTriggerPoints)
  1022. {
  1023. RunProgram(onParticleTriggerPoint);
  1024. }
  1025. }
  1026. private readonly List<uint> _onPostRenderPoints = new List<uint>();
  1027. public void OnPostRender()
  1028. {
  1029. if(!_hasDoneStart)
  1030. {
  1031. return;
  1032. }
  1033. foreach(uint onPostRenderPoint in _onPostRenderPoints)
  1034. {
  1035. RunProgram(onPostRenderPoint);
  1036. }
  1037. }
  1038. private readonly List<uint> _onPreCullPoints = new List<uint>();
  1039. public void OnPreCull()
  1040. {
  1041. if(!_hasDoneStart)
  1042. {
  1043. return;
  1044. }
  1045. foreach(uint onPreCullPoint in _onPreCullPoints)
  1046. {
  1047. RunProgram(onPreCullPoint);
  1048. }
  1049. }
  1050. private readonly List<uint> _onPreRenderPoints = new List<uint>();
  1051. public void OnPreRender()
  1052. {
  1053. if(!_hasDoneStart)
  1054. {
  1055. return;
  1056. }
  1057. foreach(uint onPreRenderPoint in _onPreRenderPoints)
  1058. {
  1059. RunProgram(onPreRenderPoint);
  1060. }
  1061. }
  1062. private readonly List<uint> _onRenderImagePoints = new List<uint>();
  1063. public void OnRenderImage(RenderTexture src, RenderTexture dest)
  1064. {
  1065. if(!_hasDoneStart)
  1066. {
  1067. return;
  1068. }
  1069. if(_onRenderImagePoints.Count == 0)
  1070. {
  1071. Graphics.Blit(src, dest);
  1072. return;
  1073. }
  1074. SetProgramVariable("onRenderImageSrc", src);
  1075. SetProgramVariable("onRenderImageDest", dest);
  1076. foreach(uint onRenderImagePoint in _onRenderImagePoints)
  1077. {
  1078. RunProgram(onRenderImagePoint);
  1079. }
  1080. }
  1081. private readonly List<uint> _onRenderObjectPoints = new List<uint>();
  1082. public void OnRenderObject()
  1083. {
  1084. if(!_hasDoneStart)
  1085. {
  1086. return;
  1087. }
  1088. foreach(uint onRenderObjectPoint in _onRenderObjectPoints)
  1089. {
  1090. RunProgram(onRenderObjectPoint);
  1091. }
  1092. }
  1093. private readonly List<uint> _onTransformChildrenChangedPoints = new List<uint>();
  1094. public void OnTransformChildrenChanged()
  1095. {
  1096. if(!_hasDoneStart)
  1097. {
  1098. return;
  1099. }
  1100. foreach(uint onTransformChildrenChangedPoint in _onTransformChildrenChangedPoints)
  1101. {
  1102. RunProgram(onTransformChildrenChangedPoint);
  1103. }
  1104. }
  1105. private readonly List<uint> _onTransformParentChangedPoints = new List<uint>();
  1106. public void OnTransformParentChanged()
  1107. {
  1108. if(!_hasDoneStart)
  1109. {
  1110. return;
  1111. }
  1112. foreach(uint onTransformParentChangedPoint in _onTransformParentChangedPoints)
  1113. {
  1114. RunProgram(onTransformParentChangedPoint);
  1115. }
  1116. }
  1117. private readonly List<uint> _onTriggerEnterPoints = new List<uint>();
  1118. public void OnTriggerEnter(Collider other)
  1119. {
  1120. if(!_hasDoneStart)
  1121. {
  1122. return;
  1123. }
  1124. SetProgramVariable("onTriggerEnterOther", other);
  1125. foreach(uint onTriggerEnterPoint in _onTriggerEnterPoints)
  1126. {
  1127. RunProgram(onTriggerEnterPoint);
  1128. }
  1129. SetProgramVariable("onTriggerEnterOther", null);
  1130. }
  1131. private readonly List<uint> _onTriggerEnter2DPoints = new List<uint>();
  1132. public void OnTriggerEnter2D(Collider2D other)
  1133. {
  1134. if(!_hasDoneStart)
  1135. {
  1136. return;
  1137. }
  1138. SetProgramVariable("onTriggerEnter2DOther", other);
  1139. foreach(uint onTriggerEnter2DPoint in _onTriggerEnter2DPoints)
  1140. {
  1141. RunProgram(onTriggerEnter2DPoint);
  1142. }
  1143. SetProgramVariable("onTriggerEnter2DOther", null);
  1144. }
  1145. private readonly List<uint> _onTriggerExitPoints = new List<uint>();
  1146. public void OnTriggerExit(Collider other)
  1147. {
  1148. if(!_hasDoneStart)
  1149. {
  1150. return;
  1151. }
  1152. SetProgramVariable("onTriggerExitOther", other);
  1153. foreach(uint onTriggerExitPoint in _onTriggerExitPoints)
  1154. {
  1155. RunProgram(onTriggerExitPoint);
  1156. }
  1157. SetProgramVariable("onTriggerExitOther", null);
  1158. }
  1159. private readonly List<uint> _onTriggerExit2DPoints = new List<uint>();
  1160. public void OnTriggerExit2D(Collider2D other)
  1161. {
  1162. if(!_hasDoneStart)
  1163. {
  1164. return;
  1165. }
  1166. SetProgramVariable("onTriggerExit2DOther", other);
  1167. foreach(uint onTriggerExit2DPoint in _onTriggerExit2DPoints)
  1168. {
  1169. RunProgram(onTriggerExit2DPoint);
  1170. }
  1171. SetProgramVariable("onTriggerExit2DOther", null);
  1172. }
  1173. private readonly List<uint> _onTriggerStayPoints = new List<uint>();
  1174. public void OnTriggerStay(Collider other)
  1175. {
  1176. if(!_hasDoneStart)
  1177. {
  1178. return;
  1179. }
  1180. SetProgramVariable("onTriggerStayOther", other);
  1181. foreach(uint onTriggerStayPoint in _onTriggerStayPoints)
  1182. {
  1183. RunProgram(onTriggerStayPoint);
  1184. }
  1185. SetProgramVariable("onTriggerStayOther", null);
  1186. }
  1187. private readonly List<uint> _onTriggerStay2DPoints = new List<uint>();
  1188. public void OnTriggerStay2D(Collider2D other)
  1189. {
  1190. if(!_hasDoneStart)
  1191. {
  1192. return;
  1193. }
  1194. SetProgramVariable("onTriggerStay2DOther", other);
  1195. foreach(uint onTriggerStay2DPoint in _onTriggerStay2DPoints)
  1196. {
  1197. RunProgram(onTriggerStay2DPoint);
  1198. }
  1199. SetProgramVariable("onTriggerStay2DOther", null);
  1200. }
  1201. private readonly List<uint> _onValidatePoints = new List<uint>();
  1202. public void OnValidate()
  1203. {
  1204. if(!_hasDoneStart)
  1205. {
  1206. return;
  1207. }
  1208. foreach(uint onValidatePoint in _onValidatePoints)
  1209. {
  1210. RunProgram(onValidatePoint);
  1211. }
  1212. }
  1213. private readonly List<uint> _onWillRenderObjectPoints = new List<uint>();
  1214. public void OnWillRenderObject()
  1215. {
  1216. if(!_hasDoneStart)
  1217. {
  1218. return;
  1219. }
  1220. foreach(uint onWillRenderObjectPoint in _onWillRenderObjectPoints)
  1221. {
  1222. RunProgram(onWillRenderObjectPoint);
  1223. }
  1224. }
  1225. #endregion
  1226. #region VRCSDK Events
  1227. #if VRC_CLIENT
  1228. private void OnNetworkReady()
  1229. {
  1230. _isNetworkReady = true;
  1231. }
  1232. #endif
  1233. private readonly List<uint> _interactPoints = new List<uint>();
  1234. public override void Interact()
  1235. {
  1236. foreach(uint interactPoint in _interactPoints)
  1237. {
  1238. RunProgram(interactPoint);
  1239. }
  1240. }
  1241. //private readonly List<uint> _onDataStorageAddedPoints = new List<uint>();
  1242. //public void OnDataStorageAdded(VRC_DataStorage ds, int idx)
  1243. //{
  1244. // if(!_hasDoneStart)
  1245. // {
  1246. // return;
  1247. // }
  1248. // SetHeapVariable("onDataStorageAddedDs", ds);
  1249. // SetHeapVariable("onDataStorageAddedIdx", idx);
  1250. // foreach(uint onDataStorageAddedPoint in _onDataStorageAddedPoints)
  1251. // {
  1252. // RunProgram(onDataStorageAddedPoint);
  1253. // }
  1254. //}
  1255. //private readonly List<uint> _onDataStorageChangedPoints = new List<uint>();
  1256. //public void OnDataStorageChanged(VRC_DataStorage ds, int idx)
  1257. //{
  1258. // if(!_hasDoneStart)
  1259. // {
  1260. // return;
  1261. // }
  1262. // SetHeapVariable("onDataStorageChangedDs", ds);
  1263. // SetHeapVariable("onDataStorageChangedIdx", idx);
  1264. // foreach(uint onDataStorageChangedPoint in _onDataStorageChangedPoints)
  1265. // {
  1266. // RunProgram(onDataStorageChangedPoint);
  1267. // }
  1268. //}
  1269. //private readonly List<uint> _onDataStorageRemovedPoints = new List<uint>();
  1270. //public void OnDataStorageRemoved(VRC_DataStorage ds, int idx)
  1271. //{
  1272. // if(!_hasDoneStart)
  1273. // {
  1274. // return;
  1275. // }
  1276. // SetHeapVariable("onDataStorageRemovedDs", ds);
  1277. // SetHeapVariable("onDataStorageRemovedIdx", idx);
  1278. // foreach(uint onDataStorageRemovedPoint in _onDataStorageRemovedPoints)
  1279. // {
  1280. // RunProgram(onDataStorageRemovedPoint);
  1281. // }
  1282. //}
  1283. private readonly List<uint> _onDropPoints = new List<uint>();
  1284. public override void OnDrop()
  1285. {
  1286. if(!_hasDoneStart)
  1287. {
  1288. return;
  1289. }
  1290. foreach(uint onDropPoint in _onDropPoints)
  1291. {
  1292. RunProgram(onDropPoint);
  1293. }
  1294. }
  1295. private readonly List<uint> _onOwnershipTransferredPoints = new List<uint>();
  1296. public void OnOwnershipTransferred()
  1297. {
  1298. if(!_hasDoneStart)
  1299. {
  1300. return;
  1301. }
  1302. foreach(uint onOwnershipTransferredPoint in _onOwnershipTransferredPoints)
  1303. {
  1304. RunProgram(onOwnershipTransferredPoint);
  1305. }
  1306. }
  1307. private readonly List<uint> _onPickupPoints = new List<uint>();
  1308. public override void OnPickup()
  1309. {
  1310. if(!_hasDoneStart)
  1311. {
  1312. return;
  1313. }
  1314. foreach(uint onPickupPoint in _onPickupPoints)
  1315. {
  1316. RunProgram(onPickupPoint);
  1317. }
  1318. }
  1319. private readonly List<uint> _onPickupUseDownPoints = new List<uint>();
  1320. public override void OnPickupUseDown()
  1321. {
  1322. if(!_hasDoneStart)
  1323. {
  1324. return;
  1325. }
  1326. foreach(uint onPickupUseDownPoint in _onPickupUseDownPoints)
  1327. {
  1328. RunProgram(onPickupUseDownPoint);
  1329. }
  1330. }
  1331. private readonly List<uint> _onPickupUseUpPoints = new List<uint>();
  1332. public override void OnPickupUseUp()
  1333. {
  1334. if(!_hasDoneStart)
  1335. {
  1336. return;
  1337. }
  1338. foreach(uint onPickupUseUpPoint in _onPickupUseUpPoints)
  1339. {
  1340. RunProgram(onPickupUseUpPoint);
  1341. }
  1342. }
  1343. private readonly List<uint> _onPlayerJoinedPoints = new List<uint>();
  1344. public void OnPlayerJoined(VRC.SDKBase.VRCPlayerApi player)
  1345. {
  1346. SetProgramVariable("onPlayerJoinedPlayer", player);
  1347. foreach(uint onPlayerJoinedPoint in _onPlayerJoinedPoints)
  1348. {
  1349. RunProgram(onPlayerJoinedPoint);
  1350. }
  1351. }
  1352. private readonly List<uint> _onPlayerLeftPoints = new List<uint>();
  1353. public void OnPlayerLeft(VRC.SDKBase.VRCPlayerApi player)
  1354. {
  1355. SetProgramVariable("onPlayerLeftPlayer", player);
  1356. foreach(uint onPlayerLeftPoint in _onPlayerLeftPoints)
  1357. {
  1358. RunProgram(onPlayerLeftPoint);
  1359. }
  1360. }
  1361. private readonly List<uint> _onSpawnPoints = new List<uint>();
  1362. public void OnSpawn()
  1363. {
  1364. if(!_hasDoneStart)
  1365. {
  1366. return;
  1367. }
  1368. foreach(uint onSpawnPoint in _onSpawnPoints)
  1369. {
  1370. RunProgram(onSpawnPoint);
  1371. }
  1372. }
  1373. private readonly List<uint> _onStationEnteredPoints = new List<uint>();
  1374. public void OnStationEntered()
  1375. {
  1376. if(!_hasDoneStart)
  1377. {
  1378. return;
  1379. }
  1380. foreach(uint onStationEnteredPoint in _onStationEnteredPoints)
  1381. {
  1382. RunProgram(onStationEnteredPoint);
  1383. }
  1384. }
  1385. private readonly List<uint> _onStationExitedPoints = new List<uint>();
  1386. public void OnStationExited()
  1387. {
  1388. if(!_hasDoneStart)
  1389. {
  1390. return;
  1391. }
  1392. foreach(uint onStationExitedPoint in _onStationExitedPoints)
  1393. {
  1394. RunProgram(onStationExitedPoint);
  1395. }
  1396. }
  1397. private readonly List<uint> _onVideoEndPoints = new List<uint>();
  1398. public void OnVideoEnd()
  1399. {
  1400. if(!_hasDoneStart)
  1401. {
  1402. return;
  1403. }
  1404. foreach(uint onVideoEndPoint in _onVideoEndPoints)
  1405. {
  1406. RunProgram(onVideoEndPoint);
  1407. }
  1408. }
  1409. private readonly List<uint> _onVideoPausePoints = new List<uint>();
  1410. public void OnVideoPause()
  1411. {
  1412. if(!_hasDoneStart)
  1413. {
  1414. return;
  1415. }
  1416. foreach(uint onVideoPausePoint in _onVideoPausePoints)
  1417. {
  1418. RunProgram(onVideoPausePoint);
  1419. }
  1420. }
  1421. private readonly List<uint> _onVideoPlayPoints = new List<uint>();
  1422. public void OnVideoPlay()
  1423. {
  1424. if(!_hasDoneStart)
  1425. {
  1426. return;
  1427. }
  1428. foreach(uint onVideoPlayPoint in _onVideoPlayPoints)
  1429. {
  1430. RunProgram(onVideoPlayPoint);
  1431. }
  1432. }
  1433. private readonly List<uint> _onVideoStartPoints = new List<uint>();
  1434. public void OnVideoStart()
  1435. {
  1436. if(!_hasDoneStart)
  1437. {
  1438. return;
  1439. }
  1440. foreach(uint onVideoStartPoint in _onVideoStartPoints)
  1441. {
  1442. RunProgram(onVideoStartPoint);
  1443. }
  1444. }
  1445. private readonly List<uint> _onPreSerializationStartPoints = new List<uint>();
  1446. public void OnPreSerialization()
  1447. {
  1448. if(!_isNetworkReady)
  1449. {
  1450. return;
  1451. }
  1452. foreach(uint OnPreSerializationStartPoint in _onPreSerializationStartPoints)
  1453. {
  1454. RunProgram(OnPreSerializationStartPoint);
  1455. }
  1456. }
  1457. private readonly List<uint> _onDeserializationStartPoints = new List<uint>();
  1458. public void OnDeserialization()
  1459. {
  1460. if(!_isNetworkReady)
  1461. {
  1462. return;
  1463. }
  1464. foreach(uint OnDeserializationStartPoint in _onDeserializationStartPoints)
  1465. {
  1466. RunProgram(OnDeserializationStartPoint);
  1467. }
  1468. }
  1469. #endregion
  1470. #region RunProgram Methods
  1471. [PublicAPI]
  1472. public static System.Action<UdonBehaviour, NetworkEventTarget, string> RunProgramAsRPCHook = null;
  1473. [PublicAPI]
  1474. public void RunProgramAsRPC(NetworkEventTarget target, string eventName)
  1475. {
  1476. RunProgramAsRPCHook?.Invoke(this, target, eventName);
  1477. }
  1478. public void RunProgram(string eventName)
  1479. {
  1480. if(program == null)
  1481. {
  1482. return;
  1483. }
  1484. foreach(string entryPoint in program.EntryPoints.GetExportedSymbols())
  1485. {
  1486. if(entryPoint != eventName)
  1487. {
  1488. continue;
  1489. }
  1490. uint address = program.EntryPoints.GetAddressFromSymbol(entryPoint);
  1491. RunProgram(address);
  1492. }
  1493. }
  1494. private void RunProgram(uint entryPoint)
  1495. {
  1496. if(_hasError)
  1497. {
  1498. return;
  1499. }
  1500. if(_udonVM == null)
  1501. {
  1502. return;
  1503. }
  1504. uint originalAddress = _udonVM.GetProgramCounter();
  1505. UdonBehaviour originalExecuting = UdonManager.Instance.currentlyExecuting;
  1506. _udonVM.SetProgramCounter(entryPoint);
  1507. UdonManager.Instance.currentlyExecuting = this;
  1508. _udonVM.DebugLogging = UdonManager.Instance.DebugLogging;
  1509. try
  1510. {
  1511. uint result = _udonVM.Interpret();
  1512. if(result != 0)
  1513. {
  1514. VRC.Core.Logger.LogError($"Udon VM execution errored, this UdonBehaviour will be halted.", _debugLevel, this);
  1515. _hasError = true;
  1516. enabled = false;
  1517. }
  1518. }
  1519. catch(UdonVMException error)
  1520. {
  1521. VRC.Core.Logger.LogError($"An exception occurred during Udon execution, this UdonBehaviour will be halted.\n{error}", _debugLevel, this);
  1522. _hasError = true;
  1523. enabled = false;
  1524. }
  1525. UdonManager.Instance.currentlyExecuting = originalExecuting;
  1526. if(originalAddress < 0xFFFFFFFC)
  1527. {
  1528. _udonVM.SetProgramCounter(originalAddress);
  1529. }
  1530. }
  1531. [PublicAPI]
  1532. public string[] GetPrograms()
  1533. {
  1534. if(program == null)
  1535. {
  1536. return new string[0];
  1537. }
  1538. return program.EntryPoints.GetExportedSymbols();
  1539. }
  1540. #endregion
  1541. #region Serialization
  1542. [SerializeField]
  1543. private string serializedPublicVariablesBytesString;
  1544. [SerializeField]
  1545. private List<UnityEngine.Object> publicVariablesUnityEngineObjects;
  1546. [SerializeField]
  1547. private DataFormat publicVariablesSerializationDataFormat = DataFormat.Binary;
  1548. void ISerializationCallbackReceiver.OnAfterDeserialize()
  1549. {
  1550. DeserializePublicVariables();
  1551. }
  1552. private void DeserializePublicVariables()
  1553. {
  1554. byte[] serializedPublicVariablesBytes = Convert.FromBase64String(serializedPublicVariablesBytesString ?? "");
  1555. publicVariables = SerializationUtility.DeserializeValue<IUdonVariableTable>(
  1556. serializedPublicVariablesBytes,
  1557. publicVariablesSerializationDataFormat,
  1558. publicVariablesUnityEngineObjects
  1559. ) ?? new UdonVariableTable();
  1560. // Validate that the type of the value can actually be cast to the declaredType to avoid InvalidCastExceptions later.
  1561. foreach(string publicVariableSymbol in publicVariables.VariableSymbols.ToArray())
  1562. {
  1563. if(!publicVariables.TryGetVariableValue(publicVariableSymbol, out object value))
  1564. {
  1565. continue;
  1566. }
  1567. if(value == null)
  1568. {
  1569. continue;
  1570. }
  1571. if(!publicVariables.TryGetVariableType(publicVariableSymbol, out Type declaredType))
  1572. {
  1573. continue;
  1574. }
  1575. if(declaredType.IsInstanceOfType(value))
  1576. {
  1577. continue;
  1578. }
  1579. if(declaredType.IsValueType)
  1580. {
  1581. publicVariables.TrySetVariableValue(publicVariableSymbol, Activator.CreateInstance(declaredType));
  1582. }
  1583. else
  1584. {
  1585. publicVariables.TrySetVariableValue(publicVariableSymbol, null);
  1586. }
  1587. }
  1588. }
  1589. void ISerializationCallbackReceiver.OnBeforeSerialize()
  1590. {
  1591. SerializePublicVariables();
  1592. }
  1593. private void SerializePublicVariables()
  1594. {
  1595. byte[] serializedPublicVariablesBytes = SerializationUtility.SerializeValue(publicVariables, publicVariablesSerializationDataFormat, out publicVariablesUnityEngineObjects);
  1596. serializedPublicVariablesBytesString = Convert.ToBase64String(serializedPublicVariablesBytes);
  1597. }
  1598. #endregion
  1599. #region IUdonEventReceiver and IUdonSyncTarget Interface
  1600. #region IUdonEventReceiver Only
  1601. public void SendCustomEvent(string eventName)
  1602. {
  1603. RunProgram(eventName);
  1604. }
  1605. public void SendCustomNetworkEvent(NetworkEventTarget target, string eventName)
  1606. {
  1607. RunProgramAsRPC(target, eventName);
  1608. }
  1609. #endregion
  1610. #region IUdonSyncTarget Only
  1611. public IUdonSyncMetadataTable SyncMetadataTable => program?.SyncMetadataTable;
  1612. public Type GetHeapVariableType(string symbolName)
  1613. {
  1614. if(!program.SymbolTable.HasAddressForSymbol(symbolName))
  1615. {
  1616. return null;
  1617. }
  1618. uint symbolAddress = program.SymbolTable.GetAddressFromSymbol(symbolName);
  1619. return program.Heap.GetHeapVariableType(symbolAddress);
  1620. }
  1621. public void SetHeapVariable(string symbolName, object value)
  1622. {
  1623. SetProgramVariable(symbolName, value);
  1624. }
  1625. public object GetHeapVariable(string symbolName)
  1626. {
  1627. return GetProgramVariable(symbolName);
  1628. }
  1629. #endregion
  1630. #region Shared
  1631. public void SetProgramVariable(string symbolName, object value)
  1632. {
  1633. if(program == null)
  1634. {
  1635. return;
  1636. }
  1637. if(!program.SymbolTable.TryGetAddressFromSymbol(symbolName, out uint symbolAddress))
  1638. {
  1639. return;
  1640. }
  1641. program.Heap.SetHeapVariable(symbolAddress, value);
  1642. }
  1643. public object GetProgramVariable(string symbolName)
  1644. {
  1645. if(program == null)
  1646. {
  1647. return null;
  1648. }
  1649. if(!program.SymbolTable.TryGetAddressFromSymbol(symbolName, out uint symbolAddress))
  1650. {
  1651. return null;
  1652. }
  1653. return program.Heap.GetHeapVariable(symbolAddress);
  1654. }
  1655. #endregion
  1656. #endregion
  1657. #region Logging Methods
  1658. private void SetupLogging()
  1659. {
  1660. _debugLevel = GetType().GetHashCode();
  1661. if(VRC.Core.Logger.DebugLevelIsDescribed(_debugLevel))
  1662. {
  1663. return;
  1664. }
  1665. VRC.Core.Logger.DescribeDebugLevel(_debugLevel, "UdonBehaviour");
  1666. VRC.Core.Logger.AddDebugLevel(_debugLevel);
  1667. }
  1668. #endregion
  1669. #region Manual Initialization Methods
  1670. public void AssignProgramAndVariables(VRC.Udon.AbstractSerializedUdonProgramAsset compiledAsset, IUdonVariableTable variables)
  1671. {
  1672. serializedProgramAsset = compiledAsset;
  1673. publicVariables = variables;
  1674. }
  1675. #endregion
  1676. }
  1677. }