Easing into C# from Python

View in #engine_unity on Slack

morrisolmsted @morrisolmsted: Got a new script I need to develop that looks at assets in a project and produce an asset list with the ability to show dependancy as well as not used textures, materials, and meshes. I know this is big but is there any good place to start to look at assets in the scenes to get me started?

Chloe_Sun @Chloe_Sun: @Chloe_Sun has joined the channel

dhruv @dhruv: https://blog.unity.com/games/introducing-unitys-latest-sample-game-gigaya

Unity Blog: Introducing Unity’s latest sample game, Gigaya | Unity Blog

Mathew_Varkki @Mathew_Varkki: @Mathew_Varkki has joined the channel

bob.w @bob.w: Probably the curve editor just ups the local sampling rate. Glad it’s not killing your builds

Jarien_Skywall @Jarien_Skywall: Hm someone replied on the thread I posted on Unity forums and said Unity is able to compress animation but only if it’s in FBX file format. So it seems duplicating the animation from the FBX to create a new asset keeps it exactly as it is (compressed), but once you edit anything in that file, it gets re-saved, as a new format, thus uncompressed. But yeah at least it doesn’t hit the asset bundles. Still obnoxious to have giant files in source control.

bob.w @bob.w: Yeah, I don’t know if they’ve got a “Request for Enhancement” system, but that might be a good candidate

Oliver_Abate @Oliver_Abate: @Oliver_Abate has joined the channel

Jarien_Skywall @Jarien_Skywall: Thanks @bob.w. Yeah I’m pretty sure there’s a way to give user feedback to Unity but I’m using the legacy animation system so I know they’re not going to update it. I’m not sure if the newer animation system works the same way and I don’t have time to look into it because I spent so much time troubleshooting this lol. (Company/project are locked to legacy animation unfortunately, this is beyond my control)

Wyatt_Marvil @Wyatt_Marvil: @Wyatt_Marvil has joined the channel

volantk @volantk: Has this been discussed here? A colleague just linked it to me. Looks like it’s filling some workflow gaps
https://www.jetbrains.com/riderflow/

JetBrains: RiderFlow for Unity: Scenery tool to build and manage your 3D space

Justin_Kovac @Justin_Kovac: @Justin_Kovac has joined the channel

Leslie_Stowe @Leslie_Stowe: @Leslie_Stowe has joined the channel

morrisolmsted @morrisolmsted: given a string array called CSVString
Never mind, stupid syntax error…:rolling_on_the_floor_laughing:
I’m struggling…
string CSVString;
int CSVCount = 0;
string textureData = “A bunch of string data”;
CSVString[CSVCount] = textureData;
I try to run it and I get a message that the last line is “Object Reference not set to an instance of an object”
what does this mean?

archo5 @archo5: CSVString is null :eyes:
seems like probably want a List<string> there instead, just need to create the object before using it, e.g. var CSVString = new List<string>();

gamato @gamato: If you’re not certain of the length of the array prior to populating data, you’ll want to go with what @archo5 mentioned and use List<string>(), otherwise you need to define CSVString via string[] CSVString = new string[intLength]();

passerby @passerby: yeah would use a list for that, or you would need to allocate the array with correct length from the start
for that case i would prolly just use the list and add to it
also if that is literally your code you can also just do a
var csvString = new List<string>{"A bunch of string data"};
or var csvString = new string[]{"A bunch of string data"}; to use a array

morrisolmsted @morrisolmsted: I have to fill the string in a for loop. What I am trying to do is build up a string array with strings that ultimately are comma seperated so I can export to a csv format.

archo5 @archo5: > what does this mean?
as for this question, I’d recommend checking this page: https://docs.microsoft.com/en-us/dotnet/api/system.nullreferenceexception?view=net-6.0

NullReferenceException Class (System)

gamato @gamato: yeah i’d go with List<string> then.

passerby @passerby: yeah if filling from a loop, would use a list and preset its capacity to the length of the loop
that way it only allocates once, but you can see use the csvString.Add syntax

var csvString = new List<string>(data.Count);

foreach (var item in data) {
    csvString.Add(item.data);
}

no clue what your data is, but would do something like that

morrisolmsted @morrisolmsted: Thank you guys.
What if I do not know the capacity of the length of the loop? Can you not make a string array without knowing the length and just adding to it as your crunching data?
I am more familiar with Python, so please excuse my questions.

gamato @gamato: Arrays need to be pre allocated in memory by its size
if you need to resize the array, its pretty expensive (you end up creating a new array)

passerby @passerby: you leave capacity blank then
Lists expand as needed
providing capacity is just a optimization that is not required

archo5 @archo5: > if you need to resize the array, its pretty expensive (you end up creating a new array)
to be fair, the list does the same internally, that’s the entire point of specifying capacity in advance

gamato @gamato: true.
I think it also depends on how often you plan on accessing the list/array

