@needle-tools/needle-component-compiler 1.7.1 → 1.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/Changelog.md CHANGED
@@ -4,6 +4,18 @@ All notable changes to this package will be documented in this file.
4
4
  The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
5
5
  and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
6
6
 
7
+ ## [1.8.0] - 2022-09-02
8
+ - Add ``@nonSerialized`` decorator for fields and methods
9
+ - Fix comment gen for unknown types
10
+
11
+ ## [1.7.3] - 2022-09-02
12
+ - Fix codegen for unknown array types
13
+ - Fix codegen for abstract classes
14
+ - Fix codegen for types imported as e.g. THREE.AnimationClip
15
+
16
+ ## [1.7.2] - 2022-07-27
17
+ - fix UnityEvent codegen
18
+
7
19
  ## [1.7.1] - 2022-07-25
8
20
  - fix array type codegen, for example ``scenes: Array<AssetReference> = [];``, see issue https://github.com/needle-tools/needle-tiny-playground/issues/285
9
21
 
package/PUBLISH.bat ADDED
@@ -0,0 +1,8 @@
1
+ @echo off
2
+ echo Press a key to publish! (close the window if you changed your mind)
3
+ pause
4
+ echo Publishing in 2 sec
5
+ timeout 2
6
+ npm set registry https://registry.npmjs.org && npm publish
7
+ echo Finished...
8
+ timeout 10
package/Readme.md CHANGED
@@ -10,6 +10,7 @@ Please run ``npm install`` first before using.
10
10
  ### Command decorators
11
11
  - ``@dont-generate-component`` add before class to skip generating a component
12
12
  - ``@generate-component`` to enforce generating a component (not required)
13
- - ``@serializeField`` field decorator, similar to ``[SerializeField]``
13
+ - ``@serializeField`` field decorator, similar to ``[SerializeField]`` in Unity
14
+ - ``@nonSerialized`` field or method decorator to skip generating c# code for a field or a method, similar to ``[NonSerialized]`` in Unity
14
15
  - ``@type MyNamespace.MyType`` decorator for fields or classes, specifiy C# type of field or class
15
16
  - ``@ifdef MY_IFDEF`` field decorator only at the moment
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@needle-tools/needle-component-compiler",
3
- "version": "1.7.1",
3
+ "version": "1.8.0",
4
4
  "description": "Compile mock unity components from typescript",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -16,5 +16,9 @@
16
16
  "name": "Needle",
17
17
  "email": "help@needle.tools",
18
18
  "url": "https://needle.tools/"
19
+ },
20
+ "repository": {
21
+ "type": "git",
22
+ "url": "git+https://github.com/needle-tools/needle-tiny-component-compiler.git"
19
23
  }
20
- }
24
+ }
@@ -12,6 +12,7 @@ var exportNextClassCommand = "@generate-component";
12
12
  var dontExportNextClassCommand = "@dont-generate-component";
13
13
  // add above field to add [SerializeField] attribute
14
14
  var serializeCommand = "@serializeField";
15
+ var dontSerializeCommand = "@nonSerialized";
15
16
  // https://regex101.com/r/ltpcKT/2
16
17
  var typePattern = new RegExp("@type ?(?<type>.+)");
17
18
  var ifdefPattern = new RegExp("@ifdef ?(?<ifdef>.+)");
@@ -21,6 +22,7 @@ var CODEGEN_MARKER_END = "// NEEDLE_CODEGEN_END";
21
22
  var exportNextClass = false;
22
23
  var dontExportNextClass = false;
23
24
  var serializeField = false;
25
+ var dontSerialize = false;
24
26
  function resetExportNextClass() {
25
27
  dontExportNextClass = false;
26
28
  exportNextClass = false;
@@ -146,6 +148,8 @@ function run(program, outputDir, sourceFile) {
146
148
  }
147
149
  else if (comment.includes(serializeCommand))
148
150
  serializeField = true;
151
+ else if (comment.includes(dontSerializeCommand))
152
+ dontSerialize = true;
149
153
  }
150
154
  if (comment.includes(exportNextClassCommand))
151
155
  exportNextClass = true;