passerby @passerby: yeah everyime a list capacity is expand, it re allocates a new backing array of double the old capacity
and coppies the the data to it
var csvString = new List<string>();
works just fine, just means behind the scenes it might reallocate a few times
but 99% chance that will not matter for your usecase

gamato @gamato: is this something happening at runtime or only in editor?

passerby @passerby: if its edit time i really would not care too much

gamato @gamato: Yeah that’s my thought

passerby @passerby: also C# can allocate and copy thigns pretty fast, the main downside to repeated allocations is hitting the GC harder
the main downside of that is some frame stutter which does not matter at edit time

dhruv @dhruv: If it’s at runtime, you’re also going to deal with cache line misses etc…
But I’m assuming in this case it won’t matter much.

archo5 @archo5: > does not matter at edit time
assuming the dataset is not in the millions (which it probably isn’t)

dhruv @dhruv: > opens terabyte CSV file

passerby @passerby: yeah the capacity thing is prolly fine, its just one of those things where i just go ahead and do it if i already have the data to do so

gamato @gamato: at that point i’d recommend EditorCoroutines :wink:

passerby @passerby: no downside to doing so

dhruv @dhruv: Also if you did have a really large CSV, it really should be accessed as a rolling buffer. But again I doubt it’s the case here

passerby @passerby: well really easy in the case of CSV or binary files to do that
but think we all are just adding complexity to what is a simple case for someone new to a engine and a langauge

morrisolmsted @morrisolmsted: its just an editor tool
Var is only allowed locally, what would I use for a global string array?

gamato @gamato: var when compiled determines the type
you can either Explicitly type the variable as string[] or Implicitly via var

passerby @passerby: yeah var can only be used in methods
if on a field you would just use List<string>
or string[]
if you used a array instead of a list
by global i assume you mean having it as a instance member or static

morrisolmsted @morrisolmsted: Global as in, my script has many procedures and functions and I want to be able to access it.

passerby @passerby: oh was making the point that C# does not have loose functions so everything has to live in a class or struct or be static

theodox @theodox: Couple of rules of thumb for Python person moving to C#:

  1. Essentially classes do double duty in C# – classes act like classes… but many things you’d do in a python module (ex: collections of static functions that don’t need to be part of a class instance) in C# are collected into classes.
  2. C# also has namespaces, but they are mostly helpful for organization – they aren’t “real” like classes. So no variables or functions just lying around in a namespace they way they might be in a python module.
  3. You almost always want to use the type-specific (confusingly, from system.collections.generic versions of containers (the angle brackets). There are ways to not do that but they are usually bad ideas. Which means you have to get used to picking types ahead of time.
  4. var means “variable of a type I’m not explicitly telling you”. the type of the var comes from the first value you assign to it – which is why var’s can only exist in a scope where they are explicitly assigned on declaration (ie var x = 1.0f but not just var x) ; If you need to declare a variable but aren’t ready to give it a value, you’ll need to declare it explicitly (float x;) You can kind of think of var the way you do a python variable – except that the var can never become something other than the kind of thing it’s initialized to. It’s still a statically typed thing.
  5. With that in mind, a C# List<type> is a Python list – it’s dynamic, it grows, you can iterate it, etc. append() becomes Add() but it’s basically the same. OTOH a C# array is a different beast, similar to the less-used python array.array Array’s are great for fixed-sized storage – if you know the size of your data in advance use an Array because they are faster, but if you don’t, use a List<>.
  6. C# tends to use interfaces where Python would use multiple inheritance or just try calling a method to see if it’s there. This helps make writing those <> things a bit less bad,
  7. Because of all the types, iteration is a bit different. You can do old-fashioned for (int i = 0; i < number ; i++) style loops or use a more python-like foreach (var thing in somecontainer) on anything that’s an IEnumerable – the interface which means “you can keep calling me for values” . Pretty much all collections will be IEnumerable . If they have explicit adds, removes, and clears they are ICollection ; if they support indexes they are IList. Here’s an intro to the relationship . If something is an IList you can get at items with squarebrackets: somecontainer[10]
  8. Unfortunately C#'s ability to jump around inside containers is not as nice as python. A lot of people use linq for managing collection data (finding, sorting, subsetting etc) – it’s powerful but wordy. You’ll miss mylist[-10:-5]
  9. Nowadays C# supports simple tuples , set up with parentheses – var test = (1,2) will give you a tuple containing two ints. You don’t get to use square brackets, though: to get the second item it’s test.Item2. You can also make fancier tuples explicity: (float, string) fred = (2.5f, "X")

interface - C# Reference

Claudio Bernasconi: When To Use IEnumerable, ICollection, IList And List - Claudio Bernasconi

passerby @passerby:

public static IEnumerable<(int Index, T Item)> Enumerate<T>(this IEnumerable<T> enumerable) {
    return enumerable.Select((x, i) => (Index: i, Item: x));
}

felt the need to create that along the way as well

morrisolmsted @morrisolmsted: Man, thank you everyone who has been so kindly trying to help me out. I love that everyone is so willing to help each other out here. Much thanks and appreciation to you all.

2 Likes