@@ -155,10 +159,10 @@ function run(program, outputDir, sourceFile) {
155
159
  if (typeMatch && typeMatch.groups) {
156
160
  // for some reason our regex does also match surrounding ( ) even tho: https://regex101.com/r/PoWK6V/1
157
161
  // so we remove them
158
- var type = typeMatch.groups["type"];
159
- type = type.replace(/\(/, "").replace(/\)/, "");
160
- console.log("Found type: ", type);
161
- lastTypeFound = type;
162
+ var type_1 = typeMatch.groups["type"];
163
+ type_1 = type_1.replace(/\(/, "").replace(/\)/, "");
164
+ console.log("Found type: ", type_1);
165
+ lastTypeFound = type_1;
162
166
  }
163
167
  var ifdefMatch = ifdefPattern.exec(comment);
164
168
  if (ifdefMatch && ifdefMatch.groups) {
@@ -168,6 +172,7 @@ function run(program, outputDir, sourceFile) {
168
172
  }
169
173
  }
170
174
  }
175
+ var skip = dontSerialize;
171
176
  switch (node.kind) {
172
177
  // Namespace
173
178
  // case ts.SyntaxKind.ModuleDeclaration:
@@ -187,13 +192,14 @@ function run(program, outputDir, sourceFile) {
187
192
  case ts.SyntaxKind.MethodDeclaration:
188
193
  lastTypeFound = null;
189
194
  serializeField = false;
195
+ dontSerialize = false;
190
196
  resetExportNextClass();
191
197
  if (!context)
192
198
  break;
193
199
  // TODO: always emit at least OnEnable method per class so generated components have toggle in editor
194
200
  var meth = node;
195
201
  // const isCoroutine = func.asteriskToken;
196
- if (meth.name) {
202
+ if (!skip && meth.name) {
197
203
  var paramsStr = "";
198
204
  for (var _g = 0, _h = meth.parameters; _g < _h.length; _g++) {
199
205
  var param = _h[_g];
@@ -201,10 +207,10 @@ function run(program, outputDir, sourceFile) {
201
207
  continue;
202
208
  if (paramsStr.length > 0)
203
209
  paramsStr += ", ";
204
- var type = tryResolveTypeRecursive(param);
205
- if (type === undefined)
206
- type = "object";
207
- paramsStr += type + " @" + param.name.getText();
210
+ var type_2 = tryResolveTypeRecursive(param);
211
+ if (type_2 === undefined)
212
+ type_2 = "object";
213
+ paramsStr += type_2 + " @" + param.name.getText();
208
214
  }
209
215
  var methodName = meth.name.getText();
210
216
  context.onBeforeMethod(methodName);
@@ -222,11 +228,14 @@ function run(program, outputDir, sourceFile) {
222
228
  var pub = isPublic(vardec);
223
229
  var visibility = pub ? "public" : "private";
224
230
  var isAccessible = pub;
225
- if (!pub && serializeField) {
231
+ dontSerialize = false;
232
+ if (serializeField) {
226
233
  console.log("[SerializeField]");
227
234
  context.appendLine("[UnityEngine.SerializeField]");
228
235
  isAccessible = true;
229
236
  }
237
+ else if (skip)
238
+ isAccessible = false;
230
239
  if (!isAccessible) {
231
240
  console.log("Skip because not public or serializeable");
232
241
  break;
@@ -238,10 +247,10 @@ function run(program, outputDir, sourceFile) {
238
247
  var typeString = lastTypeFound !== null && lastTypeFound !== void 0 ? lastTypeFound : tryResolveTypeRecursive(node);
239
248
  var postFix = "";
240
249
  var typeName = (_c = vardec.type) === null || _c === void 0 ? void 0 : _c.getText();
250
+ var shouldCommentTheLine = typeString === undefined;
241
251
  if (typeString === undefined) {
242
252
  postFix = " → Could not resolve C# type";
243
253
  }
244
- var prefix = typeString === undefined ? "// " : "";
245
254
  var assignment = "";
246
255
  if (typeString !== undefined) {
247
256
  for (var _j = 0, _k = node.getChildren(); _j < _k.length; _j++) {
@@ -284,7 +293,14 @@ function run(program, outputDir, sourceFile) {
284
293
  }
285
294
  if (typeString === undefined)
286
295
  typeString = typeName;
287
- console.log("EMIT member: " + typeString + " " + varName);
296
+ if (typeString === "[]") {
297
+ console.log("Unknown array type for \"" + varName + " " + typeName + "\" - your type is probably not known (did you just create it this session?) and you might need to regenerate the Typemap in Unity. Go to \"Needle Engine/Internal/Generate Type Map for component compiler");
298
+ // typeString = "object[]";
299
+ // assignment = " = new object[0]";
300
+ shouldCommentTheLine = true;
301
+ }
302
+ console.log("EMIT member: \"" + typeString + "\" " + varName, assignment, "Last type found:", lastTypeFound);
303
+ var prefix = shouldCommentTheLine ? "// " : "";
288
304
  context.append(prefix + visibility + " " + typeString + " " + varName + assignment + ";" + postFix + "\n");
289
305
  lastTypeFound = null;
290
306
  if (requireEndIf) {
@@ -317,7 +333,20 @@ function run(program, outputDir, sourceFile) {
317
333
  if (lastTypeFound)
318
334
  typeName_1 = lastTypeFound;
319
335
  console.log(name_2 + " inherits " + typeName_1);
320
- newContext.appendLine("public partial class " + name_2 + " : " + typeName_1);
336
+ var modifiers = "";
337
+ if (dec.modifiers) {
338
+ for (var _l = 0, _m = dec.modifiers; _l < _m.length; _l++) {
339
+ var mod = _m[_l];
340
+ switch (mod.getText()) {
341
+ case "abstract":
342
+ modifiers += " abstract";
343
+ console.log(name_2 + " is abstract");
344
+ break;
345
+ }
346
+ }
347
+ }
348
+ modifiers += " partial";
349
+ newContext.appendLine("public " + modifiers.trim() + " class " + name_2 + " : " + typeName_1);
321
350
  newContext.appendLine("{");
322
351
  newContext.indentLevel += 1;
323
352
  newContext.classEnd = dec.end;
@@ -339,10 +368,10 @@ function run(program, outputDir, sourceFile) {
339
368
  if (h.types.length <= 0)
340
369
  continue;
341
370
  for (var _b = 0, _c = h.types; _b < _c.length; _b++) {
342
- var type = _c[_b];
371
+ var type_3 = _c[_b];
343
372
  // const symbol = program.getTypeChecker().getSymbolAtLocation(type.expression);
344
373
  // console.log(symbol);
345
- var text = type.expression.getText();
374
+ var text = type_3.expression.getText();
346
375
  if (text === "Component")
347
376
  return true;
348
377
  if (text === "Behaviour")
@@ -363,28 +392,31 @@ function run(program, outputDir, sourceFile) {
363
392
  case ts.SyntaxKind.FirstLiteralToken:
364
393
  return node.getText();
365
394
  case ts.SyntaxKind.NewExpression:
366
- var type = undefined;
395
+ var type_4 = undefined;
367
396
  var args = undefined;
368
397
  for (var _i = 0, _a = node.getChildren(); _i < _a.length; _i++) {
369
398
  var ch = _a[_i];
370
- // console.log("child", ts.SyntaxKind[ch.kind]);
399
+ var text = ch.getText();
400
+ // console.log("child", ts.SyntaxKind[ch.kind], text);
371
401
  switch (ch.kind) {
402
+ case ts.SyntaxKind.Identifier:
372
403
  case ts.SyntaxKind.PropertyAccessExpression:
373
- type = tryGetTypeFromText(ch.getText());
404
+ type_4 = tryGetTypeFromText(text);
374
405
  break;
375
406
  case ts.SyntaxKind.SyntaxList:
376
- args = ch.getText();
407
+ args = text;
377
408
  break;
378
409
  }
379
410
  }
380
411
  if (!args)
381
412
  args = "";
382
- if (type)
383
- return "new " + type + "(" + args + ")";
413
+ if (type_4)
414
+ return "new " + type_4 + "(" + args + ")";
384
415
  // const expType = node.getChildren().find(c => c.kind === ts.SyntaxKind.Identifier);
385
416
  break;
386
417
  }
387
418
  var str = node.getText();
419
+ console.log("Unknown assignment:", str, ts.SyntaxKind[node.kind]);
388
420
  return str;
389
421
  }
390
422
  function isPublic(node) {
@@ -427,6 +459,14 @@ function run(program, outputDir, sourceFile) {
427
459
  return namespace;
428
460
  }
429
461
  function tryGetTypeFromText(typeName) {
462
+ // if a type is imported via some namespace e.g. THREE.AnimationClip
463
+ // we want to remove that namespace / import name
464
+ var separatorIndex = typeName.lastIndexOf(".");
465
+ if (separatorIndex > 0) {
466
+ var newName = typeName.substring(separatorIndex + 1);
467
+ console.log("Remove import name from type: \"" + typeName + "\" → \"" + newName + "\"");
468
+ typeName = newName;
469
+ }
430
470
  var res = dict[typeName];
431
471
  if (res === undefined) {
432
472
  switch (typeName) {
@@ -438,6 +478,7 @@ function run(program, outputDir, sourceFile) {
438
478
  break;
439
479
  }
440
480
  }
481
+ // console.log(typeName, res);
441
482
  return res;
442
483
  }
443
484
  function tryResolveTypeRecursive(node) {
@@ -4,6 +4,7 @@ import * as fs from "fs";
4
4
  import * as path from 'path';
5
5
 
6
6
  import * as types from "./types";
7
+ import { type } from "os";
7
8
  const dict = types.dict;
8
9
 
9
10
  // add either of these two comments above a class to enforce code gen or disable it for the next class
@@ -11,6 +12,7 @@ const exportNextClassCommand = "@generate-component";
11
12
  const dontExportNextClassCommand = "@dont-generate-component";
12
13
  // add above field to add [SerializeField] attribute
13
14
  const serializeCommand = "@serializeField";
15
+ const dontSerializeCommand = "@nonSerialized";
14
16
  // https://regex101.com/r/ltpcKT/2
15
17
  const typePattern = new RegExp("@type ?(?<type>.+)");
16
18
  const ifdefPattern = new RegExp("@ifdef ?(?<ifdef>.+)")
@@ -22,6 +24,7 @@ const CODEGEN_MARKER_END = "// NEEDLE_CODEGEN_END";
22
24
  let exportNextClass: boolean = false;
23
25
  let dontExportNextClass: boolean = false;
24
26
  let serializeField: boolean = false;
27
+ let dontSerialize: boolean = false;
25
28
  function resetExportNextClass() {
26
29
  dontExportNextClass = false;
27
30
  exportNextClass = false;
@@ -170,6 +173,8 @@ export function run(program: ts.Program, outputDir: string, sourceFile: ts.Sourc
170
173
  }
171
174
  else if (comment.includes(serializeCommand))
172
175
  serializeField = true;
176
+ else if (comment.includes(dontSerializeCommand))
177
+ dontSerialize = true;
173
178
  }
174
179
  if (comment.includes(exportNextClassCommand))
175
180
  exportNextClass = true;
@@ -194,6 +199,7 @@ export function run(program: ts.Program, outputDir: string, sourceFile: ts.Sourc
194
199
  }
195
200
  }
196
201
 
202
+ const skip = dontSerialize;
197
203
  switch (node.kind) {
198
204
  // Namespace
199
205
  // case ts.SyntaxKind.ModuleDeclaration:
@@ -213,12 +219,13 @@ export function run(program: ts.Program, outputDir: string, sourceFile: ts.Sourc
213
219
  case ts.SyntaxKind.MethodDeclaration:
214
220
  lastTypeFound = null;
215
221
  serializeField = false;
222
+ dontSerialize = false;
216
223
  resetExportNextClass();
217
224
  if (!context) break;
218
225
  // TODO: always emit at least OnEnable method per class so generated components have toggle in editor
219
226
  const meth = node as ts.MethodDeclaration;
220
227
  // const isCoroutine = func.asteriskToken;
221
- if (meth.name) {
228
+ if (!skip && meth.name) {
222
229
  let paramsStr = "";
223
230
  for (let param of meth.parameters) {
224
231
  if (!param || !param.name) continue;
@@ -245,11 +252,15 @@ export function run(program: ts.Program, outputDir: string, sourceFile: ts.Sourc
245
252
  const pub = isPublic(vardec);
246
253
  const visibility = pub ? "public" : "private";
247
254
  let isAccessible = pub;
248
- if (!pub && serializeField) {
255
+ dontSerialize = false;
256
+ if (serializeField) {
249
257
  console.log("[SerializeField]");
250
258
  context.appendLine("[UnityEngine.SerializeField]");
251
259
  isAccessible = true;
252
260
  }
261
+ else if(skip)
262
+ isAccessible = false;
263
+
253
264
  if (!isAccessible) {
254
265
  console.log("Skip because not public or serializeable")
255
266
  break;
@@ -261,10 +272,10 @@ export function run(program: ts.Program, outputDir: string, sourceFile: ts.Sourc
261
272
  let typeString = lastTypeFound ?? tryResolveTypeRecursive(node);
262
273
  let postFix = "";
263
274
  let typeName = vardec.type?.getText();
275
+ let shouldCommentTheLine = typeString === undefined;
264
276
  if (typeString === undefined) {
265
277
  postFix = " → Could not resolve C# type";
266
278
  }
267
- const prefix = typeString === undefined ? "// " : "";
268
279
  let assignment = "";
269
280
  if (typeString !== undefined) {
270
281
  for (const ch of node.getChildren()) {
@@ -305,7 +316,14 @@ export function run(program: ts.Program, outputDir: string, sourceFile: ts.Sourc
305
316
  context.appendLine("#ifdef " + ifdefSections.pop());
306
317
  }
307
318
  if (typeString === undefined) typeString = typeName;
308
- console.log("EMIT member: " + typeString + " " + varName)
319
+ if (typeString === "[]") {
320
+ console.log("Unknown array type for \"" + varName + " " + typeName + "\" - your type is probably not known (did you just create it this session?) and you might need to regenerate the Typemap in Unity. Go to \"Needle Engine/Internal/Generate Type Map for component compiler")
321
+ // typeString = "object[]";
322
+ // assignment = " = new object[0]";
323
+ shouldCommentTheLine = true;
324
+ }
325
+ console.log("EMIT member: \"" + typeString + "\" " + varName, assignment, "Last type found:", lastTypeFound);
326
+ const prefix = shouldCommentTheLine ? "// " : "";
309
327
  context.append(prefix + visibility + " " + typeString + " " + varName + assignment + ";" + postFix + "\n");
310
328
  lastTypeFound = null;
311
329
  if (requireEndIf) {
@@ -337,7 +355,19 @@ export function run(program: ts.Program, outputDir: string, sourceFile: ts.Sourc
337
355
  if (typeof inheritsComponent === "string") typeName = inheritsComponent;
338
356
  if (lastTypeFound) typeName = lastTypeFound;
339
357
  console.log(name + " inherits " + typeName);
340
- newContext.appendLine("public partial class " + name + " : " + typeName);
358
+ let modifiers = "";
359
+ if (dec.modifiers) {
360
+ for (const mod of dec.modifiers) {
361
+ switch (mod.getText()) {
362
+ case "abstract":
363
+ modifiers += " abstract";
364
+ console.log(name + " is abstract");
365
+ break;
366
+ }
367
+ }
368
+ }
369
+ modifiers += " partial";
370
+ newContext.appendLine("public " + modifiers.trim() + " class " + name + " : " + typeName);
341
371
  newContext.appendLine("{");
342
372
  newContext.indentLevel += 1;
343
373
  newContext.classEnd = dec.end;
@@ -382,13 +412,15 @@ export function run(program: ts.Program, outputDir: string, sourceFile: ts.Sourc
382
412
  let type: string | undefined = undefined;
383
413
  let args: string | undefined = undefined;
384
414
  for (const ch of node.getChildren()) {
385
- // console.log("child", ts.SyntaxKind[ch.kind]);
415
+ const text = ch.getText();
416
+ // console.log("child", ts.SyntaxKind[ch.kind], text);
386
417
  switch (ch.kind) {
418
+ case ts.SyntaxKind.Identifier:
387
419
  case ts.SyntaxKind.PropertyAccessExpression:
388
- type = tryGetTypeFromText(ch.getText());
420
+ type = tryGetTypeFromText(text);
389
421
  break;
390
422
  case ts.SyntaxKind.SyntaxList:
391
- args = ch.getText();
423
+ args = text;
392
424
  break;
393
425
  }
394
426
  }
@@ -399,6 +431,7 @@ export function run(program: ts.Program, outputDir: string, sourceFile: ts.Sourc
399
431
  break;
400
432
  }
401
433
  const str = node.getText();
434
+ console.log("Unknown assignment:", str, ts.SyntaxKind[node.kind]);
402
435
  return str;
403
436
  }
404
437
 
@@ -441,6 +474,16 @@ export function run(program: ts.Program, outputDir: string, sourceFile: ts.Sourc
441
474
  }
442
475
 
443
476
  function tryGetTypeFromText(typeName: string) {
477
+
478
+ // if a type is imported via some namespace e.g. THREE.AnimationClip
479
+ // we want to remove that namespace / import name
480
+ const separatorIndex = typeName.lastIndexOf(".");
481
+ if (separatorIndex > 0) {
482
+ let newName = typeName.substring(separatorIndex + 1);
483
+ console.log("Remove import name from type: \"" + typeName + "\" → \"" + newName + "\"");
484
+ typeName = newName;
485
+ }
486
+
444
487
  let res = dict[typeName];
445
488
  if (res === undefined) {
446
489
  switch (typeName) {
@@ -452,6 +495,7 @@ export function run(program: ts.Program, outputDir: string, sourceFile: ts.Sourc
452
495
  break;
453
496
  }
454
497
  }
498
+ // console.log(typeName, res);
455
499
  return res;
456
500
  }
457
501
 
package/src/test.ts CHANGED
@@ -1,27 +1,67 @@
1
1
  import { ThisExpression } from "typescript";
2
2
 
3
- export class SocLoader extends Behaviour {
3
+
4
+ export class SkipFieldAndMethod extends Behaviour {
4
5
 
5
- @serializeable(AssetReference)
6
- scenes: Array<AssetReference> = [];
6
+ //@nonSerialized
7
+ myMethod() {
8
+
9
+ }
10
+
11
+ // @nonSerialized
12
+ myField : string;
13
+
7
14
  }
8
- // class Test123 {}
9
-
10
- export class Bla extends Behaviour
11
- {
12
- myNumber:number = 42;
13
- myBool:boolean = true;
14
- myString:string = "test";
15
- numberArr: number[] = [1,2,3];
16
- myColor : THREE.Color = new THREE.Color(255, 0, 0);
17
- renderers = new Array<Renderer>();
18
- renderers2 : Renderer[] = [];
19
- objArr : object[];
20
- colArr: THREE.Color[] = [new THREE.Color(1,2,3)];
21
- map : Map<string> = new Map<string>();
22
- map2 : Map<object> = new Map<object>();
23
- private myThing : Test123;
24
- }
15
+
16
+
17
+ // export class ComponentWithUnknownType extends Behaviour {
18
+ // views: SomeUnknownType;
19
+ // }
20
+
21
+
22
+ // export class ComponentWithAnimationClip extends Behaviour implements IPointerClickHandler {
23
+
24
+ // @serializeable(AnimationClip)
25
+ // animation?: THREE.AnimationClip;
26
+ // }
27
+
28
+ // export abstract class MyAbstractComponent extends Behaviour {
29
+ // abstract myMethod();
30
+ // }
31
+
32
+
33
+ // export class CameraView extends Behaviour {
34
+ // static views: CameraView[] = [];
35
+ // }
36
+
37
+
38
+ // export class EventComponent extends Behaviour {
39
+ // @serializeable(EventList)
40
+ // roomChanged: EventList = new EventList();
41
+ // }
42
+
43
+ // export class SocLoader extends Behaviour {
44
+
45
+ // @serializeable(AssetReference)
46
+ // scenes: Array<AssetReference> = [];
47
+ // }
48
+ // // class Test123 {}
49
+
50
+ // export class Bla extends Behaviour
51
+ // {
52
+ // myNumber:number = 42;
53
+ // myBool:boolean = true;
54
+ // myString:string = "test";
55
+ // numberArr: number[] = [1,2,3];
56
+ // myColor : THREE.Color = new THREE.Color(255, 0, 0);
57
+ // renderers = new Array<Renderer>();
58
+ // renderers2 : Renderer[] = [];
59
+ // objArr : object[];
60
+ // colArr: THREE.Color[] = [new THREE.Color(1,2,3)];
61
+ // map : Map<string> = new Map<string>();
62
+ // map2 : Map<object> = new Map<object>();
63
+ // private myThing : Test123;
64
+ // }
25
65
 
26
66
  // //@type UnityEngine.MonoBehaviour
27
67
  // export class ButtonObject extends Interactable implements IPointerClickHandler, ISerializable